Back to index

im-sdk  12.3.91
composeIM.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 
00044               Copyright 1992 by Fuji Xerox Co., Ltd.
00045 
00046 Permission to use, copy, modify, distribute, and sell this software
00047 and its documentation for any purpose is hereby granted without fee,
00048 provided that the above copyright notice appear in all copies and
00049 that both that copyright notice and this permission notice appear
00050 in supporting documentation, and that the name of Fuji Xerox
00051 not be used in advertising or publicity pertaining to distribution
00052 of the software without specific, written prior permission.
00053 Fuji Xerox make no representations about the suitability of this
00054 software for any purpose.  It is provided
00055 "as is" without express or implied warranty.
00056 
00057 FUJI XEROX DISCLAIM ALL WARRANTIES WITH
00058 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
00059 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL FUJI XEROX BE LIABLE
00060 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00061 WHATSOEVER RESULTING FROM LOSS OF USE, DATA
00062 OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
00063 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00064 PERFORMANCE OF THIS SOFTWARE.
00065 
00066   Author: Kazunori Nishihara       Fuji Xerox
00067 
00068 ******************************************************************/
00069 
00070 
00071 #include "switchIM.h"
00072 #include "xiiimp.h"
00073 #include "iiimpIM.h"
00074 #include "guiIM.h"
00075 #include "guiIMSts.h"
00076 #include "composeIM.h"
00077 #include "XimpIm.h"
00078 #include <X11/keysym.h>
00079 #include <wchar.h>
00080 #include <unistd.h>
00081 #include <sys/stat.h>
00082 #include <sys/mman.h>
00083 #include <stdio.h>
00084 #include "status.h"
00085 #include "lookup.h"
00086 #include "codeinput.h"
00087 #include "tableinput.h"
00088 #include "trace_message.h"
00089 
00090 static Bool _Ximp_Local_OpenIM_hook(Ximp_XIM);
00091 static Status _Ximp_Local_CloseIM(XIM);
00092 static char *_Ximp_Local_SetIMValues(XIM, XIMArg*);
00093 static char *_Ximp_Local_GetIMValues(XIM, XIMArg*);
00094 static XIC _Ximp_Local_CreateIC(XIM, XIMArg*);
00095 extern int _Ximp_ctstombs(XIM, char*, int, char*, int, Status*);
00096 extern int _Ximp_ctstowcs(XIM, char*, int, wchar_t*, int, Status*);
00097 extern int Ximp_ParseStringFile(FILE *, Ximp_XIM);
00098 
00099 static
00100 XIMMethods
00101 get_local_im_methods()
00102 {
00103   static XIMMethodsRec imm;
00104   if (!imm.close) {
00105     imm.close = _Ximp_Local_CloseIM;
00106     imm.set_values = _Ximp_Local_SetIMValues;
00107     imm.get_values = _Ximp_Local_GetIMValues;
00108     imm.create_ic = _Ximp_Local_CreateIC;
00109     imm.ctstombs = _Ximp_ctstombs;
00110     imm.ctstowcs = _Ximp_ctstowcs;
00111   }
00112   return &imm;
00113 }
00114 
00115 static Status SWITCH_CloseIM(XIM);
00116 
00117 static
00118 XIMMethods
00119 get_switch_im_methods()
00120 {
00121   static XIMMethodsRec imm;
00122   if (!imm.close) {
00123     imm.close = SWITCH_CloseIM;
00124   }
00125   return &imm;
00126 }
00127 
00128 static void _Ximp_Local_DestroyIC(XIC);
00129 static void _Ximp_Local_SetFocus(XIC);
00130 static void _Ximp_Local_UnSetFocus(XIC);
00131 static char *_Ximp_Local_MbReset(XIC);
00132 static wchar_t *_Ximp_Local_WcReset(XIC);
00133 static char *_Ximp_Local_SetICValues(XIC, XIMArg*);
00134 static char *_Ximp_Local_GetICValues(XIC, XIMArg*);
00135 static int _Ximp_Local_MbLookupString(XIC, XKeyEvent*,
00136                                   char*, int, KeySym*, Status*);
00137 static int _Ximp_Local_WcLookupString(XIC, XKeyEvent*, wchar_t*, int,
00138                                   KeySym*, Status*);
00139 
00140 XICMethods
00141 get_local_ic_methods()
00142 {
00143   static XICMethodsRec icm;
00144   if (!icm.destroy) {
00145     icm.destroy = _Ximp_Local_DestroyIC;
00146     icm.set_focus = _Ximp_Local_SetFocus;
00147     icm.unset_focus = _Ximp_Local_UnSetFocus;
00148     icm.set_values = _Ximp_Local_SetICValues;
00149     icm.get_values = _Ximp_Local_GetICValues;
00150     icm.mb_reset = _Ximp_Local_MbReset;
00151     icm.wc_reset = _Ximp_Local_WcReset;
00152     icm.mb_lookup_string = _Ximp_Local_MbLookupString;
00153     icm.wc_lookup_string = _Ximp_Local_WcLookupString;
00154   }
00155   return &icm;
00156 }
00157 
00158 static void SWITCH_DestroyIC(XIC);
00159 
00160 static
00161 XICMethods
00162 get_switch_ic_methods()
00163 {
00164   static XICMethodsRec icm;
00165   if (!icm.destroy) {
00166     icm.destroy = SWITCH_DestroyIC;
00167     icm.set_focus = _Ximp_Local_SetFocus;
00168     icm.unset_focus = _Ximp_Local_UnSetFocus;
00169   }
00170   return &icm;
00171 }
00172 
00173 static char *_Ximp_Local_SetICValueData(Ximp_XIC, XIMArg *,
00174                                    int, XimpChangeaMask);
00175 
00176 extern Bool   SwitchRemoteIMState(XicCommon ic, char *localename);
00177 
00178 #define LOCAL_MB_BUFSIZE 128
00179 
00180 static Bool
00181 _LocalConnect(XimCommon im) {
00182   int num_local_im_styles;
00183 
00184   im->ximp_impart->type_list      = NULL; /* dummy */
00185   im->ximp_impart->im_server_name = NULL; /* dummy */
00186   im->ximp_impart->im_vendor_name = NULL; /* dummy */
00187   im->ximp_impart->im_proto_vl    = NULL; /* dummy */
00188   im->ximp_impart->im_proto_vnum  = 0; /* dummy */
00189   im->ximp_impart->im_ext_list    = 0; /* dummy */
00190 
00191   if (_Ximp_Local_OpenIM_hook((Ximp_XIM)im) == False) return (False);
00192 
00193   im->ximp_impart->im_styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles));
00194   if (im->ximp_impart->im_styles) {
00195     char *state_name = (char *)NULL;
00196     if (im->local_impart->top_state) {
00197       if (im->local_impart->use_binary_table)
00198        state_name = BCF_STR_STRING(im->local_impart->str_addr,
00199                                 BCF_STATE_NAME(im->local_impart->state_addr,
00200                                              (CARD32)(im->local_impart->top_state)));
00201       else
00202        state_name = im->local_impart->top_state->name;
00203     }
00204     if ((state_name != (char *)NULL) && (state_name[0] != '\0')) {
00205       /* 'name' other than "" will be displayed in the status
00206         area, so XIMStatusArea input style should be supported. */
00207       num_local_im_styles = 6;
00208     } else {
00209       num_local_im_styles = 3;
00210     }
00211     im->ximp_impart->im_styles->supported_styles = 
00212       (XIMStyle *)Xmalloc(sizeof(XIMStyle) * num_local_im_styles);
00213     im->ximp_impart->im_styles->count_styles = num_local_im_styles;
00214     if (im->ximp_impart->im_styles->supported_styles == NULL ) {
00215       Xfree(im->ximp_impart->im_styles );
00216       im->ximp_impart->im_styles = NULL;
00217       return( False );
00218     }
00219     /* XIMPreeditPosition is a fake for Motif */
00220     im->ximp_impart->im_styles->supported_styles[0] =
00221       XIMPreeditNone | XIMStatusNone;
00222     im->ximp_impart->im_styles->supported_styles[1] =
00223       XIMPreeditNothing | XIMStatusNothing;
00224     if ((state_name != (char *)NULL) && (state_name[0] != '\0')) {
00225       im->ximp_impart->im_styles->supported_styles[2] =
00226        XIMPreeditPosition | XIMStatusArea;
00227       im->ximp_impart->im_styles->supported_styles[3] =
00228        XIMPreeditNone | XIMStatusArea;
00229       im->ximp_impart->im_styles->supported_styles[4] =
00230        XIMPreeditNothing | XIMStatusArea;
00231       im->ximp_impart->im_styles->supported_styles[5] =
00232        XIMPreeditNone | XIMStatusNothing;
00233     } else {
00234       im->ximp_impart->im_styles->supported_styles[2] =
00235        XIMPreeditNone | XIMStatusNothing;
00236     }
00237   }
00238   else {
00239     return(False);
00240   }
00241 
00242   return(True);
00243 }
00244 
00245 static int
00246 ReadBinaryTable(XIMComposeIM local_impart, FILE *fp)
00247 {
00248     
00249     int              fd;
00250     struct stat      f_stat;
00251     void      *map_ptr;
00252 
00253     /* mmap */
00254     fd = fileno(fp);
00255     if(fstat(fd, &f_stat))
00256        return -1;
00257     map_ptr = mmap(0, f_stat.st_size, PROT_READ, MAP_SHARED, fd, 0);
00258     if(map_ptr == MAP_FAILED)
00259        return -1;
00260 
00261     /* set up XIMlocalIMRec struct */
00262     local_impart->map_addr = map_ptr;
00263     local_impart->map_len = f_stat.st_size;
00264     local_impart->state_addr = BCF_STATE_PTR(map_ptr);
00265     local_impart->def_addr = BCF_DEF_PTR(map_ptr);
00266     local_impart->str_addr = BCF_STR_PTR(map_ptr);
00267     local_impart->top_state = (LocalIMState *)1;
00268 
00269     return 0;
00270 }
00271 
00272 static Bool
00273 CreateDefTree(im)
00274 XimCommon im;
00275 {
00276     FILE *fp;
00277     char *name;
00278     Bool return_value = True;
00279     CARD16    signature;
00280 
00281     name = _XlcFileName(im->core.lcd, COMPOSE_FILE);
00282     if (name == (char *)NULL)
00283        return(False);
00284     fp = fopen(name, "r");
00285     Xfree(name);
00286     if (fp == (FILE *)NULL){
00287        return(False);
00288     }
00289 
00290     im->local_impart->top_state = (LocalIMState *)NULL;
00291 
00292     /* read first 2 bytes */
00293     if(fread(&signature, sizeof(CARD16), 1, fp) != 1){
00294        fclose(fp);
00295        return False;
00296     }
00297 
00298     /* binary compose file */
00299     if(signature == BCF_HDR_SIGNATURE){
00300        im->local_impart->use_binary_table = True;
00301        im->local_impart->map_addr = (void *)NULL;
00302        if(ReadBinaryTable(im->local_impart, fp) < 0)
00303            return_value =  False;
00304     }
00305     /* text compose file */
00306     else{
00307        im->local_impart->use_binary_table = False;
00308        fseek(fp, 0L, SEEK_SET);
00309 #ifdef BACKTRACK_WHEN_UNMATCHED
00310        im->ximp_impart->num_save_rooms = 
00311            Ximp_ParseStringFile(fp, im);
00312 #else
00313        if(Ximp_ParseStringFile(fp, (Ximp_XIM)im) < 0)
00314            return_value = False;
00315 #endif
00316     }
00317 
00318     fclose(fp);
00319     return (return_value);
00320 }
00321 
00322 static Bool
00323 _Ximp_Local_OpenIM_hook(xim)
00324 Ximp_XIM xim;
00325 {
00326   XimCommon im = (XimCommon)xim;
00327   im->local_impart->current_ic = (XIC)NULL;
00328   return (CreateDefTree(im));
00329 }
00330 
00331 XIM
00332 _XimpLocalOpenIM(XLCd lcd, Display *dpy, XrmDatabase rdb,
00333                char *res_name, char*res_class) {
00334   XimCommon im = 0;
00335   int i;
00336   char *mod, im_name[BUFSIZE];
00337 
00338   im = (XimCommon)Xmalloc(sizeof(XimCommonRec));
00339   if (!im) return((XIM)NULL);
00340   memset(im, 0, sizeof(XimCommonRec));
00341 
00342   if (!CommonOpenIM((XIM)im, lcd, dpy, rdb, res_name, res_class))
00343     goto Set_Error;
00344 
00345   im->methods = get_local_im_methods();
00346 
00347   im_name[0] = '\0';
00348   i = 0;
00349   if ((lcd->core->modifiers) && (*lcd->core->modifiers)) {
00350 #define       MODIFIER "@im="
00351     mod = strstr(lcd->core->modifiers, MODIFIER);
00352     if (mod) {
00353       mod += strlen(MODIFIER);
00354       while (*mod && *mod != '@' && i < BUFSIZE - 1) {
00355        im_name[i++] = *mod++;
00356       }
00357       im_name[i] = '\0';
00358     }
00359   }
00360 #undef MODIFIER
00361 
00362   if (!((0 == strcmp(im_name, "")) ||
00363        (0 == strcmp(im_name, "none")) ||
00364        (0 == strcmp(im_name, "local")))) {
00365     goto Set_Error;
00366   }
00367 
00368   if (!COMPOSE_OpenIM_SWITCH((XIM)im, lcd)) goto Set_Error;
00369   return (XIM)im;
00370  Set_Error:
00371   if (im) Xfree(im);
00372   return 0;
00373 }
00374 
00375 Status
00376 COMPOSE_OpenIM_SWITCH(XIM xim, XLCd lcd) {
00377   XimCommon im = (XimCommon)xim;
00378   XIMComposeIM local_impart = 0;
00379   char * name;
00380 
00381   local_impart = (XIMComposeIM)Xmalloc(sizeof(XIMComposeIMRec));
00382   if (!local_impart) goto Set_Error;
00383 
00384   memset(local_impart, 0, sizeof(XIMComposeIMRec));
00385 
00386   im->local_impart = local_impart;
00387 
00388   XIM_COMPOSE(im, switch_methods) = get_switch_im_methods();
00389 
00390   name = _XlcFileName(im->core.lcd, COMPOSE_FILE);
00391   if (name == (char *)NULL || access(name, R_OK) == -1) {
00392     Xfree(name);
00393     goto Set_Error;
00394   }
00395   Xfree(name);
00396 
00397   if (!_LocalConnect(im)) goto Set_Error;
00398 
00399   return True;
00400 
00401 Set_Error:
00402   _Ximp_Local_CloseIM((XIM)im);
00403   return False;
00404 }
00405 
00406 static void
00407 FreeDefTreeElements(DefTree *top) {
00408   if (top->succession) FreeDefTreeElements(top->succession);
00409   if (top->next) FreeDefTreeElements(top->next);
00410   if (top->mb) Xfree(top->mb);
00411   if (top->target_name) Xfree(top->target_name);
00412   Xfree(top);
00413 }
00414 
00415 static Status
00416 _Ximp_Local_CloseIM(xim)
00417 XIM xim;
00418 {
00419   CommonCloseIM(xim);
00420   SWITCH_CloseIM(xim);
00421   return (True);
00422 }
00423 
00424 static char *
00425 _Ximp_Local_SetIMValues(xim, arg)
00426 XIM xim;
00427 XIMArg *arg;
00428 {
00429   return(arg->name);        /* evil */
00430 }
00431 
00432 static char *
00433 _Ximp_Local_GetIMValues(xim, values)
00434 XIM xim;
00435 XIMArg *values;
00436 {
00437   XimCommon im = (XimCommon)xim;
00438   XIMArg *p;
00439   XIMStyles **value;
00440   XIMStyles *styles;
00441   int i;
00442   XIMStyles *p_style = im->ximp_impart->im_styles;
00443 
00444   if (im->local_impart == NULL)
00445     return NULL;
00446 
00447   for (p = values; p->name != NULL; p++) {
00448     if (strcmp(p->name, XNQueryInputStyle) == 0) {
00449       if ((styles = (XIMStyles *)Xmalloc(sizeof(XIMStyles) +
00450                sizeof(XIMStyle) * p_style->count_styles)) == NULL) {
00451        break;
00452       }
00453       styles->count_styles = p_style->count_styles;
00454       styles->supported_styles = (XIMStyle *)(&styles[1]);
00455       for (i = 0; i < (int)(styles->count_styles); i++) {
00456        styles->supported_styles[i] = p_style->supported_styles[i];
00457       }
00458       value = (XIMStyles **)p->value;
00459       *value = styles;
00460     } else {
00461       break;
00462     }
00463   }
00464   return (p->name);
00465 }
00466 
00467 static SwitchMode
00468 SwitchFilter(XicCommon ic, XEvent *ev) {
00469   DefTree *p = NULL;
00470   unsigned int mod_state;
00471   KeySym keysym;
00472   char buf[32];
00473 
00474   if (ev->type != KeyPress) return (False);
00475   if (ev->xkey.keycode == XIM_COMPOSE_KEYCODE) return (False);
00476 
00477   (void)XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &keysym, 0);
00478 
00479   mod_state = ev->xkey.state;
00480   mod_state &= ~(ShiftMask | LockMask);
00481 
00482   if (USE_KEYCODEINFO(((XimCommon)ic->core.im)->local_impart->top_state)) {
00483     for (p = ic->local_icpart->context; p; p = p->next) {
00484       if (p->keycode != 0) {
00485        if (((mod_state & p->modifier_mask) == p->modifier) &&
00486            (ev->xkey.keycode == p->keycode) &&
00487            (keysym == p->keysym)) {
00488          /* matched */
00489          return Switch_ON;
00490        }
00491       }
00492     }
00493   }
00494   if (p == NULL) { /* Unmatched */
00495     for (p = ic->local_icpart->context; p; p = p->next) {
00496       if (p->keycode == 0) {
00497        if (((mod_state & p->modifier_mask) == p->modifier) &&
00498            (keysym == p->keysym)) {
00499          return Switch_ON;
00500        }
00501       }
00502     }
00503   }
00504   return Switch_NOP;
00505 }
00506 
00507 Bool
00508 Ximp_Local_KeyFilter(d, w, ev, client_data)
00509      Display *d;
00510      Window w;
00511      XEvent *ev;
00512      XPointer client_data;
00513 {
00514   XicCommon ic = (XicCommon)client_data;
00515   KeySym keysym;
00516   static char buf[128];
00517   static XComposeStatus     status;
00518   unsigned int         mod_state;
00519   LocalIMState *prev_state;
00520 
00521   XimCommon im;
00522   Bool useUnicode;
00523 
00524 #ifdef BACKTRACK_WHEN_UNMATCHED
00525   static long must_be_through = 0;
00526 #endif
00527 
00528   DefTree *p = NULL;
00529   Bool returnflag = False;
00530 
00531   TRACE_MESSAGE('k', ("local_Filter\n"));
00532 
00533   if (!ic) {
00534     return False;
00535   }
00536   im = (XimCommon)ic->core.im;
00537 
00538   if (im == 0) {
00539     /* perhaps XIM instance is aleady closed, and set to NULL */
00540     _XUnregisterFilter(d, w, Ximp_Local_KeyFilter, (XPointer)ic);
00541     return False;
00542   }
00543 
00544   if (ev->type != KeyPress) return (False);
00545   if (ev->xkey.keycode == XIM_COMPOSE_KEYCODE) return (False);
00546   if (ic->local_icpart == 0) {
00547     /* most likely associated ic has been already destroyed */
00548     _XUnregisterFilter(d, w, Ximp_Local_KeyFilter, (XPointer)ic);
00549     return False;
00550   }
00551 
00552   if (((XimCommon)ic->core.im)->local_impart == 0) {
00553     _XUnregisterFilter(d, w, Ximp_Local_KeyFilter, (XPointer)ic);
00554     return False;
00555   }
00556 
00557   if (((XimCommon)ic->core.im)->local_impart->top_state == (LocalIMState *)NULL)
00558     return (False);
00559 #ifdef BACKTRACK_WHEN_UNMATCHED
00560   if (must_be_through) {
00561     must_be_through--;
00562     return (False);
00563   }
00564 #endif
00565 
00566   (void)memset((void *)(&status), 0, sizeof(XComposeStatus));
00567   (void)XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &keysym, &status);
00568   mod_state = ev->xkey.state;
00569   mod_state &= ~(ShiftMask | LockMask | Mod2Mask );
00570 
00571   if (IsModifierKey(keysym)) return (False);
00572 
00573     /* use binary table */
00574   if(((XimCommon)ic->core.im)->local_impart->use_binary_table == True){
00575     XIMComposeIM lim = ((XimCommon)ic->core.im)->local_impart;
00576     CARD32    *s_addr = lim->state_addr;
00577     CARD32    *d_addr = lim->def_addr;
00578     CARD32    index = 0;
00579     if(BCF_STATE_USE_KEYCODE(s_addr, (CARD32)(lim->top_state))){
00580       index = (CARD32)(ic->local_icpart->context);
00581       while(index){
00582        if(BCF_DEF_KEYCODE(d_addr, index) != 0){
00583          if(((mod_state & BCF_DEF_MODIFIER_MASK(d_addr, index)) == BCF_DEF_MODIFIER(d_addr, index)) &&
00584             (ev->xkey.keycode == BCF_DEF_KEYCODE(d_addr, index)) &&
00585             (keysym == BCF_DEF_KEYSYM(d_addr, index))){
00586            break;
00587          }
00588        }
00589        index = BCF_DEF_NEXT(d_addr, index);
00590       }
00591     }
00592     if(index == 0){ /* Unmatched */
00593       index = (CARD32)(ic->local_icpart->context);
00594       while(index){
00595        if(BCF_DEF_KEYCODE(d_addr, index) == 0){
00596          if(((mod_state & BCF_DEF_MODIFIER_MASK(d_addr, index)) == BCF_DEF_MODIFIER(d_addr, index)) &&
00597             (keysym == BCF_DEF_KEYSYM(d_addr, index))){
00598            break;
00599          }
00600        }
00601        index = BCF_DEF_NEXT(d_addr, index);
00602       }
00603     }
00604 
00605     if(index){ /* Matched */
00606       if(BCF_DEF_SUCCESSION(d_addr, index)){ /* Intermediate */
00607        ic->local_icpart->context = (DefTree *)BCF_DEF_SUCCESSION(d_addr, index);
00608 #ifdef BACKTRACK_WHEN_UNMATCHED
00609        /* Seve Event */
00610        bcopy(ev, &ic->ximp_icpart.saved_event[ic->ximp_icpart.num_saved++], sizeof(XKeyEvent));
00611 #endif
00612       }
00613       else{ /* Terminate (reached to leaf) */
00614        if(BCF_DEF_TARGET(d_addr, index) == 0){
00615          ic->local_icpart->composed = (DefTree *)
00616            Xmalloc(sizeof(DefTree));
00617          if (ic->local_icpart->composed == (DefTree *)NULL)
00618            return(False);
00619          memset(ic->local_icpart->composed, 0, sizeof(DefTree));
00620          bcopy((DefTree *)p, ic->local_icpart->composed, sizeof(DefTree));
00621          if (((DefTree *)p)->mb != NULL) {
00622            int l;
00623            l = strlen(p->mb);
00624            if (l > 0) {
00625              ic->local_icpart->composed->mb = (char *)Xmalloc(l+1);
00626              bcopy(((DefTree *)p)->mb, ic->local_icpart->composed->mb, l);
00627              ic->local_icpart->composed->mb[l] = '\0';
00628            }
00629          }
00630 
00631          useUnicode = (XIM_USE_UNICODE(im) &&
00632                      NULL != ic->commit_string_callback.callback);
00633 
00634          /* private XIC extension */
00635          if (useUnicode) {
00636              XIMCallback *cb = &ic->commit_string_callback;
00637              XIMUnicodeText cbtext;
00638              size_t len = 256;     /* enough */
00639              char buffer[256];
00640              memset(&cbtext, 0, sizeof(XIMUnicodeText));
00641              cbtext.string.multi_byte = buffer;
00642              cbtext.length = len;
00643              IMConvertFromUTF8ToUTF16(p->mb, strlen(p->mb),
00644                                    (char**)&cbtext.string.utf16_char,
00645                                    &len);
00646              cbtext.length -= len;
00647              cbtext.length /= sizeof(unsigned short);
00648              (*cb->callback)((XIC)ic,
00649                            cb->client_data,
00650                            (XPointer)&cbtext);
00651 
00652          } else {
00653            /* return back to client KeyPressEvent keycode == 0 */
00654            ev->xkey.keycode = XIM_COMPOSE_KEYCODE;
00655            XPutBackEvent(d, ev);
00656          }
00657        }
00658        else { /* Change state */
00659          ic->local_icpart->imstate = (LocalIMState *)BCF_DEF_TARGET(d_addr, index);
00660          Ximp_Local_Status_Set(ic);
00661          Ximp_Local_Status_Start(ic);
00662          Ximp_Local_Status_Draw(ic);
00663        }
00664        /* initialize internal state for next key sequence */
00665        ic->local_icpart->context = (DefTree *)BCF_STATE_PARSER(s_addr, (CARD32)(ic->local_icpart->imstate));
00666       }
00667       return (True);
00668     }
00669     else{ /* Unmatched */
00670       if (ic->local_icpart->context == (DefTree *)BCF_STATE_PARSER(s_addr, (CARD32)(ic->local_icpart->imstate))){
00671        return (False);
00672       }
00673       /* Error (Sequence Unmatch occured) */
00674 #ifdef BACKTRACK_WHEN_UNMATCHED
00675       XPutBackEvent(d, ev);
00676       while (ic->ximp_icpart.num_saved > 0) {
00677        ic->ximp_icpart.num_saved--;
00678        XPutBackEvent(d, &ic->ximp_icpart.saved_event[ic->ximp_icpart.num_saved]);
00679       }
00680       must_be_through = 1;
00681 #endif
00682       /* initialize internal state for next key sequence */
00683       ic->local_icpart->context = (DefTree *)BCF_STATE_PARSER(s_addr, (CARD32)(ic->local_icpart->imstate));
00684 
00685       return (True);
00686     }
00687   }
00688 
00689   /* use text compose file */
00690   else{
00691     TRACE_MESSAGE('k', ("0x%08x 0x%08x\n", ic->local_icpart->imstate,
00692                      ((XimCommon)ic->core.im)->local_impart->top_state));
00693     if (USE_KEYCODEINFO(((XimCommon)ic->core.im)->local_impart->top_state)) {
00694       for (p = ic->local_icpart->context; p; p = p->next) {
00695        if (p->keycode != 0) {
00696          if (((mod_state & p->modifier_mask) == p->modifier) &&
00697              (ev->xkey.keycode == p->keycode) &&
00698              (keysym == p->keysym)) {
00699            break;
00700          }
00701        }
00702       }
00703     }
00704     if (p == NULL) { /* Unmatched */
00705       for (p = ic->local_icpart->context; p; p = p->next) {
00706        if (p->keycode == 0) {
00707          if (((mod_state & p->modifier_mask) == p->modifier) &&
00708              (keysym == p->keysym)) {
00709            break;
00710          }
00711        }
00712       }
00713     }
00714     if (p) { /* Matched */
00715       if (p->succession) { /* Intermediate */
00716        ic->local_icpart->context = p->succession;
00717 #ifdef BACKTRACK_WHEN_UNMATCHED
00718        /* Seve Event */
00719        bcopy(ev, &ic->ximp_icpart.saved_event[ic->ximp_icpart.num_saved++], sizeof(XKeyEvent));
00720 #endif
00721        returnflag = True;
00722       } else { /* Terminate (reached to leaf) */
00723        prev_state = ic->local_icpart->imstate;
00724        if (prev_state->type == RemoteIMState) {
00725          return False;
00726        }
00727        if (p->target_name == NULL){
00728          switch (p->action) {
00729          case TopPage:
00730          case LastPage:
00731          case NextPage:
00732          case PrevPage:
00733          case UpCand:
00734          case DownCand:
00735          case NextCand:
00736          case PrevCand:
00737          case SelectCand:
00738            /* only for lookup */
00739            Ximp_Local_Lookup_Action_Filter(ic, p->action, ev);
00740            return(True);
00741          case DoConv:
00742            if (prev_state->type == CodeInputState) {
00743              Ximp_Local_Preedit_Conv(ic, ev);
00744              return(True);
00745            }
00746          case DoLookup:
00747            if (prev_state->type == CodeInputState) {
00748              Ximp_Local_Preedit_Lookup(ic, ev);
00749              return(True);
00750            }
00751            break;
00752          case NoAction:
00753            /* create a copy of Compose key, BugID: 4157565 */
00754            ic->local_icpart->composed = (DefTree *)Xmalloc(sizeof(DefTree));
00755            if (ic->local_icpart->composed == (DefTree *)NULL)
00756              return(False);
00757            memset(ic->local_icpart->composed, 0, sizeof(DefTree));
00758            bcopy((DefTree *)p, ic->local_icpart->composed, sizeof(DefTree));
00759            if (((DefTree *)p)->mb != NULL) {
00760              int l;
00761              l = strlen(p->mb);
00762              if (l > 0) {
00763               ic->local_icpart->composed->mb = (char *)Xmalloc(l+1);
00764               bcopy(((DefTree *)p)->mb, ic->local_icpart->composed->mb, l);
00765               ic->local_icpart->composed->mb[l] = '\0';
00766              }
00767            }
00768 
00769            useUnicode = (XIM_USE_UNICODE(im) &&
00770                        NULL != ic->commit_string_callback.callback);
00771            /* private XIC extension */
00772            if (useUnicode) {
00773              XIMCallback *cb = &ic->commit_string_callback;
00774              XIMUnicodeText cbtext;
00775              size_t len = 256;     /* enough */
00776              char buffer[256];
00777              memset(&cbtext, 0, sizeof(XIMUnicodeText));
00778              cbtext.string.multi_byte = buffer;
00779              cbtext.length = len;
00780              IMConvertFromUTF8ToUTF16(p->mb, strlen(p->mb),
00781                                    (char**)&cbtext.string.utf16_char,
00782                                    &len);
00783              cbtext.length -= len;
00784              cbtext.length /= sizeof(unsigned short);
00785              (*cb->callback)((XIC)ic,
00786                            cb->client_data,
00787                            (XPointer)&cbtext);
00788 
00789            } else {
00790              /* return back to client KeyPressEvent keycode == 0 */
00791              ev->xkey.keycode = XIM_COMPOSE_KEYCODE;
00792              XPutBackEvent(d, ev);
00793            }
00794            break;
00795          default:
00796            break;
00797          }
00798        } else {
00799          TRACE_MESSAGE('k', ("local_Filter: %s\n", p->target_name));
00800          ic->local_icpart->imstate = p->target;
00801          ic->local_icpart->context = ic->local_icpart->imstate->parser;
00802          if (prev_state->type == CodeInputState) {
00803            Ximp_Local_Preedit_Done(ic);
00804          } else if (prev_state->type == LookupState) {
00805            Ximp_Local_Table_Done(ic);
00806          }
00807           switch (ic->local_icpart->imstate->type) {
00808          case RemoteIMState:
00809            if (!SwitchRemoteIMState(ic,
00810                                  ic->local_icpart->imstate->language)) {
00811              ic->local_icpart->imstate = prev_state;
00812              ic->local_icpart->context = ic->local_icpart->imstate->parser;
00813              return False;
00814            }
00815            ic->local_icpart->imstate = ((XimCommon)ic->core.im)->local_impart->top_state;
00816            ic->local_icpart->context = ic->local_icpart->imstate->parser;
00817            break;
00818          case CodeInputState:
00819          case LookupState:
00820          default:
00821            Ximp_Local_Status_Set(ic);
00822            Ximp_Local_Status_Start(ic);
00823            Ximp_Local_Status_Draw(ic);
00824            if (ic->local_icpart->imstate->type == CodeInputState) {
00825              Ximp_Local_Preedit_Start(ic);
00826            }
00827            if (ic->local_icpart->imstate->type == LookupState) {
00828              Ximp_Local_Table_Start(ic);
00829            }
00830            break;
00831          }
00832        }
00833        /* initialize internal state for next key sequence */
00834        ic->local_icpart->context = ic->local_icpart->imstate->parser;
00835 #ifdef BACKTRACK_WHEN_UNMATCHED
00836        ic->ximp_icpart.num_saved = 0;
00837 #endif
00838       }
00839       return (True);
00840 
00841     } else { /* Unmatched */
00842       if (ic->local_icpart->context == ic->local_icpart->imstate->parser) {
00843        returnflag = False;
00844       }
00845       /* Error (Sequence Unmatch occured) */
00846 #ifdef BACKTRACK_WHEN_UNMATCHED
00847       XPutBackEvent(d, ev);
00848       while (ic->ximp_icpart.num_saved > 0) {
00849        ic->ximp_icpart.num_saved--;
00850        XPutBackEvent(d, &ic->ximp_icpart.saved_event[ic->ximp_icpart.num_saved]);
00851       }
00852       must_be_through = 1;
00853 #endif
00854       /* initialize internal state for next key sequence */
00855       ic->local_icpart->context = ic->local_icpart->imstate->parser;
00856       returnflag = False;
00857     }
00858   }
00859 
00860   if(ic->local_icpart->imstate->type == CodeInputState) {
00861     LocalPreeditExt *hook = (LocalPreeditExt *)(ic->local_icpart->preedit_ext);
00862     LocalIMState *state = (LocalIMState *)(ic->local_icpart->imstate);
00863     LocalLookupExt *lookup = (LocalLookupExt *)(ic->local_icpart->lookup_ext);
00864     int max_len = state->attr->_attr_u.CIstruct.max_input_len;
00865 
00866     returnflag = True;
00867     if (lookup && lookup->mapped) {
00868       Ximp_Local_Lookup_Input_Filter(ic, buf, ev);
00869     } else {
00870       if (Ximp_Local_Preedit_Draw(ic, keysym)) {
00871        if (hook && hook->preedit_len >= max_len) {
00872          Ximp_Local_Preedit_Conv(ic, ev);
00873        }
00874       } else {
00875        returnflag = False;
00876       }
00877     }
00878   } else if (ic->local_icpart->imstate->type == LookupState) {
00879     LocalLookupExt *lookup = (LocalLookupExt *)(ic->local_icpart->lookup_ext);
00880     if (lookup && lookup->mapped) {
00881       returnflag = Ximp_Local_Lookup_Input_Filter(ic, buf, ev);
00882     }
00883     Ximp_Local_Table_Draw(ic);
00884   }
00885   return(returnflag);
00886 }
00887 
00888 static XIC
00889 _Ximp_Local_CreateIC(XIM im, XIMArg *arg) {
00890   XicCommon ic = (XicCommon)NULL;
00891 
00892   ic = (XicCommon)Xmalloc(sizeof(XicCommonRec));
00893   if (ic == (XicCommon)NULL) goto Error;
00894   memset(ic, 0, sizeof(XicCommonRec));
00895 
00896   ic->core.im = (XIM)im;
00897   ic->methods = get_local_ic_methods();
00898 
00899   if (!CommonCreateIC((XIC)ic, arg)) goto Error;
00900     
00901   if (!COMPOSE_CreateIC_SWITCH((XIC)ic, arg)) goto Error;
00902 
00903   _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
00904                       KeyPress, KeyRelease,
00905                       Ximp_Local_KeyFilter, (XPointer)ic);
00906   return (XIC)ic;
00907  Error:
00908   if (ic) Xfree(ic);
00909   return 0;
00910 }
00911 Status
00912 COMPOSE_CreateIC_SWITCH(XIC xic, XIMArg *arg) {
00913   XicCommon ic = (XicCommon)xic;
00914   XimCommon im = (XimCommon)ic->core.im;
00915   XimpChangeMaskRec dummy;
00916 
00917   if ((ic->local_icpart = (XICComposeIM)Xmalloc(sizeof(XICComposeIMRec)))
00918       == (XICComposeIM)NULL) {
00919     goto Error;
00920   }
00921   memset(ic->local_icpart, 0, sizeof(XICComposeIMRec));
00922 
00923   XIC_COMPOSE(ic, switch_methods) = get_switch_ic_methods();
00924 
00925   ic->core.filter_events = KeyPressMask;
00926 
00927   if (XIM_COMPOSE(im, top_state)) {
00928     if (XIM_COMPOSE(im, use_binary_table) == True)
00929       ic->local_icpart->context =
00930        (DefTree *)BCF_STATE_PARSER(XIM_COMPOSE(im, state_addr),
00931                                 (CARD32)XIM_COMPOSE(im, top_state));
00932     else
00933       ic->local_icpart->context = XIM_COMPOSE(im, top_state)->parser;
00934   }
00935   ic->local_icpart->composed = NULL;
00936   ic->local_icpart->imstate = ((XimCommon)im)->local_impart->top_state;
00937 
00938   if (!ic->local_icpart->imstate) {
00939     fprintf(stderr, "The local IM state map is empty.  Compose file may be broken.\n");
00940     goto Error;
00941   }
00942 
00943   memset(&dummy, 0, sizeof(dummy));
00944   if (_Ximp_Local_SetICValueData((Ximp_XIC)ic, arg, XIMP_CREATE_IC, &dummy)) {
00945     goto Error;
00946   }
00947   /* Not Yet */
00948   if (!(ic->ximp_icpart->value_mask & XIMP_INPUT_STYLE)) 
00949     goto Error;
00950 
00951   ic->ximp_icpart->input_mode = BEING_BYPASSED;
00952   Ximp_Local_Status_Set(ic);
00953   Ximp_Local_Status_Start(ic);
00954   Ximp_Local_Status_Draw(ic);
00955 
00956   /* switch */
00957   if (XIM_IS_SWITCH(im)) {
00958     RegisterSwitchFilter(ic, SwitchFilter,
00959                       Ximp_Local_KeyFilter,
00960                       get_local_ic_methods());
00961   }
00962   return True;
00963 
00964  Error:
00965   if (ic->local_icpart) XFree(ic->local_icpart);
00966   return False;
00967 }
00968 
00969 static Bool
00970 _Ximp_StatusGetAttributes(ic, vl, return_name)
00971     Ximp_XIC         ic;
00972     XIMArg           *vl;
00973     char             **return_name;
00974 {
00975     XIMArg           *p;
00976     XRectangle       *p_rect;
00977     XIMCallback      *p_callback;
00978 
00979   if (((XimCommon)ic->core.im)->local_impart == NULL)
00980     return True;
00981 
00982   for(p = vl; p->name != NULL; p++) {
00983        if(strcmp(p->name, XNArea)==0) {
00984            if(XIMP_CHK_STSAREAMASK(ic)) {
00985               if((p_rect = (XRectangle *)Xmalloc(sizeof(XRectangle))) == NULL) {
00986                   *return_name = p->name;
00987                   return(False);
00988               }
00989               p_rect->x       = ic->core.status_attr.area.x;
00990               p_rect->y       = ic->core.status_attr.area.y;
00991               p_rect->width   = ic->core.status_attr.area.width;
00992               p_rect->height  = ic->core.status_attr.area.height;
00993            } else {
00994               *return_name = p->name;
00995               return(False);
00996            }
00997            *((XRectangle **)(p->value)) = p_rect;
00998        } else if(strcmp(p->name, XNAreaNeeded)==0) {
00999          unsigned int win_width, win_height;
01000          XFontSet fs = ic->core.status_attr.fontset;
01001          XFontSetExtents *fse = 0;
01002 
01003          if (!fs || !XIMP_CHK_STSFONTMASK(ic)) {
01004            SetStatusFont((XicCommon)ic, NULL);
01005            fs = ic->core.status_attr.fontset;
01006          }
01007 
01008          if((p_rect = (XRectangle *)Xmalloc(sizeof(XRectangle))) ==
01009             (XRectangle *)NULL) {
01010            *return_name = p->name;
01011            return(False);
01012          }
01013          memset(p_rect, 0, sizeof(XRectangle));
01014          p_rect->x  = p_rect->y  = 0;
01015 
01016          if (fs) fse = XExtentsOfFontSet(fs);
01017          if (fse && fse->max_logical_extent.width)
01018            win_width = fse->max_logical_extent.width * MAX_STATUS_CHARNUM * 4;
01019          else
01020            win_width = 400;
01021          if (fse && fse->max_logical_extent.height)
01022            win_height = fse->max_logical_extent.height;
01023          else
01024            win_height = 20;
01025 
01026          p_rect->width = ic->core.status_attr.area_needed.width;
01027          if (!(p_rect->width) || (p_rect->width > win_width)) {
01028            p_rect->width = win_width;
01029          }
01030 
01031          p_rect->height = ic->core.status_attr.area_needed.height;
01032          if (!(p_rect->height) || (p_rect->height > win_height)) {
01033            p_rect->height = win_height;
01034          }
01035          *((XRectangle **)(p->value)) = p_rect;
01036        } else if(strcmp(p->name, XNColormap)==0) {
01037            if(XIMP_CHK_STSCOLORMAPMASK(ic)) {
01038               *((Colormap *)(p->value)) = ic->core.status_attr.colormap;
01039            } else {
01040               *return_name = p->name;
01041               return(False);
01042            }
01043        } else if(strcmp(p->name, XNStdColormap)==0) {
01044            if(XIMP_CHK_STSSTDCOLORMAPMASK(ic)) {
01045               *((Atom *)(p->value)) = ic->core.status_attr.std_colormap;
01046            } else {
01047               *return_name = p->name;
01048               return(False);
01049            }
01050        } else if(strcmp(p->name, XNBackground)==0) {
01051            if(XIMP_CHK_STSBGMASK(ic)) {
01052               *((unsigned long *)(p->value)) = ic->core.status_attr.background;
01053            } else {
01054               *return_name = p->name;
01055               return(False);
01056            }
01057        } else if(strcmp(p->name, XNForeground)==0) {
01058            if(XIMP_CHK_STSFGMASK(ic)) {
01059               *((unsigned long *)(p->value)) = ic->core.status_attr.foreground;
01060            } else {
01061               *return_name = p->name;
01062               return(False);
01063            }
01064        } else if(strcmp(p->name, XNBackgroundPixmap)==0) {
01065            if(XIMP_CHK_STSBGPIXMAPMASK(ic)) {
01066               *((Pixmap *)(p->value)) = ic->core.status_attr.background_pixmap;
01067            } else {
01068               *return_name = p->name;
01069               return(False);
01070            }
01071        } else if(strcmp(p->name, XNFontSet)==0) {
01072            if(XIMP_CHK_STSFONTMASK(ic)) {
01073               *((XFontSet *)(p->value)) = ic->core.status_attr.fontset;
01074            } else {
01075               *return_name = p->name;
01076               return(False);
01077            }
01078        } else if(strcmp(p->name, XNLineSpace)==0) {
01079            if(XIMP_CHK_STSLINESPMASK(ic)) {
01080               *((int *)(p->value)) = ic->core.status_attr.line_spacing;
01081            } else {
01082               *return_name = p->name;
01083               return(False);
01084            }
01085        } else if(strcmp(p->name, XNCursor)==0) {
01086            if(XIMP_CHK_STSCURSORMASK(ic)) {
01087               *((Cursor *)(p->value)) = ic->core.status_attr.cursor;
01088            } else {
01089               *return_name = p->name;
01090               return(False);
01091            }
01092        } else if(strcmp(p->name, XNStatusStartCallback)==0) {
01093            if((int)ic->core.status_attr.start_callback.callback) {
01094               if((p_callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback))) == NULL) {
01095                   *return_name = p->name;
01096                   return(False);
01097               }
01098               p_callback->client_data =
01099                   ic->core.status_attr.start_callback.client_data;
01100               p_callback->callback =
01101                   ic->core.status_attr.start_callback.callback;
01102               *((XIMCallback **)(p->value)) = p_callback;
01103            } else {
01104               *return_name = p->name;
01105               return(False);
01106            }
01107        } else if(strcmp(p->name, XNStatusDrawCallback)==0) {
01108            if((int)ic->core.status_attr.draw_callback.callback) {
01109               if((p_callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback))) == NULL) {
01110                   *return_name = p->name;
01111                   return(False);
01112               }
01113               p_callback->client_data =
01114                   ic->core.status_attr.draw_callback.client_data;
01115               p_callback->callback =
01116                   ic->core.status_attr.draw_callback.callback;
01117               *((XIMCallback **)(p->value)) = p_callback;
01118            } else {
01119               *return_name = p->name;
01120               return(False);
01121            }
01122        } else if(strcmp(p->name, XNStatusDoneCallback)==0) {
01123            if((int)ic->core.status_attr.done_callback.callback) {
01124               if((p_callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback))) == NULL) {
01125                   *return_name = p->name;
01126                   return(False);
01127               }
01128               p_callback->client_data =
01129                   ic->core.status_attr.done_callback.client_data;
01130               p_callback->callback =
01131                   ic->core.status_attr.done_callback.callback;
01132               *((XIMCallback **)(p->value)) = p_callback;
01133            } else {
01134               *return_name = p->name;
01135               return(False);
01136            }
01137        }
01138     }
01139     return(True);
01140 }
01141 
01142 static Bool
01143 _Ximp_PreGetAttributes(ic, vl, return_name)
01144 Ximp_XIC       ic;
01145 XIMArg        *vl;
01146 char          **return_name;
01147 {
01148     XIMArg           *p;
01149     XRectangle       *p_rect;
01150     XPoint           *p_point;
01151     XIMCallback      *p_callback;
01152 
01153     if (((XimCommon)ic->core.im)->local_impart == NULL)
01154       return True;
01155 
01156     for(p = vl; p->name != NULL; p++) {
01157        if(strcmp(p->name, XNArea)==0) {
01158            if(XIMP_CHK_PREAREAMASK(ic)) {
01159               if((p_rect = (XRectangle *)Xmalloc(sizeof(XRectangle))) == NULL) {
01160                   *return_name = p->name;
01161                   return(False);
01162               }
01163               p_rect->x       = ic->core.preedit_attr.area.x;
01164               p_rect->y       = ic->core.preedit_attr.area.y;
01165               p_rect->width   = ic->core.preedit_attr.area.width;
01166               p_rect->height  = ic->core.preedit_attr.area.height;
01167            } else {
01168               *return_name = p->name;
01169               return(False);
01170            }
01171            *((XRectangle **)(p->value)) = p_rect;
01172        } else if(strcmp(p->name, XNAreaNeeded)==0) {
01173          unsigned int win_width, win_height;
01174          XFontSet fs = ic->core.preedit_attr.fontset;
01175          XFontSetExtents *fse = 0;
01176 
01177          if((p_rect = (XRectangle *)Xmalloc(sizeof(XRectangle))) ==
01178             (XRectangle *)NULL) {
01179            *return_name = p->name;
01180            return(False);
01181          }
01182          memset(p_rect, 0, sizeof(XRectangle));
01183          p_rect->x  = p_rect->y  = 0;
01184 
01185          if (fs) fse = XExtentsOfFontSet(fs);
01186          if (fse && fse->max_logical_extent.width)
01187            win_width = fse->max_logical_extent.width * MAX_PREEDIT_CHARNUM;
01188          else
01189            win_width = 100;
01190          if (fse && fse->max_logical_extent.height)
01191            win_height = fse->max_logical_extent.height;
01192          else
01193            win_height = 20;
01194 
01195          p_rect->width = ic->core.preedit_attr.area_needed.width;
01196          if (!(p_rect->width) || (p_rect->width > win_width)) {
01197            p_rect->width = win_width;
01198          }
01199 
01200          p_rect->height = ic->core.preedit_attr.area_needed.height;
01201          if (!(p_rect->height) || (p_rect->height > win_height)) {
01202            p_rect->height = win_height;
01203          }
01204          *((XRectangle **)(p->value)) = p_rect;
01205        } else if(strcmp(p->name, XNSpotLocation)==0) {
01206            if(XIMP_CHK_PRESPOTLMASK(ic)) {
01207               if((p_point = (XPoint *)Xmalloc(sizeof(XPoint))) == NULL) {
01208                   *return_name = p->name;
01209                   return(False);
01210               }
01211               p_point->x = ic->core.preedit_attr.spot_location.x;
01212               p_point->y = ic->core.preedit_attr.spot_location.y;
01213            } else {
01214               *return_name = p->name;
01215               return(False);
01216            }
01217            *((XPoint **)(p->value)) = p_point;
01218        } else if(strcmp(p->name, XNColormap)==0) {
01219            if(XIMP_CHK_PRECOLORMAPMASK(ic)) {
01220               *((Colormap *)(p->value)) = ic->core.preedit_attr.colormap;
01221            } else {
01222               *return_name = p->name;
01223               return(False);
01224            }
01225        } else if(strcmp(p->name, XNStdColormap)==0) {
01226            if(XIMP_CHK_PRESTDCOLORMAPMASK(ic))
01227               *((Atom *)(p->value)) = ic->core.preedit_attr.std_colormap;
01228            else {
01229               *return_name = p->name;
01230               return(False);
01231            }
01232        } else if(strcmp(p->name, XNBackground)==0) {
01233            if(XIMP_CHK_PREBGMASK(ic)) {
01234               *((unsigned long *)(p->value)) = ic->core.preedit_attr.background;
01235            } else {
01236               *return_name = p->name;
01237               return(False);
01238            }
01239        } else if(strcmp(p->name, XNForeground)==0) {
01240            if(XIMP_CHK_PREFGMASK(ic)) {
01241               *((unsigned long *)(p->value)) = ic->core.preedit_attr.foreground;
01242            } else {
01243               *return_name = p->name;
01244               return(False);
01245            }
01246        } else if(strcmp(p->name, XNBackgroundPixmap)==0) {
01247            if(XIMP_CHK_PREBGPIXMAPMASK(ic)) {
01248               *((Pixmap *)(p->value)) = ic->core.preedit_attr.background_pixmap;
01249            } else {
01250               *return_name = p->name;
01251               return(False);
01252            }
01253        } else if(strcmp(p->name, XNFontSet)==0) {
01254            if(XIMP_CHK_PREFONTMASK(ic)) {
01255               *((XFontSet *)(p->value)) = ic->core.preedit_attr.fontset;
01256            } else {
01257               *return_name = p->name;
01258               return(False);
01259            }
01260        } else if(strcmp(p->name, XNLineSpace)==0) {
01261            if(XIMP_CHK_PRELINESPMASK(ic)) {
01262               *((int *)(p->value)) = ic->core.preedit_attr.line_spacing;
01263            } else {
01264               *return_name = p->name;
01265               return(False);
01266            }
01267        } else if(strcmp(p->name, XNCursor)==0) {
01268            if(XIMP_CHK_PRECURSORMASK(ic)) {
01269               *((Cursor *)(p->value)) = ic->core.preedit_attr.cursor;
01270            } else {
01271               *return_name = p->name;
01272               return(False);
01273            }
01274        } else if(strcmp(p->name, XNPreeditStartCallback)==0) {
01275            if((int)ic->core.preedit_attr.start_callback.callback) {
01276               if((p_callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback))) == NULL) {
01277                   *return_name = p->name;
01278                   return(False);
01279               }
01280               p_callback->client_data =
01281                   ic->core.preedit_attr.start_callback.client_data;
01282               p_callback->callback =
01283                   ic->core.preedit_attr.start_callback.callback;
01284               *((XIMCallback **)(p->value)) = p_callback;
01285            } else {
01286               *return_name = p->name;
01287               return(False);
01288            }
01289        } else if(strcmp(p->name, XNPreeditDrawCallback)==0) {
01290            if((int)ic->core.preedit_attr.draw_callback.callback) {
01291               if((p_callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback))) == NULL) {
01292                   *return_name = p->name;
01293                   return(False);
01294               }
01295               p_callback->client_data =
01296                   ic->core.preedit_attr.draw_callback.client_data;
01297               p_callback->callback =
01298                   ic->core.preedit_attr.draw_callback.callback;
01299               *((XIMCallback **)(p->value)) = p_callback;
01300            } else {
01301               *return_name = p->name;
01302               return(False);
01303            }
01304        } else if(strcmp(p->name, XNPreeditDoneCallback)==0) {
01305            if((int)ic->core.preedit_attr.done_callback.callback) {
01306               if((p_callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback))) == NULL) {
01307                   *return_name = p->name;
01308                   return(False);
01309               }
01310               p_callback->client_data =
01311                   ic->core.preedit_attr.done_callback.client_data;
01312               p_callback->callback =
01313                   ic->core.preedit_attr.done_callback.callback;
01314               *((XIMCallback **)(p->value)) = p_callback;
01315            } else {
01316               *return_name = p->name;
01317               return(False);
01318            }
01319        } else if(strcmp(p->name, XNPreeditCaretCallback)==0) {
01320            if((int)ic->core.preedit_attr.caret_callback.callback) {
01321               if((p_callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback))) == NULL) {
01322                   *return_name = p->name;
01323                   return(False);
01324               }
01325               p_callback->client_data =
01326                   ic->core.preedit_attr.caret_callback.client_data;
01327               p_callback->callback =
01328                   ic->core.preedit_attr.caret_callback.callback;
01329               *((XIMCallback **)(p->value)) = p_callback;
01330            } else {
01331               *return_name = p->name;
01332               return(False);
01333            }
01334        } else if(strcmp(p->name, XNPreeditState)==0) {
01335          *((XIMPreeditState*)(p->value)) = ic->core.preedit_attr.preedit_state;
01336        } else if(strcmp(p->name, XNPreeditStateNotifyCallback)==0) {
01337          if ((int)ic->core.preedit_attr.state_notify_callback.callback) {
01338            if ((p_callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback))) == NULL) {
01339              *return_name = p->name;
01340              return(False);
01341            }
01342            p_callback->client_data =
01343              ic->core.preedit_attr.state_notify_callback.client_data;
01344            p_callback->callback =
01345              ic->core.preedit_attr.state_notify_callback.callback;
01346            *((XIMCallback **)(p->value)) = p_callback;
01347          } else {
01348            *return_name = p->name;
01349            return(False);
01350          }
01351        }
01352     }
01353     return(True);
01354 }
01355 
01356 static char *
01357 _Ximp_Local_GetICValues(XIC xic, XIMArg *arg) {
01358     XicCommon ic = (XicCommon)xic;
01359     XIMArg           *p;
01360     char             *p_char;
01361     char             *return_name = NULL;
01362     int               len;
01363 
01364     if (((XimCommon)ic->core.im)->local_impart == NULL)
01365       return NULL;
01366 
01367     for(p = arg; p->name != NULL; p++) {
01368        if(strcmp(p->name, XNInputStyle) == 0) {
01369            if(ic->ximp_icpart->value_mask & XIMP_INPUT_STYLE) {
01370               *((XIMStyle *)(p->value)) = ic->core.input_style;
01371            } else {
01372               return_name = p->name;
01373               break;
01374            }
01375        } else if(strcmp(p->name, XNClientWindow)==0) {
01376            if(ic->ximp_icpart->value_mask & XIMP_CLIENT_WIN) {
01377               *((Window *)(p->value)) = ic->core.client_window;
01378            } else {
01379               return_name = p->name;
01380               break;
01381            }
01382        } else if(strcmp(p->name, XNFocusWindow)==0) {
01383            if(XIMP_CHK_FOCUSWINMASK(ic)) {
01384               *((Window *)(p->value)) = ic->core.focus_window;
01385            } else {
01386               return_name = p->name;
01387               break;
01388            }
01389        } else if(strcmp(p->name, XNResourceName)==0) {
01390            if(ic->core.im->core.res_name != (char *)NULL) {
01391                   len = strlen(ic->core.im->core.res_name);
01392               if((p_char = Xmalloc(len+1)) == NULL) {
01393                   return_name = p->name;
01394                   break;
01395               }
01396               strcpy(p_char, ic->core.im->core.res_name);
01397               *((char **)(p->value)) = p_char;
01398            } else {
01399               return_name = p->name;
01400               break;
01401            }
01402        } else if(strcmp(p->name, XNResourceClass)==0) {
01403            if(ic->core.im->core.res_class != (char *)NULL) {
01404               len = strlen(ic->core.im->core.res_class);
01405               if((p_char = Xmalloc(len+1)) == NULL) {
01406                   return_name = p->name;
01407                   break;
01408               }
01409               strcpy(p_char, ic->core.im->core.res_class);
01410               *((char **)(p->value)) = p_char;
01411            } else {
01412               return_name = p->name;
01413               break;
01414            }
01415        } else if(strcmp(p->name, XNGeometryCallback)==0) {
01416            if(ic->ximp_icpart->value_mask & XIMP_GEOMETRY_CB) {
01417               *((XICCallback *)(p->value)) = ic->core.geometry_callback;
01418            } else {
01419               return_name = p->name;
01420               break;
01421            }
01422        } else if(strcmp(p->name, XNFilterEvents)==0) {
01423            *((unsigned long *)(p->value)) = ic->core.filter_events;
01424        } else if(strcmp(p->name, XNPreeditAttributes)==0) {
01425            if( _Ximp_PreGetAttributes((Ximp_XIC)ic, (XIMArg*)p->value,
01426                                    &return_name) == False)
01427               break;
01428        } else if(strcmp(p->name, XNStatusAttributes)==0) {
01429            if( _Ximp_StatusGetAttributes((Ximp_XIC)ic, (XIMArg*)p->value,
01430                                      &return_name) == False)
01431               break;
01432        } else if (strcmp(p->name, XNPreeditState)==0) { 
01433          *((XIMPreeditState*)(p->value)) = ic->core.preedit_attr.preedit_state;
01434        } else if (strcmp(p->name, XNPreeditStateNotifyCallback)==0) { 
01435          XIMCallback *p_callback;
01436          if ((int)ic->core.preedit_attr.state_notify_callback.callback) {
01437            if ((p_callback = (XIMCallback *)Xmalloc(sizeof(XIMCallback))) == NULL) {
01438              return_name = p->name;
01439              return(False);
01440            }
01441            p_callback->client_data =
01442              ic->core.preedit_attr.state_notify_callback.client_data;
01443            p_callback->callback =
01444              ic->core.preedit_attr.state_notify_callback.callback;
01445            *((XIMCallback **)(p->value)) = p_callback;
01446          } else {
01447            return_name = p->name;
01448            break;
01449          }
01450        }
01451     }
01452     return(return_name);
01453 }
01454 
01455 static void
01456 _Ximp_Local_DestroyIC(xic)
01457 XIC xic;
01458 {
01459   SWITCH_DestroyIC(xic);
01460   CommonDestroyIC(xic);
01461   return;
01462 }
01463 
01464 static void
01465 _Ximp_Local_SetFocus(XIC xic) {
01466   XicCommon ic = (XicCommon)xic;
01467   XIC current_ic;
01468 
01469   if (((XimCommon)ic->core.im)->local_impart == NULL)
01470     return;
01471 
01472   current_ic = ((XimCommon)ic->core.im)->local_impart->current_ic;
01473 
01474   if (current_ic != (XIC)NULL) {
01475     _Ximp_Local_UnSetFocus((XIC)current_ic);
01476   }
01477   ((XimCommon)ic->core.im)->local_impart->current_ic = (XIC)ic;
01478 
01479   if (!XIM_IS_SWITCH(ic->core.im))
01480     _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
01481                         KeyPress, KeyRelease,
01482                         Ximp_Local_KeyFilter, (XPointer)ic);
01483   Ximp_Local_Status_Set(ic);
01484   Ximp_Local_Status_Start(ic);
01485   Ximp_Local_Status_Draw(ic);
01486   return;
01487 }
01488 
01489 static void
01490 _Ximp_Local_UnSetFocus(XIC xic) {
01491   XicCommon ic = (XicCommon)xic;
01492 
01493   if (((XimCommon)ic->core.im)->local_impart == NULL)
01494     return;
01495 
01496   ((XimCommon)ic->core.im)->local_impart->current_ic = (XIC)NULL;
01497   _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
01498                    Ximp_Local_KeyFilter, (XPointer)ic);
01499 }
01500 
01501 static Bool
01502 _Ximp_PreSetAttributes(ic, attr, vl, mode, change_mask, return_name)
01503 Ximp_XIC              ic;
01504 Ximp_PreeditPropRec4 *attr;
01505 XIMArg               *vl;
01506 int                   mode;
01507 XimpChangeaMask       change_mask;
01508 char                 *return_name;
01509 {
01510        XIMArg               *p;
01511        XStandardColormap    *colormap_ret;
01512        int                   list_ret;
01513        XFontStruct          **struct_list;
01514        char                 **name_list;
01515        int                   i, len;
01516        int                   count;
01517        char                 *tmp;
01518 
01519        for(p = vl; p && p->name != NULL; p++) {
01520               TRACE_MESSAGE('a', ("local_PreSetAttributes: %s\n", p->name));
01521               if(strcmp(p->name, XNArea)==0) {
01522                      ic->core.preedit_attr.area.x = ((XRectangle *)p->value)->x;
01523                      ic->core.preedit_attr.area.y = ((XRectangle *)p->value)->y;
01524                      ic->core.preedit_attr.area.width = ((XRectangle *)p->value)->width;
01525                      ic->core.preedit_attr.area.height = ((XRectangle *)p->value)->height;
01526                      attr->Area.x      = ic->core.preedit_attr.area.x;
01527                      attr->Area.y      = ic->core.preedit_attr.area.y;
01528                      attr->Area.width  = ic->core.preedit_attr.area.width;
01529                      attr->Area.height = ic->core.preedit_attr.area.height;
01530                      XIMP_SET_PREAREAMASK(ic, change_mask);
01531 
01532               } else if(strcmp(p->name, XNAreaNeeded)==0) {
01533                      ic->core.preedit_attr.area_needed.width  = ((XRectangle *)p->value)->width;
01534                      ic->core.preedit_attr.area_needed.height = ((XRectangle *)p->value)->height;
01535                      attr->AreaNeeded.width  = ic->core.preedit_attr.area_needed.width;
01536                      attr->AreaNeeded.height = ic->core.preedit_attr.area_needed.height;
01537                      XIMP_SET_PREAREANEEDMASK(ic, change_mask);
01538 
01539               } else if(strcmp(p->name, XNSpotLocation)==0) {
01540                      ic->core.preedit_attr.spot_location.x = ((XPoint *)p->value)->x;
01541                      ic->core.preedit_attr.spot_location.y = ((XPoint *)p->value)->y;
01542                      attr->SpotLocation.x = ic->core.preedit_attr.spot_location.x;
01543                      attr->SpotLocation.y = ic->core.preedit_attr.spot_location.y;
01544                      XIMP_SET_PRESPOTLMASK(ic, change_mask);
01545 
01546               } else if(strcmp(p->name, XNColormap)==0) {
01547                      ic->core.preedit_attr.colormap = (Colormap)p->value;
01548                      attr->Colormap = ic->core.preedit_attr.colormap;
01549                      XIMP_SET_PRECOLORMAPMASK(ic, change_mask);
01550 
01551               } else if(strcmp(p->name, XNStdColormap)==0) {
01552                      if( XGetRGBColormaps(ic->core.im->core.display,
01553                                    ic->core.focus_window, &colormap_ret,
01554                                    &count, (Atom)p->value) != 0) {
01555                             ic->core.preedit_attr.std_colormap = (Atom)p->value;
01556                             attr->StdColormap = ic->core.preedit_attr.std_colormap;
01557                             XIMP_SET_PRESTDCOLORMAPMASK(ic, change_mask);
01558                      } else {
01559                             return_name = p->name;
01560                             return(False);
01561                      }
01562 
01563               } else if(strcmp(p->name, XNBackground)==0) {
01564                      ic->core.preedit_attr.background = (unsigned long)p->value;
01565                      attr->Background = ic->core.preedit_attr.background;
01566                      XIMP_SET_PREBGMASK(ic, change_mask);
01567 
01568               } else if(strcmp(p->name, XNForeground)==0) {
01569                      ic->core.preedit_attr.foreground = (unsigned long)p->value;
01570                      attr->Foreground = ic->core.preedit_attr.foreground;
01571                      XIMP_SET_PREFGMASK(ic, change_mask);
01572 
01573               } else if(strcmp(p->name, XNBackgroundPixmap)==0) {
01574                      ic->core.preedit_attr.background_pixmap = (Pixmap)p->value;
01575                      attr->Bg_Pixmap = ic->core.preedit_attr.background_pixmap;
01576                      XIMP_SET_PREBGPIXMAPMASK(ic, change_mask);
01577 
01578               } else if(strcmp(p->name, XNFontSet)==0) {
01579                 ic->core.preedit_attr.fontset = (XFontSet)p->value;
01580                 if(p->value != NULL) {
01581                   if(ic->ximp_icpart->preedit_font)
01582                     Xfree(ic->ximp_icpart->preedit_font);
01583                   list_ret = XFontsOfFontSet(ic->core.preedit_attr.fontset,
01584                                           &struct_list, &name_list);
01585                   for(i = 0, len = 0; i < list_ret; i++) {
01586                     len += (strlen(name_list[i]) + sizeof(char));
01587                   }
01588                   if( (tmp = Xmalloc(len + list_ret + sizeof(char))) == NULL ) {
01589                     return_name = p->name;
01590                     return( False );
01591                   }
01592                   tmp[0] = 0;
01593                   for(i = 0; i < list_ret; i++) {
01594                     strcat(tmp, name_list[i]);
01595                     strcat(tmp, ",");
01596                   }
01597                   tmp[len + i - 1] = 0;
01598                   ic->ximp_icpart->preedit_font = tmp;
01599                   XIMP_SET_PREFONTMASK(ic, change_mask);
01600                 } else {
01601                   return_name = p->name;
01602                   return(False);
01603                 }
01604 
01605               } else if(strcmp(p->name, XNLineSpace)==0) {
01606                   ic->core.preedit_attr.line_spacing = (long)p->value;
01607                   attr->LineSpacing = ic->core.preedit_attr.line_spacing;
01608                   XIMP_SET_PRELINESPMASK(ic, change_mask);
01609 
01610               } else if(strcmp(p->name, XNCursor)==0) {
01611                   ic->core.preedit_attr.cursor = (Cursor)p->value;
01612                   attr->Cursor = ic->core.preedit_attr.cursor;
01613                   XIMP_SET_PRECURSORMASK(ic, change_mask);
01614 
01615               } else if(strcmp(p->name, XNPreeditStartCallback)==0) {
01616                   ic->core.preedit_attr.start_callback.client_data =
01617                      ((XIMCallback *)p->value)->client_data;
01618                   ic->core.preedit_attr.start_callback.callback =
01619                      ((XIMCallback *)p->value)->callback;
01620                   ic->ximp_icpart->value_mask |= XIMP_PRE_CALLBAK;
01621 
01622               } else if(strcmp(p->name, XNPreeditDoneCallback)==0) {
01623                   ic->core.preedit_attr.done_callback.client_data =
01624                      ((XIMCallback *)p->value)->client_data;
01625                   ic->core.preedit_attr.done_callback.callback =
01626                      ((XIMCallback *)p->value)->callback;
01627                   ic->ximp_icpart->value_mask |= XIMP_PRE_CALLBAK;
01628                   
01629               } else if(strcmp(p->name, XNPreeditDrawCallback)==0) {
01630                   ic->core.preedit_attr.draw_callback.client_data =
01631                      ((XIMCallback *)p->value)->client_data;
01632                   ic->core.preedit_attr.draw_callback.callback =
01633                      ((XIMCallback *)p->value)->callback;
01634                   ic->ximp_icpart->value_mask |= XIMP_PRE_CALLBAK;
01635 
01636               } else if(strcmp(p->name, XNPreeditCaretCallback)==0) {
01637                   ic->core.preedit_attr.caret_callback.client_data =
01638                      ((XIMCallback *)p->value)->client_data;
01639                   ic->core.preedit_attr.caret_callback.callback =
01640                      ((XIMCallback *)p->value)->callback;
01641                   ic->ximp_icpart->value_mask |= XIMP_PRE_CALLBAK;
01642               } else if(strcmp(p->name, XNPreeditState)==0) {
01643                   ic->core.preedit_attr.preedit_state = (XIMPreeditState)p->value;
01644                    if (XIM_IS_SWITCH(ic->core.im))
01645                     ChangePreeditState((XicCommon)ic);
01646                 } else if (strcmp(p->name, XNPreeditStateNotifyCallback)==0) {
01647                   ic->core.preedit_attr.state_notify_callback.client_data =
01648                      ((XIMCallback *)p->value)->client_data;
01649                   ic->core.preedit_attr.state_notify_callback.callback =
01650                      ((XIMCallback *)p->value)->callback;
01651                   ic->ximp_icpart->value_mask |= XIMP_PRE_CALLBAK;
01652               }
01653        }
01654        return(True);
01655 }
01656 
01657 static Bool
01658 _Ximp_StatusSetAttributes(ic, attr, vl, mode, change_mask, return_name)
01659 Ximp_XIC              ic;
01660 Ximp_StatusPropRec4  *attr;
01661 XIMArg               *vl;
01662 int                   mode;
01663 XimpChangeaMask       change_mask;
01664 char                 *return_name;
01665 {
01666        XIMArg               *p;
01667        XStandardColormap    *colormap_ret;
01668        int                   list_ret;
01669        XFontStruct          **struct_list;
01670        char                 **name_list;
01671        int                   i, len;
01672        int                   count;
01673        char                 *tmp;
01674 
01675        for(p = vl; p && p->name != NULL; p++) {
01676               if(strcmp(p->name, XNArea)==0) {
01677                      ic->core.status_attr.area.x = ((XRectangle *)p->value)->x;
01678                      ic->core.status_attr.area.y = ((XRectangle *)p->value)->y;
01679                      ic->core.status_attr.area.width = ((XRectangle *)p->value)->width;
01680                      ic->core.status_attr.area.height = ((XRectangle *)p->value)->height;
01681                      attr->Area.x      = ic->core.status_attr.area.x;
01682                      attr->Area.y      = ic->core.status_attr.area.y;
01683                      attr->Area.width  = ic->core.status_attr.area.width;
01684                      attr->Area.height = ic->core.status_attr.area.height;
01685                      XIMP_SET_STSAREAMASK(ic, change_mask);
01686                      Ximp_Local_Status_Window((XicCommon)ic);
01687               } else if(strcmp(p->name, XNAreaNeeded)==0) {
01688                      ic->core.status_attr.area_needed.width  = ((XRectangle *)p->value)->width;
01689                      ic->core.status_attr.area_needed.height = ((XRectangle *)p->value)->height;
01690                      attr->AreaNeeded.width  = ic->core.status_attr.area_needed.width;
01691                      attr->AreaNeeded.height = ic->core.status_attr.area_needed.height;
01692                      XIMP_SET_STSAREANEEDMASK(ic, change_mask);
01693 
01694               } else if(strcmp(p->name, XNColormap)==0) {
01695                      ic->core.status_attr.colormap = (Colormap)p->value;
01696                      attr->Colormap = ic->core.status_attr.colormap;
01697                      XIMP_SET_STSCOLORMAPMASK(ic, change_mask);
01698 
01699               } else if(strcmp(p->name, XNStdColormap)==0) {
01700                      if(XGetRGBColormaps(ic->core.im->core.display,
01701                                    ic->core.focus_window, &colormap_ret,
01702                                    &count, (Atom)p->value) !=0) {
01703                             ic->core.status_attr.std_colormap = (Atom)p->value;
01704                             attr->StdColormap = ic->core.status_attr.std_colormap;
01705                             XIMP_SET_STSSTDCOLORMAPMASK(ic, change_mask);
01706                      } else {
01707                             return_name = p->name;
01708                             return(False);
01709                      }
01710 
01711               } else if(strcmp(p->name, XNBackground)==0) {
01712                      ic->core.status_attr.background = (unsigned long)p->value;
01713                      attr->Background = ic->core.status_attr.background;
01714                      XIMP_SET_STSBGMASK(ic, change_mask);
01715               } else if(strcmp(p->name, XNForeground)==0) {
01716                      ic->core.status_attr.foreground = (unsigned long)p->value;
01717                      attr->Foreground = ic->core.status_attr.foreground;
01718                      XIMP_SET_STSFGMASK(ic, change_mask);
01719               } else if(strcmp(p->name, XNBackgroundPixmap)==0) {
01720                      ic->core.status_attr.background_pixmap = (Pixmap)p->value;
01721                      attr->Bg_Pixmap = ic->core.status_attr.background_pixmap;
01722                      XIMP_SET_STSBGPIXMAPMASK(ic, change_mask);
01723 
01724               } else if(strcmp(p->name, XNFontSet)==0) {
01725                 ic->core.status_attr.fontset = (XFontSet)p->value;
01726                 if (p->value != NULL) {
01727                   if(ic->ximp_icpart->status_font)
01728                     Xfree(ic->ximp_icpart->status_font);
01729                   list_ret = XFontsOfFontSet(ic->core.status_attr.fontset,
01730                                           &struct_list, &name_list);
01731                   for(i = 0, len = 0; i < list_ret; i++) {
01732                     len += (strlen(name_list[i]) + sizeof(char));
01733                   }
01734                   if((tmp = Xmalloc(len + list_ret + sizeof(char))) == NULL){
01735                     return_name = p->name;
01736                     return( False );
01737                   }
01738                   tmp[0] = 0;
01739                   for(i = 0; i < list_ret; i++) {
01740                     strcat(tmp, name_list[i]);
01741                     strcat(tmp, ",");
01742                   }
01743                   tmp[len + i - 1] = 0;
01744                   ic->ximp_icpart->status_font = tmp;
01745                   XIMP_SET_STSFONTMASK(ic, change_mask);
01746                 } else {
01747                   return_name = p->name;
01748                   return(False);
01749                 }
01750               } else if(strcmp(p->name, XNLineSpace)==0) {
01751                   ic->core.status_attr.line_spacing = (long)p->value;
01752                   attr->LineSpacing = ic->core.status_attr.line_spacing;
01753                   XIMP_SET_STSLINESPMASK(ic, change_mask);
01754 
01755               } else if(strcmp(p->name, XNCursor)==0) {
01756                      ic->core.status_attr.cursor = (Cursor)p->value;
01757                      attr->Cursor = ic->core.status_attr.cursor;
01758                      XIMP_SET_STSCURSORMASK(ic, change_mask);
01759 
01760               } else if(strcmp(p->name, XNStatusStartCallback)==0) {
01761                   ic->core.status_attr.start_callback.client_data =
01762                      ((XIMCallback *)p->value)->client_data;
01763                      ic->core.status_attr.start_callback.callback =
01764                             ((XIMCallback *)p->value)->callback;
01765                      ic->ximp_icpart->value_mask |= XIMP_STS_CALLBAK;
01766 
01767               } else if(strcmp(p->name, XNStatusDoneCallback)==0) {
01768                   ic->core.status_attr.done_callback.client_data =
01769                             ((XIMCallback *)p->value)->client_data;
01770                   ic->core.status_attr.done_callback.callback =
01771                      ((XIMCallback *)p->value)->callback;
01772                   ic->ximp_icpart->value_mask |= XIMP_STS_CALLBAK;
01773 
01774               } else if(strcmp(p->name, XNStatusDrawCallback)==0) {
01775                   ic->core.status_attr.draw_callback.client_data =
01776                      ((XIMCallback *)p->value)->client_data;
01777                   ic->core.status_attr.draw_callback.callback =
01778                      ((XIMCallback *)p->value)->callback;
01779                   ic->ximp_icpart->value_mask |= XIMP_STS_CALLBAK;
01780               }
01781        }
01782        return(True);
01783 }
01784 
01785 static void ComposeKeyEventFilter(Ximp_XIC ic, Window old_focus_window);
01786 
01787 static char *
01788 _Ximp_Local_SetICValueData(Ximp_XIC ic, XIMArg *arg,
01789                         int mode, XimpChangeaMask change_mask) {
01790   XIMArg *p;
01791   char *return_name = NULL;
01792 
01793   for (p = arg; p->name != NULL; p++) {
01794     if (strcmp(p->name, XNInputStyle) == 0) {
01795       if (mode == XIMP_CREATE_IC) {
01796        ic->core.input_style = (XIMStyle)p->value;
01797        ic->ximp_icpart->value_mask |= XIMP_INPUT_STYLE;
01798       } else {
01799        ; /* Currently Fixed value */
01800       }
01801     } else if(strcmp(p->name, XNClientWindow)==0) {
01802       if (!(ic->ximp_icpart->value_mask & XIMP_CLIENT_WIN)) {
01803        ic->core.client_window = (Window)p->value;
01804        ic->ximp_icpart->value_mask |= XIMP_CLIENT_WIN;
01805        if (!(XIMP_CHK_FOCUSWINMASK(ic))) {
01806          ic->core.focus_window = ic->core.client_window;
01807          XIMP_SET_FOCUSWINMASK2(ic, change_mask);
01808        }
01809        Ximp_Local_Status_Create((XicCommon)ic);
01810       } else {
01811        if (ic->core.client_window == (Window)p->value)
01812          /* same window */
01813          continue;
01814  
01815        return_name = p->name;
01816        break; /* Can't change this value */
01817       }
01818     } else if(strcmp(p->name, XNFocusWindow)==0) {
01819       Window old_focus_window = 0;
01820       if ((Window)p->value != 0 &&
01821          (Window)p->value == ic->core.focus_window) {
01822        continue;
01823       }
01824       old_focus_window = ic->core.focus_window;
01825       ic->core.focus_window = (Window)p->value;
01826       XIMP_SET_FOCUSWINMASK2(ic, change_mask);
01827       ComposeKeyEventFilter(ic, old_focus_window);
01828     } else if(strcmp(p->name, XNResourceName)==0) {
01829       ic->core.im->core.res_name = (char *)p->value;
01830       ic->ximp_icpart->value_mask |= XIMP_RES_NAME;
01831            
01832     } else if(strcmp(p->name, XNResourceClass)==0) {
01833       ic->core.im->core.res_class = (char *)p->value;
01834       ic->ximp_icpart->value_mask |= XIMP_RES_CLASS;
01835            
01836     } else if(strcmp(p->name, XNGeometryCallback)==0) {
01837       ic->core.geometry_callback.client_data =
01838        ((XICCallback *)p->value)->client_data;
01839       ic->core.geometry_callback.callback =
01840        ((XICCallback *)p->value)->callback;
01841       ic->ximp_icpart->value_mask |= XIMP_GEOMETRY_CB;
01842            
01843     } else if(strcmp(p->name, XNPreeditAttributes)==0) {
01844       if( _Ximp_PreSetAttributes((Ximp_XIC)ic,
01845                              &(ic->ximp_icpart->preedit_attr),
01846                              (XIMArg*)p->value, mode, change_mask,
01847                              return_name) == False )
01848        break;
01849            
01850     } else if(strcmp(p->name, XNStatusAttributes)==0) {
01851       if( _Ximp_StatusSetAttributes((Ximp_XIC)ic,
01852                                 &(ic->ximp_icpart->status_attr),
01853                                 (XIMArg*)p->value, mode, change_mask,
01854                                 return_name) == False )
01855        break;
01856     } else if (strcmp(p->name, XNPreeditState)==0) {
01857       ic->core.preedit_attr.preedit_state = (XIMPreeditState)p->value;
01858       if (XIM_IS_SWITCH(ic->core.im))
01859        ChangePreeditState((XicCommon)ic);
01860     } else if (strcmp(p->name, XNPreeditStateNotifyCallback)==0) {
01861       ic->core.preedit_attr.state_notify_callback.client_data =
01862        ((XIMCallback *)p->value)->client_data;
01863       ic->core.preedit_attr.state_notify_callback.callback =
01864        ((XIMCallback *)p->value)->callback;
01865     } else {
01866       return_name = p->name;
01867       break;
01868     }
01869   }
01870   return(return_name);
01871 }
01872 
01873 static char *
01874 _Ximp_Local_SetICValues(XIC xic, XIMArg *arg) {
01875   XicCommon    ic = (XicCommon)xic;
01876   char        *ret;
01877   XimpChangeMaskRec   change_mask;
01878 
01879   if (((XimCommon)ic->core.im)->local_impart == NULL)
01880     return NULL;
01881 
01882   XIMP_SET_NULLMASK(change_mask);
01883   if((ret = _Ximp_Local_SetICValueData((Ximp_XIC)ic, arg,
01884                                    XIMP_SET_IC, &change_mask)))
01885     return(ret);
01886 
01887   Ximp_Local_Status_Set(ic);
01888   Ximp_Local_Status_Start(ic);
01889   Ximp_Local_Status_Draw(ic);
01890   if ((ic->ximp_icpart->value_mask & XIMP_RES_NAME)
01891       || (ic->ximp_icpart->value_mask & XIMP_RES_CLASS) )
01892     _Ximp_SetValue_Resource((Ximp_XIC)ic, &change_mask);
01893   return(ret);
01894 }
01895 
01896 static char *_Ximp_Local_MbReset(XIC xic) {
01897   XicCommon ic = (XicCommon)xic;
01898   XIMComposeIM lim = ((XimCommon)ic->core.im)->local_impart;
01899 
01900   if (ic->local_icpart == NULL)
01901     return NULL;
01902 
01903   ic->local_icpart->composed = (DefTree *)NULL;
01904   if (lim->use_binary_table == True)
01905     ic->local_icpart->context = (DefTree *)BCF_STATE_PARSER(lim->state_addr, (CARD32)(ic->local_icpart->imstate));
01906   else
01907     ic->local_icpart->context = ic->local_icpart->imstate->parser;
01908 
01909   return(NULL);
01910 }
01911 
01912 static wchar_t *
01913 _Ximp_Local_WcReset(XIC xic) {
01914   XicCommon ic = (XicCommon)xic;
01915   XIMComposeIM lim = ((XimCommon)ic->core.im)->local_impart;
01916 
01917   ic->local_icpart->composed = (DefTree *)NULL;
01918   if (lim->use_binary_table == True)
01919     ic->local_icpart->context = (DefTree *)BCF_STATE_PARSER(lim->state_addr, (CARD32)(ic->local_icpart->imstate));
01920   else
01921     ic->local_icpart->context = ic->local_icpart->imstate->parser;
01922 
01923   return(NULL);
01924 }
01925 
01926 static int
01927 _Ximp_Local_MbLookupString(XIC xic, XKeyEvent *ev, char * buffer,
01928                         int bytes, KeySym *keysym, Status *status) {
01929   XicCommon ic = (XicCommon)xic;
01930   int ret;
01931   static XComposeStatus     compose_status;
01932   XIMComposeIM lim = ((XimCommon)ic->core.im)->local_impart;
01933 
01934   if (ev->type != KeyPress) {
01935     if (status) *status = XLookupNone;
01936     return (0);
01937   }
01938   if (ev->keycode == XIM_COMPOSE_KEYCODE) { /* Composed Event */
01939     char *mb;
01940     KeySym keysym_return;
01941     if (NULL == ic->local_icpart->composed) {
01942       return 0;
01943     }
01944     if (lim->use_binary_table == True){
01945       mb = BCF_STR_STRING(lim->str_addr, BCF_DEF_MB(lim->def_addr, (CARD32)(ic->local_icpart->composed)));
01946       keysym_return = BCF_DEF_KEYSYM_RETURN(lim->def_addr, (CARD32)(ic->local_icpart->composed));
01947     }
01948     else {
01949       mb = ic->local_icpart->composed->mb;
01950       keysym_return = ic->local_icpart->composed->keysym_return;
01951     }
01952 
01953     if (NULL == mb) {
01954       return 0;
01955     }
01956 
01957     ret = strlen(mb);
01958     if (ret > bytes) {
01959       if (status) *status = XBufferOverflow;
01960       return (ret);
01961     }
01962     bcopy(mb, buffer, ret);
01963     if (keysym) {
01964       if(keysym_return)
01965        *keysym = keysym_return;
01966       else
01967        *keysym = NoSymbol;
01968     }
01969     if (status) {
01970       if (keysym_return)
01971        *status = XLookupBoth;
01972       else
01973        *status = XLookupChars;
01974     }
01975     if (ic->local_icpart->imstate->type == CodeInputState) {
01976       Ximp_Local_Preedit_Done(ic);
01977       _Ximp_Local_SetFocus(xic);
01978       return(ret);
01979     }
01980     Xfree(ic->local_icpart->composed->mb);
01981     ic->local_icpart->composed->mb = NULL;
01982     XFree(ic->local_icpart->composed);
01983     ic->local_icpart->composed = (DefTree *)NULL;
01984     return (ret);
01985   } else { /* Throughed Event */
01986     (void)memset((void *)(&compose_status), 0, sizeof(XComposeStatus));
01987     ret = _Ximp_LookupMBText((Ximp_XIC)ic, ev, (unsigned char *)buffer,
01988                           bytes, keysym, &compose_status);
01989     if (ret > 0) {
01990       if (keysym && *keysym != NoSymbol) {
01991        if (status) *status = XLookupBoth;
01992       } else {
01993        if (status) *status = XLookupChars;
01994       }
01995     } else {
01996       if (keysym && *keysym != NoSymbol) {
01997        if (status) *status = XLookupKeySym;
01998       } else {
01999        if (status) *status = XLookupNone;
02000       }
02001     }
02002   }
02003   return (ret);
02004 }
02005 
02006 static int
02007 _Ximp_Local_WcLookupString(XIC xic, XKeyEvent *ev, wchar_t * buffer, 
02008                         int wlen, KeySym *keysym, Status *status) {
02009   XicCommon ic = (XicCommon)xic;
02010   int ret;
02011   static XComposeStatus     compose_status;
02012   XIMComposeIM lim = ((XimCommon)ic->core.im)->local_impart;
02013   char *mb;
02014   size_t mb_len, wc_len;
02015   wchar_t *wc_buf;
02016   XimCommon im = (XimCommon)ic->core.im;
02017 
02018   if (ev->type != KeyPress) {
02019     if (status) *status = XLookupNone;
02020        return (0);
02021     }
02022   if (ev->keycode == XIM_COMPOSE_KEYCODE) { /* Composed Event */
02023     KeySym keysym_return;
02024     if (NULL == ic->local_icpart->composed) {
02025       return 0;
02026     }
02027     if (lim->use_binary_table == True){
02028       mb = BCF_STR_STRING(lim->str_addr, BCF_DEF_MB(lim->def_addr, (CARD32)(ic->local_icpart->composed)));
02029     } else {
02030       mb = ic->local_icpart->composed->mb;
02031     }
02032     mb_len = strlen(mb);
02033     wc_buf = (wchar_t *)Xmalloc(sizeof(wchar_t) * (mb_len + 1));
02034 
02035     wc_len = IIimpMbstoWcs(im, mb, mb_len,
02036                         wc_buf, mb_len, NULL);
02037     if(wc_len < 0)
02038       wc_len = 0;
02039     wc_buf[wc_len] = (wchar_t)0;
02040 
02041     ret = _Xwcslen(wc_buf);
02042     if (ret > wlen) {
02043       if (status) *status = XBufferOverflow;
02044       Xfree(wc_buf);
02045       return (ret);
02046     }
02047     bcopy(wc_buf, buffer, ret * sizeof(wchar_t));
02048     Xfree(wc_buf);
02049 
02050     if (lim->use_binary_table == True) {
02051       keysym_return = BCF_DEF_KEYSYM_RETURN(lim->def_addr, (CARD32)(ic->local_icpart->composed));
02052     } else {
02053       keysym_return = ic->local_icpart->composed->keysym_return;
02054     }
02055 
02056     if (keysym) {
02057       if (keysym_return)
02058        *keysym = keysym_return;
02059       else
02060        *keysym = NoSymbol;
02061     }
02062     if (status) {
02063       if (keysym_return)
02064        *status = XLookupBoth;
02065       else
02066        *status = XLookupChars;
02067     }
02068     if (ic->local_icpart->imstate->type == CodeInputState) {
02069       Ximp_Local_Preedit_Done(ic);
02070       _Ximp_Local_SetFocus(xic);
02071       return(ret);
02072     }
02073     if (ic->local_icpart->composed->mb != NULL) {
02074       Xfree(ic->local_icpart->composed->mb);
02075       ic->local_icpart->composed->mb = NULL;
02076     }
02077     XFree(ic->local_icpart->composed);
02078     ic->local_icpart->composed = (DefTree *)NULL;
02079     return (ret);
02080   } else { /* Throughed Event */
02081     (void)memset((void *)(&compose_status), 0, sizeof(XComposeStatus));
02082     ret = _Ximp_LookupWCText((Ximp_XIC)ic, ev, buffer, wlen, keysym, &compose_status);
02083     if(ret > 0) {
02084       if(keysym && *keysym != NoSymbol) {
02085        if(status) *status = XLookupBoth;
02086       } else {
02087        if(status) *status = XLookupChars;
02088       }
02089     } else {
02090       if(keysym && *keysym != NoSymbol) {
02091        if(status) *status = XLookupKeySym;
02092       } else {
02093        if(status) *status = XLookupNone;
02094       }
02095     }
02096   }
02097   return (ret);
02098 }
02099 
02100 /* Switching */
02101 static Status
02102 SWITCH_CloseIM(xim)
02103 XIM xim;
02104 {
02105   XimCommon im = (XimCommon)xim;
02106   
02107   if (!im->local_impart) return True;
02108 
02109   if (im->local_impart->use_binary_table == True){
02110     if(im->local_impart->map_addr)
02111       munmap(im->local_impart->map_addr, im->local_impart->map_len);
02112   }
02113   else{
02114     LocalIMState  *state = im->local_impart->top_state;
02115     LocalIMState  *state_p;
02116 
02117     while (state) {
02118       if(state->name) XFree(state->name);
02119       state->name = (char *)NULL;
02120 
02121       if(state->language)
02122        XFree(state->language);
02123       state->language = (char *)NULL;
02124 
02125       if (state->parser)
02126        FreeDefTreeElements(state->parser);
02127       state->parser = (DefTree *)NULL;
02128       if (state->attr) {
02129        if (state->type == LookupState) {
02130          if (state->attr->_attr_u.LUstruct.title != NULL)
02131            Xfree(state->attr->_attr_u.LUstruct.title);
02132          state->attr->_attr_u.LUstruct.title = NULL;
02133                      
02134          if (state->attr->_attr_u.LUstruct.range != NULL)
02135            Xfree(state->attr->_attr_u.LUstruct.range);
02136          state->attr->_attr_u.LUstruct.range = NULL;
02137        }
02138        Xfree(state->attr);
02139       }
02140       state->attr = NULL;
02141       state_p = state;
02142       state = state->next;
02143       Xfree(state_p);
02144       state_p = NULL;
02145     }
02146   }
02147   if (im->ximp_impart->im_styles) {
02148     XFree(im->ximp_impart->im_styles->supported_styles);
02149     XFree(im->ximp_impart->im_styles);
02150   }
02151   XFree(im->local_impart);
02152   im->local_impart = 0;
02153   return True;
02154 }
02155 
02156 static void
02157 SWITCH_DestroyIC(XIC xic) {
02158   XicCommon ic = (XicCommon)xic;
02159   XimCommon im = (XimCommon)ic->core.im;
02160   LocalStatusExt *hook;
02161 
02162   if (XIM_IS_SWITCH(im)) {
02163     UnRegisterSwitchFilter(ic, SwitchFilter,
02164                         Ximp_Local_KeyFilter,
02165                         get_local_ic_methods());
02166   }
02167 
02168   if (((XimCommon)ic->core.im)->local_impart->current_ic == (XIC)ic) {
02169     _Ximp_Local_UnSetFocus((XIC)ic);
02170   }
02171 
02172   if (ic->local_icpart) {
02173     hook = (LocalStatusExt*)(ic->local_icpart->status_ext);
02174     if (hook) {
02175       if (hook->gc) XFreeGC(ic->core.im->core.display, hook->gc);
02176       if (hook->rgc) XFreeGC(ic->core.im->core.display, hook->rgc);
02177       Xfree(hook);
02178     }
02179     Ximp_Local_Table_Destroy(ic); /* destroy table_ext */
02180     Ximp_Local_Preedit_Destroy(ic); /* destroy preedit_ext */
02181     Ximp_Local_Lookup_Destroy(ic); /* destroy lookup_ext */
02182 
02183     if (ic->gui_icpart) {
02184       XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_DESTROY, NULL);
02185       XIC_GUI(ic, change_status)((XIC)ic, STATUS_DESTROY, NULL);
02186       XIC_GUI(ic, change_lookup)((XIC)ic, LOOKUP_DESTROY, NULL);
02187     }
02188 
02189     if (ic->local_icpart->composed) {
02190       if (ic->local_icpart->composed->mb) {
02191        Xfree(ic->local_icpart->composed->mb);
02192        ic->local_icpart->composed->mb = NULL;
02193       }
02194       Xfree(ic->local_icpart->composed);
02195       ic->local_icpart->composed = NULL;
02196     }
02197   }
02198   if (ic->ximp_icpart->status_font)
02199     Xfree(ic->ximp_icpart->status_font);
02200   if (ic->ximp_icpart->preedit_font)
02201     Xfree(ic->ximp_icpart->preedit_font);
02202 
02203   if (ic->local_icpart) {
02204     Xfree(ic->local_icpart);
02205     ic->local_icpart = 0;
02206   }
02207 
02208   _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
02209                    Ximp_Local_KeyFilter, (XPointer)ic);
02210   return;
02211 }
02212 
02213 /*
02214  * Resource Extension function is called from XOpenIM().
02215  */
02216 
02217 #ifndef SINGLE_XI18NLIB
02218 void
02219 _Ximp_OpenIMResourceExtension(im)
02220 Ximp_XIM im;
02221 {
02222   /* Add extension here */
02223   return;
02224 }
02225 #endif
02226 
02227 static void
02228 ComposeKeyEventFilter(Ximp_XIC ic, Window old_focus) {
02229   _XUnregisterFilter(ic->core.im->core.display, old_focus,
02230                    Ximp_Local_KeyFilter, (XPointer)ic);
02231   _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
02232                       KeyPress, KeyRelease,
02233                       Ximp_Local_KeyFilter, (XPointer)ic);
02234   return;
02235 }