[caribou: 2/22] libcaribou: Added signals when group or modifiers change



commit 2088cfcf5a6b1d9a08b391e57a14aca6282a5820
Author: Eitan Isaacson <eitan monotonous org>
Date:   Fri Apr 22 17:30:08 2011 -0700

    libcaribou: Added signals when group or modifiers change

 configure.ac                          |    3 +-
 libcaribou/caribou-marshal.list       |    3 +-
 libcaribou/caribou-virtual-keyboard.c |   95 +++++++++++++++++++++++++++++---
 3 files changed, 90 insertions(+), 11 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 366da21..40cac78 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,7 +40,8 @@ AC_SUBST(CARIBOU_LIBS)
 PKG_CHECK_MODULES(LIBCARIBOU, [
   gdk-3.0 >= $GDK_REQUIRED,
   xtst,
-  x11
+  x11,
+  libxklavier
   ])
 AC_SUBST(LIBCARIBOU_CFLAGS)
 AC_SUBST(LIBCARIBOU_LIBS)
diff --git a/libcaribou/caribou-marshal.list b/libcaribou/caribou-marshal.list
index fa33740..6c138ac 100644
--- a/libcaribou/caribou-marshal.list
+++ b/libcaribou/caribou-marshal.list
@@ -1 +1,2 @@
-NONE:NONE
+NONE:UINT
+NONE:UINT,STRING,STRING
diff --git a/libcaribou/caribou-virtual-keyboard.c b/libcaribou/caribou-virtual-keyboard.c
index f518104..bd4d1da 100644
--- a/libcaribou/caribou-virtual-keyboard.c
+++ b/libcaribou/caribou-virtual-keyboard.c
@@ -9,16 +9,22 @@
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #include <X11/XKBlib.h>
+#include <libxklavier/xklavier.h>
 
 #define XDISPLAY GDK_DISPLAY_XDISPLAY(gdk_display_get_default ())
 
 struct _CaribouVirtualKeyboardPrivate {
+  XkbDescPtr  xkbdesc;
+  XklEngine  *xkl_engine;
+  gchar modifiers;
+  gchar group;
 };
 
 G_DEFINE_TYPE (CaribouVirtualKeyboard, caribou_virtual_keyboard, G_TYPE_OBJECT)
 
 enum {
-	PLACEHOLDER,
+    KB_MODIFIERS_CHANGED,
+    KB_GROUP_CHANGED,
 	LAST_SIGNAL
 };
 
@@ -29,15 +35,62 @@ dispose (GObject *object)
 {
   CaribouVirtualKeyboard *self = CARIBOU_VIRTUAL_KEYBOARD (object);
 
+  XkbFreeKeyboard (self->priv->xkbdesc, XkbGBN_AllComponentsMask, True);
+
   G_OBJECT_CLASS (caribou_virtual_keyboard_parent_class)->dispose (object);
 }
 
+static GdkFilterReturn
+_filter_x_evt (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
+{
+  CaribouVirtualKeyboard *self = CARIBOU_VIRTUAL_KEYBOARD (data);
+  XkbEvent *xevent = gdk_xevent;
+
+  if (xevent->any.xkb_type == XkbStateNotify) {
+    XkbStateNotifyEvent *sevent = &xevent->state;
+    if (sevent->changed & XkbGroupStateMask) {
+      XklConfigRec *config_rec;
+      self->priv->group = sevent->group;
+      config_rec = xkl_config_rec_new ();
+      xkl_config_rec_get_from_server (config_rec, self->priv->xkl_engine);
+      g_signal_emit (self, signals[KB_GROUP_CHANGED], 0,
+                     sevent->group,
+                     config_rec->layouts[sevent->group],
+                     config_rec->variants[sevent->group]);
+      g_object_unref (config_rec);
+    } else if (sevent->changed & XkbModifierStateMask) {
+      self->priv->modifiers = sevent->mods;
+      g_signal_emit (self, signals[KB_MODIFIERS_CHANGED], 0, sevent->mods);
+    }
+  }
+
+  return GDK_FILTER_CONTINUE;
+}
+
 static void
 caribou_virtual_keyboard_init (CaribouVirtualKeyboard *self)
 {
+  XkbStateRec sr;
+
   self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), CARIBOU_TYPE_VIRTUAL_KEYBOARD,
                                             CaribouVirtualKeyboardPrivate);
 
+  self->priv->xkbdesc = XkbGetKeyboard(XDISPLAY, XkbGBN_AllComponentsMask,
+                                       XkbUseCoreKbd);
+
+  self->priv->xkl_engine = xkl_engine_get_instance (XDISPLAY);
+
+  XkbGetState(XDISPLAY, XkbUseCoreKbd, &sr);
+
+  self->priv->modifiers = sr.mods;
+  self->priv->group = sr.group;
+
+  XkbSelectEvents (XDISPLAY,
+                   XkbUseCoreKbd, XkbStateNotifyMask | XkbAccessXNotifyMask,
+                   XkbStateNotifyMask | XkbAccessXNotifyMask | XkbMapNotifyMask);
+
+  gdk_window_add_filter (NULL, (GdkFilterFunc) _filter_x_evt, self);
+
 }
 
 static void
@@ -51,14 +104,38 @@ caribou_virtual_keyboard_class_init (CaribouVirtualKeyboardClass *klass)
 	object_class->dispose = dispose;
 
 	/* signals */
-	signals[PLACEHOLDER] =
-		g_signal_new ("placeholder",
-			      G_OBJECT_CLASS_TYPE (object_class),
-			      G_SIGNAL_RUN_FIRST,
-			      0,
-			      NULL, NULL,
-			      caribou_marshal_NONE__NONE,
-			      G_TYPE_NONE, 0);
+
+    /**
+     * CaribouVirtualKeyboard::modifiers-changed:
+     * @virtual_keyboard: the object that received the signal
+     * @modifiers: the modifiers that are currently active
+     *
+     * Emitted when the keyboard modifiers change.
+     */
+	signals[KB_MODIFIERS_CHANGED] =
+      g_signal_new ("modifiers-changed",
+                    G_OBJECT_CLASS_TYPE (object_class),
+                    G_SIGNAL_RUN_FIRST,
+                    0,
+                    NULL, NULL,
+                    caribou_marshal_NONE__UINT,
+                    G_TYPE_NONE, 1, G_TYPE_UINT);
+
+    /**
+     * CaribouVirtualKeyboard::group-changed:
+     * @virtual_keyboard: the object that received the signal
+     * @group: the currently active group
+     *
+     * Emitted when the keyboard group changes.
+     */
+	signals[KB_GROUP_CHANGED] =
+      g_signal_new ("group-changed",
+                    G_OBJECT_CLASS_TYPE (object_class),
+                    G_SIGNAL_RUN_FIRST,
+                    0,
+                    NULL, NULL,
+                    caribou_marshal_NONE__UINT_STRING_STRING,
+                    G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
 }
 
 /**



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]