From: Matteo Bruni <mbruni@codeweavers.com> --- dlls/winex11.drv/keyboard.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 9c18dc9f96a..f52a94f149d 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1443,15 +1443,28 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev ) * kbd_section must be held. */ static void -X11DRV_KEYBOARD_DetectLayout( Display *display ) +X11DRV_KEYBOARD_DetectLayout( Display *display, XModifierKeymap *modmap, unsigned int xkb_group ) { unsigned current, match, mismatch, seq, i, syms; int score, keyc, key, pkey, ok; - KeySym keysym = 0; + KeySym keysym; const char (*lkey)[MAIN_LEN][4]; unsigned max_seq = 0; int max_score = INT_MIN, ismatch = 0; char ckey[256][4]; + unsigned int state, altgr_mod = 0, dummy, mod; + + TRACE("display %p, mmp %p, xkb_group %u\n", display, modmap, xkb_group); + + for (mod = 0; mod < 8 * modmap->max_keypermod; mod++) + { + int xmod = 1 << (mod / modmap->max_keypermod); + + if (!(keyc = modmap->modifiermap[mod])) continue; + XkbLookupKeySym( display, keyc, xkb_group * 0x2000, &dummy, &keysym ); + if (keysym == XK_ISO_Level3_Shift) altgr_mod = xmod; + } + TRACE("AltGr is mapped to mod %#x\n", altgr_mod); syms = keysyms_per_keycode; if (syms > 4) { @@ -1460,10 +1473,13 @@ X11DRV_KEYBOARD_DetectLayout( Display *display ) } memset( ckey, 0, sizeof(ckey) ); - for (keyc = min_keycode; keyc <= max_keycode; keyc++) { + for (keyc = min_keycode; keyc <= max_keycode; keyc++) + { /* get data for keycode from X server */ - for (i = 0; i < syms; i++) { - if (!(keysym = XkbKeycodeToKeysym( display, keyc, 0, i ))) continue; + for (i = 0; i < syms; i++) + { + state = xkb_group << 13 | (i & 1 ? ShiftMask : 0) | (i & 2 ? altgr_mod : 0); + if (!XkbLookupKeySym( display, keyc, state, &dummy, &keysym )) continue; /* Allow both one-byte and two-byte national keysyms */ if ((keysym < 0x8000) && (keysym != ' ')) { @@ -1834,7 +1850,6 @@ void X11DRV_InitKeyboard( Display *display ) } } } - XFreeModifiermap(mmp); s = XkbGetState( display, XkbUseCoreKbd, &xkb_state ); xkb_group = s ? 0 : xkb_state.group; @@ -1861,8 +1876,8 @@ void X11DRV_InitKeyboard( Display *display ) XkbFreeKeyboard( xkb_desc, XkbNamesMask, True ); } - /* Detect the keyboard layout */ - X11DRV_KEYBOARD_DetectLayout( display ); + X11DRV_KEYBOARD_DetectLayout( display, mmp, xkb_group ); + XFreeModifiermap(mmp); x11drv_init_layout( display ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10550