Back to index

im-sdk  12.3.91
iiimpIM.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 
00043 #include "iiimpIM.h"
00044 #include "iiimpIC.h"
00045 #include "iiimpAuxP.h"
00046 #include <stdio.h>
00047 #include <unistd.h>
00048 #include <locale.h>
00049 #include <langinfo.h>
00050 #include <ctype.h>
00051 #include "trace_message.h"
00052 #include "iiimpSwitcher.h"
00053 
00054 #include "XIM.h"            /* for XNMultiLingualInput */
00055 
00056 static XIMStyle im_styles[] = {
00057        XIMPreeditCallbacks |XIMStatusCallbacks,
00058        XIMPreeditCallbacks | XIMStatusArea,
00059        XIMPreeditCallbacks | XIMStatusNothing,
00060        XIMPreeditPosition  | XIMStatusCallbacks,
00061        XIMPreeditPosition  | XIMStatusArea,
00062        XIMPreeditPosition  | XIMStatusNothing,
00063        XIMPreeditArea      | XIMStatusCallbacks,
00064        XIMPreeditArea      | XIMStatusArea,
00065        XIMPreeditArea      | XIMStatusNothing,
00066        XIMPreeditNothing   | XIMStatusCallbacks,
00067        XIMPreeditNothing   | XIMStatusArea,
00068        XIMPreeditNothing   | XIMStatusNothing,
00069        XIMPreeditCallbacks | XIMStatusNone,
00070        XIMPreeditPosition  | XIMStatusNone,
00071        XIMPreeditArea      | XIMStatusNone,
00072        XIMPreeditNothing   | XIMStatusNone,
00073        XIMPreeditNone       | XIMStatusCallbacks,
00074        XIMPreeditNone      | XIMStatusArea,
00075        XIMPreeditNone      | XIMStatusNothing,
00076        XIMPreeditNone      | XIMStatusNone,
00077 };
00078 
00079 /* For Interface for libX11 */
00080 extern Status IIIMP_OpenIM_SWITCH(
00081     XIM xim,
00082     XLCd lcd,
00083     Display *dpy
00084 );
00085 
00086 static Status IIIMP_CloseIM(
00087     XIM xim
00088 );
00089 
00090 extern char* IIIMP_SetIMValues(
00091     XIM xim,
00092     XIMArg* arg
00093 );
00094 extern char* IIIMP_GetIMValues(
00095     XIM xim,
00096     XIMArg* arg
00097 );
00098 
00099 static XIC IIIMP_CreateIC(
00100     XIM xim,
00101     XIMArg* arg
00102 );
00103 extern int _Ximp_ctstombs(
00104     XIM       xim,
00105     char *from,
00106     int       from_len,
00107     char *to,
00108     int       to_len,
00109     Status *state
00110 );
00111 extern int _Ximp_ctstowcs(
00112     XIM       xim,
00113     char *from,
00114     int from_len,
00115     wchar_t *to,
00116     int to_len,
00117     Status *state
00118 );
00119 
00120 extern IIIMF_status IMCreateHandle(XimCommon im);
00121 
00122 static XIMMethods
00123 get_iiimp_im_methods()
00124 {
00125   static XIMMethodsRec imm;
00126   if (!imm.close) {
00127     imm.close = IIIMP_CloseIM;
00128     imm.set_values = IIIMP_SetIMValues;
00129     imm.get_values = IIIMP_GetIMValues;
00130     imm.create_ic = IIIMP_CreateIC;
00131     imm.ctstombs = _Ximp_ctstombs;
00132     imm.ctstowcs = _Ximp_ctstowcs;
00133   }
00134   return &imm;
00135 }
00136 
00137 
00138 static Status SWITCH_CloseIM(
00139     XIM xim
00140 );
00141 
00142 static XIMMethods
00143 get_switch_im_methods()
00144 {
00145   static XIMMethodsRec imm;
00146   if (!imm.close) {
00147     imm.close = SWITCH_CloseIM;
00148   }
00149   return &imm;
00150 }
00151 
00152 /********************************************************************************
00153                     IM Language and X locale name
00154  ********************************************************************************/
00155 
00156 static im_locale_pair g_locale_list[] = {
00157   {(char*)"ja", (char*)"ja"},
00158   {(char*)"ja", (char*)"ja_JP.EUC-JP"},
00159   {(char*)"ja", (char*)"ja_JP.eucJP"},
00160   {(char*)"ja", (char*)"ja_JP.PCK"},
00161   {(char*)"ja", (char*)"ja_JP.UTF-8"},
00162   {(char*)"ko", (char*)"ko"},
00163   {(char*)"ko", (char*)"ko.UTF-8"},
00164   {(char*)"ko", (char*)"ko_KR.UTF-8"},
00165   {(char*)"ko", (char*)"ko_KR.EUC-KR"},
00166   {(char*)"ko", (char*)"ko_KR.EUC"},
00167   {(char*)"zh_CN", (char*)"zh.UTF-8"},
00168   {(char*)"zh_CN", (char*)"zh_CN.UTF-8"},
00169   {(char*)"zh_CN", (char*)"zh_CN.EUC"},
00170   {(char*)"zh_CN", (char*)"zh_CN.GB18030"},
00171   {(char*)"zh_CN", (char*)"zh_CN"},
00172   {(char*)"zh_CN", (char*)"zh"},
00173   {(char*)"zh_CN", (char*)"zh.GBK"},
00174   {(char*)"zh_CN", (char*)"zh_CN.GBK"},
00175   {(char*)"zh_TW", (char*)"zh_TW.UTF-8"},
00176   {(char*)"zh_TW", (char*)"zh_TW.BIG5"},
00177   {(char*)"zh_TW", (char*)"zh_TW.EUC-TW"},
00178   {(char*)"zh_TW", (char*)"zh_TW.EUC"},
00179   {(char*)"zh_TW", (char*)"zh_TW"},
00180   {(char*)"zh_HK", (char*)"zh_HK.BIG5HK"},
00181   {(char*)"zh_HK", (char*)"zh_HK.UTF-8"},
00182   {(char*)"zh_HK", (char*)"zh_HK"},
00183   {(char*)"th_TH", (char*)"th"},
00184   {(char*)"th_TH", (char*)"th_TH"},
00185   {(char*)"th_TH", (char*)"th_TH.UTF-8"},
00186   {(char*)"th_TH", (char*)"th_TH.TIS620"},
00187   {(char*)"th_TH", (char*)"th_TH.ISO8859-11"},
00188   {0, 0}
00189 };
00190 
00191 #define IMLIBDIR IIIMLIBDIR
00192 
00193 #define       iscomment(ch) ((ch) == '\0' || (ch) == '#')
00194 
00195 static int
00196 parseLine(
00197     char *line,
00198     char **argv,
00199     size_t argsize
00200 )
00201 {
00202     int argc = 0;
00203     char *p = line;
00204 
00205     while (argc < argsize) {
00206        while (isspace(*p)) {
00207            ++p;
00208        }
00209        if (iscomment(*p)){
00210            break;
00211        }
00212        argv[argc++] = p;
00213        while (!isspace(*p)) {
00214            ++p;
00215        }
00216        if (iscomment(*p)) {
00217            break;
00218        }
00219        *p++ = '\0';
00220     }
00221     return argc;
00222 }
00223 
00224 static void
00225 parseAliasFile(
00226     XimCommon im,
00227     FILE *fp
00228 )
00229 {
00230     char buf[BUFSIZ];
00231     size_t alias_num = 0;
00232     im_locale_pair *lang_alias = 0;
00233 
00234     while (fgets(buf, BUFSIZ, fp) != NULL) {
00235        char *p = buf;
00236        int n;
00237        char *args[2];
00238        while (isspace(*p))
00239            ++p;
00240        if (iscomment(*p))
00241            continue;
00242 
00243        n = parseLine(p, args, 2);
00244        if (n == 2) {
00245            if (alias_num == 0)
00246               lang_alias = Xmalloc(sizeof(im_locale_pair));
00247            else
00248               lang_alias = Xrealloc((void*)lang_alias,
00249                                   sizeof(im_locale_pair) * (alias_num + 1));
00250            if (!lang_alias)
00251               return;
00252            lang_alias[alias_num].alias = strdup(args[0]);
00253            lang_alias[alias_num].canonical = strdup(args[1]);
00254            alias_num++;
00255        }
00256     }
00257     /* null terminate */
00258     lang_alias = Xrealloc((void*)lang_alias,
00259                        sizeof(im_locale_pair) * (alias_num + 1));
00260     if (!lang_alias)
00261        return;
00262     lang_alias[alias_num].alias = 0;
00263     lang_alias[alias_num].canonical = 0;
00264 
00265     XIM_IIIMP(im, lang_alias) = lang_alias;
00266     return;
00267 }
00268 
00269 static void
00270 free_langalias(
00271     XimCommon im
00272 )
00273 {
00274     im_locale_pair *p1, *p;
00275 
00276     p1 = XIM_IIIMP(im, lang_alias);
00277     if (p1) {
00278        for (p = p1; p->canonical; p++) {
00279            if (p->alias) Xfree(p->alias);
00280            if (p->canonical) Xfree(p->canonical);
00281        }
00282        Xfree(p1);
00283     }
00284 }
00285 
00286 static char*
00287 getIMLangName(
00288     XimCommon im,
00289     const char *src_name
00290 )
00291 {
00292     im_locale_pair *p;
00293 
00294     if (!XIM_IIIMP(im, lang_alias)) {
00295        /*  open 'alias' file*/
00296        FILE *fp;
00297        const char *dir = getenv ("IIIMFHOME");
00298        const char *base = "language.alias";
00299 
00300        if (dir == NULL)
00301            dir = IMLIBDIR;
00302 
00303        {
00304            size_t dir_len = strlen (dir);
00305            size_t base_len = strlen (base);
00306            size_t name_len = dir_len + 1 + base_len + 1;
00307 
00308            char *file_name = Xmalloc(name_len + 1);
00309            if (file_name) {
00310               strncpy(file_name, dir, dir_len);
00311               file_name[dir_len] = '/';
00312               file_name[dir_len + 1] = 0;
00313               strncat(file_name, base, base_len);
00314               file_name[dir_len + 1 + base_len] = 0;
00315 
00316               if ((fp = fopen (file_name, "r"))) {
00317                   parseAliasFile(im, fp);
00318                   fclose(fp);
00319               }
00320                 Xfree(file_name);
00321            }
00322        }
00323     }
00324 
00325     p = (XIM_IIIMP(im, lang_alias) ? XIM_IIIMP(im, lang_alias) : g_locale_list);
00326 
00327     for (; p->canonical != 0; p++)
00328        if (!strcmp(p->alias, src_name))
00329            return p->canonical;
00330 
00331     return (char*)0;
00332 }
00333 
00334 char*
00335 im_canonicalize_langname(
00336     XimCommon im
00337 )
00338 {
00339     char *canonical, *p;
00340     const char *localename = setlocale(LC_CTYPE, NULL);
00341 
00342     canonical = getIMLangName(im, localename);
00343     if (canonical) return strdup(canonical);
00344 
00345     canonical = strdup(localename);
00346     if (!canonical) return NULL;
00347     p = strchr(canonical, '.');
00348     if (p) *p = '\0';
00349 
00350     return canonical;
00351 }
00352 
00353 IIIMCF_language
00354 get_IM_language(
00355     XimCommon im
00356 )
00357 {
00358     int i, n;
00359     const char *ll;
00360     char *lang;
00361     char *p;
00362     IIIMCF_language *plangs;
00363     IIIMF_status st;
00364 
00365     if (XIM_IIIMP(im, primary_locale)) {
00366        lang = strdup(XIM_IIIMP(im, primary_locale));
00367     } else {
00368        lang = im_canonicalize_langname(im);
00369     }
00370 
00371     if (!lang) return NULL;
00372 
00373     if (iiimcf_get_supported_languages(XIM_IIIMP(im, handle), &n, &plangs)
00374        != IIIMF_STATUS_SUCCESS)
00375        return NULL;
00376     for (i = 0; i < n; i++) {
00377        st = iiimcf_get_language_id(plangs[i], &ll);
00378        if (st != IIIMF_STATUS_SUCCESS)
00379            continue;
00380        if (strcmp(lang, ll) == 0) {
00381            free(lang);
00382            return plangs[i];
00383        }
00384     }
00385     /* try to find the supported language again with no charset locale. */
00386     p = strchr (lang, '@');
00387     if (p)
00388        *p = 0;
00389     p = strchr (lang, '.');
00390     if (p)
00391        *p = 0;
00392 
00393     for (i = 0; i < n; i++) {
00394        st = iiimcf_get_language_id(plangs[i], &ll);
00395        if (st != IIIMF_STATUS_SUCCESS)
00396            continue;
00397        if (strcmp(lang, ll) == 0) {
00398            free(lang);
00399            return plangs[i];
00400        }
00401     }
00402     /* finally try to take care of the locale, such as en */
00403     p = strchr (lang, '_');
00404     if (p)
00405        *p = 0;
00406 
00407     for (i = 0; i < n; i++) {
00408        st = iiimcf_get_language_id(plangs[i], &ll);
00409        if (st != IIIMF_STATUS_SUCCESS)
00410            continue;
00411        if (strcmp(lang, ll) == 0) {
00412            free(lang);
00413            return plangs[i];
00414        }
00415     }
00416     free(lang);
00417 
00418       /*
00419        still cannot find a match. Just take one for "en" as
00420        a default.
00421       */
00422     for (i = 0; i < n; i++) {
00423        st = iiimcf_get_language_id (plangs[i], &ll);
00424        if (st != IIIMF_STATUS_SUCCESS)
00425            continue;
00426        if (strncmp (ll, "en", 2) == 0)
00427            return plangs[i];
00428     }
00429 
00430     return NULL;
00431 }
00432 
00433 /********************************************************************************
00434                                main part
00435  ********************************************************************************/
00436 
00437 static int inited = 0;
00438 
00439 static void
00440 initialize()
00441 {
00442     if (inited == 0)
00443        iiimcf_initialize(IIIMCF_ATTR_NULL);
00444     inited++;
00445 }
00446 
00447 static void
00448 uninitialize()
00449 {
00450     if (inited == 0) return;
00451     inited--;
00452     if (inited == 0)
00453        iiimcf_finalize();
00454 }
00455 
00456 static Status
00457 IIIMP_CloseIM(
00458     XIM xim
00459 )
00460 {
00461     CommonCloseIM(xim);
00462     SWITCH_CloseIM(xim);
00463     
00464     return True;
00465 }
00466 
00467 static XIC
00468 IIIMP_CreateIC(
00469     XIM xim,
00470     XIMArg *arg
00471 )
00472 {
00473     return (XIC)CreateIC((XimCommon)xim, arg);
00474 }
00475 
00476 char*
00477 IIIMP_SetIMValues(
00478     XIM xim,
00479     XIMArg *arg
00480 )
00481 {
00482     XIMArg *p;
00483     char *return_name = NULL;
00484     XimCommon im = (XimCommon)xim;
00485 
00486     if (!xim) return arg->name;    /* nothing to do */
00487 
00488     for (p = arg; p->name != NULL; p++) {
00489        if (!strcmp(p->name, "engineInterfaceName")) {
00490            XIM_IIIMP(im, engine_name) = (char*)p->value;
00491        } else if (!strcmp(p->name, "applicationType")) {
00492            IMChangeClientType(im, (char*) p->value);
00493        } else if (!strcmp(p->name, "defaultFontName")) {
00494            XIM_IIIMP(im, default_font_name) = (char*)p->value;
00495        } else if (!strcmp(p->name, "primaryLocale")) {
00496            XIM_IIIMP(im, primary_locale) = (char*)p->value;
00497        } else if (!strcmp(p->name, XNDestroyCallback)) {
00498            im->core.destroy_callback.client_data = 
00499               ((XIMCallback *)p->value)->client_data;
00500            im->core.destroy_callback.callback = 
00501               ((XIMCallback *)p->value)->callback;
00502        } else {
00503            return_name = arg->name;
00504            break;
00505        }
00506     }
00507 
00508     return return_name;
00509 }
00510 
00511 extern void UpdateIMCharacterSubset(XimCommon);
00512 
00513 char*
00514 IIIMP_GetIMValues(
00515     XIM xim,
00516     XIMArg *arg
00517 )
00518 {
00519     XIMArg *p;
00520     int i;
00521     XimCommon im = (XimCommon)xim;
00522 
00523     if (!xim) return arg->name;    /* nothing to do */
00524 
00525     for (p = arg; p->name != NULL; p++) {
00526        TRACE_MESSAGE('v', ("  %s\n", p->name));
00527        if (!strcmp(p->name, XNQueryInputStyle)) {
00528            XIMStyles **value;
00529            XIMStyles *styles;
00530            size_t count = sizeof(im_styles)/sizeof(im_styles[0]);
00531            if ((styles = (XIMStyles*)
00532                Xmalloc(sizeof(XIMStyles) +
00533                       sizeof(XIMStyle) * count)) == NULL) {
00534               break;
00535            }
00536            styles->count_styles = count;
00537            styles->supported_styles = (XIMStyle *)(&styles[1]);
00538 
00539            for (i = 0; i < (int)(styles->count_styles); i++) {
00540               styles->supported_styles[i] = im_styles[i];
00541            }
00542            value = (XIMStyles **)p->value;
00543            *value = styles;
00544        } else if (!strcmp(p->name, XNMultiLingualInput)) {
00545            *((Bool*)(p->value)) = ((XimCommon)xim)->isUnicode;
00546        } else if (!strcmp(p->name, XNQueryExtensionVersion)) {
00547            *((int*)(p->value)) = XIIIMP_MULTILINGUAL_EXTENSION_VERSION;
00548        } else if (!strcmp(p->name, XNQueryUnicodeCharacterSubset)) {
00549            XIMUnicodeCharacterSubsets **value;
00550            XIMUnicodeCharacterSubsets *sub_sets;
00551            XIMUnicodeCharacterSubsets *im_subset;
00552            size_t count = 0;
00553 
00554            /* 
00555               when GIMLET is present, we don't let applications
00556               have their own choice windows, based on XLC_LOCALE
00557            */
00558            if (im_switcher_active(im))
00559              return p->name;
00560 
00561            /* RECONSIDER!!! */
00562            UpdateIMCharacterSubset(im);
00563 
00564            if (!im->unicode_char_subsets) break;
00565 
00566            im_subset = im->unicode_char_subsets;
00567 
00568            count = im_subset->count_subsets;
00569 
00570            if ((sub_sets = (XIMUnicodeCharacterSubsets*)
00571                Xmalloc(sizeof(XIMUnicodeCharacterSubsets) +
00572                       sizeof(XIMUnicodeCharacterSubset) * count)) == NULL) {
00573               break;
00574            }
00575            sub_sets->count_subsets = count;
00576            sub_sets->supported_subsets =
00577               (XIMUnicodeCharacterSubset*)(&sub_sets[1]);
00578 
00579            for (i = 0; i < (int)(sub_sets->count_subsets); i++) {
00580               sub_sets->supported_subsets[i] = im_subset->supported_subsets[i];
00581            }
00582            value = (XIMUnicodeCharacterSubsets **)p->value;
00583            *value = sub_sets;
00584       
00585        } else {
00586            break;
00587        }
00588     }
00589     return p->name;
00590 }
00591 
00592 XIM
00593 _IIIMP_OpenIM(
00594     XLCd lcd,
00595     Display *dpy,
00596     XrmDatabase rdb,
00597     char *res_name,
00598     char *res_class
00599 )
00600 {
00601     XimCommon im = 0;
00602 
00603     im = Xmalloc(sizeof(XimCommonRec));
00604     if (!im) goto Set_Error;
00605     memset(im, 0, sizeof(XimCommonRec));
00606 
00607     if (!CommonOpenIM((XIM)im, lcd, dpy, rdb, res_name, res_class))
00608        goto Set_Error;
00609 
00610     im->methods = get_iiimp_im_methods();
00611 
00612     if (!IIIMP_OpenIM_SWITCH((XIM)im, lcd, dpy)) goto Set_Error;
00613     return (XIM)im;
00614 
00615 Set_Error:
00616     if (im) Xfree(im);
00617     return 0;
00618 }
00619 
00620 Status
00621 IIIMP_OpenIM_SWITCH(
00622     XIM xim,
00623     XLCd lcd,
00624     Display *dpy
00625 )
00626 {
00627     XimCommon im = (XimCommon)xim;
00628     XIMIIimpIM im_private = 0;
00629     char *mod, buf[BUFSIZE];
00630     int mod_len;
00631 
00632     initialize();
00633 
00634     im_private = Xmalloc(sizeof(XIMIIimpIMRec));
00635     if (!im_private) goto Set_Error;
00636     memset(im_private, 0, sizeof (XIMIIimpIMRec));
00637     im->iiimp_impart = im_private;
00638 
00639     XIM_IIIMP(im, cb_window) = None;
00640     XIM_IIIMP(im, switch_methods) = get_switch_im_methods();
00641 
00642     buf[0] = '\0';
00643     mod_len = 0;
00644 
00645     im->core.im_name = 0;
00646     if ((lcd->core->modifiers) && (*lcd->core->modifiers)) {
00647 #define       MODIFIER "@im="
00648        mod = strstr(lcd->core->modifiers, MODIFIER);
00649        if (mod) {
00650            mod += strlen(MODIFIER);
00651 
00652            if (!strncmp(mod, "iiimp/", 6) || !strncmp(mod, "IIIMP/", 6)) {
00653               mod += 6;
00654 
00655               if (index(mod, ':')) {
00656                   while (*mod && *mod != '@' && mod_len < BUFSIZE - 1) {
00657                      buf[mod_len++] = *mod++;
00658                   }
00659                   buf[mod_len] = '\0';
00660                   im->core.im_name = Xmalloc(mod_len+1);
00661                   if (!im->core.im_name) goto Set_Error;
00662 
00663                   strcpy(im->core.im_name, buf);
00664               }
00665            }
00666        }
00667 #undef MODIFIER
00668     }
00669 
00670     if (IMCreateHandle(im) != IIIMF_STATUS_SUCCESS)
00671        goto Set_Error;
00672 
00673 
00674 #if 0 /* The following is required for asych. message handling.  */
00675     XIM_IIIMP(im, cb_window) =
00676        XCreateSimpleWindow(im->core.display,
00677                          DefaultRootWindow(im->core.display),
00678                          0, 0, 1, 1, 0, 0, 0);
00679     if (None != XIM_IIIMP(im, cb_window)) {
00680        _XRegisterFilterByType(im->core.display, XIM_IIIMP(im, cb_window),
00681                             ClientMessage, ClientMessage,
00682                             IMCBFilter, (XPointer)im);
00683     }
00684 #endif
00685 
00686     return True;
00687 
00688 Set_Error:
00689     if (im_private) {
00690        Xfree(im_private);
00691        im->iiimp_impart = NULL;
00692     }
00693     IIIMP_CloseIM((XIM)im);
00694     return False;
00695 }
00696 
00697 /* Switching */
00698 static Status
00699 SWITCH_CloseIM(
00700     XIM xim
00701 )
00702 {
00703     XimCommon im = (XimCommon)xim;
00704 
00705     IIimpFreeAllAuxData();
00706 
00707     if (im->core.im_name)
00708        Xfree(im->core.im_name);
00709 
00710     if (!im->iiimp_impart) return True;
00711 
00712 #if 0 /* The following is required for asych. message handling.  */
00713     if (None != XIM_IIIMP(im, cb_window)) {
00714        _XUnregisterFilter(im->core.display, XIM_IIIMP(im, cb_window),
00715                         IMCBFilter, (XPointer)im);
00716        XDestroyWindow(im->core.display, XIM_IIIMP(im, cb_window));
00717     }
00718 #endif
00719     if (XIM_IIIMP(im, handle)) {
00720        iiimcf_destroy_handle(XIM_IIIMP(im, handle));
00721     }
00722     IM_free_langlist(im);
00723     free_langalias(im);
00724     if (XIM_IIIMP(im, pkev_on)) {
00725        Xfree(XIM_IIIMP(im, pkev_on));
00726     }
00727     if (XIM_IIIMP(im, pkev_off)) {
00728        Xfree(XIM_IIIMP(im, pkev_off));
00729     }
00730 
00731     Xfree(im->iiimp_impart);
00732     im->iiimp_impart = 0;
00733     uninitialize();
00734     im_switcher_shutdown (im);
00735     return True;
00736 }
00737 
00738 
00739 /* only used for pluggin iiimp into
00740    X consortium based libX11
00741 */
00742 Bool
00743 _XInitIIIMP(
00744     XLCd lcd
00745 )
00746 {
00747     if (lcd == (XLCd)NULL)
00748        return False;
00749 
00750     lcd->methods->open_im = _IIIMP_OpenIM;
00751     lcd->methods->register_callback = NULL;
00752     lcd->methods->unregister_callback = NULL;
00753 
00754     return True;
00755 }
00756 
00757 /* Local Variables: */
00758 /* c-file-style: "iiim-project" */
00759 /* End: */