diff --git a/examples/simple-client/main.c b/examples/simple-client/main.c index 9a2aaffa..c8263d9e 100644 --- a/examples/simple-client/main.c +++ b/examples/simple-client/main.c @@ -152,6 +152,11 @@ main (int argc, char **argv) keyboard_id = eekboard_context_add_keyboard (context, opt_set_keyboard, NULL); + if (keyboard_id == 0) { + g_printerr ("Can't create keyboard\n"); + retval = 1; + goto out; + } eekboard_context_set_keyboard (context, keyboard_id, NULL); } diff --git a/src/client-main.c b/src/client-main.c index 58e7f3f3..4398ff35 100644 --- a/src/client-main.c +++ b/src/client-main.c @@ -102,20 +102,39 @@ enum { FOCUS_IBUS }; +static gboolean +set_keyboard (EekboardClient *client, + const gchar *keyboard) +{ + if (g_strcmp0 (keyboard, "system") == 0) { + if (!eekboard_client_enable_xkl (client)) { + g_printerr ("Can't register xklavier event listeners\n"); + return FALSE; + } + } else { + if (!eekboard_client_set_keyboard (client, keyboard)) { + g_printerr ("Can't set keyboard \"%s\"\n", keyboard); + return FALSE; + } + } + return TRUE; +} + int main (int argc, char **argv) { - EekboardClient *client; + EekboardClient *client = NULL; EekboardEekboard *eekboard; EekboardContext *context; GBusType bus_type; GDBusConnection *connection; GError *error; GOptionContext *option_context; - GMainLoop *loop; + GMainLoop *loop = NULL; gint focus; - GSettings *settings; + GSettings *settings = NULL; gchar *keyboard; + gint retval = 0; if (!gtk_init_check (&argc, &argv)) { g_printerr ("Can't init GTK\n"); @@ -186,8 +205,8 @@ main (int argc, char **argv) else { g_printerr ("Unknown focus listener \"%s\". " "Try \"atspi\" or \"ibus\"\n", focus_listener); - g_object_unref (client); - exit (1); + retval = 1; + goto out; } } @@ -202,27 +221,27 @@ main (int argc, char **argv) if (accessibility_enabled) { if (atspi_init () != 0) { g_printerr ("Can't init AT-SPI 2\n"); - g_object_unref (client); - exit (1); + retval = 1; + goto out; } if (focus == FOCUS_ATSPI && !eekboard_client_enable_atspi_focus (client)) { g_printerr ("Can't register AT-SPI focus change event listeners\n"); - g_object_unref (client); - exit (1); + retval = 1; + goto out; } if (opt_keystroke && !eekboard_client_enable_atspi_keystroke (client)) { g_printerr ("Can't register AT-SPI keystroke event listeners\n"); - g_object_unref (client); - exit (1); + retval = 1; + goto out; } } else { g_printerr ("Desktop accessibility support is disabled\n"); - g_object_unref (client); - exit (1); + retval = 1; + goto out; } } #endif /* HAVE_ATSPI */ @@ -231,21 +250,14 @@ main (int argc, char **argv) if (focus == FOCUS_IBUS) { ibus_init (); - if (focus == FOCUS_IBUS && - !eekboard_client_enable_ibus_focus (client)) { + if (!eekboard_client_enable_ibus_focus (client)) { g_printerr ("Can't register IBus focus change event listeners\n"); - g_object_unref (client); - exit (1); + retval = 1; + goto out; } } #endif /* HAVE_IBUS */ - if (!eekboard_client_enable_xkl (client)) { - g_printerr ("Can't register xklavier event listeners\n"); - g_object_unref (client); - exit (1); - } - #ifdef HAVE_XTEST if (!eekboard_client_enable_xtest (client)) { g_printerr ("Can't init xtest\n"); @@ -254,11 +266,8 @@ main (int argc, char **argv) } #endif /* HAVE_XTEST */ - keyboard = g_settings_get_string (settings, "keyboard"); - eekboard_client_set_keyboard (client, keyboard); - g_free (keyboard); - loop = g_main_loop_new (NULL, FALSE); + if (!opt_focus) { g_object_get (client, "context", &context, NULL); g_signal_connect (context, "notify::keyboard-visible", @@ -278,11 +287,25 @@ main (int argc, char **argv) g_object_get (client, "eekboard", &eekboard, NULL); g_signal_connect (eekboard, "destroyed", G_CALLBACK(on_destroyed), loop); + g_object_unref (eekboard); + + keyboard = g_settings_get_string (settings, "keyboard"); + if (!set_keyboard (client, keyboard)) { + g_free (keyboard); + retval = 1; + goto out; + } + g_free (keyboard); g_main_loop_run (loop); - g_main_loop_unref (loop); - g_object_unref (client); - g_object_unref (settings); - return 0; + out: + if (loop) + g_main_loop_unref (loop); + if (client) + g_object_unref (client); + if (settings) + g_object_unref (settings); + + return retval; } diff --git a/src/client.c b/src/client.c index a86df29b..166c3710 100644 --- a/src/client.c +++ b/src/client.c @@ -67,7 +67,6 @@ struct _EekboardClient { EekKeyboard *keyboard; XklEngine *xkl_engine; XklConfigRegistry *xkl_config_registry; - gboolean use_xkl_layout; gulong xkl_config_changed_handler; gulong xkl_state_changed_handler; @@ -102,6 +101,12 @@ struct _EekboardClientClass { G_DEFINE_TYPE (EekboardClient, eekboard_client, G_TYPE_OBJECT); +#if ENABLE_FOCUS_LISTENER +#define IS_KEYBOARD_VISIBLE(client) (!client->follows_focus) +#else /* ENABLE_FOCUS_LISTENER */ +#define IS_KEYBOARD_VISIBLE(client) TRUE +#endif /* !ENABLE_FOCUS_LISTENER */ + static GdkFilterReturn filter_xkl_event (GdkXEvent *xev, GdkEvent *event, gpointer user_data); @@ -122,7 +127,8 @@ static gboolean keystroke_listener_cb (const AtspiDeviceEvent *stroke, void *user_data); #endif /* HAVE_ATSPI */ static gboolean set_keyboard (EekboardClient *client, - const gchar *keyboard); + const gchar *keyboard); +static gboolean set_keyboard_from_xkl (EekboardClient *client); #ifdef HAVE_XTEST static void update_modifier_keycodes (EekboardClient *client); @@ -277,12 +283,6 @@ eekboard_client_init (EekboardClient *client) client->settings = g_settings_new ("org.fedorahosted.eekboard"); } -#if ENABLE_FOCUS_LISTENER -#define IS_KEYBOARD_VISIBLE(client) (!client->follows_focus) -#else /* ENABLE_FOCUS_LISTENER */ -#define IS_KEYBOARD_VISIBLE(client) TRUE -#endif /* !ENABLE_FOCUS_LISTENER */ - gboolean eekboard_client_set_keyboard (EekboardClient *client, const gchar *keyboard) @@ -290,7 +290,7 @@ eekboard_client_set_keyboard (EekboardClient *client, gboolean retval; retval = set_keyboard (client, keyboard); - if (IS_KEYBOARD_VISIBLE (client)) + if (retval && IS_KEYBOARD_VISIBLE (client)) eekboard_context_show_keyboard (client->context, NULL); return retval; } @@ -299,6 +299,8 @@ gboolean eekboard_client_enable_xkl (EekboardClient *client) { GdkDisplay *display = gdk_display_get_default (); + gboolean retval; + g_assert (display); if (!client->xkl_engine) { @@ -327,28 +329,31 @@ eekboard_client_enable_xkl (EekboardClient *client) (GdkFilterFunc) filter_xkl_event, client); - client->use_xkl_layout = FALSE; - xkl_engine_start_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE); - return TRUE; + retval = set_keyboard_from_xkl (client); + if (IS_KEYBOARD_VISIBLE (client)) + eekboard_context_show_keyboard (client->context, NULL); + + return retval; } void eekboard_client_disable_xkl (EekboardClient *client) { - client->use_xkl_layout = FALSE; - - if (client->xkl_engine) + if (client->xkl_engine) { xkl_engine_stop_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE); - if (g_signal_handler_is_connected (client->xkl_engine, - client->xkl_config_changed_handler)) - g_signal_handler_disconnect (client->xkl_engine, - client->xkl_config_changed_handler); - if (g_signal_handler_is_connected (client->xkl_engine, - client->xkl_state_changed_handler)) - g_signal_handler_disconnect (client->xkl_engine, - client->xkl_state_changed_handler); + + if (g_signal_handler_is_connected (client->xkl_engine, + client->xkl_config_changed_handler)) + g_signal_handler_disconnect (client->xkl_engine, + client->xkl_config_changed_handler); + if (g_signal_handler_is_connected (client->xkl_engine, + client->xkl_state_changed_handler)) + g_signal_handler_disconnect (client->xkl_engine, + client->xkl_state_changed_handler); + client->xkl_engine = NULL; + } } #ifdef HAVE_ATSPI @@ -680,22 +685,8 @@ on_xkl_config_changed (XklEngine *xklengine, EekboardClient *client = user_data; gboolean retval; - if (client->use_xkl_layout) { - XklConfigRec *rec; - gchar *layout, *keyboard; - - rec = xkl_config_rec_new (); - xkl_config_rec_get_from_server (rec, client->xkl_engine); - layout = eekboard_xkl_config_rec_to_string (rec); - g_object_unref (rec); - - keyboard = g_strdup_printf ("xkl:%s", layout); - g_free (layout); - retval = set_keyboard (client, keyboard); - g_free (keyboard); - - g_return_if_fail (retval); - } + retval = set_keyboard_from_xkl (client); + g_return_if_fail (retval); #ifdef HAVE_XTEST update_modifier_keycodes (client); @@ -711,10 +702,33 @@ set_keyboard (EekboardClient *client, keyboard_id = eekboard_context_add_keyboard (client->context, keyboard, NULL); + if (keyboard_id == 0) + return FALSE; + eekboard_context_set_keyboard (client->context, keyboard_id, NULL); return TRUE; } +static gboolean +set_keyboard_from_xkl (EekboardClient *client) +{ + XklConfigRec *rec; + gchar *layout, *keyboard; + gboolean retval; + + rec = xkl_config_rec_new (); + xkl_config_rec_get_from_server (rec, client->xkl_engine); + layout = eekboard_xkl_config_rec_to_string (rec); + g_object_unref (rec); + + keyboard = g_strdup_printf ("xkb:%s", layout); + g_free (layout); + retval = set_keyboard (client, keyboard); + g_free (keyboard); + + return retval; +} + static void on_xkl_state_changed (XklEngine *xklengine, XklEngineStateChange type, @@ -724,10 +738,8 @@ on_xkl_state_changed (XklEngine *xklengine, { EekboardClient *client = user_data; - if (type == GROUP_CHANGED) { - if (client->use_xkl_layout) - eekboard_context_set_group (client->context, value, NULL); - } + if (type == GROUP_CHANGED) + eekboard_context_set_group (client->context, value, NULL); } #ifdef HAVE_XTEST @@ -925,6 +937,7 @@ update_modifier_keycodes (EekboardClient *client) } } } + XFreeModifiermap (mods); } gboolean diff --git a/src/server-context.c b/src/server-context.c index 229d9291..dcd50ada 100644 --- a/src/server-context.c +++ b/src/server-context.c @@ -709,7 +709,7 @@ create_keyboard_from_string (const gchar *string) EekKeyboard *keyboard; EekLayout *layout; - if (g_str_has_prefix (string, "xkl:")) { + if (g_str_has_prefix (string, "xkb:")) { XklConfigRec *rec = eekboard_xkl_config_rec_from_string (&string[4]); layout = eek_xkl_layout_new (); diff --git a/src/xklutil.c b/src/xklutil.c index 7ea37929..86a52915 100644 --- a/src/xklutil.c +++ b/src/xklutil.c @@ -66,7 +66,7 @@ eekboard_xkl_config_rec_to_string (XklConfigRec *rec) n_layouts = g_strv_length (rec->layouts); strv = g_malloc0_n (n_layouts + 2, sizeof (gchar *)); for (sp = strv, lp = rec->layouts, vp = rec->variants; *lp; sp++, lp++) { - if (*vp != NULL) + if (*vp != NULL && **vp != '\0') *sp = g_strdup_printf ("%s(%s)", *lp, *vp++); else *sp = g_strdup_printf ("%s", *lp);