wok-next diff lxpanel/stuff/Fix-failure-to-react-to-keyboard-map-changes-initiat.patch @ rev 8638

Up: fltk-2.0.x to r7725.
author Christopher Rogers <slaxemulator@gmail.com>
date Tue Feb 15 03:33:42 2011 +0000 (2011-02-15)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/lxpanel/stuff/Fix-failure-to-react-to-keyboard-map-changes-initiat.patch	Tue Feb 15 03:33:42 2011 +0000
     1.3 @@ -0,0 +1,555 @@
     1.4 +From 438d9fdbd3e0be04de933705917d508a02b7c04b Mon Sep 17 00:00:00 2001
     1.5 +From: Marty Jack <martyj@linux.local>
     1.6 +Date: Sat, 20 Feb 2010 16:23:57 -0500
     1.7 +Subject: [PATCH 4/5] Fix failure to react to keyboard map changes initiated outside the plugin
     1.8 + - Occurred when setxkbmap was run, or when HAL configured the keyboard at X startup
     1.9 + - Caused by failure to process the NewKeyboard event
    1.10 + - Caused by dropping events due to faulty code to read them
    1.11 + - Cosmetic change, the tooltip now the Xkb Group name rather than Xkb Symbol name
    1.12 +
    1.13 +---
    1.14 + src/plugins/xkb/xkb-plugin.c |   92 +++++++++--------
    1.15 + src/plugins/xkb/xkb.c        |  236 +++++++++++++++++++++--------------------
    1.16 + src/plugins/xkb/xkb.h        |    7 +-
    1.17 + 3 files changed, 173 insertions(+), 162 deletions(-)
    1.18 +
    1.19 +diff --git a/src/plugins/xkb/xkb-plugin.c b/src/plugins/xkb/xkb-plugin.c
    1.20 +index f49a77d..80a14ba 100644
    1.21 +--- a/src/plugins/xkb/xkb-plugin.c
    1.22 ++++ b/src/plugins/xkb/xkb-plugin.c
    1.23 +@@ -1,18 +1,23 @@
    1.24 +-/*
    1.25 +-//====================================================================
    1.26 +-//  xfce4-xkb-plugin - XFCE4 Xkb Layout Indicator panel plugin
    1.27 +-// -------------------------------------------------------------------
    1.28 +-//  Alexander Iliev <sasoiliev@mamul.org>
    1.29 +-//  20-Feb-04
    1.30 +-// -------------------------------------------------------------------
    1.31 +-//  Parts of this code belong to Michael Glickman <wmalms@yahooo.com>
    1.32 +-//  and his program wmxkb.
    1.33 +-//  WARNING: DO NOT BOTHER Michael Glickman WITH QUESTIONS ABOUT THIS
    1.34 +-//           PROGRAM!!! SEND INSTEAD EMAILS TO <sasoiliev@mamul.org>
    1.35 +-//====================================================================
    1.36 +-*/
    1.37 +-
    1.38 +-/* Modified by Hong Jen Yee (PCMan) <pcman.tw@gmail.com> on 2008-04-06 for lxpanel */
    1.39 ++/**
    1.40 ++ * Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
    1.41 ++ *
    1.42 ++ * This program is free software; you can redistribute it and/or modify
    1.43 ++ * it under the terms of the GNU General Public License as published by
    1.44 ++ * the Free Software Foundation; either version 2 of the License, or
    1.45 ++ * (at your option) any later version.
    1.46 ++ *
    1.47 ++ * This program is distributed in the hope that it will be useful,
    1.48 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.49 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.50 ++ * GNU General Public License for more details.
    1.51 ++ *
    1.52 ++ * You should have received a copy of the GNU General Public License
    1.53 ++ * along with this program; if not, write to the Free Software Foundation,
    1.54 ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    1.55 ++ */
    1.56 ++
    1.57 ++/* Originally derived from xfce4-xkb-plugin, Copyright 2004 Alexander Iliev,
    1.58 ++ * which credits Michael Glickman. */
    1.59 + 
    1.60 + #ifdef HAVE_CONFIG_H
    1.61 + #include <config.h>
    1.62 +@@ -49,38 +54,45 @@ void xkb_redraw(XkbPlugin * xkb)
    1.63 +     if (xkb->display_type == IMAGE)
    1.64 +     {
    1.65 +         int size = xkb->plugin->panel->icon_size;
    1.66 +-        char * group_name = (char *) xkb_get_current_group_name_lowercase(xkb);
    1.67 +-        char * filename = g_strdup_printf("%s/%s.png", FLAGSDIR, group_name);
    1.68 +-        GdkPixbuf * unscaled_pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
    1.69 +-        g_free(filename);
    1.70 +-        g_free(group_name);
    1.71 +-
    1.72 +-        if (unscaled_pixbuf != NULL)
    1.73 ++        char * group_name = (char *) xkb_get_current_symbol_name_lowercase(xkb);
    1.74 ++        if (group_name != NULL)
    1.75 +         {
    1.76 +-            /* Loaded successfully. */
    1.77 +-            int width = gdk_pixbuf_get_width(unscaled_pixbuf);
    1.78 +-            int height = gdk_pixbuf_get_height(unscaled_pixbuf);
    1.79 +-            GdkPixbuf * pixbuf = gdk_pixbuf_scale_simple(unscaled_pixbuf, size * width / height, size, GDK_INTERP_BILINEAR);
    1.80 +-            if (pixbuf != NULL)
    1.81 ++            char * filename = g_strdup_printf("%s/%s.png", FLAGSDIR, group_name);
    1.82 ++            GdkPixbuf * unscaled_pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
    1.83 ++            g_free(filename);
    1.84 ++            g_free(group_name);
    1.85 ++
    1.86 ++            if (unscaled_pixbuf != NULL)
    1.87 +             {
    1.88 +-                gtk_image_set_from_pixbuf(GTK_IMAGE(xkb->image), pixbuf);
    1.89 +-                g_object_unref(G_OBJECT(pixbuf));
    1.90 +-                gtk_widget_hide(xkb->label);
    1.91 +-                gtk_widget_show(xkb->image);
    1.92 +-                gtk_widget_set_tooltip_text(xkb->btn, xkb_get_current_group_name(xkb));
    1.93 +-                valid_image = TRUE;
    1.94 ++                /* Loaded successfully. */
    1.95 ++                int width = gdk_pixbuf_get_width(unscaled_pixbuf);
    1.96 ++                int height = gdk_pixbuf_get_height(unscaled_pixbuf);
    1.97 ++                GdkPixbuf * pixbuf = gdk_pixbuf_scale_simple(unscaled_pixbuf, size * width / height, size, GDK_INTERP_BILINEAR);
    1.98 ++                if (pixbuf != NULL)
    1.99 ++                {
   1.100 ++                    gtk_image_set_from_pixbuf(GTK_IMAGE(xkb->image), pixbuf);
   1.101 ++                    g_object_unref(G_OBJECT(pixbuf));
   1.102 ++                    gtk_widget_hide(xkb->label);
   1.103 ++                    gtk_widget_show(xkb->image);
   1.104 ++                    gtk_widget_set_tooltip_text(xkb->btn, xkb_get_current_group_name(xkb));
   1.105 ++                    valid_image = TRUE;
   1.106 ++                }
   1.107 ++                g_object_unref(unscaled_pixbuf);
   1.108 +             }
   1.109 +-            g_object_unref(unscaled_pixbuf);
   1.110 +         }
   1.111 +     }
   1.112 + 
   1.113 +     /* Set the label. */
   1.114 +     if ((xkb->display_type == TEXT) || ( ! valid_image))
   1.115 +     {
   1.116 +-        panel_draw_label_text(xkb->plugin->panel, xkb->label, (char *) xkb_get_current_group_name(xkb), TRUE, TRUE);
   1.117 +-        gtk_widget_hide(xkb->image);
   1.118 +-        gtk_widget_show(xkb->label);
   1.119 +-        gtk_widget_set_tooltip_text(xkb->btn, NULL);
   1.120 ++        char * group_name = (char *) xkb_get_current_symbol_name(xkb);
   1.121 ++        if (group_name != NULL)
   1.122 ++        {
   1.123 ++            panel_draw_label_text(xkb->plugin->panel, xkb->label, (char *) group_name, TRUE, TRUE);
   1.124 ++            gtk_widget_hide(xkb->image);
   1.125 ++            gtk_widget_show(xkb->label);
   1.126 ++            gtk_widget_set_tooltip_text(xkb->btn, xkb_get_current_group_name(xkb));
   1.127 ++        }
   1.128 +     }
   1.129 + }
   1.130 + 
   1.131 +@@ -196,10 +208,6 @@ static int xkb_constructor(Plugin * plugin, char ** fp)
   1.132 +     /* Initialize the XKB interface. */
   1.133 +     xkb_mechanism_constructor(xkb);
   1.134 + 
   1.135 +-    /* Initialize a channel to listen for XKB events. */
   1.136 +-    GIOChannel * channel = g_io_channel_unix_new(xkb_get_connection_number(xkb));
   1.137 +-    xkb->source_id = g_io_add_watch(channel, G_IO_IN | G_IO_PRI, (GIOFunc) xkb_gio_callback, (gpointer) xkb);
   1.138 +-
   1.139 +     /* Connect signals. */
   1.140 +     g_signal_connect(xkb->btn, "button-press-event", G_CALLBACK(xkb_button_press_event), xkb);
   1.141 +     g_signal_connect(xkb->btn, "scroll-event", G_CALLBACK(xkb_scroll_event), xkb);
   1.142 +diff --git a/src/plugins/xkb/xkb.c b/src/plugins/xkb/xkb.c
   1.143 +index 5bb0c39..898a931 100644
   1.144 +--- a/src/plugins/xkb/xkb.c
   1.145 ++++ b/src/plugins/xkb/xkb.c
   1.146 +@@ -1,18 +1,23 @@
   1.147 +-/*
   1.148 +-// ====================================================================
   1.149 +-//  xfce4-xkb-plugin - XFCE4 Xkb Layout Indicator panel plugin
   1.150 +-// -------------------------------------------------------------------
   1.151 +-//  Alexander Iliev <sasoiliev@mamul.org>
   1.152 +-//  20-Feb-04
   1.153 +-// -------------------------------------------------------------------
   1.154 +-//  Parts of this code belong to Michael Glickman <wmalms@yahooo.com>
   1.155 +-//  and his program wmxkb.
   1.156 +-//  WARNING: DO NOT BOTHER Michael Glickman WITH QUESTIONS ABOUT THIS
   1.157 +-//           PROGRAM!!! SEND INSTEAD EMAILS TO <sasoiliev@mamul.org>
   1.158 +-//====================================================================
   1.159 +-*/
   1.160 +-
   1.161 +-/* Modified by Hong Jen Yee (PCMan) <pcman.tw@gmail.com> on 2008-04-06 for lxpanel */
   1.162 ++/**
   1.163 ++ * Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
   1.164 ++ *
   1.165 ++ * This program is free software; you can redistribute it and/or modify
   1.166 ++ * it under the terms of the GNU General Public License as published by
   1.167 ++ * the Free Software Foundation; either version 2 of the License, or
   1.168 ++ * (at your option) any later version.
   1.169 ++ *
   1.170 ++ * This program is distributed in the hope that it will be useful,
   1.171 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
   1.172 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   1.173 ++ * GNU General Public License for more details.
   1.174 ++ *
   1.175 ++ * You should have received a copy of the GNU General Public License
   1.176 ++ * along with this program; if not, write to the Free Software Foundation,
   1.177 ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   1.178 ++ */
   1.179 ++
   1.180 ++/* Originally derived from xfce4-xkb-plugin, Copyright 2004 Alexander Iliev,
   1.181 ++ * which credits Michael Glickman. */
   1.182 + 
   1.183 + #include "xkb.h"
   1.184 + 
   1.185 +@@ -26,9 +31,13 @@
   1.186 + #include <gdk-pixbuf/gdk-pixbuf.h>
   1.187 + #include <glib.h>
   1.188 + 
   1.189 ++/* The X Keyboard Extension: Library Specification
   1.190 ++ * http://www.xfree86.org/current/XKBlib.pdf */
   1.191 ++
   1.192 + static void xkb_enter_locale_by_process(XkbPlugin * xkb);
   1.193 + static void refresh_group_xkb(XkbPlugin * xkb);
   1.194 +-static int do_init_xkb(XkbPlugin * xkb);
   1.195 ++static int initialize_keyboard_description(XkbPlugin * xkb);
   1.196 ++static GdkFilterReturn xkb_event_filter(GdkXEvent * xevent, GdkEvent * event, XkbPlugin * xkb);
   1.197 + 
   1.198 + /* Insert a process and its layout into the hash table. */
   1.199 + static void xkb_enter_locale_by_process(XkbPlugin * xkb)
   1.200 +@@ -56,60 +65,65 @@ int xkb_get_group_count(XkbPlugin * xkb)
   1.201 +   return xkb->group_count;
   1.202 + }
   1.203 + 
   1.204 ++/* Get the current group name. */
   1.205 ++const char * xkb_get_current_group_name(XkbPlugin * xkb) 
   1.206 ++{
   1.207 ++    return xkb->group_names[xkb->current_group_xkb_no];
   1.208 ++}
   1.209 ++
   1.210 + /* Convert a group number to a symbol name. */
   1.211 + const char * xkb_get_symbol_name_by_res_no(XkbPlugin * xkb, int n) 
   1.212 + {
   1.213 +     return xkb->symbol_names[n];
   1.214 + }
   1.215 + 
   1.216 +-/* Get the current group name. */
   1.217 +-const char * xkb_get_current_group_name(XkbPlugin * xkb) 
   1.218 ++/* Get the current symbol name. */
   1.219 ++const char * xkb_get_current_symbol_name(XkbPlugin * xkb) 
   1.220 + {
   1.221 +     return xkb_get_symbol_name_by_res_no(xkb, xkb->current_group_xkb_no);
   1.222 + }
   1.223 + 
   1.224 +-/* Get the current group name converted to lowercase. */
   1.225 +-const char * xkb_get_current_group_name_lowercase(XkbPlugin * xkb) 
   1.226 ++/* Get the current symbol name converted to lowercase. */
   1.227 ++const char * xkb_get_current_symbol_name_lowercase(XkbPlugin * xkb) 
   1.228 + {
   1.229 +-    const char * tmp = xkb_get_current_group_name(xkb);
   1.230 +-    return g_utf8_strdown(tmp, -1);
   1.231 ++    const char * tmp = xkb_get_current_symbol_name(xkb);
   1.232 ++    return ((tmp != NULL) ? g_utf8_strdown(tmp, -1) : NULL);
   1.233 + }
   1.234 + 
   1.235 + /* Refresh current group number from Xkb state. */
   1.236 + static void refresh_group_xkb(XkbPlugin * xkb) 
   1.237 + {
   1.238 +     XkbStateRec xkb_state;
   1.239 +-    XkbGetState(xkb->dsp, xkb->device_id, &xkb_state);
   1.240 ++    XkbGetState(GDK_DISPLAY(), XkbUseCoreKbd, &xkb_state);
   1.241 +     xkb->current_group_xkb_no = xkb_state.group;
   1.242 + }
   1.243 + 
   1.244 +-/* Initialize the Xkb structures. */
   1.245 +-static int do_init_xkb(XkbPlugin * xkb) 
   1.246 ++/* Initialize the keyboard description initially or after a NewKeyboard event. */
   1.247 ++static int initialize_keyboard_description(XkbPlugin * xkb)
   1.248 + {
   1.249 +-    /* Create hash table. */
   1.250 +-    xkb->group_hash_table = g_hash_table_new(g_direct_hash, NULL);
   1.251 +-
   1.252 +-    /* Initialize the Xkb extension. */
   1.253 +-    int major, minor, opcode;
   1.254 +-    Bool status = XkbQueryExtension(xkb->dsp, &opcode,
   1.255 +-        &xkb->base_event_code, &xkb->base_error_code, &major, &minor);
   1.256 +-
   1.257 +-    /* Use the core keyboard. */
   1.258 +-    xkb->device_id = XkbUseCoreKbd;
   1.259 ++    /* Free the strings. */
   1.260 ++    int i;
   1.261 ++    for (i = 0; i < XkbNumKbdGroups; i += 1)
   1.262 ++    {
   1.263 ++        g_free(xkb->group_names[i]);
   1.264 ++        g_free(xkb->symbol_names[i]);
   1.265 ++        xkb->group_names[i] = NULL;
   1.266 ++        xkb->symbol_names[i] = NULL;
   1.267 ++    }
   1.268 + 
   1.269 +     /* Allocate a keyboard description structure. */
   1.270 ++    int status = False;
   1.271 +     XkbDescRec * kbd_desc_ptr = XkbAllocKeyboard();
   1.272 +     if (kbd_desc_ptr == NULL)
   1.273 +     {
   1.274 +         ERR("Failed to get keyboard description\n");
   1.275 +         goto HastaLaVista;
   1.276 +     }
   1.277 +-    kbd_desc_ptr->dpy = xkb->dsp;
   1.278 + 
   1.279 +     /* Fetch information into the keyboard description. */
   1.280 +-    XkbGetControls(xkb->dsp, XkbAllControlsMask, kbd_desc_ptr);
   1.281 +-    XkbGetNames(xkb->dsp, XkbSymbolsNameMask, kbd_desc_ptr);
   1.282 +-    XkbGetNames(xkb->dsp, XkbGroupNamesMask, kbd_desc_ptr);
   1.283 ++    XkbGetControls(GDK_DISPLAY(), XkbAllControlsMask, kbd_desc_ptr);
   1.284 ++    XkbGetNames(GDK_DISPLAY(), XkbSymbolsNameMask, kbd_desc_ptr);
   1.285 ++    XkbGetNames(GDK_DISPLAY(), XkbGroupNamesMask, kbd_desc_ptr);
   1.286 + 
   1.287 +     if (kbd_desc_ptr->names == NULL)
   1.288 +     {
   1.289 +@@ -137,12 +151,11 @@ static int do_init_xkb(XkbPlugin * xkb)
   1.290 + 
   1.291 +     /* Determine the group names.  Trim off text beginning at a '('. */
   1.292 +     const Atom * tmp_group_source = kbd_desc_ptr->names->groups;
   1.293 +-    int i;
   1.294 +     for (i = 0; i < xkb->group_count; i++)
   1.295 +     {
   1.296 +         if (tmp_group_source[i] != None)
   1.297 +         {
   1.298 +-            char * ptr = XGetAtomName(xkb->dsp, tmp_group_source[i]);
   1.299 ++            char * ptr = XGetAtomName(GDK_DISPLAY(), tmp_group_source[i]);
   1.300 +             xkb->group_names[i] = ptr;
   1.301 +             if ((ptr != NULL) && ((ptr = strchr(ptr, '('))) != NULL)
   1.302 +                 *ptr = '\0';
   1.303 +@@ -153,7 +166,7 @@ static int do_init_xkb(XkbPlugin * xkb)
   1.304 +     Atom sym_name_atom = kbd_desc_ptr->names->symbols;
   1.305 +     char * sym_name;
   1.306 +     if ((sym_name_atom == None)
   1.307 +-    || ((sym_name = XGetAtomName(xkb->dsp, sym_name_atom)) == NULL))
   1.308 ++    || ((sym_name = XGetAtomName(GDK_DISPLAY(), sym_name_atom)) == NULL))
   1.309 +         goto HastaLaVista;
   1.310 + 
   1.311 +     /* Parse and store symbol names. */
   1.312 +@@ -190,83 +203,106 @@ static int do_init_xkb(XkbPlugin * xkb)
   1.313 +     {
   1.314 +         xkb->group_count = 2;
   1.315 +         xkb->symbol_names[1] = xkb->symbol_names[0];
   1.316 +-        xkb->symbol_names[0] = strdup("us");
   1.317 +-        xkb->group_names[0] = strdup("US/ASCII");
   1.318 +-        xkb->group_names[1] = strdup("Japanese");
   1.319 ++        xkb->symbol_names[0] = g_strdup("us");
   1.320 ++        xkb->group_names[0] = g_strdup("US/ASCII");
   1.321 ++        xkb->group_names[1] = g_strdup("Japanese");
   1.322 +     }
   1.323 +     else if (count < xkb->group_count)
   1.324 +     {
   1.325 +         /* Ensure that the names are fully initialized. */
   1.326 +         int j = count, k = xkb->group_count;
   1.327 +         while(--j >= 0) xkb->symbol_names[--k] = xkb->symbol_names[j];
   1.328 +-        while(--k >= 0) xkb->symbol_names[k] = strdup("en_US");
   1.329 ++        while(--k >= 0) xkb->symbol_names[k] = g_strdup("en_US");
   1.330 +     }
   1.331 + 
   1.332 +-    /* Enxure that the names are fully initialized. */
   1.333 ++    /* Ensure that the names are fully initialized. */
   1.334 +     for (i = 0; i < xkb->group_count; i++)
   1.335 +     {
   1.336 +         if (xkb->symbol_names[i] == NULL)
   1.337 +         {
   1.338 +             ERR("\nGroup Symbol %i is undefined, set to 'U/A' !\n", i+1);
   1.339 +-            xkb->symbol_names[i] = strdup("U/A");
   1.340 ++            xkb->symbol_names[i] = g_strdup("U/A");
   1.341 +         }
   1.342 +     }
   1.343 + 
   1.344 ++    /* Create or recreate hash table.
   1.345 ++     * The layout that was associated to the windows may or may not be at the same group number,
   1.346 ++     * and worse, may no longer exist, which there is no meaningful way to deal with. */
   1.347 ++    if (xkb->group_hash_table != NULL)
   1.348 ++        g_hash_table_destroy(xkb->group_hash_table);
   1.349 ++    xkb->group_hash_table = g_hash_table_new(g_direct_hash, NULL);
   1.350 ++
   1.351 +     status = True;
   1.352 + 
   1.353 + HastaLaVista:
   1.354 +     if (kbd_desc_ptr != NULL)
   1.355 +         XkbFreeKeyboard(kbd_desc_ptr, 0, True);
   1.356 ++
   1.357 +     return status;
   1.358 + }
   1.359 + 
   1.360 ++/* GDK event filter that receives events from all windows and the Xkb extension. */
   1.361 ++static GdkFilterReturn xkb_event_filter(GdkXEvent * xevent, GdkEvent * event, XkbPlugin * xkb)
   1.362 ++{
   1.363 ++    XEvent * ev = (XEvent *) xevent;
   1.364 ++
   1.365 ++    if (ev->xany.type == xkb->base_event_code + XkbEventCode)
   1.366 ++    {
   1.367 ++        /* Xkb event. */
   1.368 ++        XkbEvent * xkbev = (XkbEvent *) ev;
   1.369 ++        if (xkbev->any.xkb_type == XkbNewKeyboardNotify)
   1.370 ++        {
   1.371 ++            initialize_keyboard_description(xkb);
   1.372 ++            refresh_group_xkb(xkb);
   1.373 ++            xkb_redraw(xkb);
   1.374 ++            xkb_enter_locale_by_process(xkb);
   1.375 ++        }
   1.376 ++        else if (xkbev->any.xkb_type == XkbStateNotify)
   1.377 ++        {
   1.378 ++            if (xkbev->state.group != xkb->current_group_xkb_no)
   1.379 ++            {
   1.380 ++                /* Switch to the new group and redraw the display. */
   1.381 ++                xkb->current_group_xkb_no = xkbev->state.group;
   1.382 ++                refresh_group_xkb(xkb);
   1.383 ++                xkb_redraw(xkb);
   1.384 ++                xkb_enter_locale_by_process(xkb);
   1.385 ++            }
   1.386 ++        }
   1.387 ++    }
   1.388 ++    return GDK_FILTER_CONTINUE;
   1.389 ++}
   1.390 ++
   1.391 + /* Initialize the Xkb interface. */
   1.392 + void xkb_mechanism_constructor(XkbPlugin * xkb)
   1.393 + {
   1.394 +-    /* Enable the Xkb extension on all clients. */
   1.395 +-    XkbIgnoreExtension(False);
   1.396 +-
   1.397 +-    /* Open the display. */
   1.398 +-    int major = XkbMajorVersion;
   1.399 +-    int minor = XkbMinorVersion;
   1.400 +-    char * display_name = "";
   1.401 +-    int event_code;
   1.402 +-    int error_rtrn;
   1.403 +-    int reason_rtrn;
   1.404 +-    xkb->dsp = XkbOpenDisplay(display_name, &event_code, &error_rtrn, &major, &minor, &reason_rtrn);
   1.405 +-
   1.406 +-    switch (reason_rtrn)
   1.407 ++    /* Initialize Xkb extension. */
   1.408 ++    int opcode;
   1.409 ++    int maj = XkbMajorVersion;
   1.410 ++    int min = XkbMinorVersion;
   1.411 ++    if ((XkbLibraryVersion(&maj, &min))
   1.412 ++    && (XkbQueryExtension(GDK_DISPLAY(), &opcode, &xkb->base_event_code, &xkb->base_error_code, &maj, &min)))
   1.413 +     {
   1.414 +-        case XkbOD_BadLibraryVersion:
   1.415 +-            ERR("Bad XKB library version.\n");
   1.416 +-            return;
   1.417 +-        case XkbOD_ConnectionRefused:
   1.418 +-            ERR("Connection to X server refused.\n");
   1.419 +-            return;
   1.420 +-        case XkbOD_BadServerVersion:
   1.421 +-            ERR("Bad X server version.\n");
   1.422 +-            return;
   1.423 +-        case XkbOD_NonXkbServer:
   1.424 +-            ERR("XKB not present.\n");
   1.425 +-            return;
   1.426 +-        case XkbOD_Success:
   1.427 +-            break;
   1.428 +-    }
   1.429 ++        /* Read the keyboard description. */
   1.430 ++        initialize_keyboard_description(xkb);
   1.431 + 
   1.432 +-    /* Initialize our mechanism. */
   1.433 +-    if (do_init_xkb(xkb) != True)
   1.434 +-        return;
   1.435 ++        /* Establish GDK event filter. */
   1.436 ++        gdk_window_add_filter(NULL, (GdkFilterFunc) xkb_event_filter, (gpointer) xkb);
   1.437 + 
   1.438 +-    /* Specify events we will receive. */
   1.439 +-    XkbSelectEventDetails(xkb->dsp, xkb->device_id, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupStateMask);
   1.440 ++        /* Specify events we will receive. */
   1.441 ++        XkbSelectEvents(GDK_DISPLAY(), XkbUseCoreKbd, XkbNewKeyboardNotifyMask, XkbNewKeyboardNotifyMask);
   1.442 ++        XkbSelectEventDetails(GDK_DISPLAY(), XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupStateMask);
   1.443 + 
   1.444 +-    /* Get current state. */
   1.445 +-    refresh_group_xkb(xkb);
   1.446 ++        /* Get current state. */
   1.447 ++        refresh_group_xkb(xkb);
   1.448 ++    }
   1.449 + }
   1.450 + 
   1.451 + /* Deallocate resources associated with Xkb interface. */
   1.452 + void xkb_mechanism_destructor(XkbPlugin * xkb) 
   1.453 + {
   1.454 ++    /* Remove event filter. */
   1.455 ++    gdk_window_remove_filter(NULL, (GdkFilterFunc) xkb_event_filter, xkb);
   1.456 ++
   1.457 +     /* Free group and symbol name memory. */
   1.458 +     int i;
   1.459 +     for (i = 0; i < xkb->group_count; i++)
   1.460 +@@ -283,21 +319,11 @@ void xkb_mechanism_destructor(XkbPlugin * xkb)
   1.461 +         }
   1.462 +     }
   1.463 + 
   1.464 +-    /* Close the display. */
   1.465 +-    XCloseDisplay(xkb->dsp);
   1.466 +-    xkb->dsp = NULL;
   1.467 +-
   1.468 +     /* Destroy the hash table. */
   1.469 +     g_hash_table_destroy(xkb->group_hash_table);
   1.470 +     xkb->group_hash_table = NULL;
   1.471 + }
   1.472 + 
   1.473 +-/* Return the connection number for the display. */
   1.474 +-int xkb_get_connection_number(XkbPlugin * xkb)
   1.475 +-{
   1.476 +-    return ConnectionNumber(xkb->dsp);
   1.477 +-}
   1.478 +-
   1.479 + /* Set the layout to the next layout. */
   1.480 + int xkb_change_group(XkbPlugin * xkb, int increment) 
   1.481 + {
   1.482 +@@ -307,33 +333,13 @@ int xkb_change_group(XkbPlugin * xkb, int increment)
   1.483 +     if (next_group >= xkb->group_count) next_group = 0;
   1.484 + 
   1.485 +     /* Execute the change. */
   1.486 +-    XkbLockGroup(xkb->dsp, xkb->device_id, next_group);
   1.487 ++    XkbLockGroup(GDK_DISPLAY(), XkbUseCoreKbd, next_group);
   1.488 +     refresh_group_xkb(xkb);
   1.489 +     xkb_redraw(xkb);
   1.490 +     xkb_enter_locale_by_process(xkb);
   1.491 +     return 1;
   1.492 + }
   1.493 + 
   1.494 +-/* Callback when activity detected on the Xkb channel. */
   1.495 +-gboolean xkb_gio_callback(GIOChannel * source, GIOCondition condition, gpointer data) 
   1.496 +-{
   1.497 +-    XkbPlugin * xkb = (XkbPlugin *) data;
   1.498 +-
   1.499 +-    XkbEvent evnt;
   1.500 +-    XNextEvent(xkb->dsp, &evnt.core);
   1.501 +-    if ((evnt.type == xkb->base_event_code)
   1.502 +-    && (evnt.any.xkb_type == XkbStateNotify)
   1.503 +-    && (evnt.state.group != xkb->current_group_xkb_no))
   1.504 +-    {
   1.505 +-        /* Switch to the new group and redraw the display. */
   1.506 +-        xkb->current_group_xkb_no = evnt.state.group;
   1.507 +-        refresh_group_xkb(xkb);
   1.508 +-        xkb_redraw(xkb);
   1.509 +-        xkb_enter_locale_by_process(xkb);
   1.510 +-    }
   1.511 +-    return TRUE;
   1.512 +-}
   1.513 +-
   1.514 + /* React to change of focus by switching to the application's layout or the default layout. */
   1.515 + void xkb_active_window_changed(XkbPlugin * xkb, gint pid)
   1.516 + {
   1.517 +@@ -345,7 +351,7 @@ void xkb_active_window_changed(XkbPlugin * xkb, gint pid)
   1.518 + 
   1.519 +     if (new_group_xkb_no < xkb->group_count)
   1.520 +     {
   1.521 +-        XkbLockGroup(xkb->dsp, xkb->device_id, new_group_xkb_no);
   1.522 ++        XkbLockGroup(GDK_DISPLAY(), XkbUseCoreKbd, new_group_xkb_no);
   1.523 +         refresh_group_xkb(xkb);
   1.524 +     }
   1.525 + }
   1.526 +diff --git a/src/plugins/xkb/xkb.h b/src/plugins/xkb/xkb.h
   1.527 +index 9265198..20c7ed3 100644
   1.528 +--- a/src/plugins/xkb/xkb.h
   1.529 ++++ b/src/plugins/xkb/xkb.h
   1.530 +@@ -49,10 +49,8 @@ typedef struct {
   1.531 +     GtkWidget * per_app_default_layout_menu;	/* Combo box of all available layouts */
   1.532 + 
   1.533 +     /* Mechanism. */
   1.534 +-    Display * dsp;				/* Handle to X display */
   1.535 +     int base_event_code;			/* Result of initializing Xkb extension */
   1.536 +     int base_error_code;
   1.537 +-    int device_id;				/* Keyboard device ID (always "core keyboard") */
   1.538 +     int current_group_xkb_no;			/* Current layout */
   1.539 +     int group_count;				/* Count of groups as returned by Xkb */
   1.540 +     char * group_names[XkbNumKbdGroups];	/* Group names as returned by Xkb */
   1.541 +@@ -67,12 +65,11 @@ extern int xkb_get_current_group_xkb_no(XkbPlugin * xkb);
   1.542 + extern int xkb_get_group_count(XkbPlugin * xkb);
   1.543 + extern const char * xkb_get_symbol_name_by_res_no(XkbPlugin * xkb, int group_res_no);
   1.544 + extern const char * xkb_get_current_group_name(XkbPlugin * xkb);
   1.545 +-extern const char * xkb_get_current_group_name_lowercase(XkbPlugin * xkb);
   1.546 ++extern const char * xkb_get_current_symbol_name(XkbPlugin * xkb);
   1.547 ++extern const char * xkb_get_current_symbol_name_lowercase(XkbPlugin * xkb);
   1.548 + extern void xkb_mechanism_constructor(XkbPlugin * xkb);
   1.549 + extern void xkb_mechanism_destructor(XkbPlugin * xkb);
   1.550 +-extern int xkb_get_connection_number(XkbPlugin * xkb);
   1.551 + extern int xkb_change_group(XkbPlugin * xkb, int increment);
   1.552 +-extern gboolean xkb_gio_callback(GIOChannel * source, GIOCondition condition, gpointer data);
   1.553 + extern void xkb_active_window_changed(XkbPlugin * xkb, GPid pid);
   1.554 + 
   1.555 + #endif
   1.556 +-- 
   1.557 +1.7.0
   1.558 +