From efa7d00c0367858dc6882db4acf75e5ba9095320 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Wed, 16 Jun 2010 15:55:06 +0900 Subject: [PATCH] eekboard: merge eekboard-gtk.c to eekboard.c --- README | 6 +- eek/eek-clutter-key-actor.c | 25 +- eek/eek-drawing.c | 30 +++ eek/eek-drawing.h | 3 + eek/eek-gtk-keyboard.c | 16 +- eek/eek-xkl-layout.c | 31 +++ src/Makefile.am | 7 +- src/eekboard-gtk.c | 484 ------------------------------------ src/eekboard.c | 302 +++++++++++++--------- 9 files changed, 252 insertions(+), 652 deletions(-) delete mode 100644 src/eekboard-gtk.c diff --git a/README b/README index e022e792..e53b317f 100644 --- a/README +++ b/README @@ -1,10 +1,10 @@ -EekBoard - a virtual keyboard for GNOME -*- outline -*- +eekboard - a virtual keyboard for GNOME -*- outline -*- -EekBoard is a virtual keyboard software package which ships with a +eekboard is a virtual keyboard software package which ships with a standalone virtual keyboard application ("eekboard"), and a library to create keyboard-like UI ("libeek"). -*NOTE* EekBoard is still under heavy development. The code has still a +*NOTE* eekboard is still under heavy development. The code has still a lot of bugs and lacks documentation. * How to test diff --git a/eek/eek-clutter-key-actor.c b/eek/eek-clutter-key-actor.c index 29203d38..15b67939 100644 --- a/eek/eek-clutter-key-actor.c +++ b/eek/eek-clutter-key-actor.c @@ -312,7 +312,6 @@ create_texture_for_key (EekKey *key) { ClutterActor *texture; cairo_t *cr; - cairo_pattern_t *pat; EekOutline *outline; EekBounds bounds; @@ -321,29 +320,7 @@ create_texture_for_key (EekKey *key) texture = clutter_cairo_texture_new (bounds.width, bounds.height); cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE(texture)); - cairo_set_line_width (cr, 1); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); - - pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0); - cairo_pattern_add_color_stop_rgba (pat, 1, 0.5, 0.5, 0.5, 1); - cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1); - - cairo_set_source (cr, pat); - - eek_draw_rounded_polygon (cr, - TRUE, - outline->corner_radius, - outline->points, - outline->num_points); - - cairo_pattern_destroy (pat); - - cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.5); - eek_draw_rounded_polygon (cr, - FALSE, - outline->corner_radius, - outline->points, - outline->num_points); + eek_draw_outline (cr, outline); cairo_destroy (cr); return texture; } diff --git a/eek/eek-drawing.c b/eek/eek-drawing.c index f942b382..733193a0 100644 --- a/eek/eek-drawing.c +++ b/eek/eek-drawing.c @@ -177,6 +177,36 @@ eek_get_fonts (EekKeyboard *keyboard, fonts[EEK_KEYSYM_CATEGORY_KEYNAME] = font_desc; } +void +eek_draw_outline (cairo_t *cr, EekOutline *outline) +{ + cairo_pattern_t *pat; + + cairo_set_line_width (cr, 1); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + + pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0); + cairo_pattern_add_color_stop_rgba (pat, 1, 0.5, 0.5, 0.5, 1); + cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1); + + cairo_set_source (cr, pat); + + eek_draw_rounded_polygon (cr, + TRUE, + outline->corner_radius, + outline->points, + outline->num_points); + + cairo_pattern_destroy (pat); + + cairo_set_source_rgba (cr, 0.3, 0.3, 0.3, 0.5); + eek_draw_rounded_polygon (cr, + FALSE, + outline->corner_radius, + outline->points, + outline->num_points); +} + /* * The functions below are borrowed from * libgnomekbd/gkbd-keyboard-drawing.c. diff --git a/eek/eek-drawing.h b/eek/eek-drawing.h index a4643a04..9f23c2a1 100644 --- a/eek/eek-drawing.h +++ b/eek/eek-drawing.h @@ -16,6 +16,9 @@ void eek_get_fonts (EekKeyboard *keyboard, PangoLayout *layout, PangoFontDescription **fonts); +void eek_draw_outline (cairo_t *cr, + EekOutline *outline); + void eek_draw_rounded_polygon (cairo_t *cr, gboolean filled, gdouble radius, diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c index 73b4f97a..8ca49d6c 100644 --- a/eek/eek-gtk-keyboard.c +++ b/eek/eek-gtk-keyboard.c @@ -117,21 +117,13 @@ draw_key (EekElement *element, gpointer user_data) EekBounds bounds; guint keysym; - gdk_cairo_set_source_color (priv->cr, priv->dark_color); - cairo_set_line_width (priv->cr, 1); - cairo_set_line_join (priv->cr, CAIRO_LINE_JOIN_ROUND); - - eek_element_get_bounds (EEK_ELEMENT(key), &bounds); - cairo_save (priv->cr); + eek_element_get_bounds (EEK_ELEMENT(key), &bounds); cairo_translate (priv->cr, bounds.x, bounds.y); outline = eek_key_get_outline (key); - eek_draw_rounded_polygon (priv->cr, - FALSE, - outline->corner_radius, - outline->points, - outline->num_points); - cairo_stroke (priv->cr); + eek_draw_outline (priv->cr, outline); + + gdk_cairo_set_source_color (priv->cr, priv->dark_color); keysym = eek_key_get_keysym (key); if (keysym != EEK_INVALID_KEYSYM) { diff --git a/eek/eek-xkl-layout.c b/eek/eek-xkl-layout.c index 4c697689..319f6699 100644 --- a/eek/eek-xkl-layout.c +++ b/eek/eek-xkl-layout.c @@ -511,6 +511,37 @@ set_xkb_component_names (EekXklLayout *layout, XklConfigRec *config) XkbComponentNamesRec names; gboolean success = FALSE; +#define DEBUG 1 +#if DEBUG + if (config->layouts) { + gint i; + + fprintf (stderr, "layout = "); + for (i = 0; config->layouts[i] != NULL; i++) + fprintf (stderr, "\"%s\" ", config->layouts[i]); + fputc ('\n', stderr); + } else + fprintf (stderr, "layouts = NULL\n"); + if (config->variants) { + gint i; + + fprintf (stderr, "variant = "); + for (i = 0; config->variants[i]; i++) + fprintf (stderr, "\"%s\" ", config->variants[i]); + fputc ('\n', stderr); + } else + fprintf (stderr, "variants = NULL\n"); + if (config->options) { + gint i; + + fprintf (stderr, "option = "); + for (i = 0; config->options[i]; i++) + fprintf (stderr, "\"%s\" ", config->options[i]); + fputc ('\n', stderr); + } else + fprintf (stderr, "options = NULL\n"); +#endif + /* Disabled since the current EekXklLayout implementation does not change the server setting. */ #if 0 diff --git a/src/Makefile.am b/src/Makefile.am index 76afeccf..6c0a8427 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,9 +16,6 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA -bin_PROGRAMS = eekboard eekboard-gtk +bin_PROGRAMS = eekboard eekboard_CFLAGS = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(CLUTTER_CFLAGS) $(CLUTTER_GTK_CFLAGS) $(GTK2_CFLAGS) $(XKB_CFLAGS) $(LIBXKLAVIER_CFLAGS) $(LIBFAKEKEY_CFLAGS) -eekboard_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkl.la $(top_builddir)/eek/libeek-clutter.la $(GOBJECT2_LIBS) $(CLUTTER_LIBS) $(CLUTTER_GTK_LIBS) $(GTK2_CFLAGS) $(XKB_LIBS) $(LIBXKLAVIER_LIBS) $(LIBFAKEKEY_LIBS) - -eekboard_gtk_CFLAGS = -I$(top_srcdir) $(GOBJECT2_CFLAGS) $(GTK2_CFLAGS) $(XKB_CFLAGS) $(LIBXKLAVIER_CFLAGS) $(LIBFAKEKEY_CFLAGS) -eekboard_gtk_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkl.la $(top_builddir)/eek/libeek-gtk.la $(GOBJECT2_LIBS) $(GTK2_CFLAGS) $(XKB_LIBS) $(LIBXKLAVIER_LIBS) $(LIBFAKEKEY_LIBS) +eekboard_LDFLAGS = $(top_builddir)/eek/libeek.la $(top_builddir)/eek/libeek-xkl.la $(top_builddir)/eek/libeek-clutter.la $(top_builddir)/eek/libeek-gtk.la $(GOBJECT2_LIBS) $(CLUTTER_LIBS) $(CLUTTER_GTK_LIBS) $(GTK2_CFLAGS) $(XKB_LIBS) $(LIBXKLAVIER_LIBS) $(LIBFAKEKEY_LIBS) diff --git a/src/eekboard-gtk.c b/src/eekboard-gtk.c deleted file mode 100644 index e431335f..00000000 --- a/src/eekboard-gtk.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright (C) 2010 Daiki Ueno - * Copyright (C) 2010 Red Hat, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "eek/eek-gtk.h" -#include "eek/eek-xkl.h" - -#define CSW 640 -#define CSH 480 - -#define LICENSE \ - "This program is free software: you can redistribute it and/or modify " \ - "it under the terms of the GNU General Public License as published by " \ - "the Free Software Foundation, either version 3 of the License, or " \ - "(at your option) any later version." \ - "\n\n" \ - "This program is distributed in the hope that it will be useful, " \ - "but WITHOUT ANY WARRANTY; without even the implied warranty of " \ - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " \ - "GNU General Public License for more details." \ - "\n\n" \ - "You should have received a copy of the GNU General Public License " \ - "along with this program. If not, see . " \ - -struct _EekBoard { - EekKeyboard *keyboard; - EekLayout *layout; /* FIXME: eek_keyboard_get_layout() */ - Display *display; - FakeKey *fakekey; - guint modifiers; - gfloat width, height; -}; -typedef struct _EekBoard EekBoard; - -static void on_about (GtkAction * action, GtkWidget *window); -static void on_monitor_key_event_toggled (GtkToggleAction *action, - GtkWidget *window); - -static const char ui_description[] = - "" - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - ""; - -#define SET_LAYOUT_UI_PATH "/MainMenu/KeyboardMenu/SetLayout/LayoutsPH" - -struct _ConfigCallbackData { - EekBoard *eekboard; - XklConfigRec *config; -}; -typedef struct _ConfigCallbackData ConfigCallbackData; - -struct _LayoutCallbackData { - EekBoard *eekboard; - GtkUIManager *ui_manager; - GtkActionGroup *action_group; - guint merge_id; -}; -typedef struct _LayoutCallbackData LayoutCallbackData; - -static const GtkActionEntry action_entry[] = { - {"FileMenu", NULL, N_("_File")}, - {"KeyboardMenu", NULL, N_("_Keyboard")}, - {"HelpMenu", NULL, N_("_Help")}, - {"Quit", GTK_STOCK_QUIT, NULL, NULL, NULL, G_CALLBACK (gtk_main_quit)}, - {"SetLayout", NULL, N_("Set Layout"), NULL, NULL, NULL}, - {"About", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK (on_about)} -}; - -static const GtkToggleActionEntry toggle_action_entry[] = { - {"MonitorKeyEvent", NULL, N_("Monitor Key Typing"), NULL, NULL, - G_CALLBACK(on_monitor_key_event_toggled), FALSE} -}; - -static void -on_about (GtkAction * action, GtkWidget *window) -{ - const gchar *authors[] = { "Daiki Ueno", NULL }; - - gtk_show_about_dialog (GTK_WINDOW (window), - "version", VERSION, - "copyright", - "Copyright \xc2\xa9 2010 Daiki Ueno\n" - "Copyright \xc2\xa9 2010 Red Hat, Inc.", - "license", LICENSE, - "comments", - _("A virtual keyboard for GNOME"), - "authors", authors, - "website", - "http://github.com/ueno/eek/", - "website-label", _("EekBoard web site"), - "wrap-license", TRUE, NULL); -} - -static void -on_monitor_key_event_toggled (GtkToggleAction *action, - GtkWidget *window) -{ - g_warning ("not implemented"); -} - -static void -on_key_pressed (EekKeyboard *keyboard, - EekKey *key, - gpointer user_data) -{ - EekBoard *eekboard = user_data; - guint keysym; - - keysym = eek_key_get_keysym (key); -#if DEBUG - g_debug ("%s %X", eek_keysym_to_string (keysym), eekboard->modifiers); -#endif - fakekey_press_keysym (eekboard->fakekey, keysym, eekboard->modifiers); - if (keysym == XK_Shift_L || keysym == XK_Shift_R) { - gint group, level; - - eekboard->modifiers ^= ShiftMask; - eek_keyboard_get_keysym_index (keyboard, &group, &level); - eek_keyboard_set_keysym_index (keyboard, group, - eekboard->modifiers & ShiftMask ? 1 : 0); - } else if (keysym == XK_Control_L || keysym == XK_Control_R) { - eekboard->modifiers ^= ControlMask; - } else if (keysym == XK_Alt_L || keysym == XK_Alt_R) { - eekboard->modifiers ^= Mod1Mask; - } -} - -static void -on_key_released (EekKeyboard *keyboard, - EekKey *key, - gpointer user_data) -{ - EekBoard *eekboard = user_data; - fakekey_release (eekboard->fakekey); -} - -static void -on_activate (GtkAction *action, gpointer user_data) -{ - ConfigCallbackData *data = user_data; - - eek_xkl_layout_set_config (EEK_XKL_LAYOUT(data->eekboard->layout), - data->config); - g_object_unref (data->config); -} - -#if 0 -static void -create_keyboard (EekBoard *eekboard, - ClutterActor *stage, - EekLayout *layout, - gfloat initial_width, - gfloat initial_height) -{ - ClutterActor *actor; - - eekboard->keyboard = eek_clutter_keyboard_new (initial_width, - initial_height); - g_signal_connect (eekboard->keyboard, "key-pressed", - G_CALLBACK(on_key_pressed), eekboard); - g_signal_connect (eekboard->keyboard, "key-released", - G_CALLBACK(on_key_released), eekboard); - eek_keyboard_set_layout (eekboard->keyboard, layout); - actor = eek_clutter_keyboard_get_actor - (EEK_CLUTTER_KEYBOARD(eekboard->keyboard)); - clutter_actor_get_size (actor, - &eekboard->width, - &eekboard->height); - clutter_container_add_actor (CLUTTER_CONTAINER(stage), actor); - clutter_actor_set_size (stage, - eekboard->width, - eekboard->height); -} - -/* FIXME: EekKeyboard should handle relayout by itself. */ -static void -on_changed (EekLayout *layout, gpointer user_data) -{ - EekBoard *eekboard = user_data; - ClutterActor *stage, *actor; - gfloat width, height; - - actor = eek_clutter_keyboard_get_actor - (EEK_CLUTTER_KEYBOARD(eekboard->keyboard)); - stage = clutter_actor_get_stage (actor); - clutter_actor_get_size (stage, &width, &height); - clutter_container_remove_actor (CLUTTER_CONTAINER(stage), actor); - g_object_unref (eekboard->keyboard); - create_keyboard (eekboard, stage, layout, width, height); - clutter_actor_get_size (stage, &eekboard->width, &eekboard->height); -} -#endif - -static void -variant_callback (XklConfigRegistry *registry, - const XklConfigItem *item, - gpointer user_data) -{ - GSList **r_variants = user_data; - XklConfigItem *_item; - - _item = g_slice_dup (XklConfigItem, item); - *r_variants = g_slist_prepend (*r_variants, _item); -} - -static void -layout_callback (XklConfigRegistry *registry, - const XklConfigItem *item, - gpointer user_data) -{ - LayoutCallbackData *data = user_data; - GtkAction *action; - GSList *variants = NULL; - char layout_action_name[128], variant_action_name[128]; - ConfigCallbackData *config; - - g_snprintf (layout_action_name, sizeof (layout_action_name), - "SetLayout%s", item->name); - action = gtk_action_new (layout_action_name, item->description, NULL, NULL); - gtk_action_group_add_action (data->action_group, action); - - xkl_config_registry_foreach_layout_variant (registry, - item->name, - variant_callback, - &variants); - - if (!variants) { - config = g_slice_new (ConfigCallbackData); - config->eekboard = data->eekboard; - config->config = xkl_config_rec_new (); - config->config->layouts = g_new0 (char *, 2); - config->config->layouts[0] = g_strdup (item->name); - config->config->layouts[1] = NULL; - config->config->variants = NULL; - g_signal_connect (action, "activate", G_CALLBACK (on_activate), - config); - g_object_unref (action); - gtk_ui_manager_add_ui (data->ui_manager, data->merge_id, - SET_LAYOUT_UI_PATH, - layout_action_name, layout_action_name, - GTK_UI_MANAGER_MENUITEM, FALSE); - } else { - char layout_path[128]; - GSList *head; - - g_object_unref (action); - gtk_ui_manager_add_ui (data->ui_manager, data->merge_id, - SET_LAYOUT_UI_PATH, - layout_action_name, layout_action_name, - GTK_UI_MANAGER_MENU, FALSE); - g_snprintf (layout_path, sizeof (layout_path), - SET_LAYOUT_UI_PATH "/%s", layout_action_name); - - for (head = variants; head; head = head->next) { - XklConfigItem *_item = head->data; - - g_snprintf (variant_action_name, sizeof (variant_action_name), - "SetVariant%s%s", item->name, _item->name); - action = gtk_action_new (variant_action_name, - _item->description, - NULL, - NULL); - - config = g_slice_new (ConfigCallbackData); - config->eekboard = data->eekboard; - config->config = xkl_config_rec_new (); - config->config->layouts = g_new0 (char *, 2); - config->config->layouts[0] = g_strdup (item->name); - config->config->layouts[1] = NULL; - config->config->variants = g_new0 (char *, 2); - config->config->variants[0] = g_strdup (_item->name); - config->config->variants[1] = NULL; - g_signal_connect (action, "activate", G_CALLBACK (on_activate), - config); - - gtk_action_group_add_action (data->action_group, action); - g_object_unref (action); - - gtk_ui_manager_add_ui (data->ui_manager, data->merge_id, - layout_path, - variant_action_name, variant_action_name, - GTK_UI_MANAGER_MENUITEM, FALSE); - g_slice_free (XklConfigItem, _item); - } - g_slist_free (variants); - } -} - -static void -create_layouts_menu (EekBoard *eekboard, GtkUIManager *ui_manager) -{ - XklEngine *engine; - XklConfigRegistry *registry; - LayoutCallbackData data; - - data.eekboard = eekboard; - data.ui_manager = ui_manager; - data.action_group = gtk_action_group_new ("Layouts"); - gtk_ui_manager_insert_action_group (data.ui_manager, data.action_group, -1); - data.merge_id = gtk_ui_manager_new_merge_id (ui_manager); - - engine = xkl_engine_get_instance (eekboard->display); - registry = xkl_config_registry_get_instance (engine); - xkl_config_registry_load (registry, FALSE); - - xkl_config_registry_foreach_layout (registry, layout_callback, &data); -} - -static void -create_menus (EekBoard *eekboard, - GtkWidget *window, - GtkUIManager * ui_manager) -{ - GtkActionGroup *action_group; - - action_group = gtk_action_group_new ("MenuActions"); - - gtk_action_group_add_actions (action_group, action_entry, - G_N_ELEMENTS (action_entry), window); - gtk_action_group_add_toggle_actions (action_group, toggle_action_entry, - G_N_ELEMENTS (toggle_action_entry), - window); - - gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); - gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, NULL); - create_layouts_menu (eekboard, ui_manager); -} - -#if 0 -static void -on_resize (GObject *object, - GParamSpec *param_spec, - gpointer user_data) -{ - EekBoard *eekboard = user_data; - GValue value = {0}; - gfloat width, height, scale; - ClutterActor *stage, *actor; - - actor = eek_clutter_keyboard_get_actor - (EEK_CLUTTER_KEYBOARD(eekboard->keyboard)); - stage = clutter_actor_get_stage (actor); - - g_object_get (G_OBJECT(stage), "width", &width, NULL); - g_object_get (G_OBJECT(stage), "height", &height, NULL); - - g_value_init (&value, G_TYPE_DOUBLE); - - scale = width > height ? width / eekboard->width : - width / eekboard->height; - - g_value_set_double (&value, scale); - g_object_set_property (G_OBJECT (stage), - "scale-x", - &value); - - g_value_set_double (&value, scale); - g_object_set_property (G_OBJECT (stage), - "scale-y", - &value); -} -#endif - -int -main (int argc, char *argv[]) -{ - EekBoard eekboard; - GtkWidget *menubar, *embed, *vbox, *window; - GtkUIManager *ui_manager; - EekBounds bounds; - - if (!gtk_init_check (&argc, &argv)) { - fprintf (stderr, "Can't init Clutter-Gtk\n"); - exit (1); - } - - memset (&eekboard, 0, sizeof eekboard); - eekboard.display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - if (!eekboard.display) { - fprintf (stderr, "Can't open display\n"); - exit (1); - } - - eekboard.fakekey = fakekey_init (eekboard.display); - if (!eekboard.fakekey) { - fprintf (stderr, "Can't init fakekey\n"); - exit (1); - } - - eekboard.layout = eek_xkl_layout_new (); - if (!eekboard.layout) { - fprintf (stderr, "Failed to create layout\n"); - exit (1); - } - -#if 0 - g_signal_connect (eekboard.layout, - "changed", - G_CALLBACK(on_changed), - &eekboard); - - g_signal_connect (stage, - "notify::width", - G_CALLBACK (on_resize), - &eekboard); - - g_signal_connect (stage, - "notify::height", - G_CALLBACK (on_resize), - &eekboard); -#endif - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_widget_set_can_focus (window, FALSE); - g_object_set (G_OBJECT(window), "accept_focus", FALSE, NULL); - gtk_window_set_title (GTK_WINDOW(window), "Keyboard"); - g_signal_connect (G_OBJECT (window), "destroy", - G_CALLBACK (gtk_main_quit), NULL); - - bounds.x = bounds.y = 0; - bounds.width = CSW; - bounds.height = CSH; - eekboard.keyboard = eek_gtk_keyboard_new (); - eek_element_set_bounds (EEK_ELEMENT(eekboard.keyboard), &bounds); - eek_keyboard_set_layout (eekboard.keyboard, eekboard.layout); - embed = eek_gtk_keyboard_get_widget (EEK_GTK_KEYBOARD (eekboard.keyboard)); - - vbox = gtk_vbox_new (FALSE, 0); - ui_manager = gtk_ui_manager_new (); - create_menus (&eekboard, window, ui_manager); - menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu"); - gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0); - gtk_container_add (GTK_CONTAINER(vbox), embed); - gtk_container_add (GTK_CONTAINER(window), vbox); - - gtk_widget_set_size_request (embed, CSW, CSH); - gtk_widget_show_all (window); - //gtk_widget_set_size_request (embed, -1, -1); - - gtk_main (); - - return 0; -} diff --git a/src/eekboard.c b/src/eekboard.c index d68db39b..d2c64544 100644 --- a/src/eekboard.c +++ b/src/eekboard.c @@ -32,6 +32,7 @@ #endif /* HAVE_CONFIG_H */ #include "eek/eek-clutter.h" +#include "eek/eek-gtk.h" #include "eek/eek-xkl.h" #define CSW 640 @@ -51,19 +52,41 @@ "You should have received a copy of the GNU General Public License " \ "along with this program. If not, see . " \ -struct _EekBoard { - EekKeyboard *keyboard; - EekLayout *layout; /* FIXME: eek_keyboard_get_layout() */ +struct _Eekboard { + gboolean use_clutter; Display *display; FakeKey *fakekey; - guint modifiers; + GtkWidget *widget; gfloat width, height; -}; -typedef struct _EekBoard EekBoard; -static void on_about (GtkAction * action, GtkWidget *window); -static void on_monitor_key_event_toggled (GtkToggleAction *action, - GtkWidget *window); + EekKeyboard *keyboard; + EekLayout *layout; /* FIXME: eek_keyboard_get_layout() */ + guint modifiers; +}; +typedef struct _Eekboard Eekboard; + +struct _ConfigCallbackData { + Eekboard *eekboard; + XklConfigRec *config; +}; +typedef struct _ConfigCallbackData ConfigCallbackData; + +struct _LayoutCallbackData { + Eekboard *eekboard; + GtkUIManager *ui_manager; + GtkActionGroup *action_group; + guint merge_id; +}; +typedef struct _LayoutCallbackData LayoutCallbackData; + +static void on_about (GtkAction *action, + GtkWidget *window); +static void on_monitor_key_event_toggled + (GtkToggleAction *action, + GtkWidget *window); +static GtkWidget *create_widget (Eekboard *eekboard, + gfloat initial_width, + gfloat initial_height); static const char ui_description[] = "" @@ -85,20 +108,6 @@ static const char ui_description[] = #define SET_LAYOUT_UI_PATH "/MainMenu/KeyboardMenu/SetLayout/LayoutsPH" -struct _ConfigCallbackData { - EekBoard *eekboard; - XklConfigRec *config; -}; -typedef struct _ConfigCallbackData ConfigCallbackData; - -struct _LayoutCallbackData { - EekBoard *eekboard; - GtkUIManager *ui_manager; - GtkActionGroup *action_group; - guint merge_id; -}; -typedef struct _LayoutCallbackData LayoutCallbackData; - static const GtkActionEntry action_entry[] = { {"FileMenu", NULL, N_("_File")}, {"KeyboardMenu", NULL, N_("_Keyboard")}, @@ -130,7 +139,7 @@ on_about (GtkAction * action, GtkWidget *window) "authors", authors, "website", "http://github.com/ueno/eek/", - "website-label", _("EekBoard web site"), + "website-label", _("Eekboard web site"), "wrap-license", TRUE, NULL); } @@ -146,7 +155,7 @@ on_key_pressed (EekKeyboard *keyboard, EekKey *key, gpointer user_data) { - EekBoard *eekboard = user_data; + Eekboard *eekboard = user_data; guint keysym; keysym = eek_key_get_keysym (key); @@ -173,7 +182,7 @@ on_key_released (EekKeyboard *keyboard, EekKey *key, gpointer user_data) { - EekBoard *eekboard = user_data; + Eekboard *eekboard = user_data; fakekey_release (eekboard->fakekey); } @@ -186,49 +195,20 @@ on_activate (GtkAction *action, data->config); } -static void -create_keyboard (EekBoard *eekboard, - ClutterActor *stage, - EekLayout *layout, - gfloat initial_width, - gfloat initial_height) -{ - ClutterActor *actor; - - eekboard->keyboard = eek_clutter_keyboard_new (initial_width, - initial_height); - g_signal_connect (eekboard->keyboard, "key-pressed", - G_CALLBACK(on_key_pressed), eekboard); - g_signal_connect (eekboard->keyboard, "key-released", - G_CALLBACK(on_key_released), eekboard); - eek_keyboard_set_layout (eekboard->keyboard, layout); - actor = eek_clutter_keyboard_get_actor - (EEK_CLUTTER_KEYBOARD(eekboard->keyboard)); - clutter_actor_get_size (actor, - &eekboard->width, - &eekboard->height); - clutter_container_add_actor (CLUTTER_CONTAINER(stage), actor); - clutter_actor_set_size (stage, - eekboard->width, - eekboard->height); -} - -/* FIXME: EekKeyboard should handle relayout by itself. */ static void on_changed (EekLayout *layout, gpointer user_data) { - EekBoard *eekboard = user_data; - ClutterActor *stage, *actor; - gfloat width, height; + Eekboard *eekboard = user_data; + GtkWidget *vbox, *widget; + + vbox = gtk_widget_get_parent (eekboard->widget); + gtk_widget_hide (eekboard->widget); + gtk_widget_destroy (eekboard->widget); - actor = eek_clutter_keyboard_get_actor - (EEK_CLUTTER_KEYBOARD(eekboard->keyboard)); - stage = clutter_actor_get_stage (actor); - clutter_actor_get_size (stage, &width, &height); - clutter_container_remove_actor (CLUTTER_CONTAINER(stage), actor); g_object_unref (eekboard->keyboard); - create_keyboard (eekboard, stage, layout, width, height); - clutter_actor_get_size (stage, &eekboard->width, &eekboard->height); + widget = create_widget (eekboard, eekboard->width, eekboard->height); + gtk_container_add (GTK_CONTAINER(vbox), widget); + gtk_widget_show_all (vbox); } static void @@ -271,7 +251,9 @@ layout_callback (XklConfigRegistry *registry, config->config->layouts = g_new0 (char *, 2); config->config->layouts[0] = g_strdup (item->name); config->config->layouts[1] = NULL; - config->config->variants = NULL; + /* reset the existing variant setting */ + config->config->variants = g_new0 (char *, 1); + config->config->variants[0] = NULL; g_signal_connect (action, "activate", G_CALLBACK (on_activate), config); g_object_unref (action); @@ -327,7 +309,7 @@ layout_callback (XklConfigRegistry *registry, } static void -create_layouts_menu (EekBoard *eekboard, GtkUIManager *ui_manager) +create_layouts_menu (Eekboard *eekboard, GtkUIManager *ui_manager) { XklEngine *engine; XklConfigRegistry *registry; @@ -347,7 +329,7 @@ create_layouts_menu (EekBoard *eekboard, GtkUIManager *ui_manager) } static void -create_menus (EekBoard *eekboard, +create_menus (Eekboard *eekboard, GtkWidget *window, GtkUIManager * ui_manager) { @@ -371,7 +353,7 @@ on_resize (GObject *object, GParamSpec *param_spec, gpointer user_data) { - EekBoard *eekboard = user_data; + Eekboard *eekboard = user_data; GValue value = {0}; gfloat width, height, scale; ClutterActor *stage, *actor; @@ -399,68 +381,135 @@ on_resize (GObject *object, &value); } -int -main (int argc, char *argv[]) +static GtkWidget * +create_widget_clutter (Eekboard *eekboard, + gfloat initial_width, + gfloat initial_height) { - EekBoard eekboard; - ClutterActor *stage; + ClutterActor *stage, *actor; ClutterColor stage_color = { 0xff, 0xff, 0xff, 0xff }; - GtkWidget *menubar, *embed, *vbox, *window; - GtkUIManager *ui_manager; - if (gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) { - fprintf (stderr, "Can't init Clutter-Gtk\n"); - exit (1); - } + eekboard->keyboard = eek_clutter_keyboard_new (initial_width, + initial_height); + eek_keyboard_set_layout (eekboard->keyboard, eekboard->layout); + g_signal_connect (eekboard->keyboard, "key-pressed", + G_CALLBACK(on_key_pressed), eekboard); + g_signal_connect (eekboard->keyboard, "key-released", + G_CALLBACK(on_key_released), eekboard); - memset (&eekboard, 0, sizeof eekboard); - eekboard.display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - if (!eekboard.display) { - fprintf (stderr, "Can't open display\n"); - exit (1); - } - - eekboard.fakekey = fakekey_init (eekboard.display); - if (!eekboard.fakekey) { - fprintf (stderr, "Can't init fakekey\n"); - exit (1); - } - - embed = gtk_clutter_embed_new (); - stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(embed)); + eekboard->widget = gtk_clutter_embed_new (); + stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(eekboard->widget)); clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color); clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); - eekboard.layout = eek_xkl_layout_new (); - if (!eekboard.layout) { - fprintf (stderr, "Failed to create layout\n"); - exit (1); + actor = eek_clutter_keyboard_get_actor + (EEK_CLUTTER_KEYBOARD(eekboard->keyboard)); + clutter_actor_get_size (actor, &eekboard->width, &eekboard->height); + clutter_container_add_actor (CLUTTER_CONTAINER(stage), actor); + clutter_actor_set_size (stage, eekboard->width, eekboard->height); + g_signal_connect (stage, "notify::width", + G_CALLBACK (on_resize), eekboard); + g_signal_connect (stage, "notify::height", + G_CALLBACK (on_resize), eekboard); + return eekboard->widget; +} + +static GtkWidget * +create_widget_gtk (Eekboard *eekboard, + gfloat initial_width, + gfloat initial_height) +{ + EekBounds bounds; + + bounds.x = bounds.y = 0; + bounds.width = initial_width; + bounds.height = initial_height; + + eekboard->keyboard = eek_gtk_keyboard_new (); + eek_keyboard_set_layout (eekboard->keyboard, eekboard->layout); + eek_element_set_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds); + g_signal_connect (eekboard->keyboard, "key-pressed", + G_CALLBACK(on_key_pressed), eekboard); + g_signal_connect (eekboard->keyboard, "key-released", + G_CALLBACK(on_key_released), eekboard); + + eekboard->widget = + eek_gtk_keyboard_get_widget (EEK_GTK_KEYBOARD (eekboard->keyboard)); + eek_element_get_bounds (EEK_ELEMENT(eekboard->keyboard), &bounds); + eekboard->width = bounds.width; + eekboard->height = bounds.height; + return eekboard->widget; +} + +static GtkWidget * +create_widget (Eekboard *eekboard, + gfloat initial_width, + gfloat initial_height) +{ + if (eekboard->use_clutter) + return create_widget_clutter (eekboard, initial_width, initial_height); + else + return create_widget_gtk (eekboard, initial_width, initial_height); +} + +Eekboard * +eekboard_new (gboolean use_clutter) +{ + Eekboard *eekboard; + + eekboard = g_slice_new0 (Eekboard); + eekboard->use_clutter = use_clutter; + eekboard->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + if (!eekboard->display) { + g_slice_free (Eekboard, eekboard); + g_warning ("Can't open display"); + return NULL; } - clutter_actor_show (stage); /* workaround for clutter-gtk (<= 0.10.2) */ - create_keyboard (&eekboard, stage, eekboard.layout, CSW, CSH); - if (!eekboard.keyboard) { - g_object_unref (eekboard.layout); - fprintf (stderr, "Failed to create keyboard\n"); + eekboard->fakekey = fakekey_init (eekboard->display); + if (!eekboard->fakekey) { + g_slice_free (Eekboard, eekboard); + g_warning ("Can't init fakekey"); + return NULL; + } + + eekboard->layout = eek_xkl_layout_new (); + if (!eekboard->layout) { + g_slice_free (Eekboard, eekboard); + g_warning ("Can't create layout"); + return NULL; + } + g_signal_connect (eekboard->layout, "changed", + G_CALLBACK(on_changed), eekboard); + + create_widget (eekboard, CSW, CSH); + + return eekboard; +} + +int +main (int argc, char *argv[]) +{ + const gchar *env; + gboolean use_clutter = TRUE; + Eekboard *eekboard; + GtkWidget *widget, *vbox, *menubar, *window; + GtkUIManager *ui_manager; + + env = g_getenv ("EEKBOARD_DISABLE_CLUTTER"); + if (env && g_strcmp0 (env, "1") == 0) + use_clutter = FALSE; + + if (use_clutter) { + if (gtk_clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) { + g_warning ("Can't init Clutter-Gtk"); + use_clutter = FALSE; + } + } + if (!use_clutter && !gtk_init_check (&argc, &argv)) { + g_warning ("Can't init GTK"); exit (1); } - clutter_actor_get_size (stage, &eekboard.width, &eekboard.height); - clutter_actor_show_all (stage); - - g_signal_connect (eekboard.layout, - "changed", - G_CALLBACK(on_changed), - &eekboard); - - g_signal_connect (stage, - "notify::width", - G_CALLBACK (on_resize), - &eekboard); - - g_signal_connect (stage, - "notify::height", - G_CALLBACK (on_resize), - &eekboard); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_can_focus (window, FALSE); @@ -470,16 +519,21 @@ main (int argc, char *argv[]) G_CALLBACK (gtk_main_quit), NULL); vbox = gtk_vbox_new (FALSE, 0); + + eekboard = eekboard_new (use_clutter); + widget = create_widget (eekboard, CSW, CSH); + ui_manager = gtk_ui_manager_new (); - create_menus (&eekboard, window, ui_manager); + create_menus (eekboard, window, ui_manager); menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu"); gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0); - gtk_container_add (GTK_CONTAINER(vbox), embed); - gtk_container_add (GTK_CONTAINER(window), vbox); - gtk_widget_set_size_request (embed, eekboard.width, eekboard.height); + gtk_container_add (GTK_CONTAINER(vbox), widget); + gtk_container_add (GTK_CONTAINER(window), vbox); + + gtk_widget_set_size_request (widget, eekboard->width, eekboard->height); gtk_widget_show_all (window); - gtk_widget_set_size_request (embed, -1, -1); + gtk_widget_set_size_request (widget, -1, -1); gtk_main ();