Fix to support input of characters with diacritic symbols using AltGr

Юрий Воротилов jurij.vorotilov at gmail.com
Mon Jul 1 15:29:05 CDT 2013


Fix to support input of characters with diacritic symbols using AltGr (e.g.
Latvian - AltGr+a=ā).
Tested on Ubuntu 12.04 and Centos 6.
I also have a bug opened in Crossover tracker:
http://www.codeweavers.com/support/tickets/browse/?ticket_id=935141

---
 dlls/winex11.drv/keyboard.c |   45
+++++++++++++++++++++++++------------------
 include/winuser.h           |    1 +
 server/queue.c              |    5 ++++-
 3 files changed, 31 insertions(+), 20 deletions(-)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20130701/5441e34d/attachment.html>
-------------- next part --------------
From 2ebb2059a487fc02497a50808858f34c4a3a0c8b Mon Sep 17 00:00:00 2001
From: Yury Vorotilov <jurij.vorotilov at gmail.com>
Date: Mon, 1 Jul 2013 22:47:31 +0300
Subject: Support input of characters with diacritic symbols using AltGr e.g.
 Latvian

---
 dlls/winex11.drv/keyboard.c |   45 +++++++++++++++++++++++++------------------
 include/winuser.h           |    1 +
 server/queue.c              |    5 ++++-
 3 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 039d15b..3bdf53b 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -64,7 +64,7 @@ static int min_keycode, max_keycode, keysyms_per_keycode;
 static KeySym *key_mapping;
 static WORD keyc2vkey[256], keyc2scan[256];
 
-static int NumLockMask, ScrollLockMask, AltGrMask; /* mask in the XKeyEvent state */
+static int NumLockMask, ScrollLockMask, ModeSwitchMask, KeyEventModifiers; /* mask in the XKeyEvent state */
 
 static CRITICAL_SECTION kbd_section;
 static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -1394,7 +1394,7 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
 
        Ref: X Keyboard Extension: Library specification (section 14.1.1 and 17.1.1) */
     /* Save also all possible modifier states. */
-    AltGrMask = event->state & (0x6000 | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
+    KeyEventModifiers = event->state & (0x6000 | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask);
 
     if (TRACE_ON(key)){
 	const char *ksname;
@@ -1422,8 +1422,9 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
     if (!vkey) return;
 
     dwFlags = 0;
-    if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP;
-    if ( vkey & 0x100 )              dwFlags |= KEYEVENTF_EXTENDEDKEY;
+    if ( event->type == KeyRelease )     dwFlags |= KEYEVENTF_KEYUP;
+    if ( vkey & 0x100 )                  dwFlags |= KEYEVENTF_EXTENDEDKEY;
+    if ( event->state & ModeSwitchMask ) dwFlags |= KEYEVENTF_MODE_SWITCH;
 
     update_lock_state( hwnd, vkey, event->state, event_time );
 
@@ -1661,23 +1662,29 @@ void X11DRV_InitKeyboard( Display *display )
     for (i = 0; i < 8; i += 1) /* There are 8 modifier keys */
     {
         int j;
-
         for (j = 0; j < mmp->max_keypermod; j += 1, kcp += 1)
-	    if (*kcp)
+            if (*kcp)
             {
-		int k;
-
-		for (k = 0; k < keysyms_per_keycode; k += 1)
-                    if (keycode_to_keysym(display, *kcp, k) == XK_Num_Lock)
-		    {
+                int k;
+                for (k = 0; k < keysyms_per_keycode; k += 1)
+                {
+                    keysym = keycode_to_keysym(display, *kcp, k);
+                    if (keysym == XK_Num_Lock)
+                    {
                         NumLockMask = 1 << i;
-                        TRACE_(key)("NumLockMask is %x\n", NumLockMask);
-		    }
-                    else if (keycode_to_keysym(display, *kcp, k) == XK_Scroll_Lock)
-		    {
+                        TRACE_(key)("NumLockMask is %X\n", NumLockMask);
+                    }
+                    else if (keysym == XK_Scroll_Lock)
+                    {
                         ScrollLockMask = 1 << i;
-                        TRACE_(key)("ScrollLockMask is %x\n", ScrollLockMask);
-		    }
+                        TRACE_(key)("ScrollLockMask is %X\n", ScrollLockMask);
+                    }
+                    else if (keysym == XK_ISO_Level3_Shift || keysym == XK_ISO_Group_Shift)
+                    {
+                        ModeSwitchMask = 1 << i;
+                        TRACE_(key)("ModeSwitchMask is %X\n", ModeSwitchMask);
+                    }
+                }
             }
     }
     XFreeModifiermap(mmp);
@@ -2508,8 +2515,8 @@ INT CDECL X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, const BYTE *lpKeyState
     }
 
     /* Restore saved AltGr state */
-    TRACE_(key)("AltGrMask = %04x\n", AltGrMask);
-    e.state |= AltGrMask;
+    TRACE_(key)("KeyEventModifiers = %04x\n", KeyEventModifiers);
+    e.state |= KeyEventModifiers;
 
     TRACE_(key)("(%04X, %04X) : faked state = 0x%04x\n",
 		virtKey, scanCode, e.state);
diff --git a/include/winuser.h b/include/winuser.h
index fb0fa95..40411ac 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -2128,6 +2128,7 @@ typedef struct tagCBTACTIVATESTRUCT
 #define KEYEVENTF_KEYUP              0x0002
 #define KEYEVENTF_UNICODE            0x0004
 #define KEYEVENTF_SCANCODE           0x0008
+#define KEYEVENTF_MODE_SWITCH        0x0010
 
   /* mouse_event flags */
 #define MOUSEEVENTF_MOVE            0x0001
diff --git a/server/queue.c b/server/queue.c
index 7aa9b14..647be45 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1744,7 +1744,10 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
     default:
         /* send WM_SYSKEY for Alt-anykey and for F10 */
         if (desktop->keystate[VK_CONTROL] & 0x80) break;
-        if (!(desktop->keystate[VK_MENU] & 0x80)) break;
+        if (!(desktop->keystate[VK_MENU] & 0x80) || input->kbd.flags & KEYEVENTF_MODE_SWITCH)
+        {
+            break;
+        }
         /* fall through */
     case VK_F10:
         message_code = (input->kbd.flags & KEYEVENTF_KEYUP) ? WM_SYSKEYUP : WM_SYSKEYDOWN;
-- 
1.7.9.5


More information about the wine-patches mailing list