Back to index

im-sdk  12.3.91
Functions
switchIM.c File Reference
#include "commonIM.h"
#include "XimpIm.h"
#include "switchIM.h"
#include "iiimpIM.h"
#include "composeIM.h"
#include "iiimpIC.h"
#include "status.h"
#include "iiimpSwitcher.h"
#include "iiimpAuxP.h"

Go to the source code of this file.

Functions

static int SwitchCloseIM (XIM)
char * IIIMP_SetIMValues (XIM, XIMArg *)
char * IIIMP_GetIMValues (XIM, XIMArg *)
static XIC SwitchCreateIC (XIM, XIMArg *)
int _Ximp_ctstombs (XIM, char *, int, char *, int, Status *)
int _Ximp_ctstowcs (XIM, char *, int, wchar_t *, int, Status *)
static XIMMethods get_switch_im_methods ()
static void DestroyIC (XIC)
static void SetFocus (XIC)
static void UnSetFocus (XIC)
static char * MbReset (XIC)
static wchar_t * WcReset (XIC)
char * IIIMP_SetICValues (XIC, XIMArg *)
char * IIIMP_GetICValues (XIC, XIMArg *)
static int MbLookupString (XIC, XKeyEvent *, char *, int, KeySym *, Status *)
static int WcLookupString (XIC, XKeyEvent *, wchar_t *, int, KeySym *, Status *)
static XICMethods get_switch_ic_methods ()
XIM _SwitchOpenIM (XLCd lcd, Display *dpy, XrmDatabase rdb, char *res_name, char *res_class)
void RegisterSwitchFilter (XicCommon ic, SwitchKeyEventProc is_switch_key, XFilterEventProc key_filter, XICMethods ic_methods)
void UnRegisterSwitchFilter (XicCommon ic, SwitchKeyEventProc is_switch_key, XFilterEventProc key_filter, XICMethods ic_methods)
void ResetSwitchFilter (XicCommon ic)
static Bool Switch_KeyFilter (Display *d, Window w, XEvent *ev, XPointer client_data)
void SwitchUpdateStatus (XicCommon ic)
void SwitchKeyEventFilter (XicCommon ic, Window old_focus)

Function Documentation

XIM _SwitchOpenIM ( XLCd  lcd,
Display *  dpy,
XrmDatabase  rdb,
char *  res_name,
char *  res_class 
)

Definition at line 113 of file switchIM.c.

