summaryrefslogtreecommitdiff
path: root/libcaribou
diff options
context:
space:
mode:
authorEitan Isaacson <eitan@monotonous.org>2011-04-22 17:30:08 -0700
committerEitan Isaacson <eitan@monotonous.org>2011-05-02 10:18:49 -0700
commit2088cfcf5a6b1d9a08b391e57a14aca6282a5820 (patch)
tree16db4a7c2a252f0db20c7e409f1a07bc7e788399 /libcaribou
parent8a098c163dab5c2a293498158a8c06923e2a9c39 (diff)
downloadcaribou-2088cfcf5a6b1d9a08b391e57a14aca6282a5820.tar.gz
libcaribou: Added signals when group or modifiers change
Diffstat (limited to 'libcaribou')
-rw-r--r--libcaribou/caribou-marshal.list3
-rw-r--r--libcaribou/caribou-virtual-keyboard.c95
2 files changed, 88 insertions, 10 deletions
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);
}
/**