Compare commits

..

9 Commits

8 changed files with 274 additions and 49 deletions

8
TODO
View File

@ -1,17 +1,17 @@
- packaging - packaging
-- GIR
-- .spec
-- debian -- debian
-- add more tests -- add more tests
- eekboard - eekboard
-- a11y -- a11y
-- display current configuration -- display current configuration
-- add command line options
-- notify user if there is no focused window -- notify user if there is no focused window
-- startup in the tray
-- rewrite in Vala
- libeek - libeek
-- matchbox-keyboard layout engine -- Caribou layout engine (XML)
-- matchbox-keyboard layout engine (XML)
-- delay initialization of XKB and XKL layouts -- delay initialization of XKB and XKL layouts
-- add eek_keyboard_find_by_position(), that takes account of section -- add eek_keyboard_find_by_position(), that takes account of section
rotation, in addition to eek_container_find_by_position() rotation, in addition to eek_container_find_by_position()

View File

@ -16,7 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA # 02110-1301 USA
AC_INIT([eekboard], [0.0.3], [ueno@unixuser.org]) AC_INIT([eekboard], [0.0.4], [ueno@unixuser.org])
AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_SRCDIR([configure.ac])
AC_PREREQ(2.63) AC_PREREQ(2.63)
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
@ -69,18 +69,15 @@ if test x$enable_clutter = xyes; then
PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], , PKG_CHECK_MODULES([CLUTTER], [clutter-1.0], ,
[AC_MSG_ERROR([Clutter not found -- install it or add --disable-clutter])]) [AC_MSG_ERROR([Clutter not found -- install it or add --disable-clutter])])
AC_DEFINE([HAVE_CLUTTER], [1], [Define if Clutter is found]) AC_DEFINE([HAVE_CLUTTER], [1], [Define if Clutter is found])
PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.90], need_swap_event_workaround=no
[enable_clutter_gtk=yes]) PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.90],,
if test x$enable_clutter_gtk = xno; then [PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.10 clutter-x11-1.0],
PKG_CHECK_MODULES([CLUTTER_GTK], [clutter-gtk-0.10], [need_swap_event_workaround=yes])])
[enable_clutter_gtk=yes])
fi
if test x$enable_clutter_gtk = xyes; then
AC_DEFINE([HAVE_CLUTTER_GTK], [1], [Define if Clutter-Gtk is found]) AC_DEFINE([HAVE_CLUTTER_GTK], [1], [Define if Clutter-Gtk is found])
fi AC_DEFINE([NEED_SWAP_EVENT_WORKAROUND], [1],
[Define if GLX_INTEL_swap_event work around is needed])
fi fi
AM_CONDITIONAL(HAVE_CLUTTER, [test x$enable_clutter = xyes]) AM_CONDITIONAL(HAVE_CLUTTER, [test x$enable_clutter = xyes])
AM_CONDITIONAL(HAVE_CLUTTER_GTK, [test x$enable_clutter_gtk = xyes])
GTK_DOC_CHECK([1.14],[--flavour no-tmpl]) GTK_DOC_CHECK([1.14],[--flavour no-tmpl])

View File

@ -8,7 +8,7 @@
<bookinfo> <bookinfo>
<title>libeek Reference Manual</title> <title>libeek Reference Manual</title>
<releaseinfo> <releaseinfo>
for libeek 0.0.3. for libeek 0.0.4.
</releaseinfo> </releaseinfo>
<copyright> <copyright>
<year>2010</year> <year>2010</year>

View File

