[caribou] Added an introspectable C library for simulating kb events.



commit fe524741da78ee7d2de10982cd9ba56bd96ce160
Author: Eitan Isaacson <eitan monotonous org>
Date:   Sat Apr 16 15:04:30 2011 -0700

    Added an introspectable C library for simulating kb events.
    
    We will use this library more extensively later for layout changes,
    and different XKB ops.

 .gitignore                            |   13 +++
 Makefile.am                           |    2 +-
 configure.ac                          |   26 +++++-
 libcaribou/Makefile.am                |   93 +++++++++++++++++
 libcaribou/caribou-marshal.list       |    1 +
 libcaribou/caribou-virtual-keyboard.c |  175 +++++++++++++++++++++++++++++++++
 libcaribou/caribou-virtual-keyboard.h |   52 ++++++++++
 libcaribou/caribou.h                  |   19 ++++
 8 files changed, 378 insertions(+), 3 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 1e85d91..f770bfb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,16 @@ po/.intltool-merge-cache
 data/caribou.schemas
 data/caribou.schemas.in
 data/org.gnome.caribou.gschema.*
+depcomp
+libcaribou/.deps/
+caribou-enum-types.[ch]
+caribou-marshal.[ch]
+libtool
+ltmain.sh
+m4
+libcaribou/.libs/
+libcaribou/Caribou-1.0.gir
+libcaribou/Caribou-1.0.typelib
+*.lo
+libcaribou/libcaribou.la
+
diff --git a/Makefile.am b/Makefile.am
index 60d3a68..8b57e28 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,3 +1,3 @@
 ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
 
-SUBDIRS = caribou bin data po
+SUBDIRS = caribou bin data po libcaribou
diff --git a/configure.ac b/configure.ac
index 977e08f..366da21 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,27 +6,45 @@ AC_INIT([caribou],
 
 AC_CONFIG_MACRO_DIR([m4])
 
+AM_PROG_LIBTOOL
+
 AM_INIT_AUTOMAKE([1.11])
 AM_MAINTAINER_MODE([enable])
 # Support silent build rules. Disable by either passing --disable-silent-rules
 # to configure or passing V=1 to make
 AM_SILENT_RULES([yes])
 
+
+AM_PATH_GLIB_2_0(2.27.5,,,gobject)
+if test "$GLIB_LIBS" = ""; then
+   AC_MSG_ERROR(GLIB 2.27.5 or later is required to build libcaribou)
+fi
+
 dnl == check for python ==
 AM_PATH_PYTHON(2.4)
 
 dnl == Library dependencies ==
 PYGOBJECT_REQUIRED=2.27.92
-GTK_REQUIRED=2.91.8
+GTK_REQUIRED=3.0.0
 CLUTTER_REQUIRED=1.5.11
+GDK_REQUIRED=3.0.0
 
 PKG_CHECK_MODULES(CARIBOU, [
   pygobject-2.0 >= $PYGOBJECT_REQUIRED,
   gtk+-3.0      >= $GTK_REQUIRED,
-  clutter-1.0   >= $CLUTTER_REQUIRED])
+  clutter-1.0   >= $CLUTTER_REQUIRED
+  ])
 AC_SUBST(CARIBOU_CFLAGS)
 AC_SUBST(CARIBOU_LIBS)
 
+PKG_CHECK_MODULES(LIBCARIBOU, [
+  gdk-3.0 >= $GDK_REQUIRED,
+  xtst,
+  x11
+  ])
+AC_SUBST(LIBCARIBOU_CFLAGS)
+AC_SUBST(LIBCARIBOU_LIBS)
+
 dnl == i18n ==
 GETTEXT_PACKAGE=caribou
 AC_SUBST(GETTEXT_PACKAGE)
@@ -41,6 +59,9 @@ IT_PROG_INTLTOOL([0.35.0])
 dnl == Documentation ==
 GNOME_DOC_INIT
 
+dnl == GObject introspection ==
+GOBJECT_INTROSPECTION_CHECK([0.10.7])
+
 dnl == generate makefiles ==
 AC_OUTPUT([
 Makefile
@@ -53,4 +74,5 @@ bin/Makefile
 bin/caribou
 data/Makefile
 data/keyboards/Makefile
+libcaribou/Makefile
 ])
