From 5bdf71f6ef4e29741c508c86ffd79ce57350768e Mon Sep 17 00:00:00 2001 From: Karsten Hopp Date: Sep 02 2015 09:20:05 +0000 Subject: - patchlevel 852 --- diff --git a/7.4.852 b/7.4.852 new file mode 100644 index 0000000..c820cba --- /dev/null +++ b/7.4.852 @@ -0,0 +1,594 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.4.852 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.4.852 +Problem: On MS-Windows console Vim uses ANSI APIs for keyboard input and + console output, it cannot input/output Unicode characters. +Solution: Use Unicode APIs for console I/O. (Ken Takata, Yasuhiro Matsumoto) +Files: src/os_win32.c, src/ui.c, runtime/doc/options.txt + + +*** ../vim-7.4.851/src/os_win32.c 2015-09-01 20:23:30.408603580 +0200 +--- src/os_win32.c 2015-09-01 20:28:43.193363546 +0200 +*************** +*** 213,220 **** + static void standend(void); + static void visual_bell(void); + static void cursor_visible(BOOL fVisible); +! static BOOL write_chars(LPCSTR pchBuf, DWORD cchToWrite); +! static char_u tgetch(int *pmodifiers, char_u *pch2); + static void create_conin(void); + static int s_cursor_visible = TRUE; + static int did_create_conin = FALSE; +--- 213,220 ---- + static void standend(void); + static void visual_bell(void); + static void cursor_visible(BOOL fVisible); +! static DWORD write_chars(char_u *pchBuf, DWORD cbToWrite); +! static WCHAR tgetch(int *pmodifiers, WCHAR *pch2); + static void create_conin(void); + static int s_cursor_visible = TRUE; + static int did_create_conin = FALSE; +*************** +*** 265,279 **** + if (!win8_or_later) + { + if (nLength == -1) +! return PeekConsoleInput(hInput, lpBuffer, 1, lpEvents); +! return ReadConsoleInput(hInput, lpBuffer, 1, &dwEvents); + } + + if (s_dwMax == 0) + { + if (nLength == -1) +! return PeekConsoleInput(hInput, lpBuffer, 1, lpEvents); +! if (!ReadConsoleInput(hInput, s_irCache, IRSIZE, &dwEvents)) + return FALSE; + s_dwIndex = 0; + s_dwMax = dwEvents; +--- 265,279 ---- + if (!win8_or_later) + { + if (nLength == -1) +! return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents); +! return ReadConsoleInputW(hInput, lpBuffer, 1, &dwEvents); + } + + if (s_dwMax == 0) + { + if (nLength == -1) +! return PeekConsoleInputW(hInput, lpBuffer, 1, lpEvents); +! if (!ReadConsoleInputW(hInput, s_irCache, IRSIZE, &dwEvents)) + return FALSE; + s_dwIndex = 0; + s_dwMax = dwEvents; +*************** +*** 868,876 **** + #endif + + #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__CYGWIN__) +! # define AChar AsciiChar + #else +! # define AChar uChar.AsciiChar + #endif + + /* The return code indicates key code size. */ +--- 868,876 ---- + #endif + + #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__CYGWIN__) +! # define UChar UnicodeChar + #else +! # define UChar uChar.UnicodeChar + #endif + + /* The return code indicates key code size. */ +*************** +*** 889,900 **** + + if (s_iIsDead == 2) + { +! pker->AChar = (CHAR) awAnsiCode[1]; + s_iIsDead = 0; + return 1; + } + +! if (pker->AChar != 0) + return 1; + + vim_memset(abKeystate, 0, sizeof (abKeystate)); +--- 889,900 ---- + + if (s_iIsDead == 2) + { +! pker->UChar = (WCHAR) awAnsiCode[1]; + s_iIsDead = 0; + return 1; + } + +! if (pker->UChar != 0) + return 1; + + vim_memset(abKeystate, 0, sizeof (abKeystate)); +*************** +*** 909,915 **** + } + + /* Clear any pending dead keys */ +! ToAscii(VK_SPACE, MapVirtualKey(VK_SPACE, 0), abKeystate, awAnsiCode, 0); + + if (uMods & SHIFT_PRESSED) + abKeystate[VK_SHIFT] = 0x80; +--- 909,915 ---- + } + + /* Clear any pending dead keys */ +! ToUnicode(VK_SPACE, MapVirtualKey(VK_SPACE, 0), abKeystate, awAnsiCode, 2, 0); + + if (uMods & SHIFT_PRESSED) + abKeystate[VK_SHIFT] = 0x80; +*************** +*** 922,932 **** + abKeystate[VK_MENU] = abKeystate[VK_RMENU] = 0x80; + } + +! s_iIsDead = ToAscii(pker->wVirtualKeyCode, pker->wVirtualScanCode, +! abKeystate, awAnsiCode, 0); + + if (s_iIsDead > 0) +! pker->AChar = (CHAR) awAnsiCode[0]; + + return s_iIsDead; + } +--- 922,932 ---- + abKeystate[VK_MENU] = abKeystate[VK_RMENU] = 0x80; + } + +! s_iIsDead = ToUnicode(pker->wVirtualKeyCode, pker->wVirtualScanCode, +! abKeystate, awAnsiCode, 2, 0); + + if (s_iIsDead > 0) +! pker->UChar = (WCHAR) awAnsiCode[0]; + + return s_iIsDead; + } +*************** +*** 953,960 **** + static BOOL + decode_key_event( + KEY_EVENT_RECORD *pker, +! char_u *pch, +! char_u *pch2, + int *pmodifiers, + BOOL fDoPost) + { +--- 953,960 ---- + static BOOL + decode_key_event( + KEY_EVENT_RECORD *pker, +! WCHAR *pch, +! WCHAR *pch2, + int *pmodifiers, + BOOL fDoPost) + { +*************** +*** 982,988 **** + } + + /* special cases */ +! if ((nModifs & CTRL) != 0 && (nModifs & ~CTRL) == 0 && pker->AChar == NUL) + { + /* Ctrl-6 is Ctrl-^ */ + if (pker->wVirtualKeyCode == '6') +--- 982,988 ---- + } + + /* special cases */ +! if ((nModifs & CTRL) != 0 && (nModifs & ~CTRL) == 0 && pker->UChar == NUL) + { + /* Ctrl-6 is Ctrl-^ */ + if (pker->wVirtualKeyCode == '6') +*************** +*** 1044,1050 **** + *pch = NUL; + else + { +! *pch = (i > 0) ? pker->AChar : NUL; + + if (pmodifiers != NULL) + { +--- 1044,1050 ---- + *pch = NUL; + else + { +! *pch = (i > 0) ? pker->UChar : NUL; + + if (pmodifiers != NULL) + { +*************** +*** 1436,1442 **** + DWORD dwNow = 0, dwEndTime = 0; + INPUT_RECORD ir; + DWORD cRecords; +! char_u ch, ch2; + + if (msec > 0) + /* Wait until the specified time has elapsed. */ +--- 1436,1442 ---- + DWORD dwNow = 0, dwEndTime = 0; + INPUT_RECORD ir; + DWORD cRecords; +! WCHAR ch, ch2; + + if (msec > 0) + /* Wait until the specified time has elapsed. */ +*************** +*** 1523,1529 **** + #ifdef FEAT_MBYTE_IME + /* Windows IME sends two '\n's with only one 'ENTER'. First: + * wVirtualKeyCode == 13. second: wVirtualKeyCode == 0 */ +! if (ir.Event.KeyEvent.uChar.UnicodeChar == 0 + && ir.Event.KeyEvent.wVirtualKeyCode == 13) + { + read_console_input(g_hConIn, &ir, 1, &cRecords); +--- 1523,1529 ---- + #ifdef FEAT_MBYTE_IME + /* Windows IME sends two '\n's with only one 'ENTER'. First: + * wVirtualKeyCode == 13. second: wVirtualKeyCode == 0 */ +! if (ir.Event.KeyEvent.UChar == 0 + && ir.Event.KeyEvent.wVirtualKeyCode == 13) + { + read_console_input(g_hConIn, &ir, 1, &cRecords); +*************** +*** 1586,1595 **** + /* + * Get a keystroke or a mouse event + */ +! static char_u +! tgetch(int *pmodifiers, char_u *pch2) + { +! char_u ch; + + for (;;) + { +--- 1586,1595 ---- + /* + * Get a keystroke or a mouse event + */ +! static WCHAR +! tgetch(int *pmodifiers, WCHAR *pch2) + { +! WCHAR ch; + + for (;;) + { +*************** +*** 1658,1668 **** + #define TYPEAHEADLEN 20 + static char_u typeahead[TYPEAHEADLEN]; /* previously typed bytes. */ + static int typeaheadlen = 0; +- #ifdef FEAT_MBYTE +- static char_u *rest = NULL; /* unconverted rest of previous read */ +- static int restlen = 0; +- int unconverted; +- #endif + + /* First use any typeahead that was kept because "buf" was too small. */ + if (typeaheadlen > 0) +--- 1658,1663 ---- +*************** +*** 1761,1798 **** + else + #endif + { +! char_u ch2 = NUL; + int modifiers = 0; + + c = tgetch(&modifiers, &ch2); + +- #ifdef FEAT_MBYTE +- /* stolen from fill_input_buf() in ui.c */ +- if (rest != NULL) +- { +- /* Use remainder of previous call, starts with an invalid +- * character that may become valid when reading more. */ +- if (restlen > TYPEAHEADLEN - typeaheadlen) +- unconverted = TYPEAHEADLEN - typeaheadlen; +- else +- unconverted = restlen; +- mch_memmove(typeahead + typeaheadlen, rest, unconverted); +- if (unconverted == restlen) +- { +- vim_free(rest); +- rest = NULL; +- } +- else +- { +- restlen -= unconverted; +- mch_memmove(rest, rest + unconverted, restlen); +- } +- typeaheadlen += unconverted; +- } +- else +- unconverted = 0; +- #endif +- + if (typebuf_changed(tb_change_cnt)) + { + /* "buf" may be invalid now if a client put something in the +--- 1756,1766 ---- + else + #endif + { +! WCHAR ch2 = NUL; + int modifiers = 0; + + c = tgetch(&modifiers, &ch2); + + if (typebuf_changed(tb_change_cnt)) + { + /* "buf" may be invalid now if a client put something in the +*************** +*** 1816,1842 **** + int n = 1; + int conv = FALSE; + +- typeahead[typeaheadlen] = c; +- if (ch2 != NUL) +- { +- typeahead[typeaheadlen + 1] = 3; +- typeahead[typeaheadlen + 2] = ch2; +- n += 2; +- } + #ifdef FEAT_MBYTE +! /* Only convert normal characters, not special keys. Need to +! * convert before applying ALT, otherwise mapping breaks +! * when 'tenc' is set. */ +! if (input_conv.vc_type != CONV_NONE +! && (ch2 == NUL || c != K_NUL)) + { +! conv = TRUE; +! typeaheadlen -= unconverted; +! n = convert_input_safe(typeahead + typeaheadlen, +! n + unconverted, TYPEAHEADLEN - typeaheadlen, +! rest == NULL ? &rest : NULL, &restlen); + } + #endif + + if (conv) + { +--- 1784,1819 ---- + int n = 1; + int conv = FALSE; + + #ifdef FEAT_MBYTE +! if (ch2 == NUL) + { +! int i; +! char_u *p; +! WCHAR ch[2]; +! +! ch[0] = c; +! if (c >= 0xD800 && c <= 0xDBFF) /* High surrogate */ +! { +! ch[1] = tgetch(&modifiers, &ch2); +! n++; +! } +! p = utf16_to_enc(ch, &n); +! if (p != NULL) +! { +! for (i = 0; i < n; i++) +! typeahead[typeaheadlen + i] = p[i]; +! vim_free(p); +! } + } ++ else + #endif ++ typeahead[typeaheadlen] = c; ++ if (ch2 != NUL) ++ { ++ typeahead[typeaheadlen + n] = 3; ++ typeahead[typeaheadlen + n + 1] = (char_u)ch2; ++ n += 2; ++ } + + if (conv) + { +*************** +*** 5366,5392 **** + + + /* +! * write `cchToWrite' characters in `pchBuf' to the screen +! * Returns the number of characters actually written (at least one). + */ +! static BOOL + write_chars( +! LPCSTR pchBuf, +! DWORD cchToWrite) + { + COORD coord = g_coord; + DWORD written; + +! FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cchToWrite, +! coord, &written); +! /* When writing fails or didn't write a single character, pretend one +! * character was written, otherwise we get stuck. */ +! if (WriteConsoleOutputCharacter(g_hConOut, pchBuf, cchToWrite, +! coord, &written) == 0 +! || written == 0) +! written = 1; + +! g_coord.X += (SHORT) written; + + while (g_coord.X > g_srScrollRegion.Right) + { +--- 5343,5415 ---- + + + /* +! * write `cbToWrite' bytes in `pchBuf' to the screen +! * Returns the number of bytes actually written (at least one). + */ +! static DWORD + write_chars( +! char_u *pchBuf, +! DWORD cbToWrite) + { + COORD coord = g_coord; + DWORD written; + +! #ifdef FEAT_MBYTE +! if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) +! { +! static WCHAR *unicodebuf = NULL; +! static int unibuflen = 0; +! int length; +! DWORD n, cchwritten, cells; +! +! length = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pchBuf, cbToWrite, 0, 0); +! if (unicodebuf == NULL || length > unibuflen) +! { +! vim_free(unicodebuf); +! unicodebuf = (WCHAR *)lalloc(length * sizeof(WCHAR), FALSE); +! unibuflen = length; +! } +! MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pchBuf, cbToWrite, +! unicodebuf, unibuflen); +! +! cells = mb_string2cells(pchBuf, cbToWrite); +! FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cells, +! coord, &written); +! /* When writing fails or didn't write a single character, pretend one +! * character was written, otherwise we get stuck. */ +! if (WriteConsoleOutputCharacterW(g_hConOut, unicodebuf, length, +! coord, &cchwritten) == 0 +! || cchwritten == 0) +! cchwritten = 1; +! +! if (cchwritten == length) +! { +! written = cbToWrite; +! g_coord.X += (SHORT)cells; +! } +! else +! { +! char_u *p = pchBuf; +! for (n = 0; n < cchwritten; n++) +! mb_cptr_adv(p); +! written = p - pchBuf; +! g_coord.X += (SHORT)mb_string2cells(pchBuf, written); +! } +! } +! else +! #endif +! { +! FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cbToWrite, +! coord, &written); +! /* When writing fails or didn't write a single character, pretend one +! * character was written, otherwise we get stuck. */ +! if (WriteConsoleOutputCharacter(g_hConOut, (LPCSTR)pchBuf, cbToWrite, +! coord, &written) == 0 +! || written == 0) +! written = 1; + +! g_coord.X += (SHORT) written; +! } + + while (g_coord.X > g_srScrollRegion.Right) + { +*** ../vim-7.4.851/src/ui.c 2015-08-11 19:13:55.146175594 +0200 +--- src/ui.c 2015-09-01 20:27:49.069924312 +0200 +*************** +*** 42,48 **** + /* Don't output anything in silent mode ("ex -s") unless 'verbose' set */ + if (!(silent_mode && p_verbose == 0)) + { +! #ifdef FEAT_MBYTE + char_u *tofree = NULL; + + if (output_conv.vc_type != CONV_NONE) +--- 42,48 ---- + /* Don't output anything in silent mode ("ex -s") unless 'verbose' set */ + if (!(silent_mode && p_verbose == 0)) + { +! #if defined(FEAT_MBYTE) && !defined(WIN3264) + char_u *tofree = NULL; + + if (output_conv.vc_type != CONV_NONE) +*************** +*** 56,62 **** + + mch_write(s, len); + +! #ifdef FEAT_MBYTE + if (output_conv.vc_type != CONV_NONE) + vim_free(tofree); + #endif +--- 56,62 ---- + + mch_write(s, len); + +! #if defined(FEAT_MBYTE) && !defined(WIN3264) + if (output_conv.vc_type != CONV_NONE) + vim_free(tofree); + #endif +*** ../vim-7.4.851/runtime/doc/options.txt 2015-07-21 17:53:11.573528028 +0200 +--- runtime/doc/options.txt 2015-09-01 20:29:21.724964297 +0200 +*************** +*** 7377,7390 **** + the GUI it only applies to the keyboard ( 'encoding' is used for the + display). Except for the Mac when 'macatsui' is off, then + 'termencoding' should be "macroman". +- In the Win32 console version the default value is the console codepage +- when it differs from the ANSI codepage. + *E617* + Note: This does not apply to the GTK+ 2 GUI. After the GUI has been + successfully initialized, 'termencoding' is forcibly set to "utf-8". + Any attempts to set a different value will be rejected, and an error + message is shown. +! For the Win32 GUI 'termencoding' is not used for typed characters, + because the Win32 system always passes Unicode characters. + When empty, the same encoding is used as for the 'encoding' option. + This is the normal value. +--- 7396,7407 ---- + the GUI it only applies to the keyboard ( 'encoding' is used for the + display). Except for the Mac when 'macatsui' is off, then + 'termencoding' should be "macroman". + *E617* + Note: This does not apply to the GTK+ 2 GUI. After the GUI has been + successfully initialized, 'termencoding' is forcibly set to "utf-8". + Any attempts to set a different value will be rejected, and an error + message is shown. +! For the Win32 GUI and console versions 'termencoding' is not used, + because the Win32 system always passes Unicode characters. + When empty, the same encoding is used as for the 'encoding' option. + This is the normal value. +*** ../vim-7.4.851/src/version.c 2015-09-01 20:23:30.408603580 +0200 +--- src/version.c 2015-09-01 20:27:43.713979797 +0200 +*************** +*** 743,744 **** +--- 743,746 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 852, + /**/ + +-- +(letter from Mark to Mike, about the film's probable certificate) + I would like to get back to the Censor and agree to lose the shits, take + the odd Jesus Christ out and lose Oh fuck off, but to retain 'fart in + your general direction', 'castanets of your testicles' and 'oral sex' + and ask him for an 'A' rating on that basis. + "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD + + /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ an exciting new programming language -- http://www.Zimbu.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org ///