summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEitan Isaacson <eitan@monotonous.org>2011-04-16 15:04:30 -0700
committerEitan Isaacson <eitan@monotonous.org>2011-04-16 15:06:47 -0700
commitfe524741da78ee7d2de10982cd9ba56bd96ce160 (patch)
tree8436e4cf506e57f1fb841cde0fdd1313b96ea485
parentbccb1c25a5ad354571eb042a778ffb36f7342241 (diff)
downloadcaribou-fe524741da78ee7d2de10982cd9ba56bd96ce160.tar.gz
Added an introspectable C library for simulating kb events.
We will use this library more extensively later for layout changes, and different XKB ops.
-rw-r--r--.gitignore13
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac26
-rw-r--r--libcaribou/Makefile.am93
-rw-r--r--libcaribou/caribou-enum-types.c.tmpl0
-rw-r--r--libcaribou/caribou-enum-types.h.tmpl0
-rw-r--r--libcaribou/caribou-marshal.list1
-rw-r--r--libcaribou/caribou-virtual-keyboard.c175
-rw-r--r--libcaribou/caribou-virtual-keyboard.h52
-rw-r--r--libcaribou/caribou.h19
10 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
--- /dev/null
+++ b/libcaribou/caribou-enum-types.c.tmpl
diff --git a/libcaribou/caribou-enum-types.h.tmpl b/libcaribou/caribou-enum-types.h.tmpl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libcaribou/caribou-enum-types.h.tmpl
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 */