Back to index

im-sdk  12.3.91
iiimpIC.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 #include "iiimpIM.h"
00043 #include "switchIM.h"
00044 #include "guiIM.h"
00045 #include "XimpIm.h"
00046 #include "iiimpIC.h"
00047 #include "status.h"
00048 #include <X11/keysym.h>            /* For IsModifierKey marco */
00049 #include <X11/Xutil.h>             /* For IsModifierKey marco */
00050 #include "iiimpUtil.h"
00051 #include "iiimpSwitcher.h"
00052 #include "iiimpAuxP.h"
00053 #include "xfactory.h"
00054 
00055 #include "status.h"
00056 
00057 extern char *SetICValueData(
00058     XicCommon ic,
00059     XIMArg *values,
00060     XICSetMode mode,
00061     XimpChangeaMask change_mask
00062 );
00063 extern char *GetICValueData(
00064     XicCommon ic,
00065     XIMArg *values,
00066     XimpChangeaMask change_mask
00067 );
00068 
00069 static void IIIMP_DestroyIC(
00070     XIC xic
00071 );
00072 static void IIIMP_SetFocus(
00073     XIC xic
00074 );
00075 static void IIIMP_UnSetFocus(
00076     XIC xic
00077 );
00078 static char *IIIMP_MbReset(
00079     XIC xic
00080 );
00081 static wchar_t *IIIMP_WcReset(
00082     XIC xic
00083 );
00084 extern char *IIIMP_SetICValues(
00085     XIC xic,
00086     XIMArg *arg
00087 );
00088 extern char *IIIMP_GetICValues(
00089     XIC xic,
00090     XIMArg *arg
00091 );
00092 static int IIIMP_MbLookupString(
00093     XIC xic,
00094     XKeyEvent *ev,
00095     char *buffer,
00096     int len,
00097     KeySym *keysym,
00098     Status *status
00099 );
00100 static int IIIMP_WcLookupString(
00101     XIC xic,
00102     XKeyEvent *ev,
00103     wchar_t *buffer,
00104     int len,
00105     KeySym *keysym,
00106     Status *status
00107 );
00108 
00109 extern IIIMCF_language *iiim_get_languages (XimCommon im, int *n_lang);
00110 
00111 extern IIIMF_status IIimpConvertToString(IIIMCF_text text,
00112                                     Bool useUnicode,
00113                                     char **pstr);
00114 static XICMethods
00115 get_iiimp_ic_methods()
00116 {
00117     static XICMethodsRec icm;
00118     if (!icm.destroy) {
00119        icm.destroy = IIIMP_DestroyIC;
00120        icm.set_focus = IIIMP_SetFocus;
00121        icm.unset_focus = IIIMP_UnSetFocus;
00122        icm.set_values = IIIMP_SetICValues;
00123        icm.get_values = IIIMP_GetICValues;
00124        icm.mb_reset = IIIMP_MbReset;
00125        icm.wc_reset = IIIMP_WcReset;
00126        icm.mb_lookup_string = IIIMP_MbLookupString;
00127        icm.wc_lookup_string = IIIMP_WcLookupString;
00128     }
00129     return &icm;
00130 }
00131 
00132 static void SWITCH_DestroyIC(XIC);
00133 
00134 static
00135 XICMethods
00136 get_switch_ic_methods()
00137 {
00138   static XICMethodsRec icm;
00139   if (!icm.destroy) {
00140     icm.destroy = SWITCH_DestroyIC;
00141     icm.set_focus = IIIMP_SetFocus;
00142     icm.unset_focus = IIIMP_UnSetFocus;
00143   }
00144   return &icm;
00145 }
00146 
00147 Bool
00148 IIIMP_Local_KeyFilter(
00149     Display *d /*unused*/,
00150     Window w /* unused */,
00151     XEvent *ev,
00152     XPointer client_data
00153 );
00154 
00155 void
00156 ChangePreeditState(
00157     XicCommon ic
00158 )
00159 {
00160     if (ic->core.preedit_attr.preedit_state == XIMPreeditEnable &&
00161        !IsConversionMode(ic)) {
00162        SetConversionMode(ic, True);
00163        IMTriggerNotify(ic, CONV_ON);
00164     }
00165     if (ic->core.preedit_attr.preedit_state == XIMPreeditDisable &&
00166        IsConversionMode(ic)) {
00167        IMTriggerNotify(ic, CONV_OFF);
00168        SetConversionMode(ic, False);
00169     }
00170     return;
00171 }
00172 
00173 void
00174 SetConversionMode(
00175     XicCommon ic,
00176     int mode
00177 )
00178 {
00179     XIC_IIIMP(ic, filtered) = mode;
00180 
00181     ic->core.preedit_attr.preedit_state = ((mode == True) ?
00182                                       XIMPreeditEnable :
00183                                       XIMPreeditDisable);
00184     if ((int)ic->core.preedit_attr.state_notify_callback.callback) {
00185        XIMPreeditStateNotifyCallbackStruct call_data;
00186        call_data.state = ic->core.preedit_attr.preedit_state;
00187        ic->core.preedit_attr.state_notify_callback.callback(
00188            (XIC)ic,
00189            ic->core.preedit_attr.state_notify_callback.client_data,
00190            (XPointer)&call_data
00191        );
00192     }
00193     if (XIM_IS_SWITCH(ic->core.im)) {
00194        if (mode == False) {        /* CONV_OFF */
00195            ResetSwitchFilter(ic);
00196            Ximp_Local_Status_Set(ic);
00197            Ximp_Local_Status_Draw(ic);
00198        } else {
00199            ic->active_filter = IIIMP_Local_KeyFilter;
00200            ic->active_methods = get_iiimp_ic_methods();
00201        }
00202     }
00203 }
00204 
00205 static SwitchMode
00206 SwitchFilter(
00207     XicCommon ic,
00208     XEvent *ev
00209 )
00210 {
00211   XimCommon im = (XimCommon)ic->core.im;
00212   if (IsConversionMode(ic)) {
00213     if (isConversionOffKey(im, ev)) {
00214       return Switch_OFF;
00215     }
00216   } else {
00217     if (isConversionOnKey(im, ev)) {
00218       return Switch_ON;
00219     }
00220   }
00221   return Switch_NOP;
00222 }
00223 
00224 Bool
00225 IIIMP_Local_KeyFilter(
00226     Display *d /*unused*/,
00227     Window w /* unused */,
00228     XEvent *ev,
00229     XPointer client_data
00230 )
00231 {
00232     XicCommon ic = (XicCommon)client_data;
00233 
00234     if (!IsIMEnabled())
00235       return False;
00236 
00237     if (ic->ximp_icpart == NULL) {
00238        /* most likely associated ic has been already destroyed */
00239        _XUnregisterFilter(d, w, IIIMP_Local_KeyFilter, (XPointer)ic);
00240        return False;
00241     }
00242     if (ev->xkey.keycode == XIM_COMPOSE_KEYCODE) {
00243        return False;
00244     }
00245     if (0 < XIC_IIIMP(ic, key_event_num)) {
00246        XIC_IIIMP(ic, key_event_num) -= 1;
00247        return False;
00248     }
00249 
00250     /*
00251      * Comment the codes below - FIXME
00252      * Key release event should be forwarded with IMForwardEvent to server
00253      */
00254     if ((KeyRelease == ev->xkey.type) &&
00255        (IIIMF_STATUS_SUCCESS !=
00256         iiimcf_is_capability_supported(XIM_IIIMP(ic->core.im, handle),
00257                                    IIIMP_CAPABILITY_KEY_RELEASE))) {
00258        XIMCallback *cb = &ic->forward_event_callback;
00259        if (NULL != cb->callback) {
00260            (*cb->callback)((XIC)ic, cb->client_data, (XPointer)ev);
00261            return True;
00262        } else {
00263            return IsConversionMode(ic);
00264        }
00265     }
00266 
00267     return IMForwardEvent(ic, ev);
00268 }
00269 
00270 extern char *im_canonicalize_langname(XimCommon im);
00271 
00272 /* Public functions */
00273 XIC
00274 CreateIC(
00275     XimCommon im,
00276     XIMArg *arg
00277 )
00278 {
00279     XicCommon ic = (XicCommon)NULL;
00280 
00281     ic = (XicCommon)Xmalloc(sizeof(XicCommonRec));
00282     if (ic == (XicCommon)NULL) goto Error;
00283     memset(ic, 0, sizeof(XicCommonRec));
00284 
00285     ic->core.im = (XIM)im;
00286     ic->methods = get_iiimp_ic_methods();
00287 
00288     if (!CommonCreateIC((XIC)ic, arg)) goto Error;
00289     
00290     if (!IIIMP_CreateIC_SWITCH((XIC)ic, arg)) goto Error;
00291 
00292     ic->current_language = im_canonicalize_langname(im);
00293 
00294     _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
00295                         KeyPress, KeyRelease,
00296                         IIIMP_Local_KeyFilter, (XPointer)ic);
00297     return (XIC)ic;
00298 Error:
00299     if (ic) Xfree(ic);
00300     return 0;
00301 }
00302 
00303 Status
00304 IIIMP_CreateIC_SWITCH(
00305     XIC xic,
00306     XIMArg *arg
00307 )
00308 {
00309     int id;
00310     XicCommon ic = (XicCommon)xic;
00311     XimCommon im = (XimCommon)ic->core.im;
00312     XimpChangeMaskRec dummy;
00313 
00314     ic->core.filter_events = KeyPressMask|ExposureMask|
00315        ButtonPressMask |PointerMotionMask;
00316     if (!(ic->iiimp_icpart = Xmalloc(sizeof(XICIIimpIMRec)))) {
00317        goto Error;
00318     }
00319     memset(ic->iiimp_icpart, 0, sizeof(XICIIimpIMRec));
00320     XIC_IIIMP(ic, switch_methods) = get_switch_ic_methods();
00321     if (IMCreateIC(im, &XIC_IIIMP(ic, context))
00322        != IIIMF_STATUS_SUCCESS) {
00323        goto Error;
00324     }
00325     id = XIM_IIIMP(im, counter);
00326     XIC_IIIMP(ic, id) = id;
00327     XIM_IIIMP(im, counter) = id + 1;
00328     SetConversionMode(ic, False);
00329 
00330     memset(&dummy, 0, sizeof(dummy));
00331     if (SetICValueData(ic, arg, CREATE_IC, &dummy)) {
00332        goto Error;
00333     }
00334 
00335     /* switch */
00336     if (XIM_IS_SWITCH(im)) {
00337        RegisterSwitchFilter(ic, SwitchFilter,
00338                           IIIMP_Local_KeyFilter,
00339                           get_iiimp_ic_methods());
00340     }
00341 
00342     return True;
00343 Error:
00344     if (ic->iiimp_icpart)
00345        Xfree(ic->iiimp_icpart);
00346     return False;
00347 }
00348 
00349 static void
00350 IIIMP_DestroyIC(
00351     XIC xic
00352 )
00353 {
00354     XicCommon ic = (XicCommon)xic;
00355 
00356     _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
00357                      IIIMP_Local_KeyFilter, (XPointer)ic);
00358     if (ic->current_language)
00359       Xfree (ic->current_language);
00360     IIimpDestroryAuxData(ic);
00361     SWITCH_DestroyIC(xic);
00362     CommonDestroyIC(xic);
00363     return;
00364 }
00365 
00366 extern Bool GetIMSettings (XicCommon ic);
00367 
00368 static void
00369 IIIMP_SetFocus(
00370     XIC xic
00371 )
00372 {
00373     XicCommon ic = (XicCommon)xic;
00374     XimCommon im = (XimCommon)ic->core.im;
00375 
00376     if (XIM_IIIMP(im, current_ic) == xic) {
00377        IIIMP_UnSetFocus(xic);
00378     }
00379     XIM_IIIMP(im, current_ic) = xic;
00380 
00381     XIC_GUI(ic, change_lookup)((XIC)ic, LOOKUP_SETFOCUS, NULL);
00382 
00383     IMChangeFocus(ic, 1);
00384 
00385     ic_switcher_set_focus (ic);
00386 
00387     if (im_switcher_active (im))
00388       {
00389        IIIMCF_language *lang_list;
00390        int n_lang;
00391        char *hotkey;
00392 
00393        lang_list = iiim_get_languages (im, &n_lang);
00394        ic_switcher_set_language_list (ic, lang_list, n_lang);
00395        ic_switcher_set_input_language (ic, NULL);
00396 
00397 // #ifdef CONFIG_HOTKEY
00398 #if 1
00399        if ((hotkey = ic_switcher_get_hotkey_with_atom (ic)) == NULL)
00400          {
00401            if (hotkey = ic_switcher_get_hotkey (ic))
00402              ic_switcher_set_hotkey (ic, hotkey);
00403          }
00404        else
00405          {
00406            char *conversion_keys;
00407 
00408            conversion_keys = ic_switcher_get_hotkey_with_type (hotkey,
00409                                                         TRIGGER_KEY_LABEL);
00410            ic_switcher_change_hotkey_with_type (ic,
00411                                            TRIGGER_KEY_LABEL,
00412                                            conversion_keys);
00413            free (conversion_keys);
00414          }
00415 
00416        if (hotkey) free (hotkey);
00417 #endif
00418       }
00419 
00420     GetIMSettings (ic);
00421 
00422     if (!XIM_IS_SWITCH(ic->core.im)) {
00423        _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
00424                             KeyPress, KeyRelease,
00425                             IIIMP_Local_KeyFilter, (XPointer)ic);
00426     }
00427     return;
00428 }
00429 
00430 static void
00431 IIIMP_UnSetFocus(
00432     XIC xic
00433 )
00434 {
00435     XicCommon ic = (XicCommon)xic;
00436     XimCommon im = (XimCommon)ic->core.im;
00437 
00438     XIM_IIIMP(im, current_ic) = (XIC)NULL;
00439 
00440     IMChangeFocus(ic, 0);
00441 
00442     _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
00443                      IIIMP_Local_KeyFilter, (XPointer)ic);
00444     return;
00445 }
00446 
00447 static char*
00448 IIIMP_MbReset(
00449     XIC xic
00450 )
00451 {
00452     XicCommon ic = (XicCommon)xic;
00453     IIIMF_status st;
00454     IIIMCF_text text;
00455     char *str = NULL;
00456     int caret, len;
00457 
00458     st = iiimcf_get_preedit_text(XIC_IIIMP(ic, context), &text, &caret);
00459     if (st == IIIMF_STATUS_SUCCESS) {
00460         st = iiimcf_get_text_length(text, &len);
00461         if (st == IIIMF_STATUS_SUCCESS && len > 0) {
00462           XICCallback *cb = &ic->core.preedit_attr.draw_callback;
00463           XimCommon im = (XimCommon)ic->core.im;
00464           Bool useUnicode = (XIM_USE_UNICODE(im) && cb->callback &&
00465                              (ic->core.input_style & XIMPreeditCallbacks));
00466           st = IIimpConvertToString(text, useUnicode, &str);
00467           if (st != IIIMF_STATUS_SUCCESS && str) {
00468             free(str);
00469             str = NULL;
00470           }
00471         }
00472     }
00473     iiimcf_reset_context(XIC_IIIMP(ic, context));
00474     ic->core.preedit_attr.preedit_state = XIMPreeditDisable;
00475     ChangePreeditState(ic);
00476     /* to unmap preedit window */
00477     XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_DONE, NULL);
00478 
00479     return str;
00480 }
00481 
00482 static wchar_t*
00483 IIIMP_WcReset(
00484     XIC xic
00485 )
00486 {
00487     XicCommon ic = (XicCommon)xic;
00488     IIIMF_status st;
00489     IIIMCF_text text;
00490     wchar_t *wc_p = NULL;
00491     int caret, len;
00492     Bool useUnicode;
00493 
00494     st = iiimcf_get_preedit_text(XIC_IIIMP(ic, context), &text, &caret);
00495     if (st == IIIMF_STATUS_SUCCESS) {
00496       st = iiimcf_get_text_length(text, &len);
00497       if (st == IIIMF_STATUS_SUCCESS && len > 0) {
00498         XICCallback *cb = &ic->core.preedit_attr.draw_callback;
00499         XimCommon im = (XimCommon)ic->core.im;
00500         char *str = NULL;
00501         Bool useUnicode = (XIM_USE_UNICODE(im) && cb->callback &&
00502                            (ic->core.input_style & XIMPreeditCallbacks));
00503         st = IIimpConvertToString(text, useUnicode, &str);
00504         if (st == IIIMF_STATUS_SUCCESS) {
00505           wc_p = (wchar_t *)Xmalloc(sizeof(wchar_t) * len);
00506           if (!IIimpMbstoWcs((XimCommon)ic->core.im,
00507                              str, len, wc_p, len, NULL)) {
00508             if (wc_p) {
00509               free(wc_p); wc_p = NULL;
00510             }
00511           }
00512         }
00513         if (str) free(str);
00514       }
00515     }
00516     iiimcf_reset_context(XIC_IIIMP(ic, context));
00517     ic->core.preedit_attr.preedit_state = XIMPreeditDisable;
00518     ChangePreeditState(ic);
00519     /* to unmap preedit window */
00520     XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_DONE, NULL);
00521 
00522     return (wchar_t*)wc_p;
00523 }
00524 
00525 char*
00526 IIIMP_SetICValues(
00527     XIC xic,
00528     XIMArg *arg
00529 )
00530 {
00531     XicCommon ic = (XicCommon)xic;
00532     XimpChangeMaskRec dummy;
00533     char *ret = NULL;
00534 
00535     memset(&dummy, 0, sizeof (dummy));
00536 
00537     ret = SetICValueData(ic, arg, SET_IC, &dummy);
00538 
00539     return ret;
00540 }
00541 
00542 char*
00543 IIIMP_GetICValues(
00544     XIC xic,
00545     XIMArg *arg
00546 )
00547 {
00548     XicCommon ic = (XicCommon)xic;
00549     XimpChangeMaskRec dummy;
00550     char *ret = NULL;
00551 
00552     memset(&dummy, 0, sizeof (dummy));
00553 
00554     (void)IMGetICValues(ic, NULL, 0);
00555 
00556     ret = GetICValueData(ic, arg, &dummy);
00557 
00558     return ret;
00559 }
00560 
00561 int
00562 IIIMP_MbLookupString_SWITCH(
00563     XIC xic,
00564     XKeyEvent *ev,
00565     char *buffer,
00566     int len,
00567     KeySym *keysym,
00568     Status *status
00569 )
00570 {
00571     if (XIM_COMPOSE_KEYCODE == ev->keycode) {
00572        return IIIMP_MbLookupString(xic, ev, buffer, len, keysym, status);
00573     } else {
00574        return 0;
00575     }
00576 }
00577 
00578 static int
00579 IIIMP_MbLookupString(
00580     XIC xic,
00581     XKeyEvent *ev,
00582     char *buffer,
00583     int len,
00584     KeySym *keysym,
00585     Status *status
00586 )
00587 {
00588     XicCommon ic = (XicCommon)xic;
00589     int ret;
00590     XComposeStatus compose_status;
00591 
00592     if (ev->keycode == XIM_COMPOSE_KEYCODE) { /* Composed Event */
00593        IIIMF_status st;
00594        IIIMCF_text text;
00595        char *str;
00596        KeySym keysym_return;
00597 
00598        keysym_return = XIC_IIIMP(ic, keysym_return);
00599 
00600        if (XIC_IIIMP(ic, committed_text_consumed)) return 0;
00601 
00602        st = iiimcf_get_committed_text(XIC_IIIMP(ic, context), &text);
00603        if (st != IIIMF_STATUS_SUCCESS) return 0;
00604        st = IIimpConvertToString(text, False, &str);
00605        if (st != IIIMF_STATUS_SUCCESS) return 0;
00606        ret = strlen(str);
00607 
00608        if (ret > len) {
00609            if (status) *status = XBufferOverflow;
00610            return 0;
00611        }
00612        memcpy(buffer, str, ret * sizeof(char));
00613        free(str);
00614        if (keysym) {
00615            if (keysym_return)
00616               *keysym = keysym_return;
00617            else
00618               *keysym = NoSymbol;
00619        }
00620        if (status) {
00621            if (keysym_return)
00622               *status = XLookupBoth;
00623            else
00624               *status = XLookupChars;
00625        }
00626        XIC_IIIMP(ic, committed_text_consumed) = True;
00627 
00628        return ret;
00629     } else { /* Throughed Event */
00630        (void)memset((void *)&compose_status, 0, sizeof(XComposeStatus));
00631        ret = _Ximp_LookupMBText((Ximp_XIC)ic, ev,
00632                              (unsigned char *)buffer,
00633                              len, keysym, &compose_status);
00634        if (ret > 0) {
00635            if (keysym && *keysym != NoSymbol) {
00636               if (status) *status = XLookupBoth;
00637            } else {
00638               if (status) *status = XLookupChars;
00639            }
00640        } else {
00641            if (keysym && *keysym != NoSymbol) {
00642               if (status) *status = XLookupKeySym;
00643            } else {
00644               if (status) *status = XLookupNone;
00645            }
00646        }
00647     }
00648 
00649     return ret;
00650 }
00651 
00652 int
00653 IIIMP_WcLookupString_SWITCH(
00654     XIC xic,
00655     XKeyEvent *ev,
00656     wchar_t *buffer,
00657     int len,
00658     KeySym *keysym,
00659     Status *status
00660 )
00661 {
00662     if (XIM_COMPOSE_KEYCODE == ev->keycode) {
00663        return IIIMP_WcLookupString(xic, ev, buffer, len, keysym, status);
00664     } else {
00665        return 0;
00666     }
00667 }
00668 
00669 static int
00670 IIIMP_WcLookupString(
00671     XIC xic,
00672     XKeyEvent *ev,
00673     wchar_t *buffer,
00674     int len,
00675     KeySym *keysym,
00676     Status *status
00677 )
00678 {
00679     XicCommon ic = (XicCommon)xic;
00680     XimCommon im = (XimCommon)ic->core.im;
00681     int ret;
00682     XComposeStatus compose_status;
00683 
00684     if (ev->keycode == XIM_COMPOSE_KEYCODE) { /* Composed Event */
00685        IIIMF_status st;
00686        Status sts;
00687        IIIMCF_text text;
00688        char *str;
00689        int byte_len;
00690        KeySym keysym_return;
00691 
00692        keysym_return = XIC_IIIMP(ic, keysym_return);
00693 
00694        if (XIC_IIIMP(ic, committed_text_consumed)) return 0;
00695 
00696        st = iiimcf_get_committed_text(XIC_IIIMP(ic, context), &text);
00697        if (st != IIIMF_STATUS_SUCCESS) return 0;
00698        st = IIimpConvertToString(text, False, &str);
00699        if (st != IIIMF_STATUS_SUCCESS) return 0;
00700        byte_len = strlen(str);
00701 
00702        if ((ret = IIimpMbstoWcs(im, str, byte_len,
00703                              buffer, len, &sts)) < 0) {
00704            ret = 0;
00705            if(status) *status = XLookupNone;
00706        } else if (sts == XBufferOverflow) {
00707            *status = XBufferOverflow;
00708            return ret; /* Immidiately return */
00709        }
00710        if (keysym) {
00711            if (keysym_return)
00712               *keysym = keysym_return;
00713            else
00714               *keysym = NoSymbol;
00715        }
00716        if (status) {
00717            if (keysym_return)
00718               *status = XLookupBoth;
00719            else
00720               *status = XLookupChars;
00721        }
00722 
00723        XIC_IIIMP(ic, committed_text_consumed) = True;
00724 
00725        return ret;
00726     } else { /* Throughed Event */
00727        (void)memset((void *)&compose_status, 0, sizeof(XComposeStatus));
00728        ret = _Ximp_LookupWCText((Ximp_XIC)ic, ev, buffer,
00729                              len, keysym, &compose_status);
00730        if (ret > 0) {
00731            if (keysym && *keysym != NoSymbol) {
00732               if (status) *status = XLookupBoth;
00733            } else {
00734               if (status) *status = XLookupChars;
00735            }
00736        } else {
00737            if (keysym && *keysym != NoSymbol) {
00738               if (status) *status = XLookupKeySym;
00739            } else {
00740               if (status) *status = XLookupNone;
00741            }
00742        }
00743     }
00744     return ret;
00745 }
00746 
00747 void
00748 HoldXKeyEvent(
00749     XicCommon ic,
00750     XEvent * ev
00751 )
00752 {
00753     XICKeyEventListRec *    kel;
00754 
00755     kel = (XICKeyEventListRec *)Xmalloc(sizeof (XICKeyEventListRec));
00756     if (NULL == kel) {
00757        return;
00758     }
00759 
00760     memcpy(&(kel->key_event), ev, sizeof (XKeyEvent));
00761     kel->next = XIC_IIIMP(ic, key_event_list);
00762     XIC_IIIMP(ic, key_event_list) = kel;
00763 
00764     return;
00765 }
00766 
00767 void
00768 PutBackXKeyEvent(
00769     XicCommon ic
00770 )
00771 {
00772     XICKeyEventListRec *    key_event_list;
00773     XICKeyEventListRec *    kel;
00774     int                     key_event_num;
00775 
00776     key_event_list = XIC_IIIMP(ic, key_event_list);
00777     if (NULL == key_event_list) {
00778        return;
00779     }
00780 
00781     key_event_num = XIC_IIIMP(ic, key_event_num);
00782     if (key_event_num < 0) {
00783        key_event_num = 0;
00784     }
00785 
00786     while (NULL != key_event_list) {
00787        if (XIM_COMPOSE_KEYCODE != key_event_list->key_event.keycode) {
00788            key_event_num += 1;
00789        }
00790        XPutBackEvent(ic->core.im->core.display,
00791                     (XEvent *)(&key_event_list->key_event));
00792        kel = key_event_list->next;
00793        Xfree(key_event_list);
00794        key_event_list = kel;
00795     }
00796 
00797     XIC_IIIMP(ic, key_event_list) = NULL;
00798     XIC_IIIMP(ic, key_event_num) = key_event_num;
00799 
00800     return;
00801 }
00802 
00803 void
00804 IIIMPKeyEventFilter(
00805     XicCommon ic,
00806     Window old_focus
00807 )
00808 {
00809     _XUnregisterFilter(ic->core.im->core.display, old_focus,
00810                      IIIMP_Local_KeyFilter, (XPointer)ic);
00811     _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
00812                         KeyPress, KeyRelease,
00813                         IIIMP_Local_KeyFilter, (XPointer)ic);
00814     return;
00815 }
00816 
00817 /* Switching */
00818 void
00819 SWITCH_DestroyIC(
00820     XIC xic
00821 )
00822 {
00823     XicCommon ic = (XicCommon)xic;
00824     XimCommon im = (XimCommon)ic->core.im;
00825 
00826     if (XIM_IS_SWITCH(im)) {
00827        UnRegisterSwitchFilter(ic, SwitchFilter,
00828                             IIIMP_Local_KeyFilter,
00829                             get_iiimp_ic_methods());
00830     }
00831 
00832     if (XIM_IIIMP(im, current_ic) == xic) {
00833        IIIMP_UnSetFocus(xic);
00834     }
00835 
00836     iiimcf_destroy_context(XIC_IIIMP(ic, context));
00837 
00838     ic_switcher_finalize (ic);
00839     if (XIC_IIIMP(ic, aux)) Xfree(XIC_IIIMP(ic, aux));
00840 
00841     _XUnregisterFilter(ic->core.im->core.display,
00842                      ic->core.focus_window,
00843                      IIIMP_Local_KeyFilter, (XPointer)ic);
00844 
00845     if (ic->gui_icpart) {
00846        XIC_GUI(ic, change_preedit)((XIC)ic, PREEDIT_DESTROY, NULL);
00847        XIC_GUI(ic, change_status)((XIC)ic, STATUS_DESTROY, NULL);
00848        XIC_GUI(ic, change_lookup)((XIC)ic, LOOKUP_DESTROY, NULL);
00849     }
00850 
00851     if (ic->iiimp_icpart) {
00852        Xfree (ic->iiimp_icpart);
00853        ic->iiimp_icpart = 0;
00854     }
00855 
00856     return;
00857 }
00858 
00859 Bool
00860 IMGetICValues(
00861     XicCommon ic,
00862     XICAttribute *ic_attr,
00863     int attr_count
00864 )
00865 {
00866     /* nothing to do from X client */
00867     return True;
00868 }
00869 
00870 Bool
00871 IMCheckIMWindow(
00872     XicCommon ic,
00873     Window window
00874 )
00875 {
00876     return (XIM_IS_IIIMP(ic->core.im)
00877            && XIM_IIIMP(ic->core.im, handle)
00878            && XFactoryCheckIMWindow(ic->core.im->core.display, window));
00879 }
00880 
00881 /* Local Variables: */
00882 /* c-file-style: "iiim-project" */
00883 /* End: */