From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/keyboard.c | 64 ++++++++++++++++++++++++++++++++++ dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 1 + 3 files changed, 66 insertions(+)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index b1c47d5258e..39f3323b1a4 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1514,6 +1514,68 @@ X11DRV_KEYBOARD_DetectLayout( Display *display ) TRACE("detected layout is "%s"\n", main_key_tab[kbd_layout].comment); }
+static void init_xkb_layouts( Display *display ) +{ + const char *rules, *model, *layouts, *layout, *variants, *variant, *options; + unsigned long count, remaining; + unsigned char *data; + int i, format; + Atom type; + + /* reset kbd_layout to some empty layout entry */ + while (main_key_tab[kbd_layout].comment) kbd_layout++; + + if (XGetWindowProperty( display, DefaultRootWindow( display ), x11drv_atom(_XKB_RULES_NAMES), 0, + 1024, False, XA_STRING, &type, &format, &count, &remaining, &data )) + data = NULL; + + if (!data || type != XA_STRING || format != 8 || remaining) + { + rules = model = layouts = variants = options = ""; + ERR( "Failed to read _XKB_RULES_NAMES property, assuming en-US QWERTY keyboard\n" ); + } + else + { + int pos = 0; + + rules = (char *)data + pos; + pos += strlen( rules ) + 1; + model = (char *)data + pos; + pos += strlen( model ) + 1; + layouts = (char *)data + pos; + pos += strlen( layouts ) + 1; + variants = (char *)data + pos; + pos += strlen( variants ) + 1; + options = (char *)data + pos; + pos += strlen( options ) + 1; + + TRACE( "Found rules %s, model %s, layouts %s, variants %s, options %s\n", debugstr_a(rules), + debugstr_a(model), debugstr_a(layouts), debugstr_a(variants), debugstr_a(options) ); + } + + /* There can be up to 4 active layouts, exposed as Xkb groups, + * with round robin if there is less than 4 configured layouts + */ + for (layout = layouts, variant = variants, i = 0; i < 4; ++i) + { + const char *next_layout = strchr( layout, ',' ), *next_variant = strchr( variant, ',' ); + int layout_len, variant_len; + + if (!next_layout) next_layout = layout + strlen( layout ); + if (!next_variant) next_variant = variant + strlen( variant ); + + layout_len = next_layout - layout; + variant_len = next_variant - variant; + + TRACE( "Found group %u layout %s variant %s\n", i, debugstr_an(layout, layout_len), debugstr_an(variant, variant_len) ); + + layout = *next_layout ? next_layout + 1 : layouts; + variant = *next_layout ? (*next_variant ? next_variant + 1 : next_variant) : variants; + } + + XFree( data ); +} +
/********************************************************************** * X11DRV_InitKeyboard @@ -1579,6 +1641,8 @@ void X11DRV_InitKeyboard( Display *display ) } XFreeModifiermap(mmp);
+ init_xkb_layouts( display ); + /* Detect the keyboard layout */ X11DRV_KEYBOARD_DetectLayout( display ); lkey = main_key_tab[kbd_layout].key; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index c6328cf3fde..ae3da561671 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -515,6 +515,7 @@ enum x11drv_atoms XATOM__GTK_WORKAREAS_D0, XATOM__XEMBED, XATOM__XEMBED_INFO, + XATOM__XKB_RULES_NAMES, XATOM_XdndAware, XATOM_XdndEnter, XATOM_XdndPosition, diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index 46f99e9b83b..6b7cab5a3f2 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -185,6 +185,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] = "_GTK_WORKAREAS_D0", "_XEMBED", "_XEMBED_INFO", + "_XKB_RULES_NAMES", "XdndAware", "XdndEnter", "XdndPosition",