summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakao Fujiwara <tfujiwar@redhat.com>2015-09-07 18:10:19 +0900
committerMatthias Clasen <mclasen@redhat.com>2015-10-09 00:19:41 -0400
commita41f02f9b1843e0f0085f801430e55f413a9bf9c (patch)
treede71f7f2f8971f7b6251f09604f7c09485214a97
parent138187755fc16afca1898bfae6df8317e1c76429 (diff)
downloadgtk+-a41f02f9b1843e0f0085f801430e55f413a9bf9c.tar.gz
GtkIMContextSimple: Load locale compose tables dynamically.
Load /usr/share/X11/locale/$LOCALE/Compose and $HOME/.XCompose dynamically. https://bugzilla.gnome.org/show_bug.cgi?id=721120
-rw-r--r--configure.ac9
-rw-r--r--gtk/Makefile.am1
-rw-r--r--gtk/gtkimcontextsimple.c189
-rw-r--r--gtk/gtkimcontextsimple.h3
4 files changed, 184 insertions, 18 deletions
diff --git a/configure.ac b/configure.ac
index d6f549d911..55ea5a95db 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1375,6 +1375,14 @@ if test x"$os_win32" = xyes; then
GTK_EXTRA_CFLAGS="$msnative_struct"
fi
+if $PKG_CONFIG --exists x11; then
+ X11_PREFIX="`$PKG_CONFIG --variable=prefix x11`"
+elif test x"$prefix" != xNONE; then
+ X11_PREFIX="$prefix"
+else
+ X11_PREFIX="$ac_default_prefix"
+fi
+
GLIB_PREFIX="`$PKG_CONFIG --variable=prefix glib-2.0`"
ATK_PREFIX="`$PKG_CONFIG --variable=prefix atk`"
PANGO_PREFIX="`$PKG_CONFIG --variable=prefix pango`"
@@ -1387,6 +1395,7 @@ AC_SUBST(GTK_EXTRA_CFLAGS)
AC_SUBST(GTK_DEP_LIBS)
AC_SUBST(GTK_DEP_CFLAGS)
+AC_SUBST(X11_PREFIX)
AC_SUBST(GLIB_PREFIX)
AC_SUBST(ATK_PREFIX)
AC_SUBST(PANGO_PREFIX)
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index fcd9f92ff4..bf33c8514e 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -14,6 +14,7 @@ AM_CPPFLAGS = \
-DGTK_COMPILATION \
-DGTK_PRINT_BACKENDS=\"$(GTK_PRINT_BACKENDS)\" \
-DGTK_PRINT_BACKEND_ENABLE_UNSUPPORTED \
+ -DX11_DATA_PREFIX=\"$(X11_PREFIX)\" \
-I$(top_builddir) \
-I$(top_builddir)/gtk \
-I$(top_srcdir) \
diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c
index a89146aa8c..03cc4515b4 100644
--- a/gtk/gtkimcontextsimple.c
+++ b/gtk/gtkimcontextsimple.c
@@ -17,6 +17,15 @@
#include "config.h"
+#include <gdk/gdk.h>
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+#ifdef GDK_WINDOWING_WAYLAND
+#include <wayland/gdkwayland.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
@@ -38,10 +47,10 @@
*/
+#define X11_DATADIR X11_DATA_PREFIX "/share/X11/locale"
+
struct _GtkIMContextSimplePrivate
{
- GSList *tables;
-
guint16 compose_buffer[GTK_MAX_COMPOSE_LEN + 1];
gunichar tentative_match;
gint tentative_match_len;
@@ -62,6 +71,8 @@ const GtkComposeTableCompact gtk_compose_table_compact = {
6
};
+static GSList *global_tables;
+
static const guint16 gtk_compose_ignore[] = {
GDK_KEY_Shift_L,
GDK_KEY_Shift_R,
@@ -89,6 +100,8 @@ static void gtk_im_context_simple_get_preedit_string (GtkIMContext
gchar **str,
PangoAttrList **attrs,
gint *cursor_pos);
+static void gtk_im_context_simple_set_client_window (GtkIMContext *context,
+ GdkWindow *window);
G_DEFINE_TYPE_WITH_PRIVATE (GtkIMContextSimple, gtk_im_context_simple, GTK_TYPE_IM_CONTEXT)
@@ -101,10 +114,120 @@ gtk_im_context_simple_class_init (GtkIMContextSimpleClass *class)
im_context_class->filter_keypress = gtk_im_context_simple_filter_keypress;
im_context_class->reset = gtk_im_context_simple_reset;
im_context_class->get_preedit_string = gtk_im_context_simple_get_preedit_string;
+ im_context_class->set_client_window = gtk_im_context_simple_set_client_window;
gobject_class->finalize = gtk_im_context_simple_finalize;
}
static void
+gtk_im_context_simple_init_compose_table (GtkIMContextSimple *im_context_simple)
+{
+ gchar *path = NULL;
+ const gchar *home;
+ const gchar *locale;
+ gchar **langs = NULL;
+ gchar **lang = NULL;
+ gchar * const sys_langs[] = { "el_gr", "fi_fi", "pt_br", NULL };
+ gchar * const *sys_lang = NULL;
+
+ path = g_build_filename (g_get_user_config_dir (), "gtk-3.0", "Compose", NULL);
+ if (g_file_test (path, G_FILE_TEST_EXISTS))
+ {
+ gtk_im_context_simple_add_compose_file (im_context_simple, path);
+ g_free (path);
+ return;
+ }
+ g_free (path);
+ path = NULL;
+
+ home = g_get_home_dir ();
+ if (home == NULL)
+ return;
+
+ path = g_build_filename (home, ".XCompose", NULL);
+ if (g_file_test (path, G_FILE_TEST_EXISTS))
+ {
+ gtk_im_context_simple_add_compose_file (im_context_simple, path);
+ g_free (path);
+ return;
+ }
+ g_free (path);
+ path = NULL;
+
+ locale = g_getenv ("LC_CTYPE");
+ if (locale == NULL)
+ locale = g_getenv ("LANG");
+ if (locale == NULL)
+ locale = "C";
+
+ /* FIXME: https://bugzilla.gnome.org/show_bug.cgi?id=751826 */
+ langs = g_get_locale_variants (locale);
+
+ for (lang = langs; *lang; lang++)
+ {
+ if (g_str_has_prefix (*lang, "en_US"))
+ break;
+ if (**lang == 'C')
+ break;
+
+ /* Other languages just include en_us compose table. */
+ for (sys_lang = sys_langs; *sys_lang; sys_lang++)
+ {
+ if (g_ascii_strncasecmp (*lang, *sys_lang, strlen (*sys_lang)) == 0)
+ {
+ path = g_build_filename (X11_DATADIR, *lang, "Compose", NULL);
+ break;
+ }
+ }
+
+ if (path == NULL)
+ continue;
+
+ if (g_file_test (path, G_FILE_TEST_EXISTS))
+ break;
+ g_free (path);
+ path = NULL;
+ }
+
+ g_strfreev (langs);
+
+ if (path != NULL)
+ gtk_im_context_simple_add_compose_file (im_context_simple, path);
+ g_free (path);
+ path = NULL;
+}
+
+static void
+init_compose_table_thread_cb (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GtkIMContextSimple *im_context_simple;
+
+ if (g_task_return_error_if_cancelled (task))
+ return;
+
+ g_return_if_fail (GTK_IS_IM_CONTEXT_SIMPLE (task_data));
+
+ im_context_simple = GTK_IM_CONTEXT_SIMPLE (task_data);
+
+ gtk_im_context_simple_init_compose_table (im_context_simple);
+}
+
+void
+init_compose_table_async (GtkIMContextSimple *im_context_simple,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task = g_task_new (NULL, cancellable, callback, user_data);
+ g_task_set_source_tag (task, init_compose_table_async);
+ g_task_set_task_data (task, im_context_simple, NULL);
+ g_task_run_in_thread (task, init_compose_table_thread_cb);
+ g_object_unref (task);
+}
+
+static void
gtk_im_context_simple_init (GtkIMContextSimple *im_context_simple)
{
im_context_simple->priv = gtk_im_context_simple_get_instance_private (im_context_simple);
@@ -113,11 +236,6 @@ gtk_im_context_simple_init (GtkIMContextSimple *im_context_simple)
static void
gtk_im_context_simple_finalize (GObject *obj)
{
- GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (obj);
- GtkIMContextSimplePrivate *priv = context_simple->priv;
-
- g_slist_free_full (priv->tables, g_free);
-
G_OBJECT_CLASS (gtk_im_context_simple_parent_class)->finalize (obj);
}
@@ -1081,7 +1199,7 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
}
else
{
- tmp_list = priv->tables;
+ tmp_list = global_tables;
while (tmp_list)
{
if (check_table (context_simple, tmp_list->data, n_compose))
@@ -1232,6 +1350,33 @@ gtk_im_context_simple_get_preedit_string (GtkIMContext *context,
*cursor_pos = len;
}
+static void
+gtk_im_context_simple_set_client_window (GtkIMContext *context,
+ GdkWindow *window)
+{
+ GdkDisplay *display;
+ GtkIMContextSimple *im_context_simple = GTK_IM_CONTEXT_SIMPLE (context);
+ gboolean run_compose_table = FALSE;
+
+ if (!window)
+ return;
+
+ display = gdk_window_get_display (window);
+
+ /* Load compose table for X11 or Wayland. */
+#ifdef GDK_WINDOWING_X11
+ if (GDK_IS_X11_DISPLAY (display))
+ run_compose_table = TRUE;
+#endif
+#ifdef GDK_WINDOWING_WAYLAND
+ if (GDK_IS_WAYLAND_DISPLAY (display))
+ run_compose_table = TRUE;
+#endif
+
+ if (run_compose_table)
+ init_compose_table_async (im_context_simple, NULL, NULL, NULL);
+}
+
/**
* gtk_im_context_simple_add_table: (skip)
* @context_simple: A #GtkIMContextSimple
@@ -1256,17 +1401,25 @@ gtk_im_context_simple_add_table (GtkIMContextSimple *context_simple,
gint max_seq_len,
gint n_seqs)
{
- GtkIMContextSimplePrivate *priv = context_simple->priv;
- GtkComposeTable *table;
+ g_return_if_fail (GTK_IS_IM_CONTEXT_SIMPLE (context_simple));
+ global_tables = gtk_compose_table_list_add_array (global_tables,
+ data, max_seq_len, n_seqs);
+}
+
+/*
+ * gtk_im_context_simple_add_compose_file:
+ * @context_simple: A #GtkIMContextSimple
+ * @compose_file: The path of compose file
+ *
+ * Adds an additional table from the X11 compose file.
+ */
+void
+gtk_im_context_simple_add_compose_file (GtkIMContextSimple *context_simple,
+ const gchar *compose_file)
+{
g_return_if_fail (GTK_IS_IM_CONTEXT_SIMPLE (context_simple));
- g_return_if_fail (data != NULL);
- g_return_if_fail (max_seq_len <= GTK_MAX_COMPOSE_LEN);
-
- table = g_new (GtkComposeTable, 1);
- table->data = data;
- table->max_seq_len = max_seq_len;
- table->n_seqs = n_seqs;
- priv->tables = g_slist_prepend (priv->tables, table);
+ global_tables = gtk_compose_table_list_add_file (global_tables,
+ compose_file);
}
diff --git a/gtk/gtkimcontextsimple.h b/gtk/gtkimcontextsimple.h
index 8c09576334..b0f2cccc97 100644
--- a/gtk/gtkimcontextsimple.h
+++ b/gtk/gtkimcontextsimple.h
@@ -69,6 +69,9 @@ void gtk_im_context_simple_add_table (GtkIMContextSimple *context_simpl
guint16 *data,
gint max_seq_len,
gint n_seqs);
+GDK_AVAILABLE_IN_3_20
+void gtk_im_context_simple_add_compose_file (GtkIMContextSimple *context_simple,
+ const gchar *compose_file);
G_END_DECLS