[Xfce4-commits] [panel-plugins/xfce4-xkb-plugin] 09/17: Move xkb-config to xkb-keyboard

noreply at xfce.org noreply at xfce.org
Sat Jun 10 14:31:42 CEST 2017


This is an automated email from the git hooks/post-receive script.

n   i   n   e   t   l   s       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository panel-plugins/xfce4-xkb-plugin.

commit bd69f3b3f405db13d0fcd82f56e498aa5743c0eb
Author: Viktor Odintsev <zakhams at gmail.com>
Date:   Tue Mar 28 10:05:07 2017 +0300

    Move xkb-config to xkb-keyboard
    
    XkbKeyboard is the object now.
    xkb-config was renamed because "config" may be confusing.
---
 panel-plugin/Makefile.am        |   4 +-
 panel-plugin/xfce4-xkb-plugin.c |  32 +-
 panel-plugin/xfce4-xkb-plugin.h |  10 +-
 panel-plugin/xkb-callbacks.c    |  32 +-
 panel-plugin/xkb-config.c       | 604 -----------------------------------
 panel-plugin/xkb-config.h       | 120 -------
 panel-plugin/xkb-keyboard.c     | 685 ++++++++++++++++++++++++++++++++++++++++
 panel-plugin/xkb-keyboard.h     |  87 +++++
 panel-plugin/xkb-properties.h   |   4 +-
 panel-plugin/xkb-util.c         |   1 -
 10 files changed, 824 insertions(+), 755 deletions(-)

diff --git a/panel-plugin/Makefile.am b/panel-plugin/Makefile.am
index b31f23f..e2fead7 100644
--- a/panel-plugin/Makefile.am
+++ b/panel-plugin/Makefile.am
@@ -11,8 +11,8 @@ libxkb_la_SOURCES = \
 	xfce4-xkb-plugin.c \
 	xkb-settings-dialog.h \
 	xkb-settings-dialog.c \
-	xkb-config.h \
-	xkb-config.c \
+	xkb-keyboard.h \
+	xkb-keyboard.c \
 	xkb-util.h \
 	xkb-util.c \
 	xkb-cairo.h \
diff --git a/panel-plugin/xfce4-xkb-plugin.c b/panel-plugin/xfce4-xkb-plugin.c
index 7dd8556..c08189f 100644
--- a/panel-plugin/xfce4-xkb-plugin.c
+++ b/panel-plugin/xfce4-xkb-plugin.c
@@ -169,8 +169,8 @@ static void
 xkb_plugin_set_group (GtkMenuItem *item,
               gpointer data)
 {
-    gint group = GPOINTER_TO_INT (data);
-    xkb_config_set_group (group);
+    MenuItemData *item_data = data;
+    xkb_keyboard_set_group (item_data->xkb->keyboard, item_data->group);
 }
 
 static t_xkb *
@@ -210,7 +210,7 @@ xkb_new (XfcePanelPlugin *plugin)
     g_signal_connect (xkb->btn, "button-release-event",
             G_CALLBACK (xkb_plugin_button_clicked), xkb);
     g_signal_connect (xkb->btn, "scroll-event",
-            G_CALLBACK (xkb_plugin_button_scrolled), NULL);
+            G_CALLBACK (xkb_plugin_button_scrolled), xkb);
 
     g_object_set (G_OBJECT (xkb->btn), "has-tooltip", TRUE, NULL);
     g_signal_connect (xkb->btn, "query-tooltip",
@@ -222,7 +222,9 @@ xkb_new (XfcePanelPlugin *plugin)
             G_CALLBACK (xkb_plugin_layout_image_draw), xkb);
     gtk_widget_show (GTK_WIDGET (xkb->layout_image));
 
-    if (xkb_config_initialize (xkb_xfconf_get_group_policy (xkb->config), xkb_state_changed, xkb))
+    xkb->keyboard = xkb_keyboard_new (xkb_xfconf_get_group_policy (xkb->config),
+            xkb_state_changed, xkb);
+    if (xkb_keyboard_get_initialized (xkb->keyboard))
     {
         xkb_refresh_gui (xkb);
         xkb_populate_popup_menu (xkb);
@@ -242,12 +244,11 @@ xkb_new (XfcePanelPlugin *plugin)
 static void
 xkb_free (t_xkb *xkb)
 {
-    xkb_config_finalize ();
-
     xkb_destroy_popup_menu (xkb);
     gtk_widget_destroy (xkb->layout_image);
     gtk_widget_destroy (xkb->btn);
 
+    g_object_unref (G_OBJECT (xkb->keyboard));
     g_object_unref (G_OBJECT (xkb->config));
 
     panel_slice_free (t_xkb, xkb);
@@ -314,6 +315,8 @@ xkb_destroy_popup_menu (t_xkb *xkb)
     {
         gtk_menu_popdown (GTK_MENU (xkb->popup));
         gtk_menu_detach (GTK_MENU (xkb->popup));
+        g_free (xkb->popup_user_data);
+        xkb->popup_user_data = NULL;
         xkb->popup = NULL;
     }
 }
@@ -324,21 +327,29 @@ xkb_populate_popup_menu (t_xkb *xkb)
     gint i, group_count;
     gchar *layout_string;
     GtkWidget *menu_item;
+    MenuItemData *popup_user_data;
 
     if (G_UNLIKELY (xkb == NULL)) return;
 
+    group_count = xkb_keyboard_get_group_count (xkb->keyboard);
+
     xkb_destroy_popup_menu (xkb);
     xkb->popup = gtk_menu_new ();
+    xkb->popup_user_data = g_new0 (MenuItemData, group_count);
+
+    popup_user_data = xkb->popup_user_data;
 
-    group_count = xkb_config_get_group_count ();
     for (i = 0; i < group_count; i++)
     {
-        layout_string = xkb_config_get_pretty_layout_name (i);
+        layout_string = xkb_keyboard_get_pretty_layout_name (xkb->keyboard, i);
 
         menu_item = gtk_menu_item_new_with_label (layout_string);
 
+        popup_user_data[i].xkb = xkb;
+        popup_user_data[i].group = i;
+
         g_signal_connect (G_OBJECT (menu_item), "activate",
-                G_CALLBACK (xkb_plugin_set_group), GINT_TO_POINTER (i));
+                G_CALLBACK (xkb_plugin_set_group), &popup_user_data[i]);
 
         gtk_widget_show (menu_item);
         gtk_menu_shell_append (GTK_MENU_SHELL (xkb->popup), menu_item);
@@ -415,5 +426,6 @@ xkb_plugin_display_scale_changed (t_xkb *xkb)
 static void
 xkb_plugin_group_policy_changed (t_xkb *xkb)
 {
-    xkb_config_set_group_policy (xkb_xfconf_get_group_policy (xkb->config));
+    xkb_keyboard_set_group_policy (xkb->keyboard,
+            xkb_xfconf_get_group_policy (xkb->config));
 }
diff --git a/panel-plugin/xfce4-xkb-plugin.h b/panel-plugin/xfce4-xkb-plugin.h
index 614f1b4..a869bde 100644
--- a/panel-plugin/xfce4-xkb-plugin.h
+++ b/panel-plugin/xfce4-xkb-plugin.h
@@ -26,7 +26,7 @@
 #ifndef _XFCE_XKB_H_
 #define _XFCE_XKB_H_
 
-#include "xkb-config.h"
+#include "xkb-keyboard.h"
 #include "xkb-xfconf.h"
 
 #include <libxfce4util/libxfce4util.h>
@@ -42,12 +42,20 @@ typedef struct
     XfcePanelPlugin *plugin;
 
     XkbXfconf *config;
+    XkbKeyboard *keyboard;
 
     /* widgets */
     GtkWidget *btn;
     GtkWidget *layout_image;
     GtkWidget *popup;
+    void *popup_user_data;
 } t_xkb;
 
