comparison os2/dw.c @ 1746:76b24619f6fa

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.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 13 Jun 2012 19:20:39 +0000
parents 7dd1659c2693
children 96c6133ce3b2
comparison
equal deleted inserted replaced
1745:7dd1659c2693 1746:76b24619f6fa
36 #include <sys/stat.h> 36 #include <sys/stat.h>
37 #ifdef __WATCOMC__ 37 #ifdef __WATCOMC__
38 #include <alloca.h> 38 #include <alloca.h>
39 #endif 39 #endif
40 #include <fcntl.h> 40 #include <fcntl.h>
41 #ifdef UNICODE
42 #include <uconv.h>
43 #include <unikbd.h>
44 #endif
41 #include "dw.h" 45 #include "dw.h"
42 46
43 #define QWP_USER 0 47 #define QWP_USER 0
44 48
45 /* The toolkit headers don't seem to have this */ 49 /* The toolkit headers don't seem to have this */
117 PRECORDCORE pCoreEmph = NULL; 121 PRECORDCORE pCoreEmph = NULL;
118 ULONG aulBuffer[4]; 122 ULONG aulBuffer[4];
119 HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop; 123 HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop;
120 HMOD wpconfig = 0, pmprintf = 0, pmmerge = 0, gbm = 0; 124 HMOD wpconfig = 0, pmprintf = 0, pmmerge = 0, gbm = 0;
121 static char _dw_exec_dir[MAX_PATH+1] = {0}; 125 static char _dw_exec_dir[MAX_PATH+1] = {0};
126
127 #ifdef UNICODE
128 /* Atom for "text/unicode" clipboard format */
129 ATOM Unicode;
130 KHAND Keyboard;
131 #endif
122 132
123 unsigned long _colors[] = { 133 unsigned long _colors[] = {
124 CLR_BLACK, 134 CLR_BLACK,
125 CLR_DARKRED, 135 CLR_DARKRED,
126 CLR_DARKGREEN, 136 CLR_DARKGREEN,
2772 return client ? client : menuowner; 2782 return client ? client : menuowner;
2773 } 2783 }
2774 return NULLHANDLE; 2784 return NULLHANDLE;
2775 } 2785 }
2776 2786
2787 #ifdef UNICODE
2788 #define MAX_CP_NAME 12 /* maximum length of a codepage name */
2789 #define MAX_CP_SPEC 64 /* maximum length of a UconvObject codepage specifier */
2790
2791 char *_WideToUTF8(UniChar *unistr)
2792 {
2793 UconvObject uconv; /* conversion object */
2794 UniChar suCodepage[MAX_CP_SPEC]; /* conversion specifier */
2795 /* Convert text to the active codepage */
2796 ULONG ulRC;
2797 char *retval = NULL;
2798
2799 /* Create the conversion object */
2800 UniMapCpToUcsCp(1208, suCodepage, MAX_CP_NAME);
2801 UniStrcat(suCodepage, (UniChar *) L"@map=cdra,path=no");
2802
2803 if((ulRC = UniCreateUconvObject(suCodepage, &uconv)) == ULS_SUCCESS)
2804 {
2805 /* Now do the conversion */
2806 ULONG ulBufLen = (UniStrlen(unistr) * 4) + 1;
2807 char *s, *pszLocalText = (char *)malloc(ulBufLen);
2808
2809 if((ulRC = UniStrFromUcs(uconv, pszLocalText,
2810 unistr, ulBufLen )) == ULS_SUCCESS)
2811 {
2812 /* (some codepages use 0x1A for substitutions; replace with ?) */
2813 while((s = strchr(pszLocalText, 0x1A)) != NULL) *s = '?';
2814 /* Output the converted text */
2815 retval = pszLocalText;
2816 }
2817 #ifdef DEBUG
2818 else
2819 dw_debug("Error pasting Unicode text:\nUniStrFromUcs() = %08X", ulRC);
2820 #endif
2821 UniFreeUconvObject(uconv);
2822 }
2823 #ifdef DEBUG
2824 else
2825 dw_debug("Error pasting Unicode text:\nUniCreateUconvObject() = %08X", ulRC);
2826 #endif
2827 return retval;
2828 }
2829 #endif
2830
2777 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) 2831 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
2778 { 2832 {
2779 int result = -1; 2833 int result = -1;
2780 SignalHandler *tmp = Root; 2834 SignalHandler *tmp = Root;
2781 ULONG origmsg = msg; 2835 ULONG origmsg = msg;
2906 } 2960 }
2907 } 2961 }
2908 break; 2962 break;
2909 case WM_CHAR: 2963 case WM_CHAR:
2910 { 2964 {
2911 int (API_FUNC keypressfunc)(HWND, char, int, int, void *) = (int (API_FUNC)(HWND, char, int, int, void *))tmp->signalfunction; 2965 int (API_FUNC keypressfunc)(HWND, char, int, int, void *, char *) = (int (API_FUNC)(HWND, char, int, int, void *, char *))tmp->signalfunction;
2912 2966
2913 if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP)) 2967 if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP))
2914 { 2968 {
2915 int vk; 2969 int vk;
2916 char ch = 0; 2970 char ch[2] = {0};
2971 char *utf8 = NULL;
2972 #ifdef UNICODE
2973 UniChar uc[2] = {0};
2974 VDKEY vdk;
2975 BYTE bscan;
2976
2977 UniTranslateKey(Keyboard, 0, CHAR4FROMMP(mp1), uc, &vdk, &bscan);
2978 utf8 = _WideToUTF8(uc);
2979 #endif
2917 2980
2918 if(SHORT1FROMMP(mp1) & KC_CHAR) 2981 if(SHORT1FROMMP(mp1) & KC_CHAR)
2919 ch = (char)SHORT1FROMMP(mp2); 2982 ch[0] = (char)SHORT1FROMMP(mp2);
2920 if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY) 2983 if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY)
2921 vk = SHORT2FROMMP(mp2); 2984 vk = SHORT2FROMMP(mp2);
2922 else 2985 else
2923 vk = SHORT1FROMMP(mp2) + 128; 2986 vk = SHORT1FROMMP(mp2) + 128;
2924 2987
2925 /* This is a hack to fix shift presses showing 2988 /* This is a hack to fix shift presses showing
2926 * up as tabs! 2989 * up as tabs!
2927 */ 2990 */
2928 if(ch == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR)) 2991 if(ch[0] == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR))
2929 { 2992 {
2930 ch = 0; 2993 ch[0] = 0;
2931 vk = VK_SHIFT; 2994 vk = VK_SHIFT;
2932 } 2995 }
2933 2996
2934 result = keypressfunc(tmp->window, ch, vk, 2997 result = keypressfunc(tmp->window, ch[0], vk,
2935 SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data); 2998 SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data, utf8 ? utf8 : ch);
2936 tmp = NULL; 2999 tmp = NULL;
3000
3001 if(utf8)
3002 free(utf8);
2937 } 3003 }
2938 } 3004 }
2939 break; 3005 break;
2940 case WM_CLOSE: 3006 case WM_CLOSE:
2941 { 3007 {
2997 if(origmsg == WM_VSCROLL || origmsg == WM_HSCROLL || tmp->message == SHORT2FROMMP(mp1) || 3063 if(origmsg == WM_VSCROLL || origmsg == WM_HSCROLL || tmp->message == SHORT2FROMMP(mp1) ||
2998 (tmp->message == SLN_SLIDERTRACK && (SHORT2FROMMP(mp1) == SLN_CHANGE || SHORT2FROMMP(mp1) == SPBN_CHANGE))) 3064 (tmp->message == SLN_SLIDERTRACK && (SHORT2FROMMP(mp1) == SLN_CHANGE || SHORT2FROMMP(mp1) == SPBN_CHANGE)))
2999 { 3065 {
3000 int svar = SLN_SLIDERTRACK; 3066 int svar = SLN_SLIDERTRACK;
3001 int id = SHORT1FROMMP(mp1); 3067 int id = SHORT1FROMMP(mp1);
3002 HWND notifyhwnd = dw_window_from_id(hWnd, id); 3068 HWND notifyhwnd = dw_window_from_id(hWnd, id);
3003 3069
3004 if(origmsg == WM_CONTROL) 3070 if(origmsg == WM_CONTROL)
3005 { 3071 {
3006 svar = SHORT2FROMMP(mp1); 3072 svar = SHORT2FROMMP(mp1);
3007 if(!notifyhwnd && WinIsWindow(dwhab, (HWND)mp2)) 3073 if(!notifyhwnd && WinIsWindow(dwhab, (HWND)mp2))
3008 notifyhwnd = (HWND)mp2; 3074 notifyhwnd = (HWND)mp2;
3009 } 3075 }
3010 3076
3011 switch(svar) 3077 switch(svar)
3012 { 3078 {
3013 case CN_ENTER: 3079 case CN_ENTER:
3014 { 3080 {
3377 } 3443 }
3378 } 3444 }
3379 if(!dw_window_get_data((HWND)mp2, "_dw_updating")) 3445 if(!dw_window_get_data((HWND)mp2, "_dw_updating"))
3380 WinPostMsg(hWnd, WM_USER, mp1, mp2); 3446 WinPostMsg(hWnd, WM_USER, mp1, mp2);
3381 } 3447 }
3382 else 3448 else
3383 _run_event(hWnd, msg, mp1, mp2); 3449 _run_event(hWnd, msg, mp1, mp2);
3384 } 3450 }
3385 break; 3451 break;
3386 } 3452 }
3387 3453
3388 if(blah && blah->oldproc) 3454 if(blah && blah->oldproc)
4169 if(newthread) 4235 if(newthread)
4170 { 4236 {
4171 dwhab = WinInitialize(0); 4237 dwhab = WinInitialize(0);
4172 dwhmq = WinCreateMsgQueue(dwhab, 0); 4238 dwhmq = WinCreateMsgQueue(dwhab, 0);
4173 #ifdef UNICODE 4239 #ifdef UNICODE
4240 /* Create the Unicode atom for copy and paste */
4241 Unicode = WinAddAtom(WinQuerySystemAtomTable(), (PSZ)"text/unicode");
4242 /* TODO: Need to figure out how to determine the correct keyboard here */
4243 UniCreateKeyboard(&Keyboard, (UniChar *) L"de", 0);
4174 /* Set the codepage to 1208 (UTF-8) */ 4244 /* Set the codepage to 1208 (UTF-8) */
4175 WinSetCp(dwhmq, 1208); 4245 WinSetCp(dwhmq, 1208);
4176 #endif 4246 #endif
4177 } 4247 }
4178 4248
11345 11415
11346 /* Deinit the GBM */ 11416 /* Deinit the GBM */
11347 if(_gbm_deinit) 11417 if(_gbm_deinit)
11348 _gbm_deinit(); 11418 _gbm_deinit();
11349 11419
11420 #ifdef UNICODE
11421 /* Deregister the Unicode clipboard format */
11422 WinDeleteAtom(WinQuerySystemAtomTable(), Unicode);
11423 #endif
11424
11350 /* Destroy the main message queue and anchor block */ 11425 /* Destroy the main message queue and anchor block */
11351 WinDestroyMsgQueue(dwhmq); 11426 WinDestroyMsgQueue(dwhmq);
11352 WinTerminate(dwhab); 11427 WinTerminate(dwhab);
11353 11428
11354 /* Free any in use modules */ 11429 /* Free any in use modules */