Use libXtst directly instead of via libfakekey.
This commit is contained in:
2
README
2
README
@ -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
|
||||||
|
|
||||||
|
|||||||
27
configure.ac
27
configure.ac
@ -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=""
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
164
src/client.c
164
src/client.c
@ -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 */
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user