Back to index

im-sdk  12.3.91
Functions
context.c File Reference
#include "iiimcfint.h"

Go to the source code of this file.

Functions

IIIMCF_context_reciiimcf_lookup_context (IIIMCF_handle_rec *ph, IIIMP_card16 ic_id)
static IIIMF_status add_context (IIIMCF_handle_rec *ph, IIIMCF_context_rec *pc)
static IIIMF_status remove_context (IIIMCF_context_rec *pc)
static IIIMF_status reset_context (IIIMCF_context_rec *pc, int full)
static IIIMF_status invalidate_context (IIIMCF_context_rec *pc)
static void free_icattribute (IIIMCF_context_rec *pc)
static IIIMF_status create_icattribute (IIIMCF_context_rec *pc, IIIMCF_attr attr)
IIIMF_status iiimcf_cleanup_context (IIIMCF_handle_rec *ph, int destroyp)
static IIIMF_status create_iiimp_icattr (IIIMCF_context_rec *pc, IIIMP_icattribute **ppicattr)
IIIMF_status iiimcf_enable_context (IIIMCF_context_rec *pc)
IIIMF_status iiimcf_create_context (IIIMCF_handle handle, IIIMCF_attr attr, IIIMCF_context *pcontext)
IIIMF_status iiimcf_context_set_attr (IIIMCF_context context, IIIMCF_attr attr)
IIIMF_status iiimcf_destroy_context (IIIMCF_context context)
IIIMF_status iiimcf_is_UIstate_changed (IIIMCF_context context, int *pflag)
IIIMF_status iiimcf_context_get_attr (IIIMCF_context context, IIIMCF_attr *pattr)
IIIMF_status iiimcf_reset_context (IIIMCF_context context)
IIIMF_status iiimcf_get_ic_id (IIIMCF_context context, int *pic_id)

Function Documentation

static IIIMF_status add_context ( IIIMCF_handle_rec ph,
IIIMCF_context_rec pc 
) [static]

Definition at line 40 of file context.c.

{
    int i;
    IIIMCF_context_rec *pc2;
    IIIMCF_context_rec **pptbl;

    pptbl = ph->ppcontext_table;
    i = pc->ic_id % ph->context_table_size;

    IIIMCF_LOCK_HANDLE(ph);
    pc2 = pptbl[i];
    if (!pc2) {
       pptbl[i] = pc;
    } else {
       pc->pnext = pc2;
       pptbl[i] = pc;
    }
    IIIMCF_UNLOCK_HANDLE(ph);

    return IIIMF_STATUS_SUCCESS;
}

Here is the caller graph for this function:

static IIIMF_status create_icattribute ( IIIMCF_context_rec pc,
IIIMCF_attr  attr 
) [static]

Definition at line 174 of file context.c.