@ -80,6 +80,9 @@ eek_gtk_keyboard_real_set_keysym_index (EekKeyboard *self,
GtkStateType state; GtkStateType state;
GtkAllocation allocation; GtkAllocation allocation;
if (!priv->widget || !gtk_widget_get_realized (priv->widget))
return;
prepare_keyboard_pixmap (keyboard); prepare_keyboard_pixmap (keyboard);
state = gtk_widget_get_state (GTK_WIDGET (priv->widget)); state = gtk_widget_get_state (GTK_WIDGET (priv->widget));
gtk_widget_get_allocation (GTK_WIDGET (priv->widget), &allocation); gtk_widget_get_allocation (GTK_WIDGET (priv->widget), &allocation);

View File

@ -400,7 +400,11 @@ eek_xkl_layout_set_model (EekXklLayout *layout,
g_return_val_if_fail (priv, FALSE); g_return_val_if_fail (priv, FALSE);
config = xkl_config_rec_new (); config = xkl_config_rec_new ();
config->model = (gchar *)model; /* config->model will be freed on g_object_unref (config) */
if (model)
config->model = g_strdup (model);
else
config->model = NULL;
success = eek_xkl_layout_set_config (layout, config); success = eek_xkl_layout_set_config (layout, config);
g_object_unref (config); g_object_unref (config);
return success; return success;
@ -424,6 +428,10 @@ eek_xkl_layout_set_layouts (EekXklLayout *layout,
g_return_val_if_fail (priv, FALSE); g_return_val_if_fail (priv, FALSE);
config = xkl_config_rec_new (); config = xkl_config_rec_new ();
/* config->layouts will be freed on g_object_unref (config) */
if (layouts)
config->layouts = g_strdupv (layouts);
else
config->layouts = layouts; config->layouts = layouts;
success = eek_xkl_layout_set_config (layout, config); success = eek_xkl_layout_set_config (layout, config);
g_object_unref (config); g_object_unref (config);
@ -448,7 +456,11 @@ eek_xkl_layout_set_variants (EekXklLayout *layout,
g_return_val_if_fail (priv, FALSE); g_return_val_if_fail (priv, FALSE);
config = xkl_config_rec_new (); config = xkl_config_rec_new ();
config->variants = variants; /* config->variants will be freed on g_object_unref (config) */
if (variants)
config->variants = g_strdupv (variants);
else
config->variants = NULL;
success = eek_xkl_layout_set_config (layout, config); success = eek_xkl_layout_set_config (layout, config);
g_object_unref (config); g_object_unref (config);
return success; return success;
@ -472,7 +484,11 @@ eek_xkl_layout_set_options (EekXklLayout *layout,
g_return_val_if_fail (priv, FALSE); g_return_val_if_fail (priv, FALSE);
config = xkl_config_rec_new (); config = xkl_config_rec_new ();
/* config->options will be freed on g_object_unref (config) */
if (options)
config->options = options; config->options = options;
else
config->options = NULL;
success = eek_xkl_layout_set_config (layout, config); success = eek_xkl_layout_set_config (layout, config);
g_object_unref (config); g_object_unref (config);
return success; return success;

View File

@ -6,10 +6,10 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: eekboard 0.0.0\n" "Project-Id-Version: eekboard 0.0.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-06-21 12:42+0900\n" "POT-Creation-Date: 2010-06-23 16:52+0900\n"
"PO-Revision-Date: 2010-06-21 12:45+0900\n" "PO-Revision-Date: 2010-06-23 16:55+0900\n"
"Last-Translator: Daiki Ueno <ueno@unixuser.org>\n" "Last-Translator: Daiki Ueno <ueno@unixuser.org>\n"
"Language-Team: Japanese\n" "Language-Team: Japanese\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -17,46 +17,74 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ../src/eekboard.c:195 #: ../src/eekboard.c:198
msgid "_File" msgid "_File"
msgstr "ファイル" msgstr "ファイル"
#: ../src/eekboard.c:196 #: ../src/eekboard.c:199
msgid "_Keyboard" msgid "_Keyboard"
msgstr "キーボード" msgstr "キーボード"
#: ../src/eekboard.c:197 #: ../src/eekboard.c:200
msgid "_Help" msgid "_Help"
msgstr "ヘルプ" msgstr "ヘルプ"
#: ../src/eekboard.c:199 #: ../src/eekboard.c:202
msgid "Country" msgid "Country"
msgstr "国" msgstr "国"
#: ../src/eekboard.c:201 #: ../src/eekboard.c:204
msgid "Language" msgid "Language"
msgstr "言語" msgstr "言語"
#: ../src/eekboard.c:203 #: ../src/eekboard.c:206
msgid "Model" msgid "Model"
msgstr "モデル" msgstr "モデル"
#: ../src/eekboard.c:205 #: ../src/eekboard.c:208
msgid "Layout" msgid "Layout"
msgstr "レイアウト" msgstr "レイアウト"
#: ../src/eekboard.c:207 #: ../src/eekboard.c:210
msgid "Option" msgid "Option"
msgstr "オプション" msgstr "オプション"
#: ../src/eekboard.c:214 #: ../src/eekboard.c:217
msgid "Monitor Key Typing" msgid "Monitor Key Typing"
msgstr "打鍵をモニタ" msgstr "打鍵をモニタ"
#: ../src/eekboard.c:232 #: ../src/eekboard.c:232
msgid "Keyboard model to display"
msgstr "表示するキーボードのモデル"
#: ../src/eekboard.c:234
msgid "Keyboard layouts to display, separated with commas"
msgstr "表示するキーボードのレイアウト,カンマ区切り"
#: ../src/eekboard.c:236
msgid "Keyboard layout options to display, separated with commas"
msgstr "表示するキーボードのオプション,カンマ区切り"
#: ../src/eekboard.c:238
msgid "List keyboard models"
msgstr "キーボードのモデルを一覧"
#: ../src/eekboard.c:240
msgid "List all available keyboard layouts and variants"
msgstr "利用可能なキーボードのレイアウトとバリアントを一覧"
#: ../src/eekboard.c:242
msgid "List all available keyboard layout options"
msgstr "利用可能なキーボードのレイアウトオプションを一覧"
#: ../src/eekboard.c:244
msgid "Display version"
msgstr "バージョンを表示"
#: ../src/eekboard.c:261
msgid "A virtual keyboard for GNOME" msgid "A virtual keyboard for GNOME"
msgstr "GNOME 向け仮想キーボード" msgstr "GNOME 向け仮想キーボード"
#: ../src/eekboard.c:236 #: ../src/eekboard.c:265
msgid "Eekboard web site" msgid "Eekboard web site"
msgstr "Eekboard のウェブサイト" msgstr "Eekboard のウェブサイト"

View File

@ -37,12 +37,7 @@ eekboard_LDFLAGS = \
$(LIBFAKEKEY_LIBS) $(LIBFAKEKEY_LIBS)
if HAVE_CLUTTER if HAVE_CLUTTER
eekboard_CFLAGS += $(CLUTTER_CFLAGS) eekboard_CFLAGS += $(CLUTTER_CFLAGS) $(CLUTTER_GTK_CFLAGS)
eekboard_LDFLAGS += $(CLUTTER_LIBS) eekboard_LDFLAGS += $(CLUTTER_LIBS) $(top_builddir)/eek/libeek-clutter.la $(CLUTTER_GTK_LIBS)
endif
if HAVE_CLUTTER_GTK
eekboard_CFLAGS += $(CLUTTER_GTK_CFLAGS)
eekboard_LDFLAGS += $(top_builddir)/eek/libeek-clutter.la $(CLUTTER_GTK_LIBS)
endif endif
endif endif

View File

@ -22,6 +22,9 @@
#if HAVE_CLUTTER_GTK #if HAVE_CLUTTER_GTK
#include <clutter-gtk/clutter-gtk.h> #include <clutter-gtk/clutter-gtk.h>
#if NEED_SWAP_EVENT_WORKAROUND
#include <clutter/x11/clutter-x11.h>
#endif
#endif #endif
#include <glib/gi18n.h> #include <glib/gi18n.h>
@ -75,6 +78,7 @@
struct _Eekboard { struct _Eekboard {
gboolean use_clutter; gboolean use_clutter;
gboolean need_swap_event_workaround;
Display *display; Display *display;
FakeKey *fakekey; FakeKey *fakekey;
GtkWidget *widget; GtkWidget *widget;
@ -143,6 +147,7 @@ static void on_monitor_key_event_toggled
(GtkToggleAction *action, (GtkToggleAction *action,
GtkWidget *window); GtkWidget *window);
#endif #endif
static void eekboard_free (Eekboard *eekboard);
static GtkWidget *create_widget (Eekboard *eekboard, static GtkWidget *create_widget (Eekboard *eekboard,
gint initial_width, gint initial_width,
gint initial_height); gint initial_height);
@ -218,6 +223,32 @@ static const GtkToggleActionEntry toggle_action_entry[] = {
}; };
#endif #endif
static gchar *opt_model = NULL;
static gchar *opt_layouts = NULL;
static gchar *opt_options = NULL;
static gboolean opt_list_models = FALSE;
static gboolean opt_list_layouts = FALSE;
static gboolean opt_list_options = FALSE;
static gboolean opt_version = FALSE;
static const GOptionEntry options[] = {
{"model", 'M', 0, G_OPTION_ARG_STRING, &opt_model,
N_("Keyboard model to display")},
{"layouts", 'L', 0, G_OPTION_ARG_STRING, &opt_layouts,
N_("Keyboard layouts to display, separated with commas")},
{"options", 'O', 0, G_OPTION_ARG_STRING, &opt_options,
N_("Keyboard layout options to display, separated with commas")},
{"list-models", '\0', 0, G_OPTION_ARG_NONE, &opt_list_models,
N_("List keyboard models")},
{"list-layouts", '\0', 0, G_OPTION_ARG_NONE, &opt_list_layouts,
N_("List all available keyboard layouts and variants")},
{"list-options", 'O', 0, G_OPTION_ARG_NONE, &opt_list_options,
N_("List all available keyboard layout options")},
{"version", 'v', 0, G_OPTION_ARG_NONE, &opt_version,
N_("Display version")},
{NULL}
};
static void static void
on_about (GtkAction * action, GtkWidget *window) on_about (GtkAction * action, GtkWidget *window)
{ {
@ -244,11 +275,8 @@ on_quit (GtkAction * action, GtkWidget *window)
{ {
Eekboard *eekboard = g_object_get_data (G_OBJECT(window), "eekboard"); Eekboard *eekboard = g_object_get_data (G_OBJECT(window), "eekboard");
g_object_unref (eekboard->keyboard); fakekey_release (eekboard->fakekey);
g_object_unref (eekboard->layout); eekboard_free (eekboard);
g_object_unref (eekboard->registry);
g_object_unref (eekboard->engine);
g_slice_free (Eekboard, eekboard);
gtk_main_quit (); gtk_main_quit ();
} }
@ -896,6 +924,26 @@ create_widget_gtk (Eekboard *eekboard,
} }
#if HAVE_CLUTTER_GTK #if HAVE_CLUTTER_GTK
#if NEED_SWAP_EVENT_WORKAROUND
static GdkFilterReturn
gtk_clutter_filter_func (GdkXEvent *native_event,
GdkEvent *event,
gpointer user_data)
{
XEvent *xevent = native_event;
clutter_x11_handle_event (xevent);
return GDK_FILTER_CONTINUE;
}
static void
on_gtk_clutter_embed_realize (GtkWidget *widget, gpointer user_data)
{
gdk_window_add_filter (NULL, gtk_clutter_filter_func, widget);
}
#endif
static GtkWidget * static GtkWidget *
create_widget_clutter (Eekboard *eekboard, create_widget_clutter (Eekboard *eekboard,
gint initial_width, gint initial_width,
@ -918,6 +966,11 @@ create_widget_clutter (Eekboard *eekboard,
G_CALLBACK(on_key_released), eekboard); G_CALLBACK(on_key_released), eekboard);
eekboard->widget = gtk_clutter_embed_new (); eekboard->widget = gtk_clutter_embed_new ();
#if NEED_SWAP_EVENT_WORKAROUND
if (eekboard->need_swap_event_workaround)
g_signal_connect (eekboard->widget, "realize",
G_CALLBACK(on_gtk_clutter_embed_realize), NULL);
#endif
stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(eekboard->widget)); stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED(eekboard->widget));
clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color); clutter_stage_set_color (CLUTTER_STAGE(stage), &stage_color);
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
@ -945,12 +998,13 @@ create_widget (Eekboard *eekboard,
#endif #endif
Eekboard * Eekboard *
eekboard_new (gboolean use_clutter) eekboard_new (gboolean use_clutter, gboolean need_swap_event_workaround)
{ {
Eekboard *eekboard; Eekboard *eekboard;
eekboard = g_slice_new0 (Eekboard); eekboard = g_slice_new0 (Eekboard);
eekboard->use_clutter = use_clutter; eekboard->use_clutter = use_clutter;
eekboard->need_swap_event_workaround = need_swap_event_workaround;
eekboard->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); eekboard->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
if (!eekboard->display) { if (!eekboard->display) {
g_slice_free (Eekboard, eekboard); g_slice_free (Eekboard, eekboard);
@ -971,6 +1025,36 @@ eekboard_new (gboolean use_clutter)
g_warning ("Can't create layout"); g_warning ("Can't create layout");
return NULL; return NULL;
} }
if (opt_model)
eek_xkl_layout_set_model (EEK_XKL_LAYOUT(eekboard->layout), opt_model);
if (opt_layouts) {
gchar **layouts, **variants;
gint i;
layouts = g_strsplit (opt_layouts, ",", -1);
variants = g_strdupv (layouts);
for (i = 0; layouts[i]; i++) {
gchar *layout = layouts[i], *variant = variants[i],
*variant_start, *variant_end;
variant_start = strchr (layout, '(');
variant_end = strrchr (layout, ')');
if (variant_start && variant_end) {
*variant_start++ = '\0';
g_strlcpy (variant, variant_start,
variant_end - variant_start + 1);
} else
*variant = '\0';
}
eek_xkl_layout_set_layouts (EEK_XKL_LAYOUT(eekboard->layout), layouts);
g_strfreev (layouts);
g_strfreev (variants);
}
if (opt_options) {
gchar **options;
options = g_strsplit (opt_options, ",", -1);
eek_xkl_layout_set_options (EEK_XKL_LAYOUT(eekboard->layout), options);
g_strfreev (options);
}
g_signal_connect (eekboard->layout, "changed", g_signal_connect (eekboard->layout, "changed",
G_CALLBACK(on_changed), eekboard); G_CALLBACK(on_changed), eekboard);
@ -979,18 +1063,91 @@ eekboard_new (gboolean use_clutter)
eekboard->registry = xkl_config_registry_get_instance (eekboard->engine); eekboard->registry = xkl_config_registry_get_instance (eekboard->engine);
xkl_config_registry_load (eekboard->registry, FALSE); xkl_config_registry_load (eekboard->registry, FALSE);
create_widget (eekboard, CSW, CSH);
return eekboard; return eekboard;
} }
static void
eekboard_free (Eekboard *eekboard)
{
if (eekboard->layout)
g_object_unref (eekboard->layout);
#if 0
if (eekboard->keyboard)
g_object_unref (eekboard->keyboard);
#endif
if (eekboard->registry)
g_object_unref (eekboard->registry);
if (eekboard->engine)
g_object_unref (eekboard->engine);
g_slice_free (Eekboard, eekboard);
}
static void
print_layout (XklConfigRegistry *registry,
const XklConfigItem *item,
gpointer user_data)
{
GSList *variants = NULL;
xkl_config_registry_foreach_layout_variant (registry,
item->name,
collect_variant,
&variants);
if (!variants)
printf ("%s: %s\n", item->name, item->description);
else {
GSList *head;
for (head = variants; head; head = head->next) {
XklConfigItem *_item = head->data;
printf ("%s(%s): %s %s\n",
item->name,
_item->name,
item->description,
_item->description);
g_slice_free (XklConfigItem, _item);
}
g_slist_free (variants);
}
}
static void
print_item (XklConfigRegistry *registry,
const XklConfigItem *item,
gpointer user_data)
{
printf ("%s: %s\n", item->name, item->description);
}
static void
print_option_group (XklConfigRegistry *registry,
const XklConfigItem *item,
gpointer user_data)
{
xkl_config_registry_foreach_option (registry,
item->name,
print_item,
NULL);
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
const gchar *env; const gchar *env;
gboolean use_clutter = USE_CLUTTER; gboolean use_clutter = USE_CLUTTER;
gboolean need_swap_event_workaround = FALSE;
Eekboard *eekboard; Eekboard *eekboard;
GtkWidget *widget, *vbox, *menubar, *window; GtkWidget *widget, *vbox, *menubar, *window;
GOptionContext *context;
context = g_option_context_new ("eekboard");
g_option_context_add_main_entries (context, options, NULL);
g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free (context);
if (opt_version) {
g_print ("eekboard %s\n", VERSION);
exit (0);
}
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, EEKBOARD_LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, EEKBOARD_LOCALEDIR);
@ -1007,6 +1164,13 @@ main (int argc, char *argv[])
g_warning ("Can't init Clutter-Gtk...fallback to GTK"); g_warning ("Can't init Clutter-Gtk...fallback to GTK");
use_clutter = FALSE; use_clutter = FALSE;
} }
#ifdef NEED_SWAP_EVENT_WORKAROUND
if (use_clutter &&
clutter_feature_available (CLUTTER_FEATURE_SWAP_EVENTS)) {
g_warning ("Enabling GLX_INTEL_swap_event workaround for Clutter-Gtk");
need_swap_event_workaround = TRUE;
}
#endif
#endif #endif
if (!use_clutter && !gtk_init_check (&argc, &argv)) { if (!use_clutter && !gtk_init_check (&argc, &argv)) {
@ -1014,6 +1178,29 @@ main (int argc, char *argv[])
exit (1); exit (1);
} }
eekboard = eekboard_new (use_clutter, need_swap_event_workaround);
if (opt_list_models) {
xkl_config_registry_foreach_model (eekboard->registry,
print_item,
NULL);
eekboard_free (eekboard);
exit (0);
}
if (opt_list_layouts) {
xkl_config_registry_foreach_layout (eekboard->registry,
print_layout,
NULL);
eekboard_free (eekboard);
exit (0);
}
if (opt_list_options) {
xkl_config_registry_foreach_option_group (eekboard->registry,
print_option_group,
NULL);
eekboard_free (eekboard);
exit (0);
}
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_can_focus (window, FALSE); gtk_widget_set_can_focus (window, FALSE);
g_object_set (G_OBJECT(window), "accept_focus", FALSE, NULL); g_object_set (G_OBJECT(window), "accept_focus", FALSE, NULL);
@ -1023,7 +1210,6 @@ main (int argc, char *argv[])
vbox = gtk_vbox_new (FALSE, 0); vbox = gtk_vbox_new (FALSE, 0);
eekboard = eekboard_new (use_clutter);
g_object_set_data (G_OBJECT(window), "eekboard", eekboard); g_object_set_data (G_OBJECT(window), "eekboard", eekboard);
widget = create_widget (eekboard, CSW, CSH); widget = create_widget (eekboard, CSW, CSH);