[PATCH 0/3] MR11045: winex11: Create layout when falling back to fuzzy detection.
Next iteration on !11037. It fixes a couple of issues and actually simplifies it a bit further. I'm quite happy of how it looks now :slight_smile: -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11045
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/winex11.drv/keyboard.c | 57 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 4e6ccc11d65..ef97f753665 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1547,35 +1547,6 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev ) return TRUE; } -static BOOL find_xkb_layout_variant( const char *name, const char **layout, const char **variant ) -{ -#ifdef SONAME_LIBXKBREGISTRY - struct rxkb_layout *iter; - - if (rxkb_context) - { - for (iter = p_rxkb_layout_first( rxkb_context ); iter; iter = p_rxkb_layout_next( iter )) - { - const char *desc = p_rxkb_layout_get_description( iter ); - - if (desc && !strcmp( name, desc )) - { - *layout = p_rxkb_layout_get_name( iter ); - *variant = p_rxkb_layout_get_variant( iter ); - return TRUE; - } - } - - WARN( "Unknown Xkb layout name %s\n", debugstr_a(name) ); - } - else - WARN( "libxkbregistry not available, falling back to fuzzy layout detection\n" ); -#else - WARN( "libxkbregistry support not compiled in, falling back to fuzzy layout detection\n" ); -#endif - return FALSE; -} - static const struct layout_id_map_entry { const char *name; @@ -2090,6 +2061,34 @@ static void init_keycode_mappings( Display *display ) } } +static BOOL find_xkb_layout_variant( const char *name, const char **layout, const char **variant ) +{ +#ifdef SONAME_LIBXKBREGISTRY + struct rxkb_layout *iter; + + if (rxkb_context) + { + for (iter = p_rxkb_layout_first( rxkb_context ); iter; iter = p_rxkb_layout_next( iter )) + { + const char *desc = p_rxkb_layout_get_description( iter ); + + if (desc && !strcmp( name, desc )) + { + *layout = p_rxkb_layout_get_name( iter ); + *variant = p_rxkb_layout_get_variant( iter ); + return TRUE; + } + } + + WARN( "Unknown Xkb layout name %s\n", debugstr_a(name) ); + } + else + WARN( "libxkbregistry not available, falling back to fuzzy layout detection\n" ); +#else + WARN( "libxkbregistry support not compiled in, falling back to fuzzy layout detection\n" ); +#endif + return FALSE; +} /* initialize or update keyboard layouts */ void init_keyboard_layouts( Display *display ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11045
From: Matteo Bruni <mbruni@codeweavers.com> We still need main_key_tab[kbd_layout] and related data to map keycodes to VK / scancodes, so we can't quite get rid of the detect_keyboard_layout() call until we take care of that. --- dlls/winex11.drv/keyboard.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index ef97f753665..50bb613e1a5 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1707,9 +1707,9 @@ static DWORD klid_from_xkb_layout( const char *layout, const char *variant ) } /* fuzzy layout detection through keysym / keycode matching, kbd_section must be held */ -static void detect_keyboard_layout( Display *display, XModifierKeymap *modmap, unsigned int xkb_group ) +static unsigned int detect_keyboard_layout( Display *display, XModifierKeymap *modmap, unsigned int xkb_group ) { - unsigned current, match, mismatch, seq, i, syms; + unsigned current, match, mismatch, seq, i, syms, best_layout = 0; int score, keyc, key, pkey, ok; KeySym keysym; const char (*lkey)[MAIN_LEN][4]; @@ -1814,7 +1814,7 @@ static void detect_keyboard_layout( Display *display, XModifierKeymap *modmap, u match, mismatch, seq, score); if (score + (int)seq > max_score + (int)max_seq) { /* best match so far */ - kbd_layout = current; + best_layout = current; max_score = score; max_seq = seq; ismatch = !mismatch; @@ -1823,9 +1823,10 @@ static void detect_keyboard_layout( Display *display, XModifierKeymap *modmap, u /* we're done, report results if necessary */ if (!ismatch) WARN("Using closest match (%s) for scan/virtual codes mapping.\n", - main_key_tab[kbd_layout].comment); + main_key_tab[best_layout].comment); - TRACE("detected layout is \"%s\"\n", main_key_tab[kbd_layout].comment); + TRACE("detected layout is \"%s\"\n", main_key_tab[best_layout].comment); + return best_layout; } @@ -2173,7 +2174,7 @@ void init_keyboard_layouts( Display *display ) XkbFreeKeyboard( xkb_desc, 0, True ); } - detect_keyboard_layout( display, mmp, xkb_group ); + kbd_layout = detect_keyboard_layout( display, mmp, xkb_group ); XFreeModifiermap( mmp ); if (xkb_lang && xkb_lang != main_key_tab[kbd_layout].lcid) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11045
From: Matteo Bruni <mbruni@codeweavers.com> --- dlls/winex11.drv/keyboard.c | 71 +++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 50bb613e1a5..3d5d2c81f03 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1669,6 +1669,14 @@ static LANGID langid_from_xkb_layout( const char *layout ) return MAKELANGID(LANG_NEUTRAL, SUBLANG_CUSTOM_UNSPECIFIED); }; +static const char *xkb_layout_from_langid( LANGID langid ) +{ + for (int i = 0; i < ARRAY_SIZE(layout_ids); i++) + if (langid == layout_ids[i].langid) + return layout_ids[i].name; + return NULL; +} + static const struct klid_map_entry { const char *layout; @@ -2062,12 +2070,16 @@ static void init_keycode_mappings( Display *display ) } } -static BOOL find_xkb_layout_variant( const char *name, const char **layout, const char **variant ) +static void find_xkb_layout_variant( Display *display, XModifierKeymap *mmp, int group, const char *name, + const char **layout, const char **variant ) { + unsigned int index; #ifdef SONAME_LIBXKBREGISTRY struct rxkb_layout *iter; - if (rxkb_context) + if (!rxkb_context) WARN( "libxkbregistry not available, falling back to fuzzy layout detection\n" ); + else if (!name) WARN( "Xkb layout name not found, falling back to fuzzy layout detection\n" ); + else { for (iter = p_rxkb_layout_first( rxkb_context ); iter; iter = p_rxkb_layout_next( iter )) { @@ -2077,23 +2089,25 @@ static BOOL find_xkb_layout_variant( const char *name, const char **layout, cons { *layout = p_rxkb_layout_get_name( iter ); *variant = p_rxkb_layout_get_variant( iter ); - return TRUE; + return; } } WARN( "Unknown Xkb layout name %s\n", debugstr_a(name) ); } - else - WARN( "libxkbregistry not available, falling back to fuzzy layout detection\n" ); #else WARN( "libxkbregistry support not compiled in, falling back to fuzzy layout detection\n" ); #endif - return FALSE; + + index = detect_keyboard_layout( display, mmp, group ); + *layout = xkb_layout_from_langid( main_key_tab[index].lcid ); + if (strstr( main_key_tab[index].comment, "dvorak" )) *variant = "dvorak"; } /* initialize or update keyboard layouts */ void init_keyboard_layouts( Display *display ) { + char *names[4] = { NULL }; unsigned int xkb_group; XkbStateRec xkb_state; XModifierKeymap *mmp; @@ -2102,6 +2116,7 @@ void init_keyboard_layouts( Display *display ) LANGID xkb_lang = 0; Status status; KeyCode *kcp; + int count; pthread_mutex_lock( &kbd_mutex ); XDisplayKeycodes( display, &min_keycode, &max_keycode ); @@ -2139,39 +2154,35 @@ void init_keyboard_layouts( Display *display ) if ((xkb_desc = XkbGetMap( display, XkbAllClientInfoMask, XkbUseCoreKbd ))) { - char *names[4]; - int count; - XkbGetNames( display, XkbGroupNamesMask, xkb_desc ); for (count = 0; count < ARRAY_SIZE(xkb_desc->names->groups); count++) if (!xkb_desc->names->groups[count]) break; if (!XGetAtomNames( display, xkb_desc->names->groups, count, names )) count = 0; - TRACE("Found %u group names\n", count); - for (int i = 0; i < count; i++) - { - const char *layout, *variant = NULL; - char buffer[1024]; - DWORD klid; - LANGID lang; + TRACE( "Found %u group names\n", count ); + XkbFreeKeyboard( xkb_desc, 0, True ); + } + else count = status ? 1 : 4; - if (!names[i]) continue; - if (find_xkb_layout_variant( names[i], &layout, &variant )) - { - lang = langid_from_xkb_layout( layout ); - klid = klid_from_xkb_layout( layout, variant ); - if (i == xkb_group) xkb_lang = lang; + for (int i = 0; i < count; i++) + { + const char *layout, *variant = NULL; + char buffer[1024]; + DWORD klid; + LANGID lang; - TRACE( "Found group %u with name %s -> layout %s:%s, lang %04x, klid %08x\n", i, debugstr_a(names[i]), - debugstr_a(layout), debugstr_a(variant), lang, klid ); + find_xkb_layout_variant( display, mmp, i, names[i], &layout, &variant ); + lang = langid_from_xkb_layout( layout ); + klid = klid_from_xkb_layout( layout, variant ); + if (i == xkb_group) xkb_lang = lang; - snprintf( buffer, ARRAY_SIZE(buffer), "%s:%s", layout, variant ); - create_layout_from_xkb( i, buffer, lang, klid ); - } - XFree( names[i] ); - } + TRACE( "Found group %u with name %s -> layout %s:%s, lang %04x, klid %08x\n", i, debugstr_a(names[i]), + debugstr_a(layout), debugstr_a(variant), lang, klid ); - XkbFreeKeyboard( xkb_desc, 0, True ); + snprintf( buffer, ARRAY_SIZE(buffer), "%s:%s", layout, variant ); + create_layout_from_xkb( i, buffer, lang, klid ); + + if (names[i]) XFree( names[i] ); } kbd_layout = detect_keyboard_layout( display, mmp, xkb_group ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11045
This merge request was approved by Matteo Bruni. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11045
This merge request was approved by Rémi Bernon. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11045
participants (4)
-
Matteo Bruni -
Matteo Bruni (@Mystral) -
Rémi Bernon -
Rémi Bernon (@rbernon)