+typedef struct
+{
+    t_xkb *xkb;
+    gint group;
+} MenuItemData;
+
 #endif
 
diff --git a/panel-plugin/xkb-callbacks.c b/panel-plugin/xkb-callbacks.c
index 9b892d5..8f08114 100644
--- a/panel-plugin/xkb-callbacks.c
+++ b/panel-plugin/xkb-callbacks.c
@@ -44,7 +44,7 @@ xkb_plugin_active_window_changed (WnckScreen *screen,
     window_id = wnck_window_get_xid (window);
     application_id = wnck_window_get_pid (window);
 
-    xkb_config_window_changed (window_id, application_id);
+    xkb_keyboard_window_changed (xkb->keyboard, window_id, application_id);
 }
 
 void
@@ -56,7 +56,7 @@ xkb_plugin_application_closed (WnckScreen *screen,
 
     application_id = wnck_application_get_pid (app);
 
-    xkb_config_application_closed (application_id);
+    xkb_keyboard_application_closed (xkb->keyboard, application_id);
 }
 
 void
@@ -68,7 +68,7 @@ xkb_plugin_window_closed (WnckScreen *screen,
 
     window_id = wnck_window_get_xid (window);
 
-    xkb_config_window_closed (window_id);
+    xkb_keyboard_window_closed (xkb->keyboard, window_id);
 }
 
 gboolean
