[openi18n-im:01450] Re: patch to provide IME switching capability via gimlet
Federic Zhang <[email protected]> Thu, 30 Jun 2005 19:47:12 +0800
| Newsgroups | gmane.comp.internationalization.input-methods |
|---|---|
| Message-ID | <[email protected]> |
Hi, Today i committed all patches with some modification, see attached iiim-gimlet-list.diff for details. To demonstrate how LE can update accordingly to send IMEInfo to server and switch IME, the attached iiim-gimlet-twle.diff can help you understand how LE is changed. In summary, load IME.so in if_GetIfInfo(), provide IMEInfo array when handle the 'IF_SUPPORTED_IMEINFO' case and add code in if_le_SetSCValue () to do actual IME switching. Please note you need to update LEContext::toggle_conversion in LE.cpp to enable the code that set value with the SC_CLIENT_INPUT_METHOD_ENGINE attribute. I verified it works well with GTK+ based application in Chinese environment. Have fun! Let me know any problem you encounter and suggestion you have! P.s Again, iiimxcf should be synced with the same change that has been made in iiimgcf. -federic > > Please review and give comment. > > Making use of the exported IME info with the previous patch, client > gathers the list of IMEs which are enabled and sends to gimlet with > the existing mechanism by modifying the le_list, the modified le_list > would be 'lang:lename-imename1,imename2;lang2:lename2'. For better > reference, the original one is 'lang:lename;lang2:lename2'. > > The IME list is appended to the lename, which is separated by ','. > gimlet interprets the list and create corresponding ime menuitems under > language submenu. Upon user's selection on specific IME, the lename > client receives is 'lang:lename-imename', then it will make new global > API, iiimcf_set_input_method_name, to update the input method name to > 'lename-imename', as the content of IIIMP_ICATTRIBUTE_INPUT_METHOD_NAME > protocol, as a result, server can get the IME name without modifying the > underline protocol. In this way, the IME switching by LE can be achieved > with the minor effort. > > Please note that there still have some problems in gimlet side if more > than LE exists for one language, i will correct them later. > > -federic
iiim-gimlet-list.diff
(text/x-patch, 16.4 KB)
Index: iiimsf/src/LE.cpp
===================================================================
--- iiimsf/src/LE.cpp (revision 2714)
+++ iiimsf/src/LE.cpp (working copy)
@@ -507,8 +507,24 @@
)
{
IMArg arg;
+ const ICAttribute &attr = pic->get_icattr();
+ const u16string preq_imename = attr.get_inputengine();
+ const UTFCHAR *imename = preq_imename.c_str();
+
bind_imlexec(pimlex);
+#if ENABLE_IME_ENGINE_SWITCH
+ /* let LE to switch to current input method engine.
+ * FIXME - doing IME switching only when new input method entry in gimlet submenu list
+ * is selected.
+ */
+ if (imename)
+ {
+ IMSetArg (arg, SC_CLIENT_INPUT_METHOD_ENGINE, imename);
+ set_values (&arg, 1);
+ }
+#endif
+
if (flag)
IMSetArg(arg, SC_TRIGGER_ON_NOTIFY, 0);
else
Index: iiimsf/src/LEMgr.cpp
===================================================================
--- iiimsf/src/LEMgr.cpp (revision 2714)
+++ iiimsf/src/LEMgr.cpp (working copy)
@@ -371,8 +371,6 @@
if (preq_lang)
LOG_DEBUG("requested lang = %s", preq_lang->c_str());
- if (preq_imdesc)
- LOG_DEBUG("requested desc = %s", preq_imdesc->get_string()->c_str());
if (pxmllecfg != NULL && preq_lang != NULL && preq_imdesc == NULL) {
/* choose LE from the order described in XML config */
IIIMLEInfoList *list, *ltmp;
Index: iiimsf/src/IIIMPUtil.cpp
===================================================================
--- iiimsf/src/IIIMPUtil.cpp (revision 2714)
+++ iiimsf/src/IIIMPUtil.cpp (working copy)
@@ -154,7 +154,31 @@
}
break;
case IIIMP_ICATTRIBUTE_INPUT_METHOD_NAME:
- icattr.set_inputmethod(CONV_IIIMP_STR(pattr->value.input_method_name));
+ {
+ if (pattr->value.input_method_name)
+ {
+ IIIMP_card16 *imename = pattr->value.input_method_name->ptr;
+ IIIMP_card16 *lename, *p;
+ const char ime_delimiter = '-';
+ int i = 0, len = pattr->value.input_method_name->len;
+
+ /* check whether the name of input method engine is included,
+ * set it to inputengine if yes.
+ */
+ p = lename = imename;
+ while (i < len && *p && *p != ime_delimiter) { ++p; ++i;}
+ if (i != len && *p == ime_delimiter)
+ {
+ *p++ = 0x0;
+ imename = p;
+
+ icattr.set_inputengine (u16string (imename, len - i));
+ icattr.set_inputmethod (u16string (lename, i));
+ }
+ else
+ icattr.set_inputmethod(CONV_IIIMP_STR(pattr->value.input_method_name));
+ }
+ }
break;
#if 0
case IIIMP_ICATTRIBUTE_INPUT_METHOD:
Index: iiimsf/src/ICHandler.hh
===================================================================
--- iiimsf/src/ICHandler.hh (revision 2714)
+++ iiimsf/src/ICHandler.hh (working copy)
@@ -22,6 +22,7 @@
private:
u16string inputmethod;
u16string inputlanguage;
+ u16string inputengine;
IMCharSubsets charsubsets;
public:
@@ -29,6 +30,8 @@
{ inputmethod = imname; }
void set_inputlanguage(const u16string& langname)
{ inputlanguage = langname; }
+ void set_inputengine(const u16string& imename)
+ { inputengine = imename; }
void set_charsubsets(const IMCharSubsets &subsets)
{ charsubsets = subsets; }
@@ -36,6 +39,7 @@
const u16string& get_inputmethod() const { return inputmethod; }
const u16string& get_inputlanguage() const { return inputlanguage; }
+ const u16string& get_inputengine() const { return inputengine; }
IMCharSubsets& get_character_subsets() { return charsubsets; }
};
Index: include/iml/SunIMMthd.h
===================================================================
--- include/iml/SunIMMthd.h (revision 2714)
+++ include/iml/SunIMMthd.h (working copy)
@@ -425,7 +425,8 @@
SC_CLIENT_LOCALE = 200,
SC_CLIENT_CHARACTER_SUBSETS,
- SC_CLIENT_INPUT_METHOD_NAME
+ SC_CLIENT_INPUT_METHOD_NAME,
+ SC_CLIENT_INPUT_METHOD_ENGINE
} SC_Attribute;
typedef enum {
Index: include/iiimcf.h
===================================================================
--- include/iiimcf.h (revision 2714)
+++ include/iiimcf.h (working copy)
@@ -401,6 +401,11 @@
int *pinput_method_language_size,
IIIMCF_language **pplanguages
);
+extern IIIMF_status iiimcf_set_input_method_name(
+ IIIMCF_input_method input_method,
+ const IIIMP_card16 *input_method_name
+);
+
extern IIIMF_status iiimcf_get_input_method_imeinfos(
IIIMCF_input_method input_method,
int *pinput_method_imeinfo_size,
Index: gnome-im-switcher/src/quick-access-menu.c
===================================================================
--- gnome-im-switcher/src/quick-access-menu.c (revision 2714)
+++ gnome-im-switcher/src/quick-access-menu.c (working copy)
@@ -118,13 +118,18 @@
if (GTK_MENU_ITEM (menuitem))
{
gchar *iiim_lang;
- gchar *lename, *lang_le;
+ gchar *lename, *lang_le, *imename;
gchar *conversion_mode;
+ gchar *le_delimiter = ":";
iiim_lang = g_strdup(g_object_get_data (G_OBJECT (menuitem), "iiim-lang-name"));
- lename = g_strdup(gtk_label_get_text (GTK_LABEL (GTK_BIN (menuitem)->child)));
- lang_le = g_strconcat(iiim_lang, ":", lename, NULL);
+ lename = g_strdup(g_object_get_data (G_OBJECT (menuitem), "iiim-lename"));
+ if (lename)
+ lang_le = g_strconcat (iiim_lang, le_delimiter, lename, NULL);
+ else
+ lang_le = g_strdup (iiim_lang);
+
gimlet_iiim_language_set (gimlet, lang_le);
free(lang_le);
@@ -158,7 +163,7 @@
}
GSList*
-get_iiimf_lang_le_list (GimletWindow *gimlet, gchar *iiim_lang_name)
+get_iiimf_lang_le_list (GimletWindow *gimlet, gchar *iiim_lang_name, gchar ***imelist)
{
const gchar *im_delimiter = ";";
gchar **input_method_list = NULL;
@@ -167,21 +172,49 @@
if (gimlet->le_list == NULL)
return NULL;
+ *imelist = NULL;
+
input_method_list = g_strsplit (gimlet->le_list, im_delimiter, -1);
if (input_method_list)
{
gchar **p;
const gchar *le_delimiter = ":";
+ const gchar ime_delimiter = '-';
gchar **le = NULL;
+ gchar **list = g_new0 (char *, 10); /* impossible that one language has more than ten LEs */
+ int num_of_le = 0;
for (p = input_method_list; *p; p++)
{
+ char *pime;
+
le = g_strsplit (*p, le_delimiter, -1);
+
+ /* probably 'le' consists of lename and imename which are separated by ime_delimiter */
+ pime = le[1];
+ while (*pime && *pime != ime_delimiter) ++pime;
+ if (*pime == ime_delimiter) *pime++ = 0x0;
+
if ((strcmp ((gchar*)le[0], iiim_lang_name) == 0) &&
!(g_slist_find_custom (lelist, le[1], (GCompareFunc)string_comp)))
- lelist = g_slist_append (lelist, le[1]);
+ {
+ lelist = g_slist_append (lelist, le[1]);
+ if (*pime) list[num_of_le++] = pime;
+ }
}
+
+ if (num_of_le)
+ {
+ int i;
+
+ *imelist = g_new0 (gchar *, num_of_le + 1);
+
+ for (i = 0; i < num_of_le; ++i)
+ if (list[i]) *imelist[i] = g_strdup (list[i]);
+ }
+
+ g_free (list);
}
g_strfreev (input_method_list);
return lelist;
@@ -210,6 +243,10 @@
char *name;
char *mnemonic_label;
char *iiim_lang_name;
+ char **imelist;
+ gchar *ime_seperator = ",";
+ int i;
+
name = gimlet_language_get_name (tmp->data);
if (strcmp (name, "ASCII") == 0)
continue;
@@ -223,46 +260,87 @@
else
key_navi[0] += 1;
- GSList *lelist = get_iiimf_lang_le_list (gimlet, iiim_lang_name);
+ GSList *lelist = get_iiimf_lang_le_list (gimlet, iiim_lang_name, &imelist);
int len = g_slist_length (lelist);
- if (len > 1)
+ if (len == 1 && !imelist)
{
+ g_object_set_data (G_OBJECT (menuitem), "iiim-lang-name",
+ iiim_lang_name);
+ g_object_set_data (G_OBJECT (menuitem), "iiim-display-name",
+ name);
+ g_object_set_data (G_OBJECT (menuitem), "iiim-lename",
+ lelist->data);
+ g_signal_connect (GTK_MENU_ITEM (menuitem), "activate",
+ G_CALLBACK (activate_cb), gimlet);
+ }
+ else
+ {
GtkWidget *le_submenu;
GtkWidget *le_submenu_item;
+ GSList *le;
le_submenu = gtk_menu_new ();
- GSList *le;
- for (le = lelist; le; le = g_slist_next (le))
+ for (i = 0, le = lelist; le; le = g_slist_next (le), ++i)
{
- le_submenu_item = gtk_menu_item_new_with_label (le->data);
- g_object_set_data (G_OBJECT (le_submenu_item), "iiim-lang-name",
- iiim_lang_name);
- g_object_set_data (G_OBJECT (le_submenu_item), "iiim-display-name",
- name);
- gtk_menu_shell_append (GTK_MENU_SHELL (le_submenu), le_submenu_item);
- g_signal_connect (le_submenu_item, "activate",
- G_CALLBACK (activate_cb), gimlet);
- gtk_widget_show (le_submenu_item);
+ if (imelist && imelist[i])
+ {
+ gchar **p, **ime_array = g_strsplit (imelist[i], ime_seperator, -1);
+
+ for (p = ime_array; *p; ++p)
+ {
+ gchar *lename = g_new0 (char, strlen (le->data) + strlen (*p) + 2);
+ gchar *ime_delimiter = "-";
+
+ g_sprintf (lename, "%s%s%s", (char *)le->data, ime_delimiter, *p);
+
+ /* here 'p' refers to the name of input method engine in UTF8 */
+ le_submenu_item = gtk_menu_item_new_with_label (*p);
+ g_object_set_data (G_OBJECT (le_submenu_item), "iiim-lang-name",
+ iiim_lang_name);
+ g_object_set_data (G_OBJECT (le_submenu_item), "iiim-display-name",
+ name);
+ g_object_set_data (G_OBJECT (le_submenu_item), "iiim-lename",
+ lename);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (le_submenu), le_submenu_item);
+ g_signal_connect (le_submenu_item, "activate",
+ G_CALLBACK (activate_cb), gimlet);
+ gtk_widget_show (le_submenu_item);
+ }
+ }
+ else
+ {
+ /* le->data stands for the name of LE */
+ le_submenu_item = gtk_menu_item_new_with_label (le->data);
+ g_object_set_data (G_OBJECT (le_submenu_item), "iiim-lang-name",
+ iiim_lang_name);
+ g_object_set_data (G_OBJECT (le_submenu_item), "iiim-display-name",
+ name);
+ g_object_set_data (G_OBJECT (le_submenu_item), "iiim-lename",
+ le->data);
+ gtk_menu_shell_append (GTK_MENU_SHELL (le_submenu), le_submenu_item);
+ g_signal_connect (le_submenu_item, "activate",
+ G_CALLBACK (activate_cb), gimlet);
+ gtk_widget_show (le_submenu_item);
+ }
}
+
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), le_submenu);
gtk_widget_show (le_submenu);
}
- else if (len == 1)
- {
- g_object_set_data (G_OBJECT (menuitem), "iiim-lang-name",
- iiim_lang_name);
- g_object_set_data (G_OBJECT (menuitem), "iiim-display-name",
- name);
- g_signal_connect (GTK_MENU_ITEM (menuitem), "activate",
- G_CALLBACK (activate_cb), gimlet);
- }
g_slist_free (lelist);
+ if (imelist)
+ {
+ for (i=0; i < len; ++i) if (imelist[i]) g_free (imelist[i]);
+
+ g_free (imelist);
+ }
+
gtk_widget_show (menuitem);
gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);
-
}
/* add separator */
Index: lib/iiimcf/input-method.c
===================================================================
--- lib/iiimcf/input-method.c (revision 2714)
+++ lib/iiimcf/input-method.c (working copy)
@@ -296,6 +296,20 @@
}
IIIMF_status
+iiimcf_set_input_method_name (
+ IIIMCF_input_method input_method,
+ const IIIMP_card16* input_method_name
+)
+{
+ IIIMCF_input_method_rec *pi = (IIIMCF_input_method_rec*) input_method;
+
+ if (pi->imname) free (pi->imname);
+ pi->imname = input_method_name;
+
+ return IIIMF_STATUS_SUCCESS;
+}
+
+IIIMF_status
iiimcf_get_input_method_imeinfos(
IIIMCF_input_method input_method,
int *pinput_method_imeinfo_size,
Index: lib/iiimcf/libiiimcf.sym
===================================================================
--- lib/iiimcf/libiiimcf.sym (revision 2714)
+++ lib/iiimcf/libiiimcf.sym (working copy)
@@ -27,6 +27,7 @@
iiimcf_get_input_method_desc
iiimcf_get_input_method_languages
iiimcf_get_input_method_imeinfos
+iiimcf_set_input_method_name
iiimcf_get_downloaded_object_descriptor
iiimcf_get_downloaded_object_filename
iiimcf_get_downloaded_objects
Index: iiimgcf/gtkimcontextiiim.c
===================================================================
--- iiimgcf/gtkimcontextiiim.c (revision 2714)
+++ iiimgcf/gtkimcontextiiim.c (working copy)
@@ -352,6 +352,49 @@
NULL);
}
+static IIIMP_card16 *
+format_utf8_string (char *utf8str)
+{
+ return (utf8str != NULL ?
+ g_utf8_to_utf16 (utf8str, -1, NULL, NULL, NULL) :
+ NULL);
+}
+
+static char *
+get_imelist (int nimeinfos, IIIMCF_imeinfo_rec **ppimeinfos)
+{
+ int i;
+ char *imelist = NULL, *p;
+
+ imelist = g_new0 (char, 1024);
+
+ p = imelist;
+ for (i = 0; i < nimeinfos; ++i)
+ {
+ char *imename = NULL;
+ char ime_seperator = ',';
+
+ if (!ppimeinfos[i]->enable) continue;
+
+ if (i) *p++ = ime_seperator;
+
+ imename = format_iiimcf_string (ppimeinfos[i]->imename);
+
+ strcpy (p, imename); /* imename shouldn't be NULL */
+ p += strlen (imename);
+
+ g_free (imename);
+ }
+
+ if (*imelist == 0)
+ {
+ g_free (imelist);
+ imelist = NULL;
+ }
+
+ return imelist;
+}
+
/*
* Get IM List
*/
@@ -366,9 +409,13 @@
IIIMCF_input_method *input_methods;
IIIMF_status st;
const char *separator = ";";
+ const char *ime_delimiter = "-";
gsize separator_len;
gchar *le_list, *ptr;
char *lename = NULL;
+ char *imelist;
+ IIIMCF_imeinfo_rec **ppimeinfos;
+ int nimeinfos;
separator_len = strlen (separator);
@@ -395,10 +442,27 @@
lename = format_iiimcf_string (u16hrn);
+ st = iiimcf_get_input_method_imeinfos (input_methods[i],
+ &nimeinfos, &ppimeinfos);
+ if (st != IIIMF_STATUS_SUCCESS)
+ goto error;
+
+ /* append the list of IME name to lename */
+ if (nimeinfos && ppimeinfos && (imelist = get_imelist (nimeinfos, ppimeinfos)))
+ {
+ char *tmp_lename = g_new0 (char, strlen (lename) + strlen (imelist) + 2);
+
+ sprintf (tmp_lename, "%s%s%s", lename, ime_delimiter, imelist);
+ g_free (lename);
+ lename = tmp_lename;
+ g_free (imelist);
+ }
+
st = iiimcf_get_input_method_languages (input_methods[i],
&nlangs, &plangs);
if (st != IIIMF_STATUS_SUCCESS)
goto error;
+
for (j = 0; j < nlangs; j++)
{
st = iiimcf_get_language_id (plangs[j],
@@ -428,6 +492,22 @@
&u16hrn, &u16domain);
lename = format_iiimcf_string (u16hrn);
+ st = iiimcf_get_input_method_imeinfos (input_methods[i],
+ &nimeinfos, &ppimeinfos);
+ if (st != IIIMF_STATUS_SUCCESS)
+ goto error;
+
+ /* append the list of IME name to lename */
+ if (nimeinfos && ppimeinfos && (imelist = get_imelist (nimeinfos, ppimeinfos)))
+ {
+ char *tmp_lename = g_new0 (char, strlen (lename) + strlen (imelist) + 2);
+
+ sprintf (tmp_lename, "%s%s%s", lename, ime_delimiter, imelist);
+ g_free (lename);
+ lename = tmp_lename;
+ g_free (imelist);
+ }
+
st = iiimcf_get_input_method_languages (input_methods[i],
&nlangs, &plangs);
if (st != IIIMF_STATUS_SUCCESS)
@@ -2645,6 +2725,11 @@
if (le_name != NULL)
{
char *idname = NULL;
+ /* probably le_name consists of 'lename' and 'imename' which are separated by '-' */
+ const char *ime_delimiter = "-";
+ char **le_ime = g_strsplit (le_name, ime_delimiter, -1);
+ char *lename = le_ime[0], *imename = le_ime[1];
+
st = iiimcf_get_supported_input_methods (iiim, &n, &pims);
if (st != IIIMF_STATUS_SUCCESS)
return;
@@ -2656,8 +2741,15 @@
return;
idname = format_iiimcf_string (u16hrn);
- if (idname != NULL && strcmp (le_name, idname) == 0)
+ if (idname != NULL && strcmp (lename, idname) == 0)
{
+ /* update the pims[i]->imname with the new imname that contains imename */
+ if (imename)
+ {
+ IIIMP_card16 *imname = format_utf8_string (le_name);
+ iiimcf_set_input_method_name (pims[i], imname);
+ }
+
g_free (idname);
found_le = TRUE;
break;
@@ -2667,6 +2759,7 @@
idname = NULL;
}
}
+ g_free (le_ime);
}
/* save conversion mode to restore this after switching */
st = iiimcf_get_current_conversion_mode (context_iiim->context,
iiim-gimlet-twle.diff
(text/x-patch, 6 KB)
Index: leif/tch_le_sun/include/sunim/SunIM.h
===================================================================
--- leif/tch_le_sun/include/sunim/SunIM.h (revision 2730)
+++ leif/tch_le_sun/include/sunim/SunIM.h (working copy)
@@ -51,6 +51,17 @@
UTFCHAR *name; /* HRN */
} IMHRN, *IMHRNList;
+typedef struct IMEINFO_ {
+ Bool enable;
+ char *ime_id; /* in ASCII */
+ UTFCHAR *imename;
+ UTFCHAR *version; /* optional */
+ UTFCHAR *description; /* optional */
+ UTFCHAR *author; /* optional */
+ UTFCHAR *copyright; /* optional */
+} IMEInfo;
+
+
typedef IMHRN IMLEName;
typedef IMHRN IMLocale;
Index: leif/tch_le_sun/include/sunim/SunIMMthd.h
===================================================================
--- leif/tch_le_sun/include/sunim/SunIMMthd.h (revision 2730)
+++ leif/tch_le_sun/include/sunim/SunIMMthd.h (working copy)
@@ -244,6 +244,7 @@
IMLEName *lename;
IMLocale *locale_list;
+ IMEInfo *imeinfo_list;
IMObjectDescriptorStruct *object_list;
Bool xsunim;
Bool need_thread_lock;
@@ -277,8 +278,13 @@
#endif /* USE_SUNIM_ADAPTER */
/* EIMIL extension */
- IF_EIMIL_HANDLE = 0x100
+ IF_EIMIL_HANDLE = 0x100,
+ /* LE extension */
+ IF_SUPPORTED_KEYRELEASE,
+ IF_SUPPORTED_IMEINFO
+
+
} IF_Attribute;
typedef enum {
@@ -295,7 +301,8 @@
SC_CLIENT_LOCALE = 200,
SC_CLIENT_CHARACTER_SUBSETS,
- SC_CLIENT_INPUT_METHOD_NAME
+ SC_CLIENT_INPUT_METHOD_NAME,
+ SC_CLIENT_INPUT_METHOD_ENGINE
} SC_Attribute;
typedef enum {
Index: leif/tch_le_sun/src/leif/le_interface.c
===================================================================
--- leif/tch_le_sun/src/leif/le_interface.c (revision 2714)
+++ leif/tch_le_sun/src/leif/le_interface.c (working copy)
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <iconv.h>
#include "le_object.h"
#include "le_info.h"
@@ -52,6 +53,12 @@
if (le_object == NULL)
return;
+ if (le_info == NULL) {
+ le_info = (LeInfoRec *) le_info_new();
+ if (le_info == NULL)
+ return;
+ }
+
for (i = 0; i < num_args; i++, args++) {
switch (args->id) {
case IF_VERSION:
@@ -72,6 +79,60 @@
case IF_NEED_THREAD_LOCK:
args->value = (IMArgVal) LE_OK;
break;
+ case IF_SUPPORTED_IMEINFO:
+ if (le_info && le_info->ime_modules)
+ {
+ ImeModuleContextRec **imm = le_info->ime_modules;
+ iconv_t *cd = iconv_open ("UTF-8", "BIG5");
+ iconv_t *ucd = iconv_open ("UTF-16", "UTF-8");
+ IMEInfo *info = (IMEInfo *)malloc (sizeof (IMEInfo) * (le_info->num_ime_modules + 1));
+ int k;
+
+ memset (info, 0, sizeof (IMEInfo) * (le_info->num_ime_modules + 1));
+ for (k=0; k < le_info->num_ime_modules; ++k)
+ {
+ ImeInfoRec *imeinfo = imm[k]->ime_module->info;
+ char *utfname;
+
+ info[k].enable = imm[k]->enabled;
+ info[k].ime_id = strdup (imeinfo->uuid);
+ if (imeinfo->encoding == ENCODE_UTF8)
+ {
+ utfname = strdup (imeinfo->name);
+ }
+ else
+ {
+ char buf[256];
+ char *inbuf = imeinfo->name;
+ int inbytesleft = strlen (imeinfo->name);
+ char *outbuf = buf;
+ int outbytesleft = 256;
+
+ memset (buf, 0, 256);
+
+ iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+
+ utfname = strdup (buf);
+ }
+{
+ UTFCHAR *buf = malloc (sizeof (UTFCHAR) * 256);
+ char *inbuf = utfname;
+ int inbytesleft = strlen (utfname);
+ char *outbuf = buf;
+ int outbytesleft = 256;
+
+ memset (buf, 0, 256 * sizeof (UTFCHAR));
+
+ iconv (ucd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+
+ info[k].imename = buf;
+}
+ }
+ iconv_close (cd);
+ iconv_close (ucd);
+ args->value = (IMArgVal)info;
+ }
+ break;
default:
break;
}
@@ -193,6 +254,59 @@
le_session_set_client_encoding(s, ENCODE_BIG5HKSCS);
}
break;
+ case SC_CLIENT_INPUT_METHOD_ENGINE:
+ if (le_info && le_info->ime_modules)
+ {
+ iconv_t *ucd = iconv_open ("UTF-8", "UTF-16");
+ iconv_t *cd = iconv_open ("UTF-8", "BIG5");
+ ImeModuleContextRec **imm = le_info->ime_modules;
+ char utfname[256];
+ ImeModuleRec *ime = NULL;
+memset (utfname, 0, 256);
+{
+ char *inbuf = p->value;
+ int inbytesleft = 0;
+ char *outbuf = utfname;
+ int outbytesleft = 256;
+ UTFCHAR *pu = p->value;
+while (*pu) { inbytesleft +=2; ++pu; }
+
+ iconv (ucd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+printf ("###TWLE encoding name in UTF8 %s\n", utfname);
+}
+ for (i=0; i < le_info->num_ime_modules; ++i)
+ {
+ char buf[256];
+ ImeInfoRec *info = imm[i]->ime_module->info;
+
+ memset (buf, 0, 256);
+ if (info->encoding != ENCODE_UTF8)
+ {
+ char *inbuf = info->name;
+ int inbytesleft = strlen (info->name);
+ char *outbuf = buf;
+ int outbytesleft = 256;
+
+ iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+ }
+ else
+ strcpy (buf, info->name);
+
+ if (!strncmp (buf, utfname, strlen (buf)))
+ {
+ ime = imm[i]->ime_module;
+ printf ("TWLE: found ime module %s\n", buf);
+ break;
+ }
+ }
+
+ if (ime)
+ le_session_switch_to_new_ime_module (s, ime);
+ iconv_close (cd);
+ iconv_close (ucd);
+ }
+
+ break;
default:
break;
}