{
    IIIMF_status st;
    IIIMCF_language_rec *plang;
    IIIMCF_input_method_rec *pim;

    memset(&pc->icattr, 0, sizeof(IIIMCF_ICAttribute_rec));

    st = iiimcf_attr_get_ptr_value(attr, IIIMCF_ATTR_INPUT_LANGUAGE, (void**) &plang);
    if (st == IIIMF_STATUS_SUCCESS) {
       pc->icattr.lang_id = strdup(plang->lang_id);
       if (!pc->icattr.lang_id) return IIIMF_STATUS_MALLOC;
    } else if (st == IIIMF_STATUS_NO_ATTR_VALUE) {
        /* client doesn't specify language */
#ifdef HAVE_SETLOCALE
        /* when we have setlocale function, try to detect most prefferable language from current locale */
        const char *lang = setlocale(LC_CTYPE, NULL);
        int i = 0;
        IIIMCF_language_rec **pplangs = pc->ph->pplangs;
        if (lang) {
            for (; i < pc->ph->num_langs; ++i) {
                if (!strncmp(pplangs[i]->lang_id, lang, strlen(pplangs[i]->lang_id))) {
                    pc->icattr.lang_id = strdup(pplangs[i]->lang_id);
                    st = IIIMF_STATUS_SUCCESS;
                    break;
                }
            }
        } else {
            goto error;
        }
#else
       goto error;
#endif
    } else {
        goto error;
    }

    st = iiimcf_attr_get_ptr_value(attr, IIIMCF_ATTR_INPUT_METHOD, (void**) &pim);
    if (st == IIIMF_STATUS_SUCCESS) {
       int len = iiimcf_string_length(pim->imname);
       pc->icattr.imname = (IIIMP_card16*) malloc(sizeof(IIIMP_card16) * len);
       if (!pc->icattr.imname) return IIIMF_STATUS_MALLOC;
       memcpy(pc->icattr.imname, pim->imname, len * sizeof(IIIMP_card16));
       pc->icattr.imname_len = len;
    } else if (st == IIIMF_STATUS_NO_ATTR_VALUE) {
       const char *imname;
       /* Using IIIMCF_ATTR_INPUT_METHOD_NAME is strongly depricated!!!
          This attribute is for backward-compatibility.
          Notice that it accepts only US-ASCII. */
       st = iiimcf_attr_get_string_value(attr,
                                     IIIMCF_ATTR_INPUT_METHOD_NAME,
                                     &imname);
       if (st == IIIMF_STATUS_SUCCESS) {
           int i, len;
           IIIMP_card16 *pu;

           len = strlen(imname);
           pu = (IIIMP_card16*) malloc(sizeof(IIIMP_card16) * len);
           if (!pu) return IIIMF_STATUS_MALLOC;
           pc->icattr.imname = pu;
           pc->icattr.imname_len = len;
           for (i = 0; i < len; i++) {
              if (((unsigned) *imname) > 0x7F) {
                  /* It's not US-ASCII! */
                  free(pc->icattr.imname);
                  return IIIMF_STATUS_ARGUMENT;
              }
              *pu++ = *imname++;
           }
       } else if (st != IIIMF_STATUS_NO_ATTR_VALUE) {
           goto error;
       }
    } else {
       goto error;
    }

    return IIIMF_STATUS_SUCCESS;

error:
    free_icattribute(pc);
    return st;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static IIIMF_status create_iiimp_icattr ( IIIMCF_context_rec pc,
IIIMP_icattribute **  ppicattr 
) [static]

Definition at line 289 of file context.c.

{
    IIIMF_status st;
    IIIMP_data_s *pds = pc->ph->data_s;
    IIIMP_string *pimstr;
    IIIMP_icattribute *pa, *pa_n;

    pa_n = NULL;
    if (pc->icattr.lang_id) {
       st = iiimf_data_string_ascii_new(pds, pc->icattr.lang_id, &pimstr);
       if (st != IIIMF_STATUS_SUCCESS) return st;
       pa_n = pa = iiimp_icattribute_input_language_new(pds, pimstr);
       if (!pa) {
           iiimp_string_delete(pds, pimstr);
           return IIIMF_STATUS_MALLOC;
       }
    }
    if (pc->icattr.imname) {
       pimstr = iiimp_string_new(pds, pc->icattr.imname_len, pc->icattr.imname);
       if (!pimstr) {
           iiimp_icattribute_list_delete(pds, pa_n);
           return IIIMF_STATUS_MALLOC;
       }
       pa = iiimp_icattribute_input_method_name_new(pds, pimstr);
       if (!pa) {
           iiimp_icattribute_list_delete(pds, pa_n);
           iiimp_string_delete(pds, pimstr);
           return IIIMF_STATUS_MALLOC;
       }
       pa->next = pa_n;
       pa_n = pa;
    }

    *ppicattr = pa_n;

    return IIIMF_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_icattribute ( IIIMCF_context_rec pc) [static]

Definition at line 165 of file context.c.

{
    if (pc->icattr.lang_id) free(pc->icattr.lang_id);
    if (pc->icattr.imname) free(pc->icattr.imname);
}

Here is the caller graph for this function:

Definition at line 261 of file context.c.

{
    IIIMF_status st1, st2;
    IIIMCF_context_rec **ppc, *pc, *pc2;
    int i;

    st2 = IIIMF_STATUS_SUCCESS;
    for (ppc = ph->ppcontext_table, i = 0;
        i < ph->context_table_size;
        ppc++, i++) {
       for (pc = *ppc; pc; pc = pc2) {
           pc2 = pc->pnext;
           if (destroyp) {
              st1 = iiimcf_destroy_context(pc);
           } else {
              st1 = invalidate_context(pc);
           }
           if (st1 != IIIMF_STATUS_SUCCESS) st2 = st1;
       }
    }

    return st2;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 545 of file context.c.

{
    IIIMCF_context_rec *pc = (IIIMCF_context_rec*) context;

    if (!pc->attr) {
       IIIMF_status st;

       st = iiimcf_create_attr(&pc->attr);
       if (st != IIIMF_STATUS_SUCCESS) return st;
    }
    *pattr = pc->attr;

    return IIIMF_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 420 of file context.c.

{
    IIIMF_status st;
    IIIMCF_context_rec *pc = (IIIMCF_context_rec*) context;
    IIIMCF_handle_rec *ph = pc->ph;
    IIIMP_message *pmes;
    IIIMP_icattribute *picattr;
    int auto_trigger_notify_flag;

    st = iiimcf_attr_get_integer_value(attr,
                                       IIIMCF_ATTR_DISABLE_AUTOMATIC_TRIGGER_NOTIFY,
                                       &auto_trigger_notify_flag);
    if (st == IIIMF_STATUS_NO_ATTR_VALUE) {
        auto_trigger_notify_flag = 1;
    } else if (st == IIIMF_STATUS_SUCCESS) {
        auto_trigger_notify_flag = !auto_trigger_notify_flag;
    } else {
        return st;
    }
    st = create_icattribute(pc, attr);
    if (st != IIIMF_STATUS_SUCCESS)
       return st;

    st = create_iiimp_icattr(pc, &picattr);
    if (st != IIIMF_STATUS_SUCCESS) {
       free_icattribute(pc);
       return st;
    }

    pmes = iiimp_seticvalues_new(ph->data_s, ph->im_id, pc->ic_id, picattr);
    st = iiimcf_request_message(ph, pmes, NULL, IM_SETICVALUES_REPLY, &pmes);
    if (st != IIIMF_STATUS_SUCCESS) {
       free_icattribute(pc);
       return st;
    }

    /* restore conversion mode */
    if (IIIMCF_IS_ENABLED(pc, IIIMCF_CONTEXT_CONVERSION_MODE)) {
       st = iiimcf_forward_trigger_notify(pc, 1);
       if (st != IIIMF_STATUS_SUCCESS) {
           IIIMCF_RESET_STATE(pc, IIIMCF_CONTEXT_CONVERSION_MODE);
           return st;
       }
    }

    if (auto_trigger_notify_flag)
       IIIMCF_SET_STATE(pc, IIIMCF_CONTEXT_AUTOMATIC_TRIGGER_NOTIFY);
    else
       IIIMCF_RESET_STATE(pc, IIIMCF_CONTEXT_AUTOMATIC_TRIGGER_NOTIFY);

    return IIIMF_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 366 of file context.c.

{
    IIIMF_status st;
    IIIMCF_handle_rec *ph = (IIIMCF_handle_rec*) handle;
    IIIMCF_context_rec *pc;
    IIIMP_message *pmes = NULL;
    int auto_trigger_notify_flag;

    st = iiimcf_attr_get_integer_value(attr,
                                   IIIMCF_ATTR_DISABLE_AUTOMATIC_TRIGGER_NOTIFY,
                                   &auto_trigger_notify_flag);
    if (st == IIIMF_STATUS_NO_ATTR_VALUE) {
       auto_trigger_notify_flag = 1;
    } else if (st == IIIMF_STATUS_SUCCESS) {
       auto_trigger_notify_flag = !auto_trigger_notify_flag;
    } else {
       return st;
    }

    pc = (IIIMCF_context_rec*) malloc(sizeof(*pc));
    if (!pc) {
       iiimp_message_delete(ph->data_s, pmes);
       return IIIMF_STATUS_MALLOC;
    }
    memset(pc, 0, sizeof(*pc));
    pc->ph = ph;
    pc->ic_id = -1;
    st = create_icattribute(pc, attr);
    if (st != IIIMF_STATUS_SUCCESS) {
       free(pc);
       return st;
    }
    st = iiimcf_enable_context(pc);
    if (st != IIIMF_STATUS_SUCCESS) {
       free_icattribute(pc);
       free(pc);
       return st;
    }

    if (auto_trigger_notify_flag)
       IIIMCF_SET_STATE(pc, IIIMCF_CONTEXT_AUTOMATIC_TRIGGER_NOTIFY);
    else
       IIIMCF_RESET_STATE(pc, IIIMCF_CONTEXT_AUTOMATIC_TRIGGER_NOTIFY);

    *pcontext = pc;

    return IIIMF_STATUS_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 477 of file context.c.

{
    IIIMF_status st1, st2;
    IIIMCF_context_rec *pc = (IIIMCF_context_rec*) context;
    IIIMCF_handle_rec *ph = pc->ph;

    st2 = IIIMF_STATUS_SUCCESS;
    if (IIIMCF_IS_CONNECTED(ph)
       && (!IIIMCF_IS_IC_INVALID(pc))) {
       IIIMP_message *pmes;

       pmes = iiimp_destroyic_new(ph->data_s, ph->im_id, pc->ic_id);
       if (pmes) {
           st1 = iiimcf_request_message(ph, pmes, pc, IM_DESTROYIC_REPLY, NULL);
           if (st1 != IIIMF_STATUS_SUCCESS) {
              st2 = st1;
           }
       } else {
           st2 = IIIMF_STATUS_MALLOC;
       }
    }

    /* Broadcast to all components that pc is now being destroyed.  */
    {
       IIIMCF_event_rec *pe;

       pe = iiimcf_make_event(IIIMCF_EVENT_TYPE_DESTROY);
       if (pe) {
           st1 = iiimcf_broadcast_event(pc, pe);
           if (st1 != IIIMF_STATUS_SUCCESS) st2 = st1;
       } else {
           st2 = IIIMF_STATUS_MALLOC;
       }
    }

    if (IIIMCF_IS_IC_INVALID(pc))
       return IIIMF_STATUS_SUCCESS;

    remove_context(pc);
    iiimcf_delete_event_storage(pc);
    iiimcf_delete_all_aux_data(pc);
    iiimcf_destruct_text(&pc->preedit_text);
    iiimcf_destruct_text(&pc->status_text);
    iiimcf_destruct_text(&pc->committed_text);
    iiimcf_destruct_lookup_choice(&pc->lookup_choice);
    free_icattribute(pc);
    if (pc->attr) iiimcf_destroy_attr(pc->attr);

    free(pc);

    return st2;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 331 of file context.c.

{
    IIIMF_status st;
    IIIMP_message *pmes = NULL;
    IIIMCF_handle_rec *ph = pc->ph;
    IIIMP_icattribute *picattr;

    st = create_iiimp_icattr(pc, &picattr);
    if (st != IIIMF_STATUS_SUCCESS) return st;
    pmes = iiimp_createic_new(ph->data_s, ph->im_id, picattr);
    st = iiimcf_request_message(ph, pmes, NULL, IM_CREATEIC_REPLY, &pmes);
    if (st != IIIMF_STATUS_SUCCESS) return st;
    pc->ic_id = pmes->ic_id;
    iiimp_message_delete(ph->data_s, pmes);
    st = add_context(ph, pc);

    /* restore conversion mode */
    if (IIIMCF_IS_ENABLED(pc, IIIMCF_CONTEXT_CONVERSION_MODE)) {
       st = iiimcf_forward_trigger_notify(pc, 1);
       if (st != IIIMF_STATUS_SUCCESS) {
           IIIMCF_RESET_STATE(pc, IIIMCF_CONTEXT_CONVERSION_MODE);
           return st;
       }
    }

    return st;
}

Here is the call graph for this function:

Here is the caller graph for this function:

IIIMF_status iiimcf_get_ic_id ( IIIMCF_context  context,
int *  pic_id 
)

Definition at line 586 of file context.c.

{
    IIIMCF_context_rec *pc = (IIIMCF_context_rec*) context;

    if (!pc) {
       *pic_id = -1;
       return IIIMF_STATUS_IC_INVALID;
    }

    *pic_id = pc->ic_id;

    if (pc->ic_id < 0)
       return IIIMF_STATUS_IC_INVALID;

    return IIIMF_STATUS_SUCCESS;
}

Here is the caller graph for this function:

IIIMF_status iiimcf_is_UIstate_changed ( IIIMCF_context  context,
int *  pflag 
)

Definition at line 533 of file context.c.

Here is the caller graph for this function:

Definition at line 20 of file context.c.

{
    int i;
    IIIMCF_context_rec *pc;
    IIIMCF_context_rec **pptbl;

    pptbl = ph->ppcontext_table;
    i = ic_id % ph->context_table_size;

    for (pc = pptbl[i]; pc; pc = pc->pnext) {
       if (pc->ic_id == ic_id) return pc;
    }

    return NULL;
}

Here is the caller graph for this function:

Definition at line 564 of file context.c.

{
    IIIMF_status st1, st2;
    IIIMCF_context_rec *pc = (IIIMCF_context_rec*) context;
    IIIMCF_handle_rec *ph = pc->ph;
    IIIMP_data_s *pds = ph->data_s;
    IIIMP_message *pmes;

    pmes = iiimp_resetic_new(pds, ph->im_id, pc->ic_id);
    if (!pmes) return IIIMF_STATUS_MALLOC;
    st1 = iiimcf_request_message(ph, pmes, pc, IM_RESETIC_REPLY, NULL);
    /* Even if requesting IM_RESETIC is fail,
       reset the internal state.  */
    st2 = reset_context(pc, 1);

    if (st1 != IIIMF_STATUS_SUCCESS) return st1;
    return st2;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 150 of file context.c.

{
    IIIMF_status st;

    if (IIIMCF_IS_IC_INVALID(pc)) return IIIMF_STATUS_SUCCESS;
    st = reset_context(pc, 0);
    remove_context(pc);
    pc->ic_id = -1;

    return st;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static IIIMF_status remove_context ( IIIMCF_context_rec pc) [static]

Definition at line 66 of file context.c.

{
    int i;
    IIIMCF_handle_rec *ph = pc->ph;
    IIIMCF_context_rec *pc1, *pc2;
    IIIMCF_context_rec **pptbl;

    pptbl = ph->ppcontext_table;
    i = pc->ic_id % ph->context_table_size;

    IIIMCF_LOCK_HANDLE(ph);
    for (pc1 = pptbl[i], pc2 = NULL; pc1; pc1 = pc1->pnext) {
       if (pc1 == pc) {
           if (pc2) {
              pc2->pnext = pc1->pnext;
           } else {
              pptbl[i] = pc1->pnext;
           }
           IIIMCF_UNLOCK_HANDLE(ph);
           return IIIMF_STATUS_SUCCESS;
       }
       pc2 = pc1;
    }
    IIIMCF_UNLOCK_HANDLE(ph);

    return IIIMF_STATUS_IC_INVALID;
}

Here is the caller graph for this function:

static IIIMF_status reset_context ( IIIMCF_context_rec pc,
int  full 
) [static]

Definition at line 97 of file context.c.

{
    IIIMF_status st;
    IIIMCF_event_rec *pe;

    /* Broadcast to all components that pc must be reset.  */
    pe = iiimcf_make_event(IIIMCF_EVENT_TYPE_RESET);
    if (pe) {
       st = iiimcf_broadcast_event(pc, pe);
    } else {
       st = IIIMF_STATUS_MALLOC; 
    }

    iiimcf_destruct_text(&pc->preedit_text);
    memset(&pc->preedit_text, 0, sizeof(pc->preedit_text));
    pc->preedit_caret_position = 0;
    iiimcf_destruct_text(&pc->status_text);
    memset(&pc->status_text, 0, sizeof(pc->status_text));
    iiimcf_destruct_text(&pc->committed_text);
    memset(&pc->committed_text, 0, sizeof(pc->committed_text));
    iiimcf_destruct_lookup_choice(&pc->lookup_choice);
    memset(&pc->lookup_choice, 0, sizeof(pc->lookup_choice));
    /* Should we clear AUX state? */

    IIIMCF_RESET_STATE(pc,
                     IIIMCF_CONTEXT_PREEDIT_ENABLED
                     | IIIMCF_CONTEXT_LOOKUP_CHOICE_ENABLED
                     | IIIMCF_CONTEXT_STATUS_ENABLED
                     | IIIMCF_CONTEXT_COMMITTED_TEXT_ENABLED);
    
    if (full) {
       /* Notice that conversion mode is persistent even
          after connection shutdown.  So avoid resetting
          IIIMCF_CONTEXT_CONVERSION_MODE.  */
       IIIMCF_RESET_STATE(pc, IIIMCF_CONTEXT_CONVERSION_MODE);
    }

    IIIMCF_SET_STATE_CHANGE(pc,
                         IIIMCF_STATE_INVALIDATED
                         | IIIMCF_STATE_STATUS_CHANGED
                         | IIIMCF_STATE_LOOKUP_CHOICE_CHANGED
                         | IIIMCF_STATE_PREEDIT_CHANGED);

    /* remove all events from the queue */
    iiimcf_delete_event_storage(pc);

    return st;
}

Here is the call graph for this function:

Here is the caller graph for this function: