To: [email protected]
Subject: Patch 6.3a.019 (extra)
Fcc: outbox
From: Bram Moolenaar <[email protected]>
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 -- [email protected] -- 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 ///