Use libXtst directly instead of via libfakekey.

This commit is contained in:
Daiki Ueno
2011-06-13 15:26:59 +09:00
parent 606f335496
commit 9d73b89a4e
6 changed files with 130 additions and 111 deletions

2
README
View File

@ -8,7 +8,7 @@ tools to implement desktop virtual keyboards.
** Dependencies ** Dependencies
REQUIRED: GLib2, GTK, PangoCairo, libxklavier, libcroco REQUIRED: GLib2, GTK, PangoCairo, libxklavier, libcroco
OPTIONAL: fakekey, at-spi2-core, Clutter, Clutter-Gtk, Python, Vala, gobject-introspection OPTIONAL: libXtst, at-spi2-core, Clutter, Clutter-Gtk, Python, Vala, gobject-introspection
** Build from git repo ** Build from git repo

View File

@ -104,21 +104,24 @@ PKG_CHECK_MODULES([LIBXKLAVIER], [libxklavier x11], ,
PKG_CHECK_MODULES([LIBCROCO], [libcroco-0.6], , PKG_CHECK_MODULES([LIBCROCO], [libcroco-0.6], ,
[AC_MSG_ERROR([libcroco not found])]) [AC_MSG_ERROR([libcroco not found])])
dnl use libfakekey to generate key events dnl use XTest to generate key events
AC_MSG_CHECKING([whether you enable fakekey]) AC_MSG_CHECKING([whether you enable XTest])
AC_ARG_ENABLE(fakekey, AC_ARG_ENABLE(xtest,
AS_HELP_STRING([--enable-fakekey=no/yes], AS_HELP_STRING([--enable-xtest=no/yes],
[Enable fakekey default=yes]),, [Enable XTest default=yes]),,
enable_fakekey=yes) enable_xtest=yes)
if test x$enable_fakekey = xyes; then if test x$enable_xtest = xyes; then
PKG_CHECK_MODULES([FAKEKEY], [libfakekey], , enable_fakekey=no) PKG_CHECK_MODULES([XTEST], [xtst], , enable_xtest=no)
if test x$enable_fakekey = xyes; then if test x$enable_xtest = xyes; then
AC_DEFINE([HAVE_FAKEKEY], [1], [Define if fakekey is found]) AC_DEFINE([HAVE_XTEST], [1], [Define if XTest is found])
fi fi
fi fi
AM_CONDITIONAL(ENABLE_FAKEKEY, [test x$enable_fakekey = xyes]) AM_CONDITIONAL(ENABLE_XTEST, [test x$enable_xtest = xyes])
AC_MSG_RESULT($enable_fakekey) AC_MSG_RESULT($enable_xtest)
focus_listeners=""
keystroke_listeners=""
focus_listeners="" focus_listeners=""
keystroke_listeners="" keystroke_listeners=""

View File

@ -41,11 +41,11 @@ eekboard_LDADD = \
$(XKB_LIBS) \ $(XKB_LIBS) \
$(LIBXKLAVIER_LIBS) $(LIBXKLAVIER_LIBS)
if ENABLE_FAKEKEY if ENABLE_XTEST
eekboard_CFLAGS += \ eekboard_CFLAGS += \
$(FAKEKEY_CFLAGS) $(XTEST_CFLAGS)
eekboard_LDADD += \ eekboard_LDADD += \
$(FAKEKEY_LIBS) $(XTEST_LIBS)
endif endif
if ENABLE_ATSPI if ENABLE_ATSPI

View File

@ -277,12 +277,12 @@ main (int argc, char **argv)
g_free (file); g_free (file);
} }
#ifdef HAVE_FAKEKEY #ifdef HAVE_XTEST
if (!eekboard_client_enable_fakekey (client)) { if (!eekboard_client_enable_xtest (client)) {
g_printerr ("Can't init fakekey\n"); g_printerr ("Can't init xtest\n");
exit (1); exit (1);
} }
#endif /* HAVE_FAKEKEY */ #endif /* HAVE_XTEST */
loop = g_main_loop_new (NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
if (!opt_focus) { if (!opt_focus) {

View File

@ -28,9 +28,9 @@
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#ifdef HAVE_FAKEKEY #ifdef HAVE_XTEST
#include <fakekey/fakekey.h> #include <X11/extensions/XTest.h>
#endif /* HAVE_FAKEKEY */ #endif /* HAVE_XTEST */
#ifdef HAVE_IBUS #ifdef HAVE_IBUS
#include <ibus.h> #include <ibus.h>
@ -42,6 +42,8 @@
#include "client.h" #include "client.h"
#include "xklutil.h" #include "xklutil.h"
#include <string.h>
#define CSW 640 #define CSW 640
#define CSH 480 #define CSH 480
@ -86,9 +88,9 @@ struct _EekboardClient {
guint ibus_focus_message_filter; guint ibus_focus_message_filter;
#endif /* HAVE_IBUS */ #endif /* HAVE_IBUS */
#ifdef HAVE_FAKEKEY #ifdef HAVE_XTEST
FakeKey *fakekey; KeyCode modifier_keycodes[8];
#endif /* HAVE_FAKEKEY */ #endif /* HAVE_XTEST */
}; };
struct _EekboardClientClass { struct _EekboardClientClass {
@ -124,6 +126,10 @@ static gboolean set_xkl_keyboard (EekboardClient *client,
const gchar *model, const gchar *model,
const gchar *layouts, const gchar *layouts,
const gchar *options); const gchar *options);
#ifdef HAVE_XTEST
static void update_modifier_keycodes
(EekboardClient *client);
#endif /* HAVE_XTEST */
static void static void
eekboard_client_set_property (GObject *object, eekboard_client_set_property (GObject *object,
@ -204,9 +210,9 @@ eekboard_client_dispose (GObject *object)
} }
#endif /* HAVE_IBUS */ #endif /* HAVE_IBUS */
#ifdef HAVE_FAKEKEY #ifdef HAVE_XTEST
eekboard_client_disable_fakekey (client); eekboard_client_disable_xtest (client);
#endif /* HAVE_FAKEKEY */ #endif /* HAVE_XTEST */
if (client->context) { if (client->context) {
if (client->eekboard) { if (client->eekboard) {
@ -227,12 +233,6 @@ eekboard_client_dispose (GObject *object)
client->keyboard = NULL; client->keyboard = NULL;
} }
#ifdef HAVE_FAKEKEY
if (client->fakekey) {
client->fakekey = NULL;
}
#endif /* HAVE_FAKEKEY */
if (client->display) { if (client->display) {
gdk_display_close (client->display); gdk_display_close (client->display);
client->display = NULL; client->display = NULL;
@ -302,9 +302,6 @@ eekboard_client_init (EekboardClient *client)
client->ibus_bus = NULL; client->ibus_bus = NULL;
client->ibus_focus_message_filter = 0; client->ibus_focus_message_filter = 0;
#endif /* HAVE_IBUS */ #endif /* HAVE_IBUS */
#ifdef HAVE_FAKEKEY
client->fakekey = NULL;
#endif /* HAVE_FAKEKEY */
} }
gboolean gboolean
@ -683,8 +680,7 @@ on_xkl_config_changed (XklEngine *xklengine,
g_return_if_fail (retval); g_return_if_fail (retval);
#ifdef HAVE_FAKEKEY #ifdef HAVE_FAKEKEY
if (client->fakekey) update_modifier_keycodes (client);
fakekey_reload_keysyms (client->fakekey);
#endif /* HAVE_FAKEKEY */ #endif /* HAVE_FAKEKEY */
} }
@ -789,22 +785,59 @@ on_xkl_state_changed (XklEngine *xklengine,
} }
} }
#ifdef HAVE_FAKEKEY #ifdef HAVE_XTEST
G_INLINE_FUNC FakeKeyModifier static void
get_fakekey_modifiers (EekModifierType modifiers) send_fake_modifier_key_event (EekboardClient *client,
EekModifierType modifiers,
gboolean is_pressed)
{ {
FakeKeyModifier retval = 0; gint i;
if (modifiers & EEK_SHIFT_MASK) for (i = 0; i < G_N_ELEMENTS(client->modifier_keycodes); i++) {
retval |= FAKEKEYMOD_SHIFT; if (modifiers & (1 << i)) {
if (modifiers & EEK_CONTROL_MASK) guint keycode = client->modifier_keycodes[i];
retval |= FAKEKEYMOD_CONTROL;
if (modifiers & EEK_MOD1_MASK)
retval |= FAKEKEYMOD_ALT;
if (modifiers & EEK_META_MASK)
retval |= FAKEKEYMOD_META;
return retval; g_return_if_fail (keycode > 0);
XTestFakeKeyEvent (GDK_DISPLAY_XDISPLAY (client->display),
keycode,
is_pressed,
CurrentTime);
}
}
}
static void
send_fake_key_event (EekboardClient *client,
EekKey *key,
gboolean is_pressed)
{
EekSymbol *symbol;
EekModifierType modifiers;
guint xkeysym;
guint keycode;
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
/* Ignore special keys and modifiers */
if (!EEK_IS_KEYSYM(symbol) || eek_symbol_is_modifier (symbol))
return;
xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
g_return_if_fail (xkeysym > 0);
keycode = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (client->display),
xkeysym);
g_return_if_fail (keycode > 0);
modifiers = eek_keyboard_get_modifiers (client->keyboard);
send_fake_modifier_key_event (client, modifiers, is_pressed);
XTestFakeKeyEvent (GDK_DISPLAY_XDISPLAY (client->display),
keycode,
is_pressed,
CurrentTime);
XSync (GDK_DISPLAY_XDISPLAY (client->display), False);
} }
static void static void
@ -813,35 +846,7 @@ on_key_pressed (EekKeyboard *keyboard,
gpointer user_data) gpointer user_data)
{ {
EekboardClient *client = user_data; EekboardClient *client = user_data;
EekSymbol *symbol; send_fake_key_event (client, key, TRUE);
g_assert (client->fakekey);
symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (EEK_IS_KEYSYM(symbol) && !eek_symbol_is_modifier (symbol)) {
guint xkeysym;
guint keycode;
EekModifierType modifiers;
FakeKeyModifier fakekey_modifiers;
xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
g_return_if_fail (xkeysym > 0);
keycode = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (client->display),
xkeysym);
g_return_if_fail (keycode > 0);
modifiers = eek_keyboard_get_modifiers (client->keyboard);
fakekey_modifiers = get_fakekey_modifiers (modifiers);
fakekey_send_keyevent (client->fakekey,
keycode,
TRUE,
fakekey_modifiers);
fakekey_send_keyevent (client->fakekey,
keycode,
FALSE,
fakekey_modifiers);
}
} }
static void static void
@ -850,23 +855,37 @@ on_key_released (EekKeyboard *keyboard,
gpointer user_data) gpointer user_data)
{ {
EekboardClient *client = user_data; EekboardClient *client = user_data;
send_fake_key_event (client, key, FALSE);
}
g_assert (client->fakekey); static void
fakekey_release (client->fakekey); update_modifier_keycodes (EekboardClient *client)
{
XModifierKeymap *mods;
gint i, j;
mods = XGetModifierMapping (GDK_DISPLAY_XDISPLAY (client->display));
for (i = 0; i < 8; i++) {
client->modifier_keycodes[i] = 0;
for (j = 0; j < mods->max_keypermod; j++) {
KeyCode keycode = mods->modifiermap[mods->max_keypermod * i + j];
if (keycode != 0) {
client->modifier_keycodes[i] = keycode;
break;
}
}
}
} }
gboolean gboolean
eekboard_client_enable_fakekey (EekboardClient *client) eekboard_client_enable_xtest (EekboardClient *client)
{ {
if (!client->display) { if (!client->display) {
client->display = gdk_display_get_default (); client->display = gdk_display_get_default ();
} }
g_assert (client->display); g_assert (client->display);
if (!client->fakekey) { update_modifier_keycodes (client);
client->fakekey = fakekey_init (GDK_DISPLAY_XDISPLAY (client->display));
}
g_assert (client->fakekey);
client->key_pressed_handler = client->key_pressed_handler =
g_signal_connect (client->keyboard, "key-pressed", g_signal_connect (client->keyboard, "key-pressed",
@ -879,11 +898,8 @@ eekboard_client_enable_fakekey (EekboardClient *client)
} }
void void
eekboard_client_disable_fakekey (EekboardClient *client) eekboard_client_disable_xtest (EekboardClient *client)
{ {
if (client->fakekey)
fakekey_release (client->fakekey);
if (g_signal_handler_is_connected (client->keyboard, if (g_signal_handler_is_connected (client->keyboard,
client->key_pressed_handler)) client->key_pressed_handler))
g_signal_handler_disconnect (client->keyboard, g_signal_handler_disconnect (client->keyboard,
@ -922,4 +938,4 @@ eekboard_client_load_keyboard_from_file (EekboardClient *client,
return retval; return retval;
} }
#endif /* HAVE_FAKEKEY */ #endif /* HAVE_XTEST */

View File

@ -54,8 +54,8 @@ gboolean eekboard_client_enable_atspi_keystroke
void eekboard_client_disable_atspi_keystroke void eekboard_client_disable_atspi_keystroke
(EekboardClient *client); (EekboardClient *client);
gboolean eekboard_client_enable_fakekey (EekboardClient *client); gboolean eekboard_client_enable_xtest (EekboardClient *client);
void eekboard_client_disable_fakekey (EekboardClient *client); void eekboard_client_disable_xtest (EekboardClient *client);
gboolean eekboard_client_enable_ibus_focus gboolean eekboard_client_enable_ibus_focus
(EekboardClient *client); (EekboardClient *client);