@@ -95,7 +95,7 @@ xkb_plugin_layout_image_draw (GtkWidget *widget,
     state = gtk_widget_get_state_flags (GTK_WIDGET (xkb->btn));
     style_ctx = gtk_widget_get_style_context (GTK_WIDGET (xkb->btn));
     gtk_style_context_get_color (style_ctx, state, &rgba);
-    group_name = xkb_config_get_group_name (-1);
+    group_name = xkb_keyboard_get_group_name (xkb->keyboard, -1);
 
     DBG ("img_exposed: actual h/v (%d/%d)",
          actual_hsize, actual_vsize);
@@ -104,8 +104,8 @@ xkb_plugin_layout_image_draw (GtkWidget *widget,
     {
         xkb_cairo_draw_flag (cr, group_name,
                 actual_hsize, actual_vsize,
-                xkb_config_variant_index_for_group (-1),
-                xkb_config_get_max_group_count (),
+                xkb_keyboard_variant_index_for_group (xkb->keyboard, -1),
+                xkb_keyboard_get_max_group_count (xkb->keyboard),
                 display_scale,
                 rgba
         );
@@ -114,7 +114,7 @@ xkb_plugin_layout_image_draw (GtkWidget *widget,
     {
         xkb_cairo_draw_label (cr, group_name,
                 actual_hsize, actual_vsize,
-                xkb_config_variant_index_for_group (-1),
+                xkb_keyboard_variant_index_for_group (xkb->keyboard, -1),
                 display_scale,
                 rgba
         );
@@ -124,7 +124,7 @@ xkb_plugin_layout_image_draw (GtkWidget *widget,
         gtk_style_context_get (style_ctx, state, "font", &desc, NULL);
         xkb_cairo_draw_label_system (cr, group_name,
                 actual_hsize, actual_vsize,
-                xkb_config_variant_index_for_group (-1),
+                xkb_keyboard_variant_index_for_group (xkb->keyboard, -1),
                 desc, rgba
         );
     }
@@ -144,7 +144,7 @@ xkb_plugin_button_clicked (GtkButton *btn,
     {
         xkb = data;
         released = event->type == GDK_BUTTON_RELEASE;
-        display_popup = xkb_config_get_group_count () > 2;
+        display_popup = xkb_keyboard_get_group_count (xkb->keyboard) > 2;
 
         if (display_popup && !released)
         {
@@ -154,7 +154,7 @@ xkb_plugin_button_clicked (GtkButton *btn,
 
         if (!display_popup && released)
         {
-            xkb_config_next_group ();
+            xkb_keyboard_next_group (xkb->keyboard);
             return FALSE;
         }
     }
@@ -166,15 +166,17 @@ xkb_plugin_button_scrolled (GtkWidget *btn,
                             GdkEventScroll *event,
                             gpointer data)
 {
+    t_xkb *xkb = data;
+
     switch (event->direction)
     {
       case GDK_SCROLL_UP:
       case GDK_SCROLL_RIGHT:
-          xkb_config_next_group ();
+          xkb_keyboard_next_group (xkb->keyboard);
           return TRUE;
       case GDK_SCROLL_DOWN:
       case GDK_SCROLL_LEFT:
-          xkb_config_prev_group ();
+          xkb_keyboard_prev_group (xkb->keyboard);
           return TRUE;
       default:
         return FALSE;
@@ -222,15 +224,15 @@ xkb_plugin_set_tooltip (GtkWidget *widget,
     gchar *layout_name;
     GdkPixbuf *pixbuf;
 
-    group = xkb_config_get_current_group ();
+    group = xkb_keyboard_get_current_group (xkb->keyboard);
 
     if (xkb_xfconf_get_display_tooltip_icon (xkb->config))
     {
-        pixbuf = xkb_config_get_tooltip_pixbuf (group);
+        pixbuf = xkb_keyboard_get_tooltip_pixbuf (xkb->keyboard, group);
         gtk_tooltip_set_icon (tooltip, pixbuf);
     }
 
-    layout_name = xkb_config_get_pretty_layout_name (group);
+    layout_name = xkb_keyboard_get_pretty_layout_name (xkb->keyboard, group);
 
     gtk_tooltip_set_text (tooltip, layout_name);
 
diff --git a/panel-plugin/xkb-config.c b/panel-plugin/xkb-config.c
deleted file mode 100644
index b84fd09..0000000
--- a/panel-plugin/xkb-config.c
+++ /dev/null
@@ -1,604 +0,0 @@
-/* vim: set backspace=2 ts=4 softtabstop=4 sw=4 cinoptions=>4 expandtab autoindent smartindent: */
-/* xkb-config.c
- * Copyright (C) 2008 Alexander Iliev <sasoiliev at mamul.org>
- *
- * Parts of this program comes from the XfKC tool:
- * Copyright (C) 2006 Gauvain Pocentek <gauvainpocentek at gmail.com>
- *
- * A part of this file comes from the gnome keyboard capplet (control-center):
- * Copyright (C) 2003 Sergey V. Oudaltsov <svu at users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "xkb-config.h"
-#include "xkb-util.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <libxklavier/xklavier.h>
-
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include <librsvg/rsvg.h>
-
-#ifndef DEBUG
-#undef G_DISABLE_ASSERT
-#define G_DISABLE_ASSERT
-#endif
-
-typedef struct
-{
-    gchar      *group_name;
-    gchar      *variant;
-    gchar      *pretty_layout_name;
-    GdkPixbuf  *tooltip_pixbuf;
-} t_group_data;
-
-typedef struct
-{
-    XklEngine            *engine;
-
-    t_group_data         *group_data;
-
-    t_group_policy        group_policy;
-    GHashTable           *variant_index_by_group;
-
-    GHashTable           *application_map;
-    GHashTable           *window_map;
-
-    guint                 current_window_id;
-    guint                 current_application_id;
-
-    gint                  group_count;
-    gint                  current_group;
-
-    XkbCallback           callback;
-    gpointer              callback_data;
-} t_xkb_config;
-
-static t_xkb_config *config;
-
-static void         xkb_config_xkl_state_changed        (XklEngine *engine,
-                                                         XklEngineStateChange change,
-                                                         gint group,
-                                                         gboolean restore,
-                                                         gpointer user_data);
-
-static void         xkb_config_xkl_config_changed       (XklEngine *engine,
-                                                         gpointer user_data);
-
-static GdkFilterReturn
-                    handle_xevent                       (GdkXEvent * xev,
-                                                         GdkEvent * event);
-
-static void         xkb_config_free                     ();
-static void         xkb_config_update_from_xkl          ();
-static void         xkb_config_initialize_xkb_options   (const XklConfigRec *config_rec);
-
-/* ---------------------- implementation ------------------------- */
-
-gboolean
-xkb_config_initialize (t_group_policy group_policy,
-               XkbCallback callback,
-               gpointer callback_data)
-{
-    config = g_new0 (t_xkb_config, 1);
-
-    config->group_policy = group_policy;
-
-    config->callback = callback;
-    config->callback_data = callback_data;
-
-    config->engine = xkl_engine_get_instance (gdk_x11_get_default_xdisplay ());
-
-    if (!config->engine)
-    {
-        return FALSE;
-    }
-
-    xkb_config_update_from_xkl ();
-
-    xkl_engine_set_group_per_toplevel_window (config->engine, FALSE);
-
-    xkl_engine_start_listen (config->engine, XKLL_TRACK_KEYBOARD_STATE);
-
-    g_signal_connect (config->engine,
-            "X-state-changed",
-            G_CALLBACK (xkb_config_xkl_state_changed),
-            NULL);
-    g_signal_connect (config->engine,
-            "X-config-changed",
-            G_CALLBACK (xkb_config_xkl_config_changed),
-            NULL);
-    gdk_window_add_filter (NULL, (GdkFilterFunc) handle_xevent, NULL);
-
-    return TRUE;
-}
-
-static gchar *
-xkb_config_xkb_description (XklConfigItem *config_item)
-{
-  gchar *ci_description;
-  gchar *description;
-
-  ci_description = g_strstrip (config_item->description);
-
-  if (ci_description[0] == 0)
-    description = g_strdup (config_item->name);
-  else
-    description = g_locale_to_utf8 (ci_description, -1, NULL, NULL, NULL);
-
-  return description;
-}
-
-static gchar*
-xkb_config_create_pretty_layout_name (XklConfigRegistry *registry,
-                                      XklConfigItem *config_item,
-                                      gchar *layout_name,
-                                      gchar *layout_variant)
-{
-    gchar *pretty_layout_name;
-
-    g_snprintf (config_item->name, sizeof (config_item->name),
-                "%s", layout_variant);
-    if (xkl_config_registry_find_variant (registry, layout_name, config_item))
-    {
-        pretty_layout_name = xkb_config_xkb_description (config_item);
-    }
-    else
-    {
-        g_snprintf (config_item->name, sizeof (config_item->name),
-                    "%s", layout_name);
-        if (xkl_config_registry_find_layout (registry, config_item))
-        {
-            pretty_layout_name = xkb_config_xkb_description (config_item);
-        }
-        else
-        {
-            pretty_layout_name = xkb_util_get_layout_string (layout_name,
-                                                             layout_variant);
-        }
-    }
-
-    return pretty_layout_name;
-}
-
-static void
-xkb_config_initialize_xkb_options (const XklConfigRec *config_rec)
-{
-    GHashTable *index_variants;
-    gchar **group;
-    gint val, i;
-    gpointer pval;
-    gchar *imgfilename;
-    XklConfigRegistry *registry;
-    XklConfigItem *config_item;
-
-    xkb_config_free ();
-
-    group = config_rec->layouts;
-    config->group_count = 0;
-    while (*group)
-    {
-        group++;
-        config->group_count++;
-    }
-
-    config->window_map = g_hash_table_new (g_direct_hash, NULL);
-    config->application_map = g_hash_table_new (g_direct_hash, NULL);
-    config->group_data = (t_group_data *) g_new0 (typeof (t_group_data),
-                                                  config->group_count);
-    config->variant_index_by_group = g_hash_table_new (NULL, NULL);
-    index_variants = g_hash_table_new (g_str_hash, g_str_equal);
-
-    registry = xkl_config_registry_get_instance (config->engine);
-    xkl_config_registry_load (registry, FALSE);
-    config_item = xkl_config_item_new ();
-
-    for (i = 0; i < config->group_count; i++)
-    {
-        t_group_data *group_data = &config->group_data[i];
-        RsvgHandle *handle;
-
-        group_data->group_name = g_strdup (config_rec->layouts[i]);
-
-        group_data->variant = (config_rec->variants[i] == NULL)
-            ? g_strdup ("") : g_strdup (config_rec->variants[i]);
-
-        pval = g_hash_table_lookup (
-                index_variants,
-                group_data->group_name
-        );
-        val = (pval != NULL) ? GPOINTER_TO_INT (pval) : 0;
-        val++;
-        g_hash_table_insert (
-                config->variant_index_by_group,
-                GINT_TO_POINTER (i),
-                GINT_TO_POINTER (val)
-        );
-        g_hash_table_insert (
-                index_variants,
-                group_data->group_name,
-                GINT_TO_POINTER (val)
-        );
-
-        imgfilename = xkb_util_get_flag_filename (group_data->group_name);
-        handle = rsvg_handle_new_from_file (imgfilename, NULL);
-        if (handle)
-        {
-            GdkPixbuf *tmp = rsvg_handle_get_pixbuf (handle);
-            group_data->tooltip_pixbuf =
-                gdk_pixbuf_scale_simple (tmp, 30, 22, GDK_INTERP_BILINEAR);
-            g_object_unref (tmp);
-            rsvg_handle_close (handle, NULL);
-            g_object_unref (handle);
-        }
-        g_free (imgfilename);
-
-        group_data->pretty_layout_name =
-            xkb_config_create_pretty_layout_name (registry, config_item,
-                                                  group_data->group_name,
-                                                  group_data->variant);
-    }
-    g_object_unref (config_item);
-    g_object_unref (registry);
-    g_hash_table_destroy (index_variants);
-}
-
-static void
-xkb_config_free (void)
-{
-    gint i;
-
-    g_assert (config != NULL);
-
-    if (config->variant_index_by_group)
-        g_hash_table_destroy (config->variant_index_by_group);
-
-    if (config->window_map)
-        g_hash_table_destroy (config->window_map);
-
-    if (config->application_map)
-        g_hash_table_destroy (config->application_map);
-
-    if (config->group_data)
-    {
-        for (i = 0; i < config->group_count; i++)
-        {
-            t_group_data *group_data = &config->group_data[i];
-            g_free (group_data->group_name);
-            g_free (group_data->variant);
-            g_free (group_data->pretty_layout_name);
-            if (group_data->tooltip_pixbuf)
-            {
-                g_object_unref (group_data->tooltip_pixbuf);
-            }
-        }
-        g_free (config->group_data);
-    }
-}
-
-void
-xkb_config_finalize (void)
-{
-    xkl_engine_stop_listen (config->engine, XKLL_TRACK_KEYBOARD_STATE);
-    g_object_unref (config->engine);
-
-    xkb_config_free ();
-    g_free (config);
-
-    gdk_window_remove_filter (NULL, (GdkFilterFunc) handle_xevent, NULL);
-}
-
-gint
-xkb_config_get_current_group (void)
-{
-    return config->current_group;
-}
-
-gboolean
-xkb_config_set_group (gint group)
-{
-    g_assert (config != NULL);
-
-    if (G_UNLIKELY (group < 0 || group >= config->group_count))
-    {
-        return FALSE;
-    }
-
-    xkl_engine_lock_group (config->engine, group);
-    config->current_group = group;
-
-    return TRUE;
-}
-
-gboolean
-xkb_config_next_group (void)
-{
-    xkl_engine_lock_group (config->engine,
-            xkl_engine_get_next_group (config->engine));
-
-    return TRUE;
-}
-
-gboolean
-xkb_config_prev_group (void)
-{
-    xkl_engine_lock_group (config->engine,
-            xkl_engine_get_prev_group (config->engine));
-
-    return TRUE;
-}
-
-void
-xkb_config_set_group_policy (t_group_policy group_policy)
-{
-    config->group_policy = group_policy;
-}
-
-static void
-xkb_config_update_from_xkl (void)
-{
-    XklConfigRec *config_rec;
-
-
-    g_assert (config != NULL);
-
-    config_rec = xkl_config_rec_new ();
-    xkl_config_rec_get_from_server (config_rec, config->engine);
-
-    xkb_config_initialize_xkb_options (config_rec);
-
-    g_object_unref (config_rec);
-}
-
-void
-xkb_config_window_changed (guint new_window_id, guint application_id)
-{
-    gint group;
-    gpointer key, value;
-    GHashTable *hashtable;
-    guint id;
-
-    g_assert (config != NULL);
-
-    id = 0;
-    hashtable = NULL;
-
-    switch (config->group_policy)
-    {
-        case GROUP_POLICY_GLOBAL:
-            return;
-
-        case GROUP_POLICY_PER_WINDOW:
-            hashtable = config->window_map;
-            id = new_window_id;
-            config->current_window_id = id;
-            break;
-
-        case GROUP_POLICY_PER_APPLICATION:
-            hashtable = config->application_map;
-            id = application_id;
-            config->current_application_id = id;
-            break;
-    }
-
-    group = 0;
-
-    if (g_hash_table_lookup_extended (hashtable, GINT_TO_POINTER (id), &key, &value))
-    {
-        group = GPOINTER_TO_INT (value);
-    }
-    else
-    {
-        g_hash_table_insert (hashtable,
-                             GINT_TO_POINTER (id),
-                             GINT_TO_POINTER (group));
-    }
-
-    xkb_config_set_group (group);
-}
-
-void
-xkb_config_application_closed (guint application_id)
-{
-    g_assert (config != NULL);
-
-    switch (config->group_policy)
-    {
-        case GROUP_POLICY_GLOBAL:
-        case GROUP_POLICY_PER_WINDOW:
-            return;
-
-        case GROUP_POLICY_PER_APPLICATION:
-            g_hash_table_remove (
-                    config->application_map,
-                    GINT_TO_POINTER (application_id)
-            );
-
-            break;
-    }
-}
-
-void
-xkb_config_window_closed (guint window_id)
-{
-    g_assert (config != NULL);
-
-    switch (config->group_policy)
-    {
-        case GROUP_POLICY_GLOBAL:
-        case GROUP_POLICY_PER_APPLICATION:
-            return;
-
-        case GROUP_POLICY_PER_WINDOW:
-            g_hash_table_remove (
-                    config->window_map,
-                    GINT_TO_POINTER (window_id)
-            );
-
-            break;
-    }
-}
-
-gint
-xkb_config_get_group_count (void)
-{
-    g_assert (config != NULL);
-
-    return config->group_count;
-}
-
-guint xkb_config_get_max_group_count (void)
-{
-    return xkl_engine_get_max_num_groups(config->engine);
-}
-
-const gchar*
-xkb_config_get_group_name (gint group)
-{
-    g_assert (config != NULL);
-
-    if (G_UNLIKELY (group >= config->group_count))
-        return NULL;
-
-    if (group == -1)
-        group = xkb_config_get_current_group ();
-
-    return config->group_data[group].group_name;
-}
-
-const gchar*
-xkb_config_get_variant (gint group)
-{
-    g_assert (config != NULL);
-
-    if (G_UNLIKELY (group >= config->group_count))
-        return NULL;
-
-    if (group == -1)
-        group = xkb_config_get_current_group ();
-
-    return config->group_data[group].variant;
-}
-
-void
-xkb_config_xkl_state_changed (XklEngine *engine,
-                              XklEngineStateChange change,
-                              gint group,
-                              gboolean restore,
-                              gpointer user_data)
-{
-    if (change == GROUP_CHANGED)
-    {
-        config->current_group = group;
-
-        switch (config->group_policy)
-        {
-            case GROUP_POLICY_GLOBAL:
-                break;
-
-            case GROUP_POLICY_PER_WINDOW:
-                g_hash_table_insert (
-                        config->window_map,
-                        GINT_TO_POINTER (config->current_window_id),
-                        GINT_TO_POINTER (group)
-                );
-                break;
-
-            case GROUP_POLICY_PER_APPLICATION:
-                g_hash_table_insert (
-                        config->application_map,
-                        GINT_TO_POINTER (config->current_application_id),
-                        GINT_TO_POINTER (group)
-                );
-            break;
-        }
-
-        if (config->callback != NULL) config->callback (group, FALSE, config->callback_data);
-    }
-}
-
-void
-xkb_config_xkl_config_changed (XklEngine *engine, gpointer user_data)
-{
-    xkb_config_update_from_xkl ();
-
-    if (config->callback != NULL)
-    {
-        xkb_config_set_group (0);
-        config->callback (0, TRUE, config->callback_data);
-    }
-}
-
-gint
-xkb_config_variant_index_for_group (gint group)
-{
-    gpointer presult;
-    gint result;
-
-    g_return_val_if_fail (config != NULL, 0);
-
-    if (group == -1) group = xkb_config_get_current_group ();
-
-    presult = g_hash_table_lookup (
-            config->variant_index_by_group,
-            GINT_TO_POINTER (group)
-    );
-    if (presult == NULL) return 0;
-
-    result = GPOINTER_TO_INT (presult);
-    result = (result <= 0) ? 0 : result - 1;
-    return result;
-}
-
-GdkFilterReturn
-handle_xevent (GdkXEvent * xev, GdkEvent * event)
-{
-    XEvent *xevent = (XEvent *) xev;
-
-    xkl_engine_filter_events (config->engine, xevent);
-
-    return GDK_FILTER_CONTINUE;
-}
-
-XklConfigRegistry*
-xkb_config_get_xkl_registry (void)
-{
-    XklConfigRegistry *registry;
-
-    if (!config) return NULL;
-
-    registry = xkl_config_registry_get_instance (config->engine);
-    xkl_config_registry_load (registry, FALSE);
-
-    return registry;
-}
-
-GdkPixbuf*
-xkb_config_get_tooltip_pixbuf (gint group)
-{
-    return config->group_data[group].tooltip_pixbuf;
-}
-
-gchar*
-xkb_config_get_pretty_layout_name (gint group)
-{
-    return config->group_data[group].pretty_layout_name;
-}
diff --git a/panel-plugin/xkb-config.h b/panel-plugin/xkb-config.h
deleted file mode 100644
index c06cd16..0000000
--- a/panel-plugin/xkb-config.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* vim: set backspace=2 ts=4 softtabstop=4 sw=4 cinoptions=>4 expandtab autoindent smartindent: */
-/* xkb-config.h
- * Copyright (C) 2008 Alexander Iliev <sasoiliev at mamul.org>
- *
- * Parts of this program comes from the XfKC tool:
- * Copyright (C) 2006 Gauvain Pocentek <gauvainpocentek at gmail.com>
- *
- * A part of this file comes from the gnome keyboard capplet (control-center):
- * Copyright (C) 2003 Sergey V. Oudaltsov <svu at users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef _XKB_CONFIG_H_
-#define _XKB_CONFIG_H_
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <gdk/gdk.h>
-#include <libxklavier/xklavier.h>
-
-#include "xkb-properties.h"
-
-typedef void        (*XkbCallback)                  (gint current_group,
-                                                     gboolean groups_changed,
-                                                     gpointer user_data);
-
-gboolean          xkb_config_initialize                   (t_group_policy group_policy,
-                                                           XkbCallback callback,
-                                                           gpointer data);
-void              xkb_config_finalize                     (void);
-void              xkb_config_set_group_policy             (t_group_policy group_policy);
-gint              xkb_config_get_group_count              (void);
-guint             xkb_config_get_max_group_count          (void);
-const gchar*      xkb_config_get_group_name               (gint group);
-const gchar*      xkb_config_get_variant                  (gint group);
-gboolean          xkb_config_set_group                    (gint group);
-gboolean          xkb_config_next_group                   (void);
-gboolean          xkb_config_prev_group                   (void);
-gint              xkb_config_variant_index_for_group      (gint group);
-
-void              xkb_config_window_changed               (guint new_window_id,
-                                                           guint application_id);
-void              xkb_config_application_closed           (guint application_id);
-void              xkb_config_window_closed                (guint window_id);
-GdkPixbuf*        xkb_config_get_tooltip_pixbuf           (gint group);
-gchar*            xkb_config_get_pretty_layout_name       (gint group);
-gint              xkb_config_get_current_group            (void);
-
-/* TODO: remove this function - xkl structures should not be used outside xkb-config */
-XklConfigRegistry*
-                  xkb_config_get_xkl_registry             (void);
-
-#ifdef DEBUG
-
-#define XKB_DEBUG(...) \
-    do { g_fprintf (stderr, "[[ XFCE XKB PLUGIN ]]: "__VA_ARGS__); g_fprintf (stderr, "\n"); } while (0)
-
-#define XKB_DEBUG_KBD(kbd, msg) g_printf("DUMPING KEYBOARD SETTINGS [[[%s]]] {%d}: ", msg, kbd);\
-    if (kbd) { \
-        g_printf ("\n\
-          model: %s [%d]\n\
-          layouts: %s [%d]\n\
-          variants: %s [%d]\n\
-          options: %s [%d]\n", \
-                kbd->model, kbd->model, \
-                kbd->layouts, kbd->layouts, \
-                kbd->variants, kbd->variants, \
-                kbd->options, kbd->options); \
-    } else { \
-        g_printf("NULL\n"); \
-    }
-
-#define XKB_DEBUG_CONFIG_REC(crec, msg) g_printf("DUMPING CONFIG REC [[[%s]]] {%d}: ", msg, (int) crec);\
-    if (crec) { \
-        g_printf ("\n\
-            model: %s [%d]\n\
-            layouts: %s [%d]\n\
-            variants: %s [%d]\n", \
-                crec->model, (int) crec->model, \
-                g_strjoinv (",", crec->layouts), (int) crec->layouts, \
-                g_strjoinv (",", crec->variants), (int) crec->variants); \
-    } else { \
-        g_printf ("NULL\n"); \
-    }
-
-#define XKB_DEBUG_GROUP_NAMES(groupnames, i, count) \
-    for (i = 0; i < count; i++) {\
-        if (groupnames && groupnames[i]) { \
-            XKB_DEBUG("group : %s", groupnames[i]); \
-        } \
-    }
-
-#else
-
-#define XKB_DEBUG(...)
-#define XKB_DEBUG_KBD(kbd, msg)
-#define XKB_DEBUG_CONFIG_REC(crec, msg)
-#define XKB_DEBUG_GROUP_NAMES(groupnames, i, count)
-
-#endif
-
-#endif
-
diff --git a/panel-plugin/xkb-keyboard.c b/panel-plugin/xkb-keyboard.c
new file mode 100644
index 0000000..5730a4a
--- /dev/null
+++ b/panel-plugin/xkb-keyboard.c
@@ -0,0 +1,685 @@
+/* vim: set backspace=2 ts=4 softtabstop=4 sw=4 cinoptions=>4 expandtab autoindent smartindent: */
+/* xkb-keyboard.c
+ * Copyright (C) 2008 Alexander Iliev <sasoiliev at mamul.org>
+ *
+ * Parts of this program comes from the XfKC tool:
+ * Copyright (C) 2006 Gauvain Pocentek <gauvainpocentek at gmail.com>
+ *
+ * A part of this file comes from the gnome keyboard capplet (control-center):
+ * Copyright (C) 2003 Sergey V. Oudaltsov <svu at users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "xkb-keyboard.h"
+#include "xkb-util.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libxklavier/xklavier.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <librsvg/rsvg.h>
+
+#ifndef DEBUG
+#undef G_DISABLE_ASSERT
+#define G_DISABLE_ASSERT
+#endif
+
+typedef struct
+{
+    gchar                *group_name;
+    gchar                *variant;
+    gchar                *pretty_layout_name;
+    GdkPixbuf            *tooltip_pixbuf;
+} XkbGroupData;
+
+struct _XkbKeyboardClass
+{
+    GObjectClass __parent__;
+};
+
+struct _XkbKeyboard
+{
+    GObject __parent__;
+    
+    XklEngine            *engine;
+
+    XkbGroupData         *group_data;
+
+    XkbGroupPolicy        group_policy;
+    GHashTable           *variant_index_by_group;
+
+    GHashTable           *application_map;
+    GHashTable           *window_map;
+
+    guint                 current_window_id;
+    guint                 current_application_id;
+
+    gint                  group_count;
+    gint                  current_group;
+
+    XkbCallback           callback;
+    gpointer              callback_data;
+};
+
+static void              xkb_keyboard_xkl_state_changed        (XklEngine *engine,
+                                                                XklEngineStateChange change,
+                                                                gint group,
+                                                                gboolean restore,
+                                                                gpointer user_data);
+
+static void              xkb_keyboard_xkl_config_changed       (XklEngine *engine,
+                                                                gpointer user_data);
+
+static GdkFilterReturn   xkb_keyboard_handle_xevent            (GdkXEvent * xev,
+                                                                GdkEvent * event,
+                                                                gpointer user_data);
+
+static void              xkb_keyboard_free                     (XkbKeyboard *keyboard);
+static void              xkb_keyboard_finalize                 (GObject *object);
+static void              xkb_keyboard_update_from_xkl          (XkbKeyboard *keyboard);
+static void              xkb_keyboard_initialize_xkb_options   (XkbKeyboard *keyboard,
+                                                                const XklConfigRec *config_rec);
+
+/* ---------------------- implementation ------------------------- */
+
+G_DEFINE_TYPE (XkbKeyboard, xkb_keyboard, G_TYPE_OBJECT)
+
+static void
+xkb_keyboard_class_init (XkbKeyboardClass *klass)
+{
+    GObjectClass *gobject_class;
+
+    gobject_class = G_OBJECT_CLASS (klass);
+    gobject_class->finalize = xkb_keyboard_finalize;
+}
+
+static void
+xkb_keyboard_init (XkbKeyboard *keyboard)
+{
+    keyboard->engine = NULL;
+    keyboard->group_data = NULL;
+    keyboard->group_policy = GROUP_POLICY_GLOBAL;
+
+    keyboard->variant_index_by_group = NULL;
+    keyboard->application_map = NULL;
+    keyboard->window_map = NULL;
+
+    keyboard->current_window_id = 0;
+    keyboard->current_application_id = 0;
+
+    keyboard->group_count = 0;
+    keyboard->current_group = 0;
+
+    keyboard->callback = NULL;
+    keyboard->callback_data = NULL;
+}
+
+XkbKeyboard *
+xkb_keyboard_new (XkbGroupPolicy group_policy,
+                  XkbCallback callback,
+                  gpointer callback_data)
+{
+    XkbKeyboard *keyboard = g_object_new (TYPE_XKB_KEYBOARD, NULL);
+
+    keyboard->group_policy = group_policy;
+
+    keyboard->callback = callback;
+    keyboard->callback_data = callback_data;
+
+    keyboard->engine = xkl_engine_get_instance (gdk_x11_get_default_xdisplay ());
+
+    if (keyboard->engine)
+    {
+        xkb_keyboard_update_from_xkl (keyboard);
+
+        xkl_engine_set_group_per_toplevel_window (keyboard->engine, FALSE);
+
+        xkl_engine_start_listen (keyboard->engine, XKLL_TRACK_KEYBOARD_STATE);
+
+        g_signal_connect (keyboard->engine,
+                "X-state-changed",
+                G_CALLBACK (xkb_keyboard_xkl_state_changed),
+                keyboard);
+        g_signal_connect (keyboard->engine,
+                "X-config-changed",
+                G_CALLBACK (xkb_keyboard_xkl_config_changed),
+                keyboard);
+        gdk_window_add_filter (NULL, xkb_keyboard_handle_xevent, keyboard);
+    }
+
+    return keyboard;
+}
+
+gboolean
+xkb_keyboard_get_initialized (XkbKeyboard *keyboard)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), FALSE);
+    return G_LIKELY (keyboard->engine != NULL);
+}
+
+static gchar *
+xkb_keyboard_xkb_description (XklConfigItem *config_item)
+{
+    gchar *ci_description;
+    gchar *description;
+
+    ci_description = g_strstrip (config_item->description);
+
+    if (ci_description[0] == 0)
+        description = g_strdup (config_item->name);
+    else
+        description = g_locale_to_utf8 (ci_description, -1, NULL, NULL, NULL);
+
+    return description;
+}
+
+static gchar*
+xkb_keyboard_create_pretty_layout_name (XklConfigRegistry *registry,
+                                        XklConfigItem *config_item,
+                                        gchar *layout_name,
+                                        gchar *layout_variant)
+{
+    gchar *pretty_layout_name;
+
+    g_snprintf (config_item->name, sizeof (config_item->name),
+                "%s", layout_variant);
+    if (xkl_config_registry_find_variant (registry, layout_name, config_item))
+    {
+        pretty_layout_name = xkb_keyboard_xkb_description (config_item);
+    }
+    else
+    {
+        g_snprintf (config_item->name, sizeof (config_item->name),
+                    "%s", layout_name);
+        if (xkl_config_registry_find_layout (registry, config_item))
+        {
+            pretty_layout_name = xkb_keyboard_xkb_description (config_item);
+        }
+        else
+        {
+            pretty_layout_name = xkb_util_get_layout_string (layout_name,
+                                                             layout_variant);
+        }
+    }
+
+    return pretty_layout_name;
+}
+
+static void
+xkb_keyboard_initialize_xkb_options (XkbKeyboard *keyboard,
+                                     const XklConfigRec *config_rec)
+{
+    GHashTable *index_variants;
+    gchar **group;
+    gint val, i;
+    gpointer pval;
+    gchar *imgfilename;
+    XklConfigRegistry *registry;
+    XklConfigItem *config_item;
+
+    xkb_keyboard_free (keyboard);
+
+    group = config_rec->layouts;
+    keyboard->group_count = 0;
+    while (*group)
+    {
+        group++;
+        keyboard->group_count++;
+    }
+
+    keyboard->window_map = g_hash_table_new (g_direct_hash, NULL);
+    keyboard->application_map = g_hash_table_new (g_direct_hash, NULL);
+    keyboard->group_data = (XkbGroupData *) g_new0 (XkbGroupData,
+            keyboard->group_count);
+    keyboard->variant_index_by_group = g_hash_table_new (NULL, NULL);
+    index_variants = g_hash_table_new (g_str_hash, g_str_equal);
+
+    registry = xkl_config_registry_get_instance (keyboard->engine);
+    xkl_config_registry_load (registry, FALSE);
+    config_item = xkl_config_item_new ();
+
+    for (i = 0; i < keyboard->group_count; i++)
+    {
+        XkbGroupData *group_data = &keyboard->group_data[i];
+        RsvgHandle *handle;
+
+        group_data->group_name = g_strdup (config_rec->layouts[i]);
+
+        group_data->variant = (config_rec->variants[i] == NULL)
+            ? g_strdup ("") : g_strdup (config_rec->variants[i]);
+
+        pval = g_hash_table_lookup (
+                index_variants,
+                group_data->group_name
+        );
+        val = (pval != NULL) ? GPOINTER_TO_INT (pval) : 0;
+        val++;
+        g_hash_table_insert (
+                keyboard->variant_index_by_group,
+                GINT_TO_POINTER (i),
+                GINT_TO_POINTER (val)
+        );
+        g_hash_table_insert (
+                index_variants,
+                group_data->group_name,
+                GINT_TO_POINTER (val)
+        );
+
+        imgfilename = xkb_util_get_flag_filename (group_data->group_name);
+        handle = rsvg_handle_new_from_file (imgfilename, NULL);
+        if (handle)
+        {
+            GdkPixbuf *tmp = rsvg_handle_get_pixbuf (handle);
+            group_data->tooltip_pixbuf =
+                gdk_pixbuf_scale_simple (tmp, 30, 22, GDK_INTERP_BILINEAR);
+            g_object_unref (tmp);
+            rsvg_handle_close (handle, NULL);
+            g_object_unref (handle);
+        }
+        g_free (imgfilename);
+
+        group_data->pretty_layout_name =
+            xkb_keyboard_create_pretty_layout_name (registry, config_item,
+                                                    group_data->group_name,
+                                                    group_data->variant);
+    }
+    g_object_unref (config_item);
+    g_object_unref (registry);
+    g_hash_table_destroy (index_variants);
+}
+
+static void
+xkb_keyboard_free (XkbKeyboard *keyboard)
+{
+    gint i;
+
+    if (keyboard->variant_index_by_group)
+        g_hash_table_destroy (keyboard->variant_index_by_group);
+
+    if (keyboard->window_map)
+        g_hash_table_destroy (keyboard->window_map);
+
+    if (keyboard->application_map)
+        g_hash_table_destroy (keyboard->application_map);
+
+    if (keyboard->group_data)
+    {
+        for (i = 0; i < keyboard->group_count; i++)
+        {
+            XkbGroupData *group_data = &keyboard->group_data[i];
+            g_free (group_data->group_name);
+            g_free (group_data->variant);
+            g_free (group_data->pretty_layout_name);
+            if (group_data->tooltip_pixbuf)
+            {
+                g_object_unref (group_data->tooltip_pixbuf);
+            }
+        }
+        g_free (keyboard->group_data);
+    }
+}
+
+static void
+xkb_keyboard_finalize (GObject *object)
+{
+    XkbKeyboard *keyboard = XKB_KEYBOARD (object);
+
+    if (keyboard->engine)
+    {
+        xkl_engine_stop_listen (keyboard->engine, XKLL_TRACK_KEYBOARD_STATE);
+        g_object_unref (keyboard->engine);
+
+        gdk_window_remove_filter (NULL, xkb_keyboard_handle_xevent, keyboard);
+    }
+
+    xkb_keyboard_free (keyboard);
+    
+    G_OBJECT_CLASS (xkb_keyboard_parent_class)->finalize (object);
+}
+
+gboolean
+xkb_keyboard_set_group (XkbKeyboard *keyboard, gint group)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), FALSE);
+
+    if (G_UNLIKELY (keyboard->engine == NULL || group < 0 || group >= keyboard->group_count))
+    {
+        return FALSE;
+    }
+
+    xkl_engine_lock_group (keyboard->engine, group);
+    keyboard->current_group = group;
+
+    return TRUE;
+}
+
+gboolean
+xkb_keyboard_next_group (XkbKeyboard *keyboard)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), FALSE);
+
+    if (G_UNLIKELY (keyboard->engine == NULL))
+    {
+        return FALSE;
+    }
+
+    xkl_engine_lock_group (keyboard->engine,
+            xkl_engine_get_next_group (keyboard->engine));
+
+    return TRUE;
+}
+
+gboolean
+xkb_keyboard_prev_group (XkbKeyboard *keyboard)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), FALSE);
+
+    if (G_UNLIKELY (keyboard->engine == NULL))
+    {
+        return FALSE;
+    }
+
+    xkl_engine_lock_group (keyboard->engine,
+            xkl_engine_get_prev_group (keyboard->engine));
+
+    return TRUE;
+}
+
+void
+xkb_keyboard_set_group_policy (XkbKeyboard *keyboard,
+                               XkbGroupPolicy group_policy)
+{
+    g_return_if_fail (IS_XKB_KEYBOARD (keyboard));
+    keyboard->group_policy = group_policy;
+}
+
+static void
+xkb_keyboard_update_from_xkl (XkbKeyboard *keyboard)
+{
+    XklConfigRec *config_rec;
+
+    config_rec = xkl_config_rec_new ();
+    xkl_config_rec_get_from_server (config_rec, keyboard->engine);
+
+    xkb_keyboard_initialize_xkb_options (keyboard, config_rec);
+
+    g_object_unref (config_rec);
+}
+
+void
+xkb_keyboard_window_changed (XkbKeyboard *keyboard,
+                             guint new_window_id,
+                             guint application_id)
+{
+    gint group;
+    gpointer key, value;
+    GHashTable *hashtable;
+    guint id;
+
+    g_return_if_fail (IS_XKB_KEYBOARD (keyboard));
+
+    id = 0;
+    hashtable = NULL;
+
+    switch (keyboard->group_policy)
+    {
+        case GROUP_POLICY_GLOBAL:
+            return;
+
+        case GROUP_POLICY_PER_WINDOW:
+            hashtable = keyboard->window_map;
+            id = new_window_id;
+            keyboard->current_window_id = id;
+            break;
+
+        case GROUP_POLICY_PER_APPLICATION:
+            hashtable = keyboard->application_map;
+            id = application_id;
+            keyboard->current_application_id = id;
+            break;
+    }
+
+    group = 0;
+
+    if (g_hash_table_lookup_extended (hashtable, GINT_TO_POINTER (id), &key, &value))
+    {
+        group = GPOINTER_TO_INT (value);
+    }
+    else
+    {
+        g_hash_table_insert (hashtable,
+                             GINT_TO_POINTER (id),
+                             GINT_TO_POINTER (group));
+    }
+
+    xkb_keyboard_set_group (keyboard, group);
+}
+
+void
+xkb_keyboard_application_closed (XkbKeyboard *keyboard,
+                                 guint application_id)
+{
+    g_return_if_fail (IS_XKB_KEYBOARD (keyboard));
+
+    switch (keyboard->group_policy)
+    {
+        case GROUP_POLICY_GLOBAL:
+        case GROUP_POLICY_PER_WINDOW:
+            return;
+
+        case GROUP_POLICY_PER_APPLICATION:
+            g_hash_table_remove (
+                    keyboard->application_map,
+                    GINT_TO_POINTER (application_id)
+            );
+
+            break;
+    }
+}
+
+void
+xkb_keyboard_window_closed (XkbKeyboard *keyboard,
+                            guint window_id)
+{
+    g_return_if_fail (IS_XKB_KEYBOARD (keyboard));
+
+    switch (keyboard->group_policy)
+    {
+        case GROUP_POLICY_GLOBAL:
+        case GROUP_POLICY_PER_APPLICATION:
+            return;
+
+        case GROUP_POLICY_PER_WINDOW:
+            g_hash_table_remove (
+                    keyboard->window_map,
+                    GINT_TO_POINTER (window_id)
+            );
+
+            break;
+    }
+}
+
+gint
+xkb_keyboard_get_group_count (XkbKeyboard *keyboard)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), 0);
+
+    return keyboard->group_count;
+}
+
+guint
+xkb_keyboard_get_max_group_count (XkbKeyboard *keyboard)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), 0);
+
+    if (G_UNLIKELY (keyboard->engine == NULL))
+    {
+        return 0;
+    }
+
+    return xkl_engine_get_max_num_groups(keyboard->engine);
+}
+
+const gchar*
+xkb_keyboard_get_group_name (XkbKeyboard *keyboard,
+                             gint group)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), NULL);
+
+    if (G_UNLIKELY (group >= keyboard->group_count))
+        return NULL;
+
+    if (group == -1)
+        group = xkb_keyboard_get_current_group (keyboard);
+
+    return keyboard->group_data[group].group_name;
+}
+
+const gchar*
+xkb_keyboard_get_variant (XkbKeyboard *keyboard,
+                          gint group)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), NULL);
+
+    if (G_UNLIKELY (group >= keyboard->group_count))
+        return NULL;
+
+    if (group == -1)
+        group = xkb_keyboard_get_current_group (keyboard);
+
+    return keyboard->group_data[group].variant;
+}
+
+static void
+xkb_keyboard_xkl_state_changed (XklEngine *engine,
+                                XklEngineStateChange change,
+                                gint group,
+                                gboolean restore,
+                                gpointer user_data)
+{
+    XkbKeyboard *keyboard = user_data;
+
+    if (change == GROUP_CHANGED)
+    {
+        keyboard->current_group = group;
+
+        switch (keyboard->group_policy)
+        {
+            case GROUP_POLICY_GLOBAL:
+                break;
+
+            case GROUP_POLICY_PER_WINDOW:
+                g_hash_table_insert (
+                        keyboard->window_map,
+                        GINT_TO_POINTER (keyboard->current_window_id),
+                        GINT_TO_POINTER (group)
+                );
+                break;
+
+            case GROUP_POLICY_PER_APPLICATION:
+                g_hash_table_insert (
+                        keyboard->application_map,
+                        GINT_TO_POINTER (keyboard->current_application_id),
+                        GINT_TO_POINTER (group)
+                );
+            break;
+        }
+
+        if (keyboard->callback != NULL)
+            keyboard->callback (group, FALSE, keyboard->callback_data);
+    }
+}
+
+static void
+xkb_keyboard_xkl_config_changed (XklEngine *engine,
+                                 gpointer user_data)
+{
+    XkbKeyboard *keyboard = user_data;
+
+    xkb_keyboard_update_from_xkl (keyboard);
+
+    if (keyboard->callback != NULL)
+    {
+        xkb_keyboard_set_group (keyboard, 0);
+        keyboard->callback (0, TRUE, keyboard->callback_data);
+    }
+}
+
+gint
+xkb_keyboard_variant_index_for_group (XkbKeyboard *keyboard,
+                                      gint group)
+{
+    gpointer presult;
+    gint result;
+
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), 0);
+
+    if (group == -1) group = xkb_keyboard_get_current_group (keyboard);
+
+    presult = g_hash_table_lookup (
+            keyboard->variant_index_by_group,
+            GINT_TO_POINTER (group)
+    );
+    if (presult == NULL) return 0;
+
+    result = GPOINTER_TO_INT (presult);
+    result = (result <= 0) ? 0 : result - 1;
+    return result;
+}
+
+static GdkFilterReturn
+xkb_keyboard_handle_xevent (GdkXEvent * xev, GdkEvent * event, gpointer user_data)
+{
+    XkbKeyboard *keyboard = user_data;
+    XEvent *xevent = (XEvent *) xev;
+
+    xkl_engine_filter_events (keyboard->engine, xevent);
+
+    return GDK_FILTER_CONTINUE;
+}
+
+GdkPixbuf *
+xkb_keyboard_get_tooltip_pixbuf (XkbKeyboard *keyboard,
+                                 gint group)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), NULL);
+    return keyboard->group_data[group].tooltip_pixbuf;
+}
+
+gchar*
+xkb_keyboard_get_pretty_layout_name (XkbKeyboard *keyboard,
+                                     gint group)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), NULL);
+    return keyboard->group_data[group].pretty_layout_name;
+}
+
+gint
+xkb_keyboard_get_current_group (XkbKeyboard *keyboard)
+{
+    g_return_val_if_fail (IS_XKB_KEYBOARD (keyboard), 0);
+    return keyboard->current_group;
+}
diff --git a/panel-plugin/xkb-keyboard.h b/panel-plugin/xkb-keyboard.h
new file mode 100644
index 0000000..213e353
--- /dev/null
+++ b/panel-plugin/xkb-keyboard.h
@@ -0,0 +1,87 @@
+/* vim: set backspace=2 ts=4 softtabstop=4 sw=4 cinoptions=>4 expandtab autoindent smartindent: */
+/* xkb-keyboard.h
+ * Copyright (C) 2008 Alexander Iliev <sasoiliev at mamul.org>
+ *
+ * Parts of this program comes from the XfKC tool:
+ * Copyright (C) 2006 Gauvain Pocentek <gauvainpocentek at gmail.com>
+ *
+ * A part of this file comes from the gnome keyboard capplet (control-center):
+ * Copyright (C) 2003 Sergey V. Oudaltsov <svu at users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _xkb_keyboard_H_
+#define _xkb_keyboard_H_
+
+#include <gdk/gdk.h>
+#include <libxklavier/xklavier.h>
+
+#include "xkb-properties.h"
+
+G_BEGIN_DECLS
+
+typedef struct _XkbKeyboardClass      XkbKeyboardClass;
+typedef struct _XkbKeyboard           XkbKeyboard;
+
+#define TYPE_XKB_KEYBOARD             (xkb_keyboard_get_type ())
+#define XKB_KEYBOARD(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_XKB_KEYBOARD, XkbKeyboard))
+#define XKB_KEYBOARD_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  TYPE_XKB_KEYBOARD, XkbKeyboardClass))
+#define IS_XKB_KEYBOARD(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_XKB_KEYBOARD))
+#define IS_XKB_KEYBOARD_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  TYPE_XKB_KEYBOARD))
+#define XKB_KEYBOARD_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  TYPE_XKB_KEYBOARD, XkbKeyboard))
+
+typedef void      (*XkbCallback)                            (gint current_group,
+                                                             gboolean groups_changed,
+                                                             gpointer user_data);
+
+GType             xkb_keyboard_get_type                     (void)                           G_GNUC_CONST;
+
+XkbKeyboard      *xkb_keyboard_new                          (XkbGroupPolicy group_policy,
+                                                             XkbCallback callback,
+                                                             gpointer data);
+
+gboolean          xkb_keyboard_get_initialized              (XkbKeyboard     *keyboard);
+void              xkb_keyboard_set_group_policy             (XkbKeyboard     *keyboard,
+                                                             XkbGroupPolicy   group_policy);
+gint              xkb_keyboard_get_group_count              (XkbKeyboard     *keyboard);
+guint             xkb_keyboard_get_max_group_count          (XkbKeyboard     *keyboard);
+const gchar*      xkb_keyboard_get_group_name               (XkbKeyboard     *keyboard,
+                                                             gint             group);
+const gchar*      xkb_keyboard_get_variant                  (XkbKeyboard     *keyboard,
+                                                             gint             group);
+gboolean          xkb_keyboard_set_group                    (XkbKeyboard     *keyboard,
+                                                             gint             group);
+gboolean          xkb_keyboard_next_group                   (XkbKeyboard     *keyboard);
+gboolean          xkb_keyboard_prev_group                   (XkbKeyboard     *keyboard);
+gint              xkb_keyboard_variant_index_for_group      (XkbKeyboard     *keyboard,
+                                                             gint             group);
+
+void              xkb_keyboard_window_changed               (XkbKeyboard     *keyboard,
+                                                             guint            new_window_id,
+                                                             guint            application_id);
+void              xkb_keyboard_application_closed           (XkbKeyboard     *keyboard,
+                                                             guint            application_id);
+void              xkb_keyboard_window_closed                (XkbKeyboard     *keyboard,
+                                                             guint            window_id);
+GdkPixbuf*        xkb_keyboard_get_tooltip_pixbuf           (XkbKeyboard     *keyboard,
+                                                             gint             group);
+gchar*            xkb_keyboard_get_pretty_layout_name       (XkbKeyboard     *keyboard,
+                                                             gint             group);
+gint              xkb_keyboard_get_current_group            (XkbKeyboard     *keyboard);
+
+G_END_DECLS
+
+#endif
diff --git a/panel-plugin/xkb-properties.h b/panel-plugin/xkb-properties.h
index 62450cb..0265ba6 100644
--- a/panel-plugin/xkb-properties.h
+++ b/panel-plugin/xkb-properties.h
@@ -36,7 +36,7 @@ typedef enum
     DISPLAY_TYPE_IMAGE              = 0,
     DISPLAY_TYPE_TEXT               = 1,
     DISPLAY_TYPE_SYSTEM             = 2
-} t_display_type;
+} XkbDisplayType;
 
 #define DISPLAY_SCALE_MIN             0
 #define DISPLAY_SCALE_MAX             100
@@ -46,7 +46,7 @@ typedef enum
     GROUP_POLICY_GLOBAL             = 0,
     GROUP_POLICY_PER_WINDOW         = 1,
     GROUP_POLICY_PER_APPLICATION    = 2
-} t_group_policy;
+} XkbGroupPolicy;
 
 #endif
 
diff --git a/panel-plugin/xkb-util.c b/panel-plugin/xkb-util.c
index 7ea77e2..4ffd6ab 100644
--- a/panel-plugin/xkb-util.c
+++ b/panel-plugin/xkb-util.c
@@ -27,7 +27,6 @@
 #include <cairo/cairo.h>
 
 #include "xkb-util.h"
-#include "xkb-config.h" // TODO : REMOVE THIS
 
 gchar*
 xkb_util_get_flag_filename (const gchar* group_name)

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list