diff options
author | Tor Lillqvist <tml@iki.fi> | 2004-10-01 19:53:55 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@src.gnome.org> | 2004-10-01 19:53:55 +0000 |
commit | 8439956a9caa505b280eba27eb75c2f93ec5d0e3 (patch) | |
tree | 65d4d443b738a4eda185452344779b950e54dd52 /modules/input | |
parent | 49174ac1bea2f26430d9176982b4adf4f0b3dfbc (diff) | |
download | gdk-pixbuf-8439956a9caa505b280eba27eb75c2f93ec5d0e3.tar.gz |
Set _gdk_input_ignore_wintab to FALSE, thus enabling tablet input by
2004-10-01 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkglobals-win32.c: Set _gdk_input_ignore_wintab to
FALSE, thus enabling tablet input by default.
* gdk/win32/gdkmain-win32.c (_gdk_windowing_args): Accept the
--use-wintab option again (but without effect, as this is now the
default, see above). (#153788)
* modules/input/gtkimcontextime.c: Numerous changes.
Remove the ifdef UNICODE conditionals. Always use the
wide-character Imm* API. It is present also in Windows 98 and
Me. (Not Windows 95, but I think we don't care about that.) Using
the multibyte API wouldn't work anyway on systems where the system
codepage doesn't support the language the user uses an IME for, so
for instance I wouldn't be able to test this module on my English
Windows 2000 although I do have C, J and K IMEs available.
Guard against IMM not being active, always check ImmGetContext()
returning NULL. Work to some extent even without any IME. Fixes
#153800 at least partially.
* modules/input/imime.c (ime_info): Rename to "ime" to match the
naming pattern of other input modules. Make it default for
ja:ko:zh only.
Diffstat (limited to 'modules/input')
-rw-r--r-- | modules/input/gtkimcontextime.c | 339 | ||||
-rw-r--r-- | modules/input/imime.c | 4 |
2 files changed, 163 insertions, 180 deletions
diff --git a/modules/input/gtkimcontextime.c b/modules/input/gtkimcontextime.c index 82397bbb9..ad560925c 100644 --- a/modules/input/gtkimcontextime.c +++ b/modules/input/gtkimcontextime.c @@ -1,5 +1,5 @@ /* - * gtkimmoduleime + * gtkimcontextime.c * Copyright (C) 2003 Takuro Ashie * Copyright (C) 2003-2004 Kazuki IWAMOTO * @@ -18,7 +18,6 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * - * $Id$ */ /* @@ -34,6 +33,8 @@ #include "gdk/gdkkeysyms.h" #include "gtk/gtkwidget.h" +#include <pango/pango-utils.h> + /* avoid warning */ #ifdef STRICT # undef STRICT @@ -104,10 +105,10 @@ static void gtk_im_context_ime_set_use_preedit (GtkIMContext *context, gboolean use_preedit); /* GtkIMContextIME's private functions */ -static void gtk_im_context_ime_set_preedit_font (GtkIMContext *context, - PangoFont *font); +static void gtk_im_context_ime_set_preedit_font (GtkIMContext *context); + static GdkFilterReturn - gtk_im_context_ime_message_filter (GdkXEvent *xevent, +gtk_im_context_ime_message_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data); static void get_window_position (GdkWindow *win, @@ -268,7 +269,6 @@ gtk_im_context_ime_set_client_window (GtkIMContext *context, GdkWindow *client_window) { GtkIMContextIME *context_ime; - HWND hwnd = NULL; g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context)); context_ime = GTK_IM_CONTEXT_IME (context); @@ -276,17 +276,18 @@ gtk_im_context_ime_set_client_window (GtkIMContext *context, if (client_window) { HIMC himc; + HWND hwnd; hwnd = GDK_WINDOW_HWND (client_window); - - /* get default ime context */ himc = ImmGetContext (hwnd); - context_ime->opened = ImmGetOpenStatus (himc); - ImmGetConversionStatus (himc, - &context_ime->priv->conversion_mode, - &context_ime->priv->sentence_mode); - ImmReleaseContext (hwnd, himc); - + if (himc) + { + context_ime->opened = ImmGetOpenStatus (himc); + ImmGetConversionStatus (himc, + &context_ime->priv->conversion_mode, + &context_ime->priv->sentence_mode); + ImmReleaseContext (hwnd, himc); + } } else if (context_ime->focus) { @@ -302,36 +303,34 @@ gtk_im_context_ime_filter_keypress (GtkIMContext *context, GdkEventKey *event) { GtkIMContextIME *context_ime; - HWND hwnd; - HIMC himc; gboolean retval = FALSE; + guint32 c; g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (context), FALSE); g_return_val_if_fail (event, FALSE); if (event->type == GDK_KEY_RELEASE) - return retval; + return FALSE; context_ime = GTK_IM_CONTEXT_IME (context); + if (!context_ime->focus) return FALSE; + if (!GDK_IS_WINDOW (context_ime->client_window)) return FALSE; - hwnd = GDK_WINDOW_HWND (context_ime->client_window); - himc = ImmGetContext (hwnd); - - /* FIXME!! event->string is deprecated */ - if (event->string && *event->string - && !g_unichar_iscntrl (g_utf8_get_char_validated (event->string, - strlen (event->string)))) + c = gdk_keyval_to_unicode (event->keyval); + if (c) { - g_signal_emit_by_name (G_OBJECT (context_ime), "commit", event->string); + guchar utf8[10]; + int len = g_unichar_to_utf8 (c, utf8); + utf8[len] = 0; + + g_signal_emit_by_name (G_OBJECT (context_ime), "commit", utf8); retval = TRUE; } - ImmReleaseContext (hwnd, himc); - return retval; } @@ -369,100 +368,41 @@ get_utf8_preedit_string (GtkIMContextIME *context_ime, gint *pos_ret) if (pos_ret) *pos_ret = 0; - /* - g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (context_ime), - g_strdup ("")); - */ - hwnd = GDK_WINDOW_HWND (context_ime->client_window); himc = ImmGetContext (hwnd); - - /* shouldn't return NULL */ - g_return_val_if_fail (himc, g_strdup ("")); + if (!himc) + return g_strdup (""); if (context_ime->preediting) { - gpointer buf; glong len; - GError *error = NULL; - -#ifdef UNICODE - len = ImmGetCompositionString (himc, GCS_COMPSTR, NULL, 0); - buf = g_malloc (len); - if (len > 0 && buf) - { - ImmGetCompositionString (himc, GCS_COMPSTR, buf, len); - len /= sizeof (gunichar2); - utf8str = g_utf16_to_utf8 (buf, len, NULL, NULL, &error); - if (error) - { - g_warning ("%s", error->message); - g_error_free (error); - } - - if (pos_ret) - { - pos = ImmGetCompositionString (himc, GCS_CURSORPOS, NULL, 0); - if (pos < 0 || len < pos) - { - g_warning ("ImmGetCompositionString: " - "Invalid cursor position!"); - pos = 0; - } - } - g_free (buf); - } -#else /* not UNICODE */ - len = ImmGetCompositionString (himc, GCS_COMPSTR, NULL, 0); - buf = g_malloc (len); - if (len > 0 && buf) - { - ImmGetCompositionString (himc, GCS_COMPSTR, buf, len); - utf8str = g_locale_to_utf8 (buf, len, NULL, NULL, &error); - if (error) - { - g_warning ("%s", error->message); - g_error_free (error); - } - if (pos_ret) - { - pos = ImmGetCompositionString (himc, GCS_CURSORPOS, NULL, 0); - /* get cursor position by offset */ - if (pos < len && utf8str) - { - gchar *tmpstr; - - tmpstr = g_locale_to_utf8 (buf, pos, NULL, NULL, &error); - if (error) - { - g_warning ("%s", error->message); - g_error_free (error); - } - if (tmpstr) - { - pos = g_utf8_strlen (tmpstr, -1); - } - else - { - pos = 0; - } - g_free (tmpstr); - } - else if (pos == len && utf8str) - { - pos = g_utf8_strlen (utf8str, -1); - } - else - { - g_warning ("ImmGetCompositionString: " - "Invalid cursor position!"); - pos = 0; - } - } - g_free (buf); - } -#endif /* not UNICODE */ + len = ImmGetCompositionStringW (himc, GCS_COMPSTR, NULL, 0); + if (len > 0) + { + GError *error = NULL; + gpointer buf = g_alloca (len); + + ImmGetCompositionStringW (himc, GCS_COMPSTR, buf, len); + len /= 2; + utf8str = g_utf16_to_utf8 (buf, len, NULL, NULL, &error); + if (error) + { + g_warning ("%s", error->message); + g_error_free (error); + } + + if (pos_ret) + { + pos = ImmGetCompositionStringW (himc, GCS_CURSORPOS, NULL, 0); + if (pos < 0 || len < pos) + { + g_warning ("ImmGetCompositionString: " + "Invalid cursor position!"); + pos = 0; + } + } + } } if (!utf8str) @@ -487,12 +427,10 @@ get_pango_attr_list (GtkIMContextIME *context_ime, const gchar *utf8str) HWND hwnd; HIMC himc; - /* g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (context_ime), attr); */ - hwnd = GDK_WINDOW_HWND (context_ime->client_window); himc = ImmGetContext (hwnd); - - g_return_val_if_fail (himc, attrs); + if (!himc) + return attrs; if (context_ime->preediting) { @@ -505,9 +443,9 @@ get_pango_attr_list (GtkIMContextIME *context_ime, const gchar *utf8str) /* * get attributes list of IME. */ - len = ImmGetCompositionString (himc, GCS_COMPATTR, NULL, 0); - buf = g_malloc (len); - ImmGetCompositionString (himc, GCS_COMPATTR, buf, len); + len = ImmGetCompositionStringA (himc, GCS_COMPATTR, NULL, 0); + buf = g_alloca (len); + ImmGetCompositionStringA (himc, GCS_COMPATTR, buf, len); /* * schr and echr are pointer in utf8str. @@ -518,30 +456,10 @@ get_pango_attr_list (GtkIMContextIME *context_ime, const gchar *utf8str) /* * spos and epos are buf(attributes list of IME) position by * bytes. - * If UNICODE is defined, this value is same with UTF-8 offset. - * If it's not defined, this value is same with bytes position - * of locale encoded preedit string. - * + * Using the wide-char API, this value is same with UTF-8 offset. */ -#ifdef UNICODE - epos = g_utf8_pointer_to_offset (utf8str, echr); -#else /* not UNICODE */ - gchar *tmpstr; - GError *error = NULL; - - epos = spos; - tmpstr = g_locale_from_utf8 (schr, echr - schr, NULL, NULL, &error); - if (error) - { - g_warning ("%s", error->message); - g_error_free (error); - } - if (tmpstr) - { - epos += strlen (tmpstr); - g_free (tmpstr); - } -#endif /* not UNICODE */ + epos = g_utf8_pointer_to_offset (utf8str, echr); + /* * sidx and eidx are positions in utf8str by bytes. */ @@ -592,7 +510,6 @@ get_pango_attr_list (GtkIMContextIME *context_ime, const gchar *utf8str) sidx = eidx; } } - g_free (buf); } ImmReleaseContext (hwnd, himc); @@ -645,6 +562,9 @@ gtk_im_context_ime_focus_in (GtkIMContext *context) if (!GDK_IS_WINDOW (context_ime->client_window)) return; + /* swtich current context */ + context_ime->focus = TRUE; + hwnd = GDK_WINDOW_HWND (context_ime->client_window); himc = ImmGetContext (hwnd); if (!himc) @@ -679,9 +599,6 @@ gtk_im_context_ime_focus_in (GtkIMContext *context) /* warning? */ } - /* swtich current context */ - context_ime->focus = TRUE; - /* restore preedit context */ ImmSetConversionStatus (himc, context_ime->priv->conversion_mode, @@ -693,10 +610,10 @@ gtk_im_context_ime_focus_in (GtkIMContext *context) ImmSetOpenStatus (himc, TRUE); if (context_ime->preediting) { - ImmSetCompositionString (himc, - SCS_SETSTR, - context_ime->priv->comp_str, - context_ime->priv->comp_str_len, NULL, 0); + ImmSetCompositionStringW (himc, + SCS_SETSTR, + context_ime->priv->comp_str, + context_ime->priv->comp_str_len, NULL, 0); FREE_PREEDIT_BUFFER (context_ime); } } @@ -718,6 +635,9 @@ gtk_im_context_ime_focus_out (GtkIMContext *context) if (!GDK_IS_WINDOW (context_ime->client_window)) return; + /* swtich current context */ + context_ime->focus = FALSE; + hwnd = GDK_WINDOW_HWND (context_ime->client_window); himc = ImmGetContext (hwnd); if (!himc) @@ -737,20 +657,20 @@ gtk_im_context_ime_focus_out (GtkIMContext *context) FREE_PREEDIT_BUFFER (context_ime); context_ime->priv->comp_str_len - = ImmGetCompositionString (himc, GCS_COMPSTR, NULL, 0); + = ImmGetCompositionStringW (himc, GCS_COMPSTR, NULL, 0); context_ime->priv->comp_str = g_malloc (context_ime->priv->comp_str_len); - ImmGetCompositionString (himc, GCS_COMPSTR, - context_ime->priv->comp_str, - context_ime->priv->comp_str_len); + ImmGetCompositionStringW (himc, GCS_COMPSTR, + context_ime->priv->comp_str, + context_ime->priv->comp_str_len); context_ime->priv->read_str_len - = ImmGetCompositionString (himc, GCS_COMPREADSTR, NULL, 0); + = ImmGetCompositionStringW (himc, GCS_COMPREADSTR, NULL, 0); context_ime->priv->read_str = g_malloc (context_ime->priv->read_str_len); - ImmGetCompositionString (himc, GCS_COMPREADSTR, - context_ime->priv->read_str, - context_ime->priv->read_str_len); + ImmGetCompositionStringW (himc, GCS_COMPREADSTR, + context_ime->priv->read_str, + context_ime->priv->read_str_len); } ImmSetOpenStatus (himc, FALSE); @@ -790,9 +710,6 @@ gtk_im_context_ime_focus_out (GtkIMContext *context) "cannot find toplevel window."); } - /* swtich current context */ - context_ime->focus = FALSE; - /* clean */ ImmReleaseContext (hwnd, himc); } @@ -844,7 +761,6 @@ gtk_im_context_ime_set_use_preedit (GtkIMContext *context, context_ime->use_preedit = use_preedit; if (context_ime->preediting) { - /* FIXME */ HWND hwnd; HIMC himc; @@ -852,18 +768,26 @@ gtk_im_context_ime_set_use_preedit (GtkIMContext *context, himc = ImmGetContext (hwnd); if (!himc) return; + + /* FIXME: What to do? */ + + ImmReleaseContext (hwnd, himc); } } static void -gtk_im_context_ime_set_preedit_font (GtkIMContext *context, PangoFont *font) +gtk_im_context_ime_set_preedit_font (GtkIMContext *context) { GtkIMContextIME *context_ime; GtkWidget *widget = NULL; HWND hwnd; HIMC himc; + HKL ime = GetKeyboardLayout (0); + const gchar *lang; + gunichar wc; PangoContext *pango_context; + PangoFont *font; LOGFONT *logfont; g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context)); @@ -886,8 +810,69 @@ gtk_im_context_ime_set_preedit_font (GtkIMContext *context, PangoFont *font) if (!pango_context) goto ERROR_OUT; - if (!font) + /* Try to make sure we use a font that actually can show the + * language in question. + */ + + switch (PRIMARYLANGID (LOWORD (ime))) + { + case LANG_JAPANESE: + lang = "ja"; break; + case LANG_KOREAN: + lang = "ko"; break; + case LANG_CHINESE: + switch (SUBLANGID (LOWORD (ime))) + { + case SUBLANG_CHINESE_TRADITIONAL: + lang = "zh_TW"; break; + case SUBLANG_CHINESE_SIMPLIFIED: + lang = "zh_CN"; break; + case SUBLANG_CHINESE_HONGKONG: + lang = "zh_HK"; break; + case SUBLANG_CHINESE_SINGAPORE: + lang = "zh_SG"; break; + case SUBLANG_CHINESE_MACAU: + lang = "zh_MO"; break; + default: + lang = "zh"; break; + } + break; + default: + lang = ""; break; + } + + if (lang[0]) + { + /* We know what language it is. Look for a character, any + * character, that language needs. + */ + PangoLanguage *pango_lang = pango_language_from_string (lang); + PangoFontset *fontset = + pango_context_load_fontset (pango_context, + widget->style->font_desc, + pango_lang); + gunichar *sample = + g_utf8_to_ucs4 (pango_language_get_sample_string (pango_lang), + -1, NULL, NULL, NULL); + wc = 0x4E00; /* In all CJK languages? */ + if (sample != NULL) + { + int i; + + for (i = 0; sample[i]; i++) + if (g_unichar_iswide (sample[i])) + { + wc = sample[i]; + break; + } + g_free (sample); + } + font = pango_fontset_get_font (fontset, wc); + g_object_unref (fontset); + } + else font = pango_context_load_font (pango_context, widget->style->font_desc); + if (!font) goto ERROR_OUT; @@ -895,6 +880,8 @@ gtk_im_context_ime_set_preedit_font (GtkIMContext *context, PangoFont *font) if (logfont) ImmSetCompositionFont (himc, logfont); + g_object_unref (font); + ERROR_OUT: /* clean */ ImmReleaseContext (hwnd, himc); @@ -962,21 +949,17 @@ gtk_im_context_ime_message_filter (GdkXEvent *xevent, if (msg->lParam & GCS_RESULTSTR) { gsize len; - gpointer buf; gchar *utf8str = NULL; GError *error = NULL; - len = ImmGetCompositionString (himc, GCS_RESULTSTR, NULL, 0); - buf = g_alloca (len); - if (len > 0 && buf) + len = ImmGetCompositionStringW (himc, GCS_RESULTSTR, NULL, 0); + + if (len > 0) { - ImmGetCompositionString (himc, GCS_RESULTSTR, buf, len); -#ifdef UNICODE - len /= sizeof (gunichar2); - utf8str = g_utf16_to_utf8 (buf, len, NULL, NULL, &error); -#else /* not UNICODE */ - utf8str = g_locale_to_utf8 (buf, len, NULL, NULL, &error); -#endif /* not UNICODE */ + gpointer buf = g_alloca (len); + ImmGetCompositionStringW (himc, GCS_RESULTSTR, buf, len); + len /= 2; + utf8str = g_utf16_to_utf8 (buf, len, NULL, NULL, &error); if (error) { g_warning ("%s", error->message); @@ -1017,7 +1000,7 @@ gtk_im_context_ime_message_filter (GdkXEvent *xevent, { case IMN_SETOPENSTATUS: context_ime->opened = ImmGetOpenStatus (himc); - gtk_im_context_ime_set_preedit_font (context, NULL); + gtk_im_context_ime_set_preedit_font (context); break; default: diff --git a/modules/input/imime.c b/modules/input/imime.c index 6100876e5..75291e1a3 100644 --- a/modules/input/imime.c +++ b/modules/input/imime.c @@ -26,11 +26,11 @@ #include <string.h> static const GtkIMContextInfo ime_info = { - "win32ime", + "ime", "Windows IME", "gtk+", "", - "*", + "ja:ko:zh", }; static const GtkIMContextInfo *info_list[] = { |