To: vim-dev@vim.org Subject: Patch 6.3a.019 (extra) Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.3a.019 (extra) Problem: Win32: typing non-latin1 characters doesn't work. Solution: Invoke _OnChar() directly to avoid that the argument is truncated to a byte. Convert the UTF-16 character to bytes according to 'encoding' and ignore 'termencoding'. Same for _OnSysChar(). Files: src/gui_w32.c, src/gui_w48.c *** ../vim-6.3a.018/src/gui_w32.c Wed May 12 17:24:27 2004 --- src/gui_w32.c Thu May 13 14:15:10 2004 *************** *** 611,617 **** HANDLE_MSG(hwnd, WM_DEADCHAR, _OnDeadChar); HANDLE_MSG(hwnd, WM_SYSDEADCHAR, _OnDeadChar); /* HANDLE_MSG(hwnd, WM_ACTIVATE, _OnActivate); */ - HANDLE_MSG(hwnd, WM_CHAR, _OnChar); HANDLE_MSG(hwnd, WM_CLOSE, _OnClose); /* HANDLE_MSG(hwnd, WM_COMMAND, _OnCommand); */ HANDLE_MSG(hwnd, WM_DESTROY, _OnDestroy); --- 611,616 ---- *************** *** 643,648 **** --- 642,653 ---- _OnEndSession(); break; + case WM_CHAR: + /* Don't use HANDLE_MSG() for WM_CHAR, it truncates wParam to a single + * byte while we want the UTF-16 character value. */ + _OnChar(hwnd, wParam, (int)(short)LOWORD(lParam)); + return 0L; + case WM_SYSCHAR: /* * if 'winaltkeys' is "no", or it's "menu" and it's not a menu *************** *** 655,661 **** || (p_wak[0] == 'm' && !gui_is_menu_shortcut((int)wParam)) ) #endif ! return HANDLE_WM_SYSCHAR((hwnd), (wParam), (lParam), (_OnSysChar)); #ifdef FEAT_MENU else return MyWindowProc(hwnd, uMsg, wParam, lParam); --- 660,669 ---- || (p_wak[0] == 'm' && !gui_is_menu_shortcut((int)wParam)) ) #endif ! { ! _OnSysChar(hwnd, wParam, (int)(short)LOWORD(lParam)); ! return 0L; ! } #ifdef FEAT_MENU else return MyWindowProc(hwnd, uMsg, wParam, lParam); *************** *** 663,669 **** case WM_SYSKEYUP: #ifdef FEAT_MENU ! /* Thus used to be done only when menu is active: ALT key is used for * that. But that caused problems when menu is disabled and using * Alt-Tab-Esc: get into a strange state where no mouse-moved events * are received, mouse pointer remains hidden. */ --- 671,677 ---- case WM_SYSKEYUP: #ifdef FEAT_MENU ! /* This used to be done only when menu is active: ALT key is used for * that. But that caused problems when menu is disabled and using * Alt-Tab-Esc: get into a strange state where no mouse-moved events * are received, mouse pointer remains hidden. */ *** ../vim-6.3a.018/src/gui_w48.c Wed May 12 17:24:27 2004 --- src/gui_w48.c Thu May 13 14:09:17 2004 *************** *** 476,483 **** } /* * Key hit, add it to the input buffer. - * Careful: CSI arrives as 0xffffff9b. */ static void _OnChar( --- 476,539 ---- } /* + * Convert Unicode character "ch" to bytes in "string[slen]". + * Return the length. + */ + static int + char_to_string(ch, string, slen) + int ch; + char_u *string; + int slen; + { + int len; + int i; + #ifdef FEAT_MBYTE + WCHAR wstring[2]; + char_u *ws = NULL;; + + /* "ch" is a UTF-16 character. Convert it to a string of bytes. When + * "enc_codepage" is non-zero use the standard Win32 function, otherwise + * use our own conversion function (e.g., for UTF-8). */ + wstring[0] = ch; + if (enc_codepage > 0) + len = WideCharToMultiByte(enc_codepage, 0, wstring, 1, string, slen, + 0, NULL); + else + { + len = 1; + ws = ucs2_to_enc(wstring, &len); + if (ws == NULL) + len = 0; + else + { + if (len > slen) /* just in case */ + len = slen; + mch_memmove(string, ws, len); + vim_free(ws); + } + } + if (len == 0) + #endif + { + string[0] = ch; + len = 1; + } + + for (i = 0; i < len; ++i) + if (string[i] == CSI && len <= slen - 2) + { + /* Insert CSI as K_CSI. */ + mch_memmove(string + i + 3, string + i + 1, len - i - 1); + string[++i] = KS_EXTRA; + string[++i] = (int)KE_CSI; + len += 2; + } + + return len; + } + + /* * Key hit, add it to the input buffer. */ static void _OnChar( *************** *** 486,516 **** int cRepeat) { char_u string[40]; ! string[0] = ch; ! if (string[0] == Ctrl_C && ctrl_c_interrupts) { trash_input_buf(); got_int = TRUE; } ! if (string[0] == CSI) ! { ! /* Insert CSI as K_CSI. */ ! string[1] = KS_EXTRA; ! string[2] = (int)KE_CSI; ! add_to_input_buf(string, 3); ! } ! else ! { ! int len = 1; ! ! #ifdef FEAT_MBYTE ! if (input_conv.vc_type != CONV_NONE) ! len = convert_input(string, len, sizeof(string)); ! #endif ! add_to_input_buf(string, len); ! } } /* --- 542,557 ---- int cRepeat) { char_u string[40]; + int len = 0; ! len = char_to_string(ch, string, 40); ! if (len == 1 && string[0] == Ctrl_C && ctrl_c_interrupts) { trash_input_buf(); got_int = TRUE; } ! add_to_input_buf(string, len); } /* *************** *** 565,594 **** string[len++] = K_SECOND((int)ch); string[len++] = K_THIRD((int)ch); } - else if (ch == CSI) - { - string[len++] = CSI; - string[len++] = KS_EXTRA; - string[len++] = (int)KE_CSI; - } else { ! string[len++] = ch; ! #ifdef FEAT_MBYTE ! if (input_conv.vc_type != CONV_NONE) ! len += convert_input(string + len - 1, 1, sizeof(string) - len) - 1; ! else if (enc_utf8 && string[len - 1] >= 0x80) ! { ! /* convert to utf-8 */ ! string[len] = string[len - 1] & 0xbf; ! string[len - 1] = ((unsigned)string[len - 1] >> 6) + 0xc0; ! if (string[len++] == CSI) ! { ! string[len++] = KS_EXTRA; ! string[len++] = (int)KE_CSI; ! } ! } ! #endif } add_to_input_buf(string, len); --- 606,616 ---- string[len++] = K_SECOND((int)ch); string[len++] = K_THIRD((int)ch); } else { ! /* Although the documentation isn't clear about it, we assume "ch" is ! * a Unicode character. */ ! len += char_to_string(ch, string + len, 40 - len); } add_to_input_buf(string, len); *************** *** 1509,1515 **** { MSG msg; UINT vk = 0; /* Virtual key */ ! char_u string[3]; int i; int modifiers = 0; int key; --- 1531,1537 ---- { MSG msg; UINT vk = 0; /* Virtual key */ ! char_u string[40]; int i; int modifiers = 0; int key; *************** *** 1649,1661 **** } else { ! int len = 1; ! string[0] = key; ! #ifdef FEAT_MBYTE ! if (input_conv.vc_type != CONV_NONE) ! len = convert_input(string, len, sizeof(string)); ! #endif add_to_input_buf(string, len); } break; --- 1671,1680 ---- } else { ! int len; ! /* Handle "key" as a Unicode character. */ ! len = char_to_string(key, string, 40); add_to_input_buf(string, len); } break; *** ../vim-6.3a.018/src/version.c Wed May 12 21:56:02 2004 --- src/version.c Thu May 13 14:19:09 2004 *************** *** 643,644 **** --- 643,646 ---- { /* Add new patch number below this line */ + /**/ + 19, /**/ -- Microsoft's definition of a boolean: TRUE, FALSE, MAYBE "Embrace and extend"...? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///