Mercurial > dwindows
comparison os2/dw.c @ 1755:9f7fc4fca5a6
In Unicode mode on OS/2, handle pasting to entryfields and MLEs
ourselves so we can use the Unicode clipboard and conversion
to UTF-8 of keyboard scan codes that the PM procedures don't handle.
Added Alex Taylor to the copyrights due to use of clipuni code.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sat, 16 Jun 2012 11:16:46 +0000 |
parents | 2d3cd1f616a9 |
children | 873960d28f01 |
comparison
equal
deleted
inserted
replaced
1754:eeec5ceec7a5 | 1755:9f7fc4fca5a6 |
---|---|
4 * | 4 * |
5 * (C) 2000-2012 Brian Smith <brian@dbsoft.org> | 5 * (C) 2000-2012 Brian Smith <brian@dbsoft.org> |
6 * (C) 2003-2011 Mark Hessling <mark@rexx.org> | 6 * (C) 2003-2011 Mark Hessling <mark@rexx.org> |
7 * (C) 2000 Achim Hasenmueller <achimha@innotek.de> | 7 * (C) 2000 Achim Hasenmueller <achimha@innotek.de> |
8 * (C) 2000 Peter Nielsen <peter@pmview.com> | 8 * (C) 2000 Peter Nielsen <peter@pmview.com> |
9 * (C) 2007 Alex Taylor (some code borrowed from clipuni) | |
9 * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit) | 10 * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit) |
10 * | 11 * |
11 */ | 12 */ |
12 #define INCL_DOS | 13 #define INCL_DOS |
13 #define INCL_DOSERRORS | 14 #define INCL_DOSERRORS |
1109 { | 1110 { |
1110 int height = _get_height(parent); | 1111 int height = _get_height(parent); |
1111 | 1112 |
1112 return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl); | 1113 return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl); |
1113 } | 1114 } |
1115 | |
1116 #ifdef UNICODE | |
1117 #define MAX_CP_NAME 12 /* maximum length of a codepage name */ | |
1118 #define MAX_CP_SPEC 64 /* maximum length of a UconvObject codepage specifier */ | |
1119 | |
1120 char *_WideToUTF8(UniChar *unistr) | |
1121 { | |
1122 /* Convert text to UTF-8 codepage */ | |
1123 char *retval = NULL; | |
1124 /* Now do the conversion */ | |
1125 ULONG ulBufLen = (UniStrlen(unistr) * 4) + 1; | |
1126 char *s, *pszLocalText = (char *)malloc(ulBufLen); | |
1127 | |
1128 if(UniStrFromUcs(Uconv, pszLocalText, | |
1129 unistr, ulBufLen) == ULS_SUCCESS) | |
1130 { | |
1131 /* (some codepages use 0x1A for substitutions; replace with ?) */ | |
1132 while((s = strchr(pszLocalText, 0x1A)) != NULL) *s = '?'; | |
1133 /* Output the converted text */ | |
1134 retval = pszLocalText; | |
1135 } | |
1136 else if(pszLocalText) | |
1137 free(pszLocalText); | |
1138 return retval; | |
1139 } | |
1140 | |
1141 UniChar *_UTF8toWide(char *utf8str) | |
1142 { | |
1143 /* Convert text to Unicode */ | |
1144 UniChar *retval = NULL; | |
1145 /* Now do the conversion */ | |
1146 UniChar *buf = calloc(strlen(utf8str) + 1, sizeof(UniChar)); | |
1147 | |
1148 if(UniStrToUcs(Uconv, buf, | |
1149 utf8str, strlen(utf8str) * sizeof(UniChar)) == ULS_SUCCESS) | |
1150 { | |
1151 /* Output the converted text */ | |
1152 retval = buf; | |
1153 } | |
1154 else if(buf) | |
1155 free(buf); | |
1156 return retval; | |
1157 } | |
1158 #endif | |
1114 | 1159 |
1115 /* This function calculates how much space the widgets and boxes require | 1160 /* This function calculates how much space the widgets and boxes require |
1116 * and does expansion as necessary. | 1161 * and does expansion as necessary. |
1117 */ | 1162 */ |
1118 static void _resize_box(Box *thisbox, int *depth, int x, int y, int pass) | 1163 static void _resize_box(Box *thisbox, int *depth, int x, int y, int pass) |
2285 } | 2330 } |
2286 else | 2331 else |
2287 WinSetFocus(HWND_DESKTOP, handle); | 2332 WinSetFocus(HWND_DESKTOP, handle); |
2288 } | 2333 } |
2289 | 2334 |
2335 #ifdef UNICODE | |
2336 void _combine_text(HWND handle, USHORT pos1, char *text, char *pastetext) | |
2337 { | |
2338 char *combined = calloc((text ? strlen(text) : 0) + strlen(pastetext) + 1, 1); | |
2339 SHORT newsel = pos1 + strlen(pastetext); | |
2340 | |
2341 /* Combine the two strings into 1... or just use pastetext if no text */ | |
2342 if(text) | |
2343 strncpy(combined, text, pos1); | |
2344 strcat(combined, pastetext); | |
2345 if(text && pos1 < strlen(text)) | |
2346 strcat(combined, &text[pos1]); | |
2347 | |
2348 /* Set the new combined text to the entryfield */ | |
2349 dw_window_set_text(handle, combined); | |
2350 /* Move the cursor to the old selection start plus paste length */ | |
2351 WinSendMsg(handle, EM_SETSEL, MPFROM2SHORT(newsel, newsel), 0); | |
2352 /* Free temporary memory */ | |
2353 free(combined); | |
2354 } | |
2355 #endif | |
2356 | |
2290 #define ENTRY_CUT 60901 | 2357 #define ENTRY_CUT 60901 |
2291 #define ENTRY_COPY 60902 | 2358 #define ENTRY_COPY 60902 |
2292 #define ENTRY_PASTE 60903 | 2359 #define ENTRY_PASTE 60903 |
2293 #define ENTRY_UNDO 60904 | 2360 #define ENTRY_UNDO 60904 |
2294 #define ENTRY_SALL 60905 | 2361 #define ENTRY_SALL 60905 |
2349 /* MLE */ | 2416 /* MLE */ |
2350 if(strncmp(tmpbuf, "#10", 4)==0) | 2417 if(strncmp(tmpbuf, "#10", 4)==0) |
2351 { | 2418 { |
2352 switch(command) | 2419 switch(command) |
2353 { | 2420 { |
2421 #ifdef UNICODE | |
2422 case ENTRY_CUT: | |
2423 case ENTRY_COPY: | |
2424 case ENTRY_PASTE: | |
2425 { | |
2426 /* MLE insertion points (for querying selection) */ | |
2427 IPT ipt1, ipt2; | |
2428 | |
2429 /* Get the selected text */ | |
2430 ipt1 = (IPT)WinSendMsg(hWnd, MLM_QUERYSEL, MPFROMSHORT(MLFQS_MINSEL), 0); | |
2431 ipt2 = (IPT)WinSendMsg(hWnd, MLM_QUERYSEL, MPFROMSHORT(MLFQS_MAXSEL), 0); | |
2432 | |
2433 /* Get the selection and put on clipboard for copy and cut */ | |
2434 if(command != ENTRY_PASTE) | |
2435 { | |
2436 char *text = (char *)malloc((ULONG)WinSendMsg(hWnd, MLM_QUERYFORMATTEXTLENGTH, MPFROMLONG(ipt1), MPFROMLONG(ipt2 - ipt1)) + 1); | |
2437 ULONG ulCopied = (ULONG)WinSendMsg(hWnd, MLM_QUERYSELTEXT, MPFROMP(text), 0); | |
2438 | |
2439 dw_clipboard_set_text(text, ulCopied); | |
2440 free(text); | |
2441 } | |
2442 /* Clear selection for cut and paste */ | |
2443 if(command != ENTRY_COPY) | |
2444 WinSendMsg(hWnd, MLM_CLEAR, 0, 0); | |
2445 if(command == ENTRY_PASTE) | |
2446 { | |
2447 char *text = dw_clipboard_get_text(); | |
2448 | |
2449 if(text) | |
2450 { | |
2451 WinSendMsg(hWnd, MLM_INSERT, MPFROMP(text), 0); | |
2452 dw_free(text); | |
2453 } | |
2454 } | |
2455 } | |
2456 return (MRESULT)0; | |
2457 #else | |
2354 case ENTRY_CUT: | 2458 case ENTRY_CUT: |
2355 return WinSendMsg(hWnd, MLM_CUT, 0, 0); | 2459 return WinSendMsg(hWnd, MLM_CUT, 0, 0); |
2356 case ENTRY_COPY: | 2460 case ENTRY_COPY: |
2357 return WinSendMsg(hWnd, MLM_COPY, 0, 0); | 2461 return WinSendMsg(hWnd, MLM_COPY, 0, 0); |
2358 case ENTRY_PASTE: | 2462 case ENTRY_PASTE: |
2359 return WinSendMsg(hWnd, MLM_PASTE, 0, 0); | 2463 return WinSendMsg(hWnd, MLM_PASTE, 0, 0); |
2464 #endif | |
2360 case ENTRY_UNDO: | 2465 case ENTRY_UNDO: |
2361 return WinSendMsg(hWnd, MLM_UNDO, 0, 0); | 2466 return WinSendMsg(hWnd, MLM_UNDO, 0, 0); |
2362 case ENTRY_SALL: | 2467 case ENTRY_SALL: |
2363 { | 2468 { |
2364 ULONG len = (ULONG)WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0); | 2469 ULONG len = (ULONG)WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0); |
2376 | 2481 |
2377 if(handle) | 2482 if(handle) |
2378 { | 2483 { |
2379 switch(command) | 2484 switch(command) |
2380 { | 2485 { |
2486 #ifdef UNICODE | |
2487 case ENTRY_CUT: | |
2488 case ENTRY_COPY: | |
2489 case ENTRY_PASTE: | |
2490 { | |
2491 /* Get the selected text */ | |
2492 char *text = dw_window_get_text(handle); | |
2493 ULONG sel = (ULONG)WinSendMsg(handle, EM_QUERYSEL, 0, 0); | |
2494 SHORT pos1 = SHORT1FROMMP(sel), pos2 = SHORT2FROMMP(sel); | |
2495 | |
2496 /* Get the selection and put on clipboard for copy and cut */ | |
2497 if(text) | |
2498 { | |
2499 if(command != ENTRY_PASTE) | |
2500 { | |
2501 if(pos2 > pos1) | |
2502 { | |
2503 text[pos2] = 0; | |
2504 | |
2505 dw_clipboard_set_text(&text[pos1], pos2 - pos1); | |
2506 } | |
2507 } | |
2508 free(text); | |
2509 } | |
2510 /* Clear selection for cut and paste */ | |
2511 if(command != ENTRY_COPY) | |
2512 WinSendMsg(handle, EM_CLEAR, 0, 0); | |
2513 text = dw_window_get_text(handle); | |
2514 if(command == ENTRY_PASTE) | |
2515 { | |
2516 char *pastetext = dw_clipboard_get_text(); | |
2517 | |
2518 if(pastetext) | |
2519 { | |
2520 _combine_text(handle, pos1, text, pastetext); | |
2521 /* Free temporary memory */ | |
2522 dw_free(pastetext); | |
2523 } | |
2524 } | |
2525 if(text) | |
2526 free(text); | |
2527 } | |
2528 return (MRESULT)0; | |
2529 #else | |
2381 case ENTRY_CUT: | 2530 case ENTRY_CUT: |
2382 return WinSendMsg(handle, EM_CUT, 0, 0); | 2531 return WinSendMsg(handle, EM_CUT, 0, 0); |
2383 case ENTRY_COPY: | 2532 case ENTRY_COPY: |
2384 return WinSendMsg(handle, EM_COPY, 0, 0); | 2533 return WinSendMsg(handle, EM_COPY, 0, 0); |
2385 case ENTRY_PASTE: | 2534 case ENTRY_PASTE: |
2386 return WinSendMsg(handle, EM_PASTE, 0, 0); | 2535 return WinSendMsg(handle, EM_PASTE, 0, 0); |
2536 #endif | |
2387 case ENTRY_SALL: | 2537 case ENTRY_SALL: |
2388 { | 2538 { |
2389 LONG len = WinQueryWindowTextLength(hWnd); | 2539 LONG len = WinQueryWindowTextLength(hWnd); |
2390 return WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT(0, (SHORT)len), 0); | 2540 return WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT(0, (SHORT)len), 0); |
2391 } | 2541 } |
2432 /* When you hit escape we get this value and the | 2582 /* When you hit escape we get this value and the |
2433 * window hangs for reasons unknown. (in an MLE) | 2583 * window hangs for reasons unknown. (in an MLE) |
2434 */ | 2584 */ |
2435 else if(SHORT1FROMMP(mp2) == 283) | 2585 else if(SHORT1FROMMP(mp2) == 283) |
2436 return (MRESULT)TRUE; | 2586 return (MRESULT)TRUE; |
2437 | 2587 #ifdef UNICODE |
2588 else if(!SHORT1FROMMP(mp2)) | |
2589 { | |
2590 UniChar uc[2] = {0}; | |
2591 VDKEY vdk; | |
2592 BYTE bscan; | |
2593 char *utf8; | |
2594 | |
2595 UniTranslateKey(Keyboard, SHORT1FROMMP(mp1) & KC_SHIFT ? 1 : 0, CHAR4FROMMP(mp1), uc, &vdk, &bscan); | |
2596 | |
2597 if((utf8 = _WideToUTF8(uc)) != NULL) | |
2598 { | |
2599 if(*utf8) | |
2600 { | |
2601 /* MLE */ | |
2602 if(strncmp(tmpbuf, "#10", 4)==0) | |
2603 { | |
2604 WinSendMsg(hWnd, MLM_INSERT, MPFROMP(utf8), 0); | |
2605 } | |
2606 else /* Other */ | |
2607 { | |
2608 HWND handle = hWnd; | |
2609 | |
2610 /* Get the entryfield handle from multi window controls */ | |
2611 if(strncmp(tmpbuf, "#2", 3)==0) | |
2612 handle = WinWindowFromID(hWnd, 667); | |
2613 | |
2614 if(handle) | |
2615 { | |
2616 char *text = dw_window_get_text(handle); | |
2617 ULONG sel = (ULONG)WinSendMsg(hWnd, EM_QUERYSEL, 0, 0); | |
2618 SHORT pos1 = SHORT1FROMMP(sel), pos2 = SHORT2FROMMP(sel); | |
2619 | |
2620 WinSendMsg(handle, EM_CLEAR, 0, 0); | |
2621 _combine_text(handle, pos1, text, utf8); | |
2622 | |
2623 if(text) | |
2624 free(text); | |
2625 } | |
2626 } | |
2627 } | |
2628 free(utf8); | |
2629 } | |
2630 } | |
2631 #endif | |
2438 break; | 2632 break; |
2439 case WM_SIZE: | 2633 case WM_SIZE: |
2440 { | 2634 { |
2441 /* If it's a slider... make sure it shows the correct value */ | 2635 /* If it's a slider... make sure it shows the correct value */ |
2442 if(strncmp(tmpbuf, "#38", 4)==0) | 2636 if(strncmp(tmpbuf, "#38", 4)==0) |
2782 | 2976 |
2783 return client ? client : menuowner; | 2977 return client ? client : menuowner; |
2784 } | 2978 } |
2785 return NULLHANDLE; | 2979 return NULLHANDLE; |
2786 } | 2980 } |
2787 | |
2788 #ifdef UNICODE | |
2789 #define MAX_CP_NAME 12 /* maximum length of a codepage name */ | |
2790 #define MAX_CP_SPEC 64 /* maximum length of a UconvObject codepage specifier */ | |
2791 | |
2792 char *_WideToUTF8(UniChar *unistr) | |
2793 { | |
2794 /* Convert text to UTF-8 codepage */ | |
2795 char *retval = NULL; | |
2796 /* Now do the conversion */ | |
2797 ULONG ulBufLen = (UniStrlen(unistr) * 4) + 1; | |
2798 char *s, *pszLocalText = (char *)malloc(ulBufLen); | |
2799 | |
2800 if(UniStrFromUcs(Uconv, pszLocalText, | |
2801 unistr, ulBufLen) == ULS_SUCCESS) | |
2802 { | |
2803 /* (some codepages use 0x1A for substitutions; replace with ?) */ | |
2804 while((s = strchr(pszLocalText, 0x1A)) != NULL) *s = '?'; | |
2805 /* Output the converted text */ | |
2806 retval = pszLocalText; | |
2807 } | |
2808 else if(pszLocalText) | |
2809 free(pszLocalText); | |
2810 return retval; | |
2811 } | |
2812 | |
2813 UniChar *_UTF8toWide(char *utf8str) | |
2814 { | |
2815 /* Convert text to Unicode */ | |
2816 UniChar *retval = NULL; | |
2817 /* Now do the conversion */ | |
2818 UniChar *buf = calloc(strlen(utf8str) + 1, sizeof(UniChar)); | |
2819 | |
2820 if(UniStrToUcs(Uconv, buf, | |
2821 utf8str, strlen(utf8str) * sizeof(UniChar)) == ULS_SUCCESS) | |
2822 { | |
2823 /* Output the converted text */ | |
2824 retval = buf; | |
2825 } | |
2826 else if(buf) | |
2827 free(buf); | |
2828 return retval; | |
2829 } | |
2830 #endif | |
2831 | 2981 |
2832 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | 2982 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
2833 { | 2983 { |
2834 int result = -1; | 2984 int result = -1; |
2835 SignalHandler *tmp = Root; | 2985 SignalHandler *tmp = Root; |