diff --git a/libcaribou/Makefile.am b/libcaribou/Makefile.am
new file mode 100644
index 0000000..c7f7a0a
--- /dev/null
+++ b/libcaribou/Makefile.am
@@ -0,0 +1,93 @@
+INCLUDES =                              \
+        -DG_LOG_DOMAIN=\"libcaribou\"   \
+        -I$(top_srcdir)                 \
+        $(LIBCARIBOU_CFLAGS)
+
+
+MARSHAL_GENERATED = caribou-marshal.c caribou-marshal.h
+MKENUMS_GENERATED = caribou-enum-types.c caribou-enum-types.h
+
+caribou-marshal.h: caribou-marshal.list
+	$(AM_V_GEN) ( $(GLIB_GENMARSHAL) --prefix=caribou_marshal $(srcdir)/caribou-marshal.list --header > caribou-marshal.tmp \
+	&& mv caribou-marshal.tmp caribou-marshal.h ) \
+	|| ( rm -f caribou-marshal.tmp && exit 1 )
+
+caribou-marshal.c: caribou-marshal.h
+	$(AM_V_GEN) ( (echo '#include "caribou-marshal.h"'; $(GLIB_GENMARSHAL) --prefix=caribou_marshal $(srcdir)/caribou-marshal.list --body) > caribou-marshal.tmp \
+	&& mv caribou-marshal.tmp caribou-marshal.c ) \
+	|| ( rm -f caribou-marshal.tmp && exit 1 )
+
+caribou-enum-types.h: $(caribou_headers)
+	$(AM_V_GEN) ( cd $(srcdir) && $(GLIB_MKENUMS) --template caribou-enum-types.h.tmpl \
+		$(caribou_headers) ) > caribou-enum-types.h.tmp \
+	&& mv caribou-enum-types.h.tmp caribou-enum-types.h \
+	|| rm -f caribou-enum-type.h.tmp
+
+caribou-enum-types.c: $(libcaribouinclude_HEADERS)
+	$(AM_V_GEN) ( cd $(srcdir) && $(GLIB_MKENUMS) --template caribou-enum-types.c.tmpl \
+		$(caribou_headers) ) > caribou-enum-types.c.tmp \
+	&& mv caribou-enum-types.c.tmp caribou-enum-types.c \
+	|| rm -f caribou-enum-type.c.tmp
+
+BUILT_SOURCES = $(MARSHAL_GENERATED) $(MKENUMS_GENERATED)
+
+CLEANFILES = $(MARSHAL_GENERATED) $(MKENUMS_GENERATED)
+
+libcaribouincludedir = $(includedir)/libcaribou
+
+caribou_headers =		  \
+	caribou.h		      \
+	caribou-virtual-keyboard.h
+
+libcaribouinclude_HEADERS =	\
+	$(caribou_headers)	 \
+	caribou-enum-types.h
+
+lib_LTLIBRARIES = libcaribou.la
+
+libcaribou_la_LIBADD = \
+	$(LIBCARIBOU_LIBS)
+
+libcaribou_la_SOURCES =		\
+	$(BUILT_SOURCES)	    \
+	caribou-virtual-keyboard.c
+
+#
+# Introspection support
+#
+include $(INTROSPECTION_MAKEFILE)
+INTROSPECTION_GIRS =
+INTROSPECTION_SCANNER_ARGS = --add-include-path=.
+INTROSPECTION_COMPILER_ARGS = --includedir=.
+
+if HAVE_INTROSPECTION
+
+gi_caribou_files = \
+	$(filter-out caribou.h caribou-enum-types.% caribou-marshal.h,\
+	   $(caribou_headers) $(filter-out %.h, $(libcaribou_la_SOURCES)))
+# gi_built_caribou_files = caribou-enum-types.h
+
+Caribou-1.0.gir: libcaribou.la
+Caribou_1_0_gir_INCLUDES = Gdk-3.0
+Caribou_1_0_gir_CFLAGS = $(INCLUDES)
+Caribou_1_0_gir_LIBS = libcaribou.la
+Caribou_1_0_gir_EXPORT_PACKAGES = libcaribou
+Caribou_1_0_gir_SCANNERFLAGS = --c-include "libcaribou/caribou.h"
+Caribou_1_0_gir_FILES = \
+	$(addprefix $(srcdir)/, $(gi_caribou_files)) \
+	$(foreach f,$(gi_built_caribou_files), \
+	   $(if $(shell test -f $(addprefix $(srcdir)/,$(f)) && echo yes), \
+	      $(addprefix $(srcdir)/,$(f)), \
+	      $(f)))
+
+INTROSPECTION_GIRS += Caribou-1.0.gir
+
+girdir = $(datadir)/gir-1.0
+gir_DATA = $(INTROSPECTION_GIRS)
+
+typelibsdir = $(libdir)/girepository-1.0
+typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+CLEANFILES += $(gir_DATA) $(typelibs_DATA)
+
+endif
\ No newline at end of file
diff --git a/libcaribou/caribou-enum-types.c.tmpl b/libcaribou/caribou-enum-types.c.tmpl
new file mode 100644
index 0000000..e69de29
diff --git a/libcaribou/caribou-enum-types.h.tmpl b/libcaribou/caribou-enum-types.h.tmpl
new file mode 100644
index 0000000..e69de29
diff --git a/libcaribou/caribou-marshal.list b/libcaribou/caribou-marshal.list
new file mode 100644
index 0000000..fa33740
--- /dev/null
+++ b/libcaribou/caribou-marshal.list
@@ -0,0 +1 @@
+NONE:NONE
diff --git a/libcaribou/caribou-virtual-keyboard.c b/libcaribou/caribou-virtual-keyboard.c
new file mode 100644
index 0000000..50846f8
--- /dev/null
+++ b/libcaribou/caribou-virtual-keyboard.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011, Eitan Isaacson <eitan monotonous org>
+ */
+
+#include "caribou-virtual-keyboard.h"
+#include "caribou-marshal.h"
+#include <X11/Xlib.h>
+#include <X11/extensions/XTest.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <X11/XKBlib.h>
+
+struct _CaribouVirtualKeyboardPrivate {
+  GdkDisplay *display;
+};
+
+G_DEFINE_TYPE (CaribouVirtualKeyboard, caribou_virtual_keyboard, G_TYPE_OBJECT)
+
+enum {
+	PLACEHOLDER,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+dispose (GObject *object)
+{
+  CaribouVirtualKeyboard *self = CARIBOU_VIRTUAL_KEYBOARD (object);
+
+  G_OBJECT_CLASS (caribou_virtual_keyboard_parent_class)->dispose (object);
+}
+
+static void
+caribou_virtual_keyboard_init (CaribouVirtualKeyboard *self)
+{
+  self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), CARIBOU_TYPE_VIRTUAL_KEYBOARD,
+                                            CaribouVirtualKeyboardPrivate);
+
+  self->priv->display = gdk_display_get_default ();
+}
+
+static void
+caribou_virtual_keyboard_class_init (CaribouVirtualKeyboardClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (CaribouVirtualKeyboardPrivate));
+
+	/* virtual method override */
+	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);
+}
+
+/**
+ * caribou_virtual_keyboard_new:
+ *
+ * Create a new #CaribouVirtualKeyboard.
+ *
+ * Returns: A new #CaribouVirtualKeyboard.
+ */
+CaribouVirtualKeyboard *
+caribou_virtual_keyboard_new ()
+{
+  return g_object_new (CARIBOU_TYPE_VIRTUAL_KEYBOARD, NULL);
+}
+
+static Display *
+_get_xdisplay (CaribouVirtualKeyboard *self)
+{
+  g_return_if_fail (self != NULL);
+
+  return GDK_DISPLAY_XDISPLAY (self->priv->display);
+}
+
+static KeyCode
+keycode_for_keyval (guint                   keyval,
+                    guint                  *modmask)
+{
+  GdkKeymap *km = gdk_keymap_get_default ();
+  GdkKeymapKey *kmk;
+  gint len;
+  KeyCode keycode;
+
+  g_return_val_if_fail (modmask != NULL, 0);
+
+  if (gdk_keymap_get_entries_for_keyval (km, keyval, &kmk, &len)) {
+    keycode = kmk[0].keycode;
+    *modmask = (kmk[0].level == 1) ? GDK_SHIFT_MASK : 0;
+    g_free (kmk);
+  }
+
+  return keycode;
+}
+
+/**
+ * caribou_virtual_keyboard_mod_latch:
+ * @mask: the modifier mask
+ *
+ * Simulate a keyboard modifier key press
+ */
+void
+caribou_virtual_keyboard_mod_latch (CaribouVirtualKeyboard *self,
+                                    int                     mask)
+{
+  Bool b;
+  b = XkbLatchModifiers(_get_xdisplay (self), XkbUseCoreKbd, mask, mask);
+  g_print ("latching %d %d\n", mask, b);
+  gdk_display_sync (self->priv->display);
+}
+
+/**
+ * caribou_virtual_keyboard_mod_unlatch:
+ * @mask: the modifier mask
+ *
+ * Simulate a keyboard modifier key release
+ */
+void
+caribou_virtual_keyboard_mod_unlatch (CaribouVirtualKeyboard *self,
+                                      int                     mask)
+{
+  g_print ("unlatching %d\n", mask);
+  XkbLatchModifiers(_get_xdisplay (self), XkbUseCoreKbd, mask, 0);
+  gdk_display_sync (self->priv->display);
+}
+
+/**
+ * caribou_virtual_keyboard_keyval_press:
+ * @keyval: the keyval to simulate
+ *
+ * Simulate a keyboard key press with a given keyval.
+ */
+void
+caribou_virtual_keyboard_keyval_press (CaribouVirtualKeyboard *self,
+                                       guint                   keyval)
+{
+  guint mask;
+  KeyCode keycode = keycode_for_keyval (keyval, &mask);
+  
+  if (mask != 0)
+    caribou_virtual_keyboard_mod_latch (self, mask);
+
+  XTestFakeKeyEvent(_get_xdisplay (self), keycode, TRUE, CurrentTime);
+  gdk_display_sync (self->priv->display);
+}
+
+/**
+ * caribou_virtual_keyboard_keyval_release:
+ * @keyval: the keyval to simulate
+ *
+ * Simulate a keyboard key press with a given keyval.
+ */
+void
+caribou_virtual_keyboard_keyval_release (CaribouVirtualKeyboard *self,
+                                         guint                   keyval)
+{
+  guint mask;
+  KeyCode keycode = keycode_for_keyval (keyval, &mask);
+
+  XTestFakeKeyEvent(_get_xdisplay (self), keycode, FALSE, CurrentTime);
+
+  if (mask != 0)
+    caribou_virtual_keyboard_mod_unlatch (self, mask);
+
+  gdk_display_sync (self->priv->display);
+}
diff --git a/libcaribou/caribou-virtual-keyboard.h b/libcaribou/caribou-virtual-keyboard.h
new file mode 100644
index 0000000..01e7499
--- /dev/null
+++ b/libcaribou/caribou-virtual-keyboard.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011, Eitan Isaacson <eitan monotonous org>
+ */
+
+#ifndef CARIBOU_VIRTUAL_KEYBOARD_H
+#define CARIBOU_VIRTUAL_KEYBOARD_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CARIBOU_TYPE_VIRTUAL_KEYBOARD            (caribou_virtual_keyboard_get_type ())
+#define CARIBOU_VIRTUAL_KEYBOARD(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CARIBOU_TYPE_VIRTUAL_KEYBOARD, CaribouVirtualKeyboard))
+#define CARIBOU_VIRTUAL_KEYBOARD_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CARIBOU_TYPE_VIRTUAL_KEYBOARD, CaribouVirtualKeyboardClass))
+#define CARIBOU_IS_VIRTUAL_KEYBOARD(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CARIBOU_TYPE_VIRTUAL_KEYBOARD))
+#define CARIBOU_IS_VIRTUAL_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), CARIBOU_TYPE_VIRTUAL_KEYBOARD))
+#define CARIBOU_VIRTUAL_KEYBOARD_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), CARIBOU_TYPE_VIRTUAL_KEYBOARD, CaribouVirtualKeyboardClass))
+
+typedef struct _CaribouVirtualKeyboard CaribouVirtualKeyboard;
+typedef struct _CaribouVirtualKeyboardClass CaribouVirtualKeyboardClass;
+typedef struct _CaribouVirtualKeyboardPrivate CaribouVirtualKeyboardPrivate;
+
+struct _CaribouVirtualKeyboard {
+  GObject parent;
+
+  CaribouVirtualKeyboardPrivate *priv;
+};
+
+struct _CaribouVirtualKeyboardClass {
+  GObjectClass parent_class;
+
+};
+
+GType caribou_virtual_keyboard_get_type (void);
+
+CaribouVirtualKeyboard *caribou_virtual_keyboard_new ();
+
+void caribou_virtual_keyboard_keyval_press (CaribouVirtualKeyboard *self,
+                                            guint                   keyval);
+
+void caribou_virtual_keyboard_keyval_release (CaribouVirtualKeyboard *self,
+                                              guint                   keyval);
+
+void caribou_virtual_keyboard_mod_latch (CaribouVirtualKeyboard *self,
+                                         int                     mask);
+
+void caribou_virtual_keyboard_mod_unlatch (CaribouVirtualKeyboard *self,
+                                           int                     mask);
+
+G_END_DECLS
+
+#endif /* CARIBOU_VIRTUAL_KEYBOARD_H */
diff --git a/libcaribou/caribou.h b/libcaribou/caribou.h
new file mode 100644
index 0000000..66b4c9f
--- /dev/null
+++ b/libcaribou/caribou.h
@@ -0,0 +1,19 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2011, Eitan Isaacson <eitan monotonous org>
+ */
+
+#ifndef CARIBOU_H
+#define CARIBOU_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libcaribou/caribou-virtual-keyboard.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CARIBOU_H */



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