Fix modifier handling using libfakekey.

This commit is contained in:
Daiki Ueno
2011-02-01 16:29:08 +09:00
parent 0f33ced9bc
commit 4b590dc05d

View File

@ -47,6 +47,7 @@ struct _EekboardSystemClient {
EekKeyboard *keyboard; EekKeyboard *keyboard;
Accessible *accessible; Accessible *accessible;
GdkDisplay *display;
XklEngine *xkl_engine; XklEngine *xkl_engine;
XklConfigRegistry *xkl_config_registry; XklConfigRegistry *xkl_config_registry;
FakeKey *fakekey; FakeKey *fakekey;
@ -135,6 +136,11 @@ eekboard_system_client_dispose (GObject *object)
client->fakekey = NULL; client->fakekey = NULL;
} }
if (client->display) {
gdk_display_close (client->display);
client->display = NULL;
}
G_OBJECT_CLASS (eekboard_system_client_parent_class)->dispose (object); G_OBJECT_CLASS (eekboard_system_client_parent_class)->dispose (object);
} }
@ -162,6 +168,7 @@ eekboard_system_client_init (EekboardSystemClient *client)
{ {
client->keyboard = NULL; client->keyboard = NULL;
client->accessible = NULL; client->accessible = NULL;
client->display = NULL;
client->xkl_engine = NULL; client->xkl_engine = NULL;
client->xkl_config_registry = NULL; client->xkl_config_registry = NULL;
client->focus_listener = NULL; client->focus_listener = NULL;
@ -177,12 +184,16 @@ eekboard_system_client_init (EekboardSystemClient *client)
gboolean gboolean
eekboard_system_client_enable_xkl (EekboardSystemClient *client) eekboard_system_client_enable_xkl (EekboardSystemClient *client)
{ {
if (!client->xkl_engine) { if (!client->display) {
Display *display; client->display = gdk_display_get_default ();
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
client->xkl_engine = xkl_engine_get_instance (display);
} }
g_assert (client->display);
if (!client->xkl_engine) {
client->xkl_engine =
xkl_engine_get_instance (GDK_DISPLAY_XDISPLAY (client->display));
}
g_assert (client->xkl_engine);
if (!client->xkl_config_registry) { if (!client->xkl_config_registry) {
client->xkl_config_registry = client->xkl_config_registry =
@ -366,6 +377,9 @@ on_xkl_config_changed (XklEngine *xklengine,
EekboardSystemClient *client = user_data; EekboardSystemClient *client = user_data;
set_keyboard (client); set_keyboard (client);
if (client->fakekey)
fakekey_reload_keysyms (client->fakekey);
} }
static void static void
@ -379,6 +393,8 @@ set_keyboard (EekboardSystemClient *client)
g_object_unref (client->keyboard); g_object_unref (client->keyboard);
layout = eek_xkl_layout_new (); layout = eek_xkl_layout_new ();
client->keyboard = eek_keyboard_new (layout, CSW, CSH); client->keyboard = eek_keyboard_new (layout, CSW, CSH);
eek_keyboard_set_modifier_behavior (client->keyboard,
EEK_MODIFIER_BEHAVIOR_LATCH);
keyboard_name = g_strdup_printf ("keyboard%d", keyboard_serial++); keyboard_name = g_strdup_printf ("keyboard%d", keyboard_serial++);
eek_element_set_name (EEK_ELEMENT(client->keyboard), keyboard_name); eek_element_set_name (EEK_ELEMENT(client->keyboard), keyboard_name);
@ -404,6 +420,23 @@ on_xkl_state_changed (XklEngine *xklengine,
} }
} }
G_INLINE_FUNC FakeKeyModifier
get_fakekey_modifiers (EekModifierType modifiers)
{
FakeKeyModifier retval = 0;
if (modifiers & EEK_SHIFT_MASK)
retval |= FAKEKEYMOD_SHIFT;
if (modifiers & EEK_CONTROL_MASK)
retval |= FAKEKEYMOD_CONTROL;
if (modifiers & EEK_MOD1_MASK)
retval |= FAKEKEYMOD_ALT;
if (modifiers & EEK_META_MASK)
retval |= FAKEKEYMOD_META;
return retval;
}
static void static void
on_key_pressed (EekboardProxy *proxy, on_key_pressed (EekboardProxy *proxy,
guint keycode, guint keycode,
@ -412,14 +445,29 @@ on_key_pressed (EekboardProxy *proxy,
EekboardSystemClient *client = user_data; EekboardSystemClient *client = user_data;
EekKey *key; EekKey *key;
EekSymbol *symbol; EekSymbol *symbol;
EekModifierType modifiers;
g_assert (client->fakekey); g_assert (client->fakekey);
modifiers = eek_keyboard_get_modifiers (client->keyboard);
key = eek_keyboard_find_key_by_keycode (client->keyboard, keycode); key = eek_keyboard_find_key_by_keycode (client->keyboard, keycode);
if (!key) {
// g_debug ("Can't find key for keycode %u", keycode);
return;
}
symbol = eek_key_get_symbol_with_fallback (key, 0, 0); symbol = eek_key_get_symbol_with_fallback (key, 0, 0);
if (EEK_IS_KEYSYM(symbol) && !eek_symbol_is_modifier (symbol)) if (EEK_IS_KEYSYM(symbol) && !eek_symbol_is_modifier (symbol)) {
fakekey_press_keysym (client->fakekey, fakekey_send_keyevent (client->fakekey,
eek_keysym_get_xkeysym (EEK_KEYSYM(symbol)), keycode,
eek_keyboard_get_modifiers (client->keyboard)); True,
get_fakekey_modifiers (modifiers));
fakekey_send_keyevent (client->fakekey,
keycode,
False,
get_fakekey_modifiers (modifiers));
}
g_signal_emit_by_name (key, "pressed");
} }
static void static void
@ -428,19 +476,28 @@ on_key_released (EekboardProxy *proxy,
gpointer user_data) gpointer user_data)
{ {
EekboardSystemClient *client = user_data; EekboardSystemClient *client = user_data;
EekKey *key;
g_assert (client->fakekey); g_assert (client->fakekey);
fakekey_release (client->fakekey); fakekey_release (client->fakekey);
key = eek_keyboard_find_key_by_keycode (client->keyboard, keycode);
if (!key) {
// g_debug ("Can't find key for keycode %u", keycode);
return;
}
g_signal_emit_by_name (key, "released");
} }
gboolean gboolean
eekboard_system_client_enable_fakekey (EekboardSystemClient *client) eekboard_system_client_enable_fakekey (EekboardSystemClient *client)
{ {
if (!client->fakekey) { if (!client->display) {
Display *display; client->display = gdk_display_get_default ();
}
g_assert (client->display);
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); if (!client->fakekey) {
client->fakekey = fakekey_init (display); client->fakekey = fakekey_init (GDK_DISPLAY_XDISPLAY (client->display));
} }
g_assert (client->fakekey); g_assert (client->fakekey);