@@ -213,8 +213,8 @@ static void standout(void);
213213static void standend (void );
214214static void visual_bell (void );
215215static void cursor_visible (BOOL fVisible );
216- static BOOL write_chars (LPCSTR pchBuf , DWORD cchToWrite );
217- static char_u tgetch (int * pmodifiers , char_u * pch2 );
216+ static DWORD write_chars (char_u * pchBuf , DWORD cbToWrite );
217+ static WCHAR tgetch (int * pmodifiers , WCHAR * pch2 );
218218static void create_conin (void );
219219static int s_cursor_visible = TRUE;
220220static int did_create_conin = FALSE;
@@ -265,15 +265,15 @@ read_console_input(
265265 if (!win8_or_later )
266266 {
267267 if (nLength == -1 )
268- return PeekConsoleInput (hInput , lpBuffer , 1 , lpEvents );
269- return ReadConsoleInput (hInput , lpBuffer , 1 , & dwEvents );
268+ return PeekConsoleInputW (hInput , lpBuffer , 1 , lpEvents );
269+ return ReadConsoleInputW (hInput , lpBuffer , 1 , & dwEvents );
270270 }
271271
272272 if (s_dwMax == 0 )
273273 {
274274 if (nLength == -1 )
275- return PeekConsoleInput (hInput , lpBuffer , 1 , lpEvents );
276- if (!ReadConsoleInput (hInput , s_irCache , IRSIZE , & dwEvents ))
275+ return PeekConsoleInputW (hInput , lpBuffer , 1 , lpEvents );
276+ if (!ReadConsoleInputW (hInput , s_irCache , IRSIZE , & dwEvents ))
277277 return FALSE;
278278 s_dwIndex = 0 ;
279279 s_dwMax = dwEvents ;
@@ -868,9 +868,9 @@ static const struct
868868#endif
869869
870870#if defined(__GNUC__ ) && !defined(__MINGW32__ ) && !defined(__CYGWIN__ )
871- # define AChar AsciiChar
871+ # define UChar UnicodeChar
872872#else
873- # define AChar uChar.AsciiChar
873+ # define UChar uChar.UnicodeChar
874874#endif
875875
876876/* The return code indicates key code size. */
@@ -889,12 +889,12 @@ win32_kbd_patch_key(
889889
890890 if (s_iIsDead == 2 )
891891 {
892- pker -> AChar = (CHAR ) awAnsiCode [1 ];
892+ pker -> UChar = (WCHAR ) awAnsiCode [1 ];
893893 s_iIsDead = 0 ;
894894 return 1 ;
895895 }
896896
897- if (pker -> AChar != 0 )
897+ if (pker -> UChar != 0 )
898898 return 1 ;
899899
900900 vim_memset (abKeystate , 0 , sizeof (abKeystate ));
@@ -909,7 +909,7 @@ win32_kbd_patch_key(
909909 }
910910
911911 /* Clear any pending dead keys */
912- ToAscii (VK_SPACE , MapVirtualKey (VK_SPACE , 0 ), abKeystate , awAnsiCode , 0 );
912+ ToUnicode (VK_SPACE , MapVirtualKey (VK_SPACE , 0 ), abKeystate , awAnsiCode , 2 , 0 );
913913
914914 if (uMods & SHIFT_PRESSED )
915915 abKeystate [VK_SHIFT ] = 0x80 ;
@@ -922,11 +922,11 @@ win32_kbd_patch_key(
922922 abKeystate [VK_MENU ] = abKeystate [VK_RMENU ] = 0x80 ;
923923 }
924924
925- s_iIsDead = ToAscii (pker -> wVirtualKeyCode , pker -> wVirtualScanCode ,
926- abKeystate , awAnsiCode , 0 );
925+ s_iIsDead = ToUnicode (pker -> wVirtualKeyCode , pker -> wVirtualScanCode ,
926+ abKeystate , awAnsiCode , 2 , 0 );
927927
928928 if (s_iIsDead > 0 )
929- pker -> AChar = (CHAR ) awAnsiCode [0 ];
929+ pker -> UChar = (WCHAR ) awAnsiCode [0 ];
930930
931931 return s_iIsDead ;
932932}
@@ -953,8 +953,8 @@ static BOOL g_fJustGotFocus = FALSE;
953953 static BOOL
954954decode_key_event (
955955 KEY_EVENT_RECORD * pker ,
956- char_u * pch ,
957- char_u * pch2 ,
956+ WCHAR * pch ,
957+ WCHAR * pch2 ,
958958 int * pmodifiers ,
959959 BOOL fDoPost )
960960{
@@ -982,7 +982,7 @@ decode_key_event(
982982 }
983983
984984 /* special cases */
985- if ((nModifs & CTRL ) != 0 && (nModifs & ~CTRL ) == 0 && pker -> AChar == NUL )
985+ if ((nModifs & CTRL ) != 0 && (nModifs & ~CTRL ) == 0 && pker -> UChar == NUL )
986986 {
987987 /* Ctrl-6 is Ctrl-^ */
988988 if (pker -> wVirtualKeyCode == '6' )
@@ -1044,7 +1044,7 @@ decode_key_event(
10441044 * pch = NUL ;
10451045 else
10461046 {
1047- * pch = (i > 0 ) ? pker -> AChar : NUL ;
1047+ * pch = (i > 0 ) ? pker -> UChar : NUL ;
10481048
10491049 if (pmodifiers != NULL )
10501050 {
@@ -1436,7 +1436,7 @@ WaitForChar(long msec)
14361436 DWORD dwNow = 0 , dwEndTime = 0 ;
14371437 INPUT_RECORD ir ;
14381438 DWORD cRecords ;
1439- char_u ch , ch2 ;
1439+ WCHAR ch , ch2 ;
14401440
14411441 if (msec > 0 )
14421442 /* Wait until the specified time has elapsed. */
@@ -1523,7 +1523,7 @@ WaitForChar(long msec)
15231523#ifdef FEAT_MBYTE_IME
15241524 /* Windows IME sends two '\n's with only one 'ENTER'. First:
15251525 * wVirtualKeyCode == 13. second: wVirtualKeyCode == 0 */
1526- if (ir .Event .KeyEvent .uChar . UnicodeChar == 0
1526+ if (ir .Event .KeyEvent .UChar == 0
15271527 && ir .Event .KeyEvent .wVirtualKeyCode == 13 )
15281528 {
15291529 read_console_input (g_hConIn , & ir , 1 , & cRecords );
@@ -1586,10 +1586,10 @@ create_conin(void)
15861586/*
15871587 * Get a keystroke or a mouse event
15881588 */
1589- static char_u
1590- tgetch (int * pmodifiers , char_u * pch2 )
1589+ static WCHAR
1590+ tgetch (int * pmodifiers , WCHAR * pch2 )
15911591{
1592- char_u ch ;
1592+ WCHAR ch ;
15931593
15941594 for (;;)
15951595 {
@@ -1658,11 +1658,6 @@ mch_inchar(
16581658#define TYPEAHEADLEN 20
16591659 static char_u typeahead [TYPEAHEADLEN ]; /* previously typed bytes. */
16601660 static int typeaheadlen = 0 ;
1661- #ifdef FEAT_MBYTE
1662- static char_u * rest = NULL ; /* unconverted rest of previous read */
1663- static int restlen = 0 ;
1664- int unconverted ;
1665- #endif
16661661
16671662 /* First use any typeahead that was kept because "buf" was too small. */
16681663 if (typeaheadlen > 0 )
@@ -1761,38 +1756,11 @@ mch_inchar(
17611756 else
17621757#endif
17631758 {
1764- char_u ch2 = NUL ;
1759+ WCHAR ch2 = NUL ;
17651760 int modifiers = 0 ;
17661761
17671762 c = tgetch (& modifiers , & ch2 );
17681763
1769- #ifdef FEAT_MBYTE
1770- /* stolen from fill_input_buf() in ui.c */
1771- if (rest != NULL )
1772- {
1773- /* Use remainder of previous call, starts with an invalid
1774- * character that may become valid when reading more. */
1775- if (restlen > TYPEAHEADLEN - typeaheadlen )
1776- unconverted = TYPEAHEADLEN - typeaheadlen ;
1777- else
1778- unconverted = restlen ;
1779- mch_memmove (typeahead + typeaheadlen , rest , unconverted );
1780- if (unconverted == restlen )
1781- {
1782- vim_free (rest );
1783- rest = NULL ;
1784- }
1785- else
1786- {
1787- restlen -= unconverted ;
1788- mch_memmove (rest , rest + unconverted , restlen );
1789- }
1790- typeaheadlen += unconverted ;
1791- }
1792- else
1793- unconverted = 0 ;
1794- #endif
1795-
17961764 if (typebuf_changed (tb_change_cnt ))
17971765 {
17981766 /* "buf" may be invalid now if a client put something in the
@@ -1816,27 +1784,36 @@ mch_inchar(
18161784 int n = 1 ;
18171785 int conv = FALSE;
18181786
1819- typeahead [typeaheadlen ] = c ;
1820- if (ch2 != NUL )
1821- {
1822- typeahead [typeaheadlen + 1 ] = 3 ;
1823- typeahead [typeaheadlen + 2 ] = ch2 ;
1824- n += 2 ;
1825- }
18261787#ifdef FEAT_MBYTE
1827- /* Only convert normal characters, not special keys. Need to
1828- * convert before applying ALT, otherwise mapping <M-x> breaks
1829- * when 'tenc' is set. */
1830- if (input_conv .vc_type != CONV_NONE
1831- && (ch2 == NUL || c != K_NUL ))
1788+ if (ch2 == NUL )
18321789 {
1833- conv = TRUE;
1834- typeaheadlen -= unconverted ;
1835- n = convert_input_safe (typeahead + typeaheadlen ,
1836- n + unconverted , TYPEAHEADLEN - typeaheadlen ,
1837- rest == NULL ? & rest : NULL , & restlen );
1790+ int i ;
1791+ char_u * p ;
1792+ WCHAR ch [2 ];
1793+
1794+ ch [0 ] = c ;
1795+ if (c >= 0xD800 && c <= 0xDBFF ) /* High surrogate */
1796+ {
1797+ ch [1 ] = tgetch (& modifiers , & ch2 );
1798+ n ++ ;
1799+ }
1800+ p = utf16_to_enc (ch , & n );
1801+ if (p != NULL )
1802+ {
1803+ for (i = 0 ; i < n ; i ++ )
1804+ typeahead [typeaheadlen + i ] = p [i ];
1805+ vim_free (p );
1806+ }
18381807 }
1808+ else
18391809#endif
1810+ typeahead [typeaheadlen ] = c ;
1811+ if (ch2 != NUL )
1812+ {
1813+ typeahead [typeaheadlen + n ] = 3 ;
1814+ typeahead [typeaheadlen + n + 1 ] = (char_u )ch2 ;
1815+ n += 2 ;
1816+ }
18401817
18411818 if (conv )
18421819 {
@@ -5366,27 +5343,73 @@ cursor_visible(BOOL fVisible)
53665343
53675344
53685345/*
5369- * write `cchToWrite' characters in `pchBuf' to the screen
5370- * Returns the number of characters actually written (at least one).
5346+ * write `cbToWrite' bytes in `pchBuf' to the screen
5347+ * Returns the number of bytes actually written (at least one).
53715348 */
5372- static BOOL
5349+ static DWORD
53735350write_chars (
5374- LPCSTR pchBuf ,
5375- DWORD cchToWrite )
5351+ char_u * pchBuf ,
5352+ DWORD cbToWrite )
53765353{
53775354 COORD coord = g_coord ;
53785355 DWORD written ;
53795356
5380- FillConsoleOutputAttribute (g_hConOut , g_attrCurrent , cchToWrite ,
5381- coord , & written );
5382- /* When writing fails or didn't write a single character, pretend one
5383- * character was written, otherwise we get stuck. */
5384- if (WriteConsoleOutputCharacter (g_hConOut , pchBuf , cchToWrite ,
5385- coord , & written ) == 0
5386- || written == 0 )
5387- written = 1 ;
5357+ #ifdef FEAT_MBYTE
5358+ if (enc_codepage >= 0 && (int )GetACP () != enc_codepage )
5359+ {
5360+ static WCHAR * unicodebuf = NULL ;
5361+ static int unibuflen = 0 ;
5362+ int length ;
5363+ DWORD n , cchwritten , cells ;
53885364
5389- g_coord .X += (SHORT ) written ;
5365+ length = MultiByteToWideChar (CP_UTF8 , 0 , (LPCSTR )pchBuf , cbToWrite , 0 , 0 );
5366+ if (unicodebuf == NULL || length > unibuflen )
5367+ {
5368+ vim_free (unicodebuf );
5369+ unicodebuf = (WCHAR * )lalloc (length * sizeof (WCHAR ), FALSE);
5370+ unibuflen = length ;
5371+ }
5372+ MultiByteToWideChar (CP_UTF8 , 0 , (LPCSTR )pchBuf , cbToWrite ,
5373+ unicodebuf , unibuflen );
5374+
5375+ cells = mb_string2cells (pchBuf , cbToWrite );
5376+ FillConsoleOutputAttribute (g_hConOut , g_attrCurrent , cells ,
5377+ coord , & written );
5378+ /* When writing fails or didn't write a single character, pretend one
5379+ * character was written, otherwise we get stuck. */
5380+ if (WriteConsoleOutputCharacterW (g_hConOut , unicodebuf , length ,
5381+ coord , & cchwritten ) == 0
5382+ || cchwritten == 0 )
5383+ cchwritten = 1 ;
5384+
5385+ if (cchwritten == length )
5386+ {
5387+ written = cbToWrite ;
5388+ g_coord .X += (SHORT )cells ;
5389+ }
5390+ else
5391+ {
5392+ char_u * p = pchBuf ;
5393+ for (n = 0 ; n < cchwritten ; n ++ )
5394+ mb_cptr_adv (p );
5395+ written = p - pchBuf ;
5396+ g_coord .X += (SHORT )mb_string2cells (pchBuf , written );
5397+ }
5398+ }
5399+ else
5400+ #endif
5401+ {
5402+ FillConsoleOutputAttribute (g_hConOut , g_attrCurrent , cbToWrite ,
5403+ coord , & written );
5404+ /* When writing fails or didn't write a single character, pretend one
5405+ * character was written, otherwise we get stuck. */
5406+ if (WriteConsoleOutputCharacter (g_hConOut , (LPCSTR )pchBuf , cbToWrite ,
5407+ coord , & written ) == 0
5408+ || written == 0 )
5409+ written = 1 ;
5410+
5411+ g_coord .X += (SHORT ) written ;
5412+ }
53905413
53915414 while (g_coord .X > g_srScrollRegion .Right )
53925415 {
0 commit comments