Skip to content

Instantly share code, notes, and snippets.

@ananace
Created March 28, 2023 18:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ananace/e181fa5ba4b016a957f91109bbb0d22f to your computer and use it in GitHub Desktop.
Save ananace/e181fa5ba4b016a957f91109bbb0d22f to your computer and use it in GitHub Desktop.
Wine keyboard layout mapping patch
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index b1c47d5258e..a7a393b5102 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1402,6 +1402,35 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
return TRUE;
}
+/* From the point of view of this function there are two types of
+ * keys: those for which the mapping to vkey and scancode depends on
+ * the keyboard layout (i.e., letters, numbers, punctuation) and those
+ * for which it doesn't (control keys); since this function is used to
+ * recognize the keyboard layout and map keysyms to vkeys and
+ * scancodes, we are only concerned about the first type, and map
+ * everything in the second type to zero.
+ */
+static char keysym_to_char( KeySym keysym )
+{
+ /* Dead keys */
+ if (0xfe50 <= keysym && keysym < 0xfed0)
+ return KEYBOARD_MapDeadKeysym( keysym );
+
+ /* Control keys (there is nothing allocated below 0xfc00, but I
+ take some margin in case something is added in the future) */
+ if (0xf000 <= keysym && keysym < 0x10000)
+ return 0;
+
+ /* XFree86 vendor keys */
+ if (0x10000000 <= keysym)
+ return 0;
+
+ /* "Normal" keys: return last octet, because our tables don't have
+ more than that; it would be better to extend the tables and
+ compare the whole keysym, but it's a lot of work... */
+ return keysym & 0xff;
+}
+
/**********************************************************************
* X11DRV_KEYBOARD_DetectLayout
*
@@ -1432,22 +1461,7 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
/* get data for keycode from X server */
for (i = 0; i < syms; i++) {
if (!(keysym = XkbKeycodeToKeysym( display, keyc, 0, i ))) continue;
- /* Allow both one-byte and two-byte national keysyms */
- if ((keysym < 0x8000) && (keysym != ' '))
- {
- if (!XkbTranslateKeySym(display, &keysym, 0, &ckey[keyc][i], 1, NULL))
- {
- TRACE("XKB could not translate keysym %04lx\n", keysym);
- /* FIXME: query what keysym is used as Mode_switch, fill XKeyEvent
- * with appropriate ShiftMask and Mode_switch, use XLookupString
- * to get character in the local encoding.
- */
- ckey[keyc][i] = keysym & 0xFF;
- }
- }
- else {
- ckey[keyc][i] = KEYBOARD_MapDeadKeysym(keysym);
- }
+ ckey[keyc][i] = keysym_to_char(keysym);
}
}
@@ -1623,19 +1637,7 @@ void X11DRV_InitKeyboard( Display *display )
int maxlen=0,maxval=-1,ok;
for (i=0; i<syms; i++) {
keysym = XkbKeycodeToKeysym( display, keyc, 0, i );
- if ((keysym<0x8000) && (keysym!=' '))
- {
- if (!XkbTranslateKeySym(display, &keysym, 0, &ckey[i], 1, NULL))
- {
- /* FIXME: query what keysym is used as Mode_switch, fill XKeyEvent
- * with appropriate ShiftMask and Mode_switch, use XLookupString
- * to get character in the local encoding.
- */
- ckey[i] = (keysym <= 0x7F) ? keysym : 0;
- }
- } else {
- ckey[i] = KEYBOARD_MapDeadKeysym(keysym);
- }
+ ckey[i] = keysym_to_char(keysym);
}
/* find key with longest match streak */
for (keyn=0; keyn<MAIN_LEN; keyn++) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment