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;