{
    XimCommon im = 0;
    char *disableMultiScriptIM = getenv("DISABLE_MULTI_SCRIPT_IM");

    if (disableMultiScriptIM &&
       !strcmp("true", disableMultiScriptIM)) return 0; /* hidden feature */

    im = Xmalloc(sizeof(XimCommonRec));
    if (!im) goto Error;
    memset(im, 0, sizeof(XimCommonRec));

    if (!CommonOpenIM((XIM)im, lcd, dpy, rdb, res_name, res_class))
       goto Error;

    im->methods = get_switch_im_methods();

    if (!im_switcher_active(im))
      if (!COMPOSE_OpenIM_SWITCH((XIM)im, lcd)) goto Error;

    if (!IIIMP_OpenIM_SWITCH((XIM)im, lcd, dpy)) goto Error;

    return (XIM)im;

Error:
    if (im) Xfree(im);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _Ximp_ctstombs ( XIM  ,
char *  ,
int  ,
char *  ,
int  ,
Status *   
)

Definition at line 238 of file XimpConv.c.

{
    Ximp_XIM   im = (Ximp_XIM)xim;
    XlcConv    conv = im->ximp_impart->ctom_conv;
    int               from_left;
    int               to_left;
    int               from_savelen;
    int               to_savelen;
    int               from_cnvlen;
    int               to_cnvlen;
    char      *from_buf;
    char      *to_buf, *tmp_buf;
    Status     tmp_state;
  
    if (!state)
       state = &tmp_state;

    if (!conv || !from || !from_len) {
       *state = XLookupNone;
       return 0;
    }

    if (to && to_len) {
       from_left = from_len;
#ifdef sun
       to_left = to_len;
#else
       to_left = to_len - 1;
#endif
       from_cnvlen = 0;
       to_cnvlen = 0;
       for (;;) {
           from_savelen = from_left;
           to_savelen = to_left;
           from_buf = &from[from_cnvlen];
           to_buf = &to[to_cnvlen];
           if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
                             (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
              *state = XLookupNone;
              return 0;
           }
           from_cnvlen += (from_savelen - from_left);
           to_cnvlen += (to_savelen - to_left);
           if (from_left == 0) {
              if (to_cnvlen > 0) {
#ifndef sun
                  to[to_cnvlen] = '\0';
#endif
                  *state = XLookupChars;
              } else {
                  *state = XLookupNone;
              }
              return to_cnvlen;
           }
           if (to_left == 0)
              break;
           /* Overflow : the to_left length is so small that it cannot 
              accomodate the first mb character in the next conversion block */
           if (to_left < MB_CUR_MAX)
              break;
       }
    }

    from_left = from_len;
    from_cnvlen = 0;
    to_cnvlen = 0;
    /* BugId : 4253988. In case the from_buf is bigger than the to_buffer,
       we need to return the required buffer size and status as XBufferOverflow.       We create a tmp buffer equals 8 times the from_len and do conversion.
    */ 
    to_left = (8 * from_len) ;
    tmp_buf = (char *)malloc(to_left);
    for (;;) {
       from_savelen = from_left;
       from_buf = &from[from_cnvlen];
       to_savelen = to_left;
       to_buf = &tmp_buf[to_cnvlen];
       if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
                             (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
           *state = XLookupNone;
           return 0;
       }
       from_cnvlen += (from_savelen - from_left);
       to_cnvlen += (to_savelen - to_left);
       if (from_left == 0) {
           if (to_cnvlen > 0)
              *state = XBufferOverflow;
           else
              *state = XLookupNone;
           break;
       }
    }
    free(tmp_buf);
    return to_cnvlen;
}

Here is the call graph for this function:

int _Ximp_ctstowcs ( XIM  ,
char *  ,
int  ,
wchar_t *  ,
int  ,
Status *   
)

Definition at line 340 of file XimpConv.c.

{
    Ximp_XIM   im = (Ximp_XIM)xim;
    XlcConv    conv = im->ximp_impart->ctow_conv;
    int               from_left;
    int               to_left;
    int               from_savelen;
    int               to_savelen;
    int               from_cnvlen;
    int               to_cnvlen;
    char      *from_buf;
    wchar_t   *to_buf, *tmp_buf;
    Status     tmp_state;

    if (!state)
       state = &tmp_state;

    if (!conv || !from || !from_len) {
       *state = XLookupNone;
       return 0;
    }

    if (to && to_len) {
       from_left = from_len;
#ifdef sun
       to_left = to_len;
#else
       to_left = to_len - 1;
#endif
       from_cnvlen = 0;
       to_cnvlen = 0;
       for (;;) {
           from_savelen = from_left;
           to_savelen = to_left;
           from_buf = &from[from_cnvlen];
           to_buf = &to[to_cnvlen];
           if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
                             (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
              *state = XLookupNone;
              return 0;
           }
           from_cnvlen += (from_savelen - from_left);
           to_cnvlen += (to_savelen - to_left);
           if (from_left == 0) {
              if (to_cnvlen > 0) {
#ifndef sun
                  to[to_cnvlen] = (wchar_t)'\0';
#endif
                  *state = XLookupChars;
              } else {
                  *state = XLookupNone;
              }
              return to_cnvlen;
           }
           if (to_left == 0)
              break;
           /* Overflow : the to_left length is so small that it cannot 
              accomodate the first mb character in the next conversion block */
           if (to_left < sizeof(wchar_t)) {
              break;
           }
       }
    }
              
    from_left = from_len;
    from_cnvlen = 0;
    to_cnvlen = 0;
    /* BugId : 4253988. In case the from_buf is bigger than the to_buffer,
       we need to return the required buffer size and status as XBufferOverflow.       We create a tmp buffer equals 8 times the from_len and do conversion.
    */ 
    to_left = (8 * from_len) ;
    tmp_buf = (wchar_t *)malloc(to_left * sizeof(wchar_t));
    for (;;) {
       from_savelen = from_left;
       from_buf = &from[from_cnvlen];
       to_savelen = to_left;
       to_buf = &tmp_buf[to_cnvlen];
       if (_XlcConvert(conv, (XPointer *)&from_buf, &from_left,
                             (XPointer *)&to_buf, &to_left, NULL, 0) < 0) {
           *state = XLookupNone;
           return 0;
       }
       from_cnvlen += (from_savelen - from_left);
       to_cnvlen += (MAXINT - to_left);
       if (from_left == 0) {
           if (to_cnvlen > 0)
              *state = XBufferOverflow;
           else
              *state = XLookupNone;
           break;
       }
    }
    free(tmp_buf);
    return to_cnvlen;
}

Here is the call graph for this function:

static void DestroyIC ( XIC  xic) [static]

Definition at line 317 of file switchIM.c.

{
    XicCommon ic = (XicCommon)xic;

    _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
                     Switch_KeyFilter, (XPointer)ic);

    IIimpDestroryAuxData(ic);

    if (ic->local_icpart)
      XIC_COMPOSE(ic, switch_methods)->destroy(xic);
    XIC_IIIMP(ic, switch_methods)->destroy(xic);

    CommonDestroyIC(xic);

    return;
}

Here is the call graph for this function:

static XICMethods get_switch_ic_methods ( ) [static]

Definition at line 94 of file switchIM.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static XIMMethods get_switch_im_methods ( ) [static]

Definition at line 63 of file switchIM.c.

Here is the call graph for this function:

Here is the caller graph for this function:

char* IIIMP_GetICValues ( XIC  ,
XIMArg  
)

Definition at line 543 of file iiimpIC.c.

{
    XicCommon ic = (XicCommon)xic;
    XimpChangeMaskRec dummy;
    char *ret = NULL;

    memset(&dummy, 0, sizeof (dummy));

    (void)IMGetICValues(ic, NULL, 0);

    ret = GetICValueData(ic, arg, &dummy);

    return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* IIIMP_GetIMValues ( XIM  ,
XIMArg  
)

Definition at line 514 of file iiimpIM.c.

{
    XIMArg *p;
    int i;
    XimCommon im = (XimCommon)xim;

    if (!xim) return arg->name;    /* nothing to do */

    for (p = arg; p->name != NULL; p++) {
       TRACE_MESSAGE('v', ("  %s\n", p->name));
       if (!strcmp(p->name, XNQueryInputStyle)) {
           XIMStyles **value;
           XIMStyles *styles;
           size_t count = sizeof(im_styles)/sizeof(im_styles[0]);
           if ((styles = (XIMStyles*)
               Xmalloc(sizeof(XIMStyles) +
                      sizeof(XIMStyle) * count)) == NULL) {
              break;
           }
           styles->count_styles = count;
           styles->supported_styles = (XIMStyle *)(&styles[1]);

           for (i = 0; i < (int)(styles->count_styles); i++) {
              styles->supported_styles[i] = im_styles[i];
           }
           value = (XIMStyles **)p->value;
           *value = styles;
       } else if (!strcmp(p->name, XNMultiLingualInput)) {
           *((Bool*)(p->value)) = ((XimCommon)xim)->isUnicode;
       } else if (!strcmp(p->name, XNQueryExtensionVersion)) {
           *((int*)(p->value)) = XIIIMP_MULTILINGUAL_EXTENSION_VERSION;
       } else if (!strcmp(p->name, XNQueryUnicodeCharacterSubset)) {
           XIMUnicodeCharacterSubsets **value;
           XIMUnicodeCharacterSubsets *sub_sets;
           XIMUnicodeCharacterSubsets *im_subset;
           size_t count = 0;

           /* 
              when GIMLET is present, we don't let applications
              have their own choice windows, based on XLC_LOCALE
           */
           if (im_switcher_active(im))
             return p->name;

           /* RECONSIDER!!! */
           UpdateIMCharacterSubset(im);

           if (!im->unicode_char_subsets) break;

           im_subset = im->unicode_char_subsets;

           count = im_subset->count_subsets;

           if ((sub_sets = (XIMUnicodeCharacterSubsets*)
               Xmalloc(sizeof(XIMUnicodeCharacterSubsets) +
                      sizeof(XIMUnicodeCharacterSubset) * count)) == NULL) {
              break;
           }
           sub_sets->count_subsets = count;
           sub_sets->supported_subsets =
              (XIMUnicodeCharacterSubset*)(&sub_sets[1]);

           for (i = 0; i < (int)(sub_sets->count_subsets); i++) {
              sub_sets->supported_subsets[i] = im_subset->supported_subsets[i];
           }
           value = (XIMUnicodeCharacterSubsets **)p->value;
           *value = sub_sets;
      
       } else {
           break;
       }
    }
    return p->name;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* IIIMP_SetICValues ( XIC  ,
XIMArg  
)

Definition at line 526 of file iiimpIC.c.

{
    XicCommon ic = (XicCommon)xic;
    XimpChangeMaskRec dummy;
    char *ret = NULL;

    memset(&dummy, 0, sizeof (dummy));

    ret = SetICValueData(ic, arg, SET_IC, &dummy);

    return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* IIIMP_SetIMValues ( XIM  ,
XIMArg  
)

Definition at line 477 of file iiimpIM.c.

{
    XIMArg *p;
    char *return_name = NULL;
    XimCommon im = (XimCommon)xim;

    if (!xim) return arg->name;    /* nothing to do */

    for (p = arg; p->name != NULL; p++) {
       if (!strcmp(p->name, "engineInterfaceName")) {
           XIM_IIIMP(im, engine_name) = (char*)p->value;
       } else if (!strcmp(p->name, "applicationType")) {
           IMChangeClientType(im, (char*) p->value);
       } else if (!strcmp(p->name, "defaultFontName")) {
           XIM_IIIMP(im, default_font_name) = (char*)p->value;
       } else if (!strcmp(p->name, "primaryLocale")) {
           XIM_IIIMP(im, primary_locale) = (char*)p->value;
       } else if (!strcmp(p->name, XNDestroyCallback)) {
           im->core.destroy_callback.client_data = 
              ((XIMCallback *)p->value)->client_data;
           im->core.destroy_callback.callback = 
              ((XIMCallback *)p->value)->callback;
       } else {
           return_name = arg->name;
           break;
       }
    }

    return return_name;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int MbLookupString ( XIC  xic,
XKeyEvent *  ev,
char *  buffer,
int  bytes,
KeySym keysym,
Status *  status 
) [static]

Definition at line 389 of file switchIM.c.

{
    XicCommon ic = (XicCommon)xic;
    int ret;

    ret = IIIMP_MbLookupString_SWITCH(xic, ev, buffer, bytes, keysym, status);
    if (0 < ret) {
       return ret;
    }

    return ic->active_methods->mb_lookup_string(xic,
                                          ev, buffer,
                                          bytes, keysym,
                                          status);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char * MbReset ( XIC  xic) [static]

Definition at line 365 of file switchIM.c.

{
    XicCommon ic = (XicCommon)xic;

    _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
                     Switch_KeyFilter, (XPointer)ic);
    return ic->active_methods->mb_reset(xic);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void RegisterSwitchFilter ( XicCommon  ic,
SwitchKeyEventProc  is_switch_key,
XFilterEventProc  key_filter,
XICMethods  ic_methods 
)

Definition at line 164 of file switchIM.c.

{
    SwitchFilterEventRec *rec;

    rec = (SwitchFilterEventList)Xmalloc(sizeof(SwitchFilterEventRec));
    if (!rec)
       return;
    rec->is_switch_key = is_switch_key;
    rec->key_filter = key_filter;
    rec->ic_methods = ic_methods;
    rec->next = ic->switch_filters;
    ic->switch_filters = rec;
    return;
}

Here is the caller graph for this function:

Definition at line 206 of file switchIM.c.

{
    extern Bool Ximp_Local_KeyFilter(Display *, Window, XEvent*, XPointer);

    ic->active_filter = Ximp_Local_KeyFilter; /* default */
    ic->active_methods = get_local_ic_methods();
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void SetFocus ( XIC  xic) [static]

Definition at line 338 of file switchIM.c.

{
    XicCommon ic = (XicCommon)xic;

    _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
                        KeyPress, KeyRelease,
                        Switch_KeyFilter, (XPointer)ic);
    ic->active_methods->set_focus(xic);
  
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Bool Switch_KeyFilter ( Display *  d,
Window  w,
XEvent *  ev,
XPointer  client_data 
) [static]

Definition at line 225 of file switchIM.c.

{
    XicCommon ic = (XicCommon)client_data;
    SwitchFilterEventList filter;
    SwitchMode mode;
#ifndef ALLOW_SWITCH_FROM_REMOTE_TO_LOCAL
    Bool IIIMP_Local_KeyFilter(Display *d /*unused*/,
                            Window w /* unused */,
                            XEvent *ev, XPointer client_data);
#endif

    if (im_switcher_active((XimCommon)ic->core.im))
      return IIIMP_Local_KeyFilter (d, w, ev, client_data);

    for (filter = ic->switch_filters; filter; filter = filter->next) {
       if (ev->type == KeyPress)
           mode = filter->is_switch_key(ic, ev);
       else
           mode = Switch_NOP;
       switch (mode) {
         case Switch_ON:
          if (filter->next && filter->next->is_switch_key(ic, ev) == Switch_ON) {
              /* If this key is used for the next filter too, give way 
                to the next */
              ic->active_filter = filter->next->key_filter;
              ic->active_methods = filter->next->ic_methods;
          } else {
              ic->active_filter = filter->key_filter;
              ic->active_methods = filter->ic_methods;
          }
          goto call_filter;
         case Switch_OFF:
          if (ic->active_filter) {
              /* Before turn off active filter, pass the event to the
                handler because it may need to process the event to
                finalize operations.  */
              ic->active_filter(d, w, ev, client_data);
          }
          ResetSwitchFilter(ic);
          goto call_filter;
         case Switch_NOP:
         default:
#ifndef ALLOW_SWITCH_FROM_REMOTE_TO_LOCAL
          if (ic->active_filter == IIIMP_Local_KeyFilter)
              goto call_filter;
#endif
          break;
       }
    }
call_filter:
    if (!ic->active_filter) {
       ResetSwitchFilter(ic);
    }
    return ic->active_filter(d, w, ev, client_data);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Status SwitchCloseIM ( XIM  xim) [static]

Definition at line 149 of file switchIM.c.

{
    XimCommon im = (XimCommon)xim;

    XIM_COMPOSE(im, switch_methods)->close(xim);
    XIM_IIIMP(im, switch_methods)->close(xim);

    CommonCloseIM((XIM)im);

    return True;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static XIC SwitchCreateIC ( XIM  xim,
XIMArg arg 
) [static]

Definition at line 287 of file switchIM.c.

{
    XicCommon ic = 0;
    ic = Xmalloc(sizeof(XicCommonRec));
    if (!ic) goto Error;;
    memset(ic, 0, sizeof(XicCommonRec));

    ic->core.im = xim;
    ic->methods = get_switch_ic_methods();

    if (!CommonCreateIC((XIC)ic, arg)) goto Error;
    
    if (!im_switcher_active((XimCommon)ic->core.im))
      if (!COMPOSE_CreateIC_SWITCH((XIC)ic, arg)) goto Error;
    if (!IIIMP_CreateIC_SWITCH((XIC)ic, arg)) goto Error;

    ic->core.filter_events = KeyPressMask;

    ResetSwitchFilter(ic);

    return (XIC)ic;
Error:
    if (ic) Xfree(ic);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SwitchKeyEventFilter ( XicCommon  ic,
Window  old_focus 
)

Definition at line 450 of file switchIM.c.

{
    _XUnregisterFilter(ic->core.im->core.display, old_focus,
                     Switch_KeyFilter, (XPointer)ic);
    _XRegisterFilterByType(ic->core.im->core.display, ic->core.focus_window,
                        KeyPress, KeyRelease,
                        Switch_KeyFilter, (XPointer)ic);
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 435 of file switchIM.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void UnRegisterSwitchFilter ( XicCommon  ic,
SwitchKeyEventProc  is_switch_key,
XFilterEventProc  key_filter,
XICMethods  ic_methods 
)

Definition at line 185 of file switchIM.c.

{
    SwitchFilterEventList *prev, fl;

    for (prev = &ic->switch_filters; (fl = *prev) != NULL; ) {
       if (fl->is_switch_key == is_switch_key &&
           fl->key_filter == key_filter && fl->ic_methods == ic_methods) {
           *prev = fl->next;
           Xfree((char *)fl);
       } else
           prev = &fl->next;
    }
    return;
}

Here is the caller graph for this function:

static void UnSetFocus ( XIC  xic) [static]

Definition at line 353 of file switchIM.c.

{
    XicCommon ic = (XicCommon)xic;

    ic->active_methods->unset_focus(xic);
  
    return;
}

Here is the caller graph for this function:

static int WcLookupString ( XIC  xic,
XKeyEvent *  ev,
wchar_t *  buffer,
int  wlen,
KeySym keysym,
Status *  status 
) [static]

Definition at line 413 of file switchIM.c.

{
    XicCommon ic = (XicCommon)xic;
    int ret;
    ret = IIIMP_WcLookupString_SWITCH(xic, ev, buffer, wlen, keysym, status);
    if (0 < ret) {
       return ret;
    }
    return ic->active_methods->wc_lookup_string(xic,
                                          ev, buffer,
                                          wlen, keysym,
                                          status);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static wchar_t * WcReset ( XIC  xic) [static]

Definition at line 377 of file switchIM.c.

{
    XicCommon ic = (XicCommon)xic;

    _XUnregisterFilter(ic->core.im->core.display, ic->core.focus_window,
                     Switch_KeyFilter, (XPointer)ic);
    return ic->active_methods->wc_reset(xic);
}

Here is the call graph for this function:

Here is the caller graph for this function: