# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1339615239 0 # Node ID 76b24619f6fa5dff42cc837998bc954f994bb167 # Parent 7dd1659c26932d74ccf8bdcc195950b33bb37b92 Experimental OS/2 code adding utf8 input conversion... Also added optional utf8 parameter to key press callback. Need to figure out how to load the correct keyboard layout. diff -r 7dd1659c2693 -r 76b24619f6fa dwtest.c --- a/dwtest.c Mon Jun 04 22:44:51 2012 +0000 +++ b/dwtest.c Wed Jun 13 19:20:39 2012 +0000 @@ -531,13 +531,13 @@ return TRUE; } -int DWSIGNAL keypress_callback(HWND window, char ch, int vk, int state, void *data) +int DWSIGNAL keypress_callback(HWND window, char ch, int vk, int state, void *data, char *utf8) { char tmpbuf[100]; if ( ch ) - sprintf( tmpbuf, "Key: %c(%d) Modifiers: %s(%d)", ch, ch, resolve_keymodifiers(state), state ); + sprintf( tmpbuf, "Key: %c(%d) Modifiers: %s(%d) utf8 %s", ch, ch, resolve_keymodifiers(state), state, utf8 ); else - sprintf( tmpbuf, "Key: %s(%d) Modifiers: %s(%d)", resolve_keyname(vk), vk, resolve_keymodifiers(state), state ); + sprintf( tmpbuf, "Key: %s(%d) Modifiers: %s(%d) utf8 %s", resolve_keyname(vk), vk, resolve_keymodifiers(state), state, utf8 ); dw_window_set_text( status1, tmpbuf); return 0; } diff -r 7dd1659c2693 -r 76b24619f6fa makefile.vac --- a/makefile.vac Mon Jun 04 22:44:51 2012 +0000 +++ b/makefile.vac Wed Jun 13 19:20:39 2012 +0000 @@ -21,6 +21,9 @@ .\dw.obj so32dll.lib tcp32dll.lib + libuls.lib + libconv.lib + unikbd.lib << IMPLIB DW.LIB OS2\DW.DEF copy dw.lib lib\dw.lib diff -r 7dd1659c2693 -r 76b24619f6fa os2/dw.c --- a/os2/dw.c Mon Jun 04 22:44:51 2012 +0000 +++ b/os2/dw.c Wed Jun 13 19:20:39 2012 +0000 @@ -38,6 +38,10 @@ #include #endif #include +#ifdef UNICODE +#include +#include +#endif #include "dw.h" #define QWP_USER 0 @@ -120,6 +124,12 @@ HMOD wpconfig = 0, pmprintf = 0, pmmerge = 0, gbm = 0; static char _dw_exec_dir[MAX_PATH+1] = {0}; +#ifdef UNICODE +/* Atom for "text/unicode" clipboard format */ +ATOM Unicode; +KHAND Keyboard; +#endif + unsigned long _colors[] = { CLR_BLACK, CLR_DARKRED, @@ -2774,6 +2784,50 @@ return NULLHANDLE; } +#ifdef UNICODE +#define MAX_CP_NAME 12 /* maximum length of a codepage name */ +#define MAX_CP_SPEC 64 /* maximum length of a UconvObject codepage specifier */ + +char *_WideToUTF8(UniChar *unistr) +{ + UconvObject uconv; /* conversion object */ + UniChar suCodepage[MAX_CP_SPEC]; /* conversion specifier */ + /* Convert text to the active codepage */ + ULONG ulRC; + char *retval = NULL; + + /* Create the conversion object */ + UniMapCpToUcsCp(1208, suCodepage, MAX_CP_NAME); + UniStrcat(suCodepage, (UniChar *) L"@map=cdra,path=no"); + + if((ulRC = UniCreateUconvObject(suCodepage, &uconv)) == ULS_SUCCESS) + { + /* Now do the conversion */ + ULONG ulBufLen = (UniStrlen(unistr) * 4) + 1; + char *s, *pszLocalText = (char *)malloc(ulBufLen); + + if((ulRC = UniStrFromUcs(uconv, pszLocalText, + unistr, ulBufLen )) == ULS_SUCCESS) + { + /* (some codepages use 0x1A for substitutions; replace with ?) */ + while((s = strchr(pszLocalText, 0x1A)) != NULL) *s = '?'; + /* Output the converted text */ + retval = pszLocalText; + } +#ifdef DEBUG + else + dw_debug("Error pasting Unicode text:\nUniStrFromUcs() = %08X", ulRC); +#endif + UniFreeUconvObject(uconv); + } +#ifdef DEBUG + else + dw_debug("Error pasting Unicode text:\nUniCreateUconvObject() = %08X", ulRC); +#endif + return retval; +} +#endif + MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { int result = -1; @@ -2908,15 +2962,24 @@ break; case WM_CHAR: { - int (API_FUNC keypressfunc)(HWND, char, int, int, void *) = (int (API_FUNC)(HWND, char, int, int, void *))tmp->signalfunction; + int (API_FUNC keypressfunc)(HWND, char, int, int, void *, char *) = (int (API_FUNC)(HWND, char, int, int, void *, char *))tmp->signalfunction; if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP)) { int vk; - char ch = 0; + char ch[2] = {0}; + char *utf8 = NULL; +#ifdef UNICODE + UniChar uc[2] = {0}; + VDKEY vdk; + BYTE bscan; + + UniTranslateKey(Keyboard, 0, CHAR4FROMMP(mp1), uc, &vdk, &bscan); + utf8 = _WideToUTF8(uc); +#endif if(SHORT1FROMMP(mp1) & KC_CHAR) - ch = (char)SHORT1FROMMP(mp2); + ch[0] = (char)SHORT1FROMMP(mp2); if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY) vk = SHORT2FROMMP(mp2); else @@ -2925,15 +2988,18 @@ /* This is a hack to fix shift presses showing * up as tabs! */ - if(ch == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR)) + if(ch[0] == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR)) { - ch = 0; + ch[0] = 0; vk = VK_SHIFT; } - result = keypressfunc(tmp->window, ch, vk, - SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data); + result = keypressfunc(tmp->window, ch[0], vk, + SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data, utf8 ? utf8 : ch); tmp = NULL; + + if(utf8) + free(utf8); } } break; @@ -2999,14 +3065,14 @@ { int svar = SLN_SLIDERTRACK; int id = SHORT1FROMMP(mp1); - HWND notifyhwnd = dw_window_from_id(hWnd, id); - - if(origmsg == WM_CONTROL) - { - svar = SHORT2FROMMP(mp1); - if(!notifyhwnd && WinIsWindow(dwhab, (HWND)mp2)) + HWND notifyhwnd = dw_window_from_id(hWnd, id); + + if(origmsg == WM_CONTROL) + { + svar = SHORT2FROMMP(mp1); + if(!notifyhwnd && WinIsWindow(dwhab, (HWND)mp2)) notifyhwnd = (HWND)mp2; - } + } switch(svar) { @@ -3379,8 +3445,8 @@ if(!dw_window_get_data((HWND)mp2, "_dw_updating")) WinPostMsg(hWnd, WM_USER, mp1, mp2); } - else - _run_event(hWnd, msg, mp1, mp2); + else + _run_event(hWnd, msg, mp1, mp2); } break; } @@ -4171,6 +4237,10 @@ dwhab = WinInitialize(0); dwhmq = WinCreateMsgQueue(dwhab, 0); #ifdef UNICODE + /* Create the Unicode atom for copy and paste */ + Unicode = WinAddAtom(WinQuerySystemAtomTable(), (PSZ)"text/unicode"); + /* TODO: Need to figure out how to determine the correct keyboard here */ + UniCreateKeyboard(&Keyboard, (UniChar *) L"de", 0); /* Set the codepage to 1208 (UTF-8) */ WinSetCp(dwhmq, 1208); #endif @@ -11347,6 +11417,11 @@ if(_gbm_deinit) _gbm_deinit(); +#ifdef UNICODE + /* Deregister the Unicode clipboard format */ + WinDeleteAtom(WinQuerySystemAtomTable(), Unicode); +#endif + /* Destroy the main message queue and anchor block */ WinDestroyMsgQueue(dwhmq); WinTerminate(dwhab);