Back to index

im-sdk  12.3.91
message.c
Go to the documentation of this file.
00001 /*
00002   message.c
00003 */
00004 
00005 #include "iiimcfint.h"
00006 
00007 static IIIMF_status
00008 iiimcf_reply_to_foward_event_with_operations(
00009     IIIMCF_context_rec *pc,
00010     IIIMP_message *pmes
00011 )
00012 {
00013     IIIMCF_handle_rec *ph = pc->ph;
00014     IIIMP_operation *pop = pmes->v.forward_event_with_operations_reply.operation;
00015     IIIMP_message *preply;
00016 
00017     preply = iiimp_forward_event_with_operations_reply_new(ph->data_s,
00018                                                     ph->im_id,
00019                                                     pc->ic_id,
00020                                                     pop);
00021     if (!preply) return IIIMF_STATUS_MALLOC;
00022 
00023     return iiimcf_send_message(ph, preply, 1);
00024 }
00025 
00026 static IIIMF_status
00027 iiimcf_reply_aux_message(
00028     IIIMCF_handle_rec *ph,
00029     IIIMP_message *pmes
00030 )
00031 {
00032     IIIMP_string *pimname;
00033     IIIMP_message *preply;
00034 
00035     if (pmes->opcode == IM_AUX_START) {
00036        pimname = iiimp_string_new(ph->data_s,
00037                                pmes->v.aux_start.input_method_name->len,
00038                                pmes->v.aux_start.input_method_name->ptr);
00039        if (!pimname) return IIIMF_STATUS_MALLOC;
00040        preply = iiimp_aux_start_reply_new(ph->data_s, pmes->im_id, pmes->ic_id,
00041                                       pmes->v.aux_start.class_index,
00042                                       pimname);
00043     } else if (pmes->opcode == IM_AUX_DRAW) {
00044        pimname = iiimp_string_new(ph->data_s,
00045                                pmes->v.aux_draw.input_method_name->len,
00046                                pmes->v.aux_draw.input_method_name->ptr);
00047        if (!pimname) return IIIMF_STATUS_MALLOC;
00048        preply = iiimp_aux_draw_reply_new(ph->data_s, pmes->im_id, pmes->ic_id,
00049                                      pmes->v.aux_draw.class_index,
00050                                      pimname);
00051     } else if (pmes->opcode == IM_AUX_DONE) {
00052        pimname = iiimp_string_new(ph->data_s,
00053                                pmes->v.aux_done.input_method_name->len,
00054                                pmes->v.aux_done.input_method_name->ptr);
00055        if (!pimname) return IIIMF_STATUS_MALLOC;
00056        preply = iiimp_aux_done_reply_new(ph->data_s, pmes->im_id, pmes->ic_id,
00057                                      pmes->v.aux_done.class_index,
00058                                      pimname);
00059     } else {
00060        return IIIMF_STATUS_ARGUMENT;
00061     }
00062 
00063     if (!preply) {
00064        iiimp_string_delete(ph->data_s, pimname);
00065        return IIIMF_STATUS_MALLOC;
00066     }
00067 
00068     return iiimcf_send_message(ph, preply, 1);
00069 }
00070 
00071 static IIIMF_status
00072 iiimcf_reply_message(
00073     IIIMCF_handle_rec *ph,
00074     IIIMP_message *pmes
00075 )
00076 {
00077     if (!pmes) return IIIMF_STATUS_MALLOC;
00078     return iiimcf_send_message(ph, pmes, 1);
00079 }
00080 
00081 /*
00082  * Process the message, pmes.
00083  * pmes is automatically deleted.
00084  */
00085 IIIMF_status
00086 iiimcf_process_message(
00087     IIIMCF_handle_rec *ph,
00088     IIIMP_message *pmes
00089 )
00090 {
00091     IIIMF_status st = IIIMF_STATUS_SUCCESS;
00092     IIIMF_status st_r = IIIMF_STATUS_SUCCESS;
00093     IIIMP_message *preply;
00094     IIIMCF_context_rec *pc;
00095 
00096     if (pmes->ic_id >= 0) {
00097        pc = iiimcf_lookup_context(ph, pmes->ic_id);
00098        if (!pc) {
00099             iiimp_message_delete(ph->data_s, pmes);
00100             return IIIMF_STATUS_IC_INVALID;
00101         }
00102     } else {
00103        pc = NULL;
00104     }
00105     switch (pmes->opcode) {
00106       case IM_CONNECT_REPLY:
00107        if (ph->im_id >= 0)
00108           return IIIMF_STATUS_SEQUENCE_STATE;
00109        ph->im_id = pmes->im_id;
00110        break;
00111 
00112       case IM_PROTOCOL_VERSION:
00113        ph->server_protocol_version = pmes->v.protocol_version.number;
00114        ph->num_of_hkprofiles = 0;
00115        ph->num_of_ns = 0;
00116        ph->num_of_nsl = 0;
00117        ph->curr_profile_id = -1;
00118        break;
00119 
00120       case IM_REGISTER_TRIGGER_KEYS:
00121        st = iiimcf_register_trigger_keys(ph, pmes);
00122        break;
00123 
00124       case IM_REGISTER_HOTKEYS:
00125        st = iiimcf_register_hotkeys(ph, pmes);
00126        break;
00127 
00128       case IM_TRIGGER_NOTIFY:
00129        if (pmes->v.trigger_notify.flag == 0)
00130           st = iiimcf_receive_trigger_notify(pc, 1);
00131        else
00132           st = iiimcf_receive_trigger_notify(pc, 0);
00133 
00134        preply = iiimp_trigger_notify_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00135        st_r = iiimcf_reply_message(ph, preply);
00136        break;
00137 
00138       case IM_HOTKEY_NOTIFY:
00139        st = iiimcf_receive_hotkey_notify(pc);
00140 
00141        preply = iiimp_hotkey_notify_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00142        st_r = iiimcf_reply_message(ph, preply);
00143        break;
00144 
00145       case IM_HOTKEY_STATE_NOTIFY:
00146        if (pmes->v.hotkey_state_notify.current_state_flag) {
00147            st = iiimcf_receive_trigger_notify(pc, 1);
00148        } else {
00149            st = iiimcf_receive_trigger_notify(pc, 0);
00150        }
00151 
00152        /*
00153         preply = iiimp_hotkey_state_notify_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00154         st_r = iiimcf_reply_message(ph, preply);
00155        */
00156        break;
00157 
00158       case IM_SELECT_HOTKEY_PROFILE:
00159        ph->curr_scope = pmes->v.select_hotkey_profile.scope;
00160        ph->curr_profile_id = pmes->v.select_hotkey_profile.profile_id;
00161 
00162        /* maybe we sould reply this message */
00163        break;
00164 
00165       case IM_FILE_OPERATION:
00166        st = iiimcf_perform_file_operation(ph, pmes);
00167        break;
00168 
00169       case IM_FORWARD_EVENT:
00170        st = iiimcf_receive_forwarded_event(pc, pmes);
00171        preply = iiimp_forward_event_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00172        st_r = iiimcf_reply_message(ph, preply);
00173        break;
00174 
00175       case IM_FORWARD_EVENT_WITH_OPERATIONS:
00176        st_r = iiimcf_reply_to_foward_event_with_operations(pc, pmes);
00177        break;
00178 
00179       case IM_PREEDIT_START:
00180        st = iiimcf_toggle_preedit(pc, 1);
00181        preply = iiimp_preedit_start_reply_new(ph->data_s, ph->im_id, pc->ic_id, -1);
00182        st_r = iiimcf_reply_message(ph, preply);
00183        break;
00184       case IM_PREEDIT_DRAW:
00185        st = iiimcf_update_preedit(pc, pmes);
00186        preply = iiimp_preedit_draw_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00187        st_r = iiimcf_reply_message(ph, preply);
00188        break;
00189       case IM_PREEDIT_DONE:
00190        st = iiimcf_toggle_preedit(pc, 0);
00191        preply = iiimp_preedit_done_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00192        st_r = iiimcf_reply_message(ph, preply);
00193        break;
00194 
00195       case IM_STATUS_START:
00196        st = iiimcf_toggle_status(pc, 1);
00197        preply = iiimp_status_start_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00198        st_r = iiimcf_reply_message(ph, preply);
00199        break;
00200       case IM_STATUS_DRAW:
00201        st = iiimcf_update_status(pc, pmes);
00202        preply = iiimp_status_draw_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00203        st_r = iiimcf_reply_message(ph, preply);
00204        break;
00205       case IM_STATUS_DONE:
00206        st = iiimcf_toggle_status(pc, 0);
00207        preply = iiimp_status_done_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00208        st_r = iiimcf_reply_message(ph, preply);
00209        break;
00210 
00211       case IM_LOOKUP_CHOICE_START:
00212        st = iiimcf_lookup_choice_start(pc, pmes);
00213        preply = iiimp_lookup_choice_start_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00214        st_r = iiimcf_reply_message(ph, preply);
00215        break;
00216       case IM_LOOKUP_CHOICE_DRAW:
00217        st = iiimcf_update_lookup_choice(pc, pmes);
00218        preply = iiimp_lookup_choice_draw_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00219        st_r = iiimcf_reply_message(ph, preply);
00220        break;
00221       case IM_LOOKUP_CHOICE_PROCESS:
00222        st = iiimcf_process_lookup_choice(pc, pmes);
00223        preply = iiimp_lookup_choice_process_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00224        st_r = iiimcf_reply_message(ph, preply);
00225        break;
00226       case IM_LOOKUP_CHOICE_DONE:
00227        st = iiimcf_lookup_choice_done(pc);
00228        preply = iiimp_lookup_choice_done_reply_new(ph->data_s, ph->im_id, pc->ic_id);
00229        st_r = iiimcf_reply_message(ph, preply);
00230        break;
00231 
00232       case IM_AUX_START:
00233        st = iiimcf_enable_aux(pc, pmes);
00234        st_r = iiimcf_reply_aux_message(ph, pmes);
00235        break;
00236       case IM_AUX_DRAW:
00237        st = iiimcf_update_aux_draw(pc, pmes);
00238        st_r = iiimcf_reply_aux_message(ph, pmes);
00239        break;
00240       case IM_AUX_DONE:
00241        st = iiimcf_disable_aux(pc, pmes);
00242        st_r = iiimcf_reply_aux_message(ph, pmes);
00243        break;
00244 
00245       case IM_COMMIT_STRING:
00246        st = iiimcf_commit_string(pc, pmes);
00247        break;
00248 
00249       case IM_SETIMVALUES:
00250        st = iiimcf_setimvalues(ph, pmes);
00251        preply = iiimp_setimvalues_reply_new(ph->data_s, ph->im_id);
00252        st_r = iiimcf_reply_message(ph, preply);
00253        break;
00254     }
00255 
00256     iiimp_message_delete(ph->data_s, pmes);
00257     if (st_r != IIIMF_STATUS_SUCCESS) return st_r;
00258 
00259     return st;
00260 }
00261 
00262 static int
00263 match_message(
00264     IIIMCF_handle_rec *ph,
00265     IIIMCF_context_rec *pc,
00266     int opcode,
00267     IIIMP_message *pmes
00268 )
00269 {
00270     if (opcode != pmes->opcode) return 0;
00271     if ((ph->im_id < 0) && (opcode == IM_CONNECT_REPLY)) return 1;
00272     if (ph->im_id != pmes->im_id) return 0;
00273     if (!pc) return 1;
00274     if (pc->ic_id != pmes->ic_id) return 0;
00275 
00276     return 1;
00277 }
00278 
00279 IIIMF_status
00280 iiimcf_wait_message(
00281     IIIMCF_handle_rec *ph,
00282     IIIMCF_context_rec *pc,
00283     int opcode,
00284     IIIMP_message **ppmes
00285 )
00286 {
00287     IIIMF_status st;
00288     IIIMP_message *pmes;
00289 
00290     for (;;) {
00291        st = iiimcf_receive_message(ph, &pmes);
00292        if (st != IIIMF_STATUS_SUCCESS) return st;
00293 
00294        if (match_message(ph, pc, opcode, pmes)) {
00295            if (ppmes) {
00296               *ppmes = pmes;
00297            } else {
00298               iiimp_message_delete(ph->data_s, pmes);
00299            }
00300            return IIIMF_STATUS_SUCCESS;
00301        }
00302 
00303        st = iiimcf_process_message(ph, pmes);
00304        if (st != IIIMF_STATUS_SUCCESS) return st;
00305     }
00306 
00307     return IIIMF_STATUS_SUCCESS;
00308 }
00309 
00310 /*
00311  * Send pmes, which is deleted, and then wait for the responce of
00312  * (pc, opcode), return set it to ppmes if it is not NULL.
00313  * Notice that this function allows pmes == *ppmes!!!
00314  */
00315 IIIMF_status
00316 iiimcf_request_message(
00317     IIIMCF_handle_rec *ph,
00318     IIIMP_message *pmes,
00319     IIIMCF_context_rec *pc,
00320     int opcode,
00321     IIIMP_message **ppmes
00322 )
00323 {
00324     IIIMF_status st;
00325 
00326     IIIMCF_LOCK_HANDLE(ph);
00327 
00328     /* By other threads, IC may be invalidated.
00329        So check it first because valid IC is indispensable
00330        for reply message.  */
00331     if (pc && IIIMCF_IS_IC_INVALID(pc)) {
00332         iiimp_message_delete(ph->data_s, pmes);
00333        IIIMCF_UNLOCK_HANDLE(ph);
00334        return IIIMF_STATUS_IC_INVALID;
00335     }
00336 
00337     if (!IIIMCF_IS_CONNECTED(ph)) {
00338        if (ph->disable_automatic_connection_restoration) {
00339             iiimp_message_delete(ph->data_s, pmes);
00340             IIIMCF_UNLOCK_HANDLE(ph);
00341            return IIIMF_STATUS_CONNECTION_CLOSED;
00342         }
00343 
00344        st = iiimcf_connect(ph);
00345        if (st != IIIMF_STATUS_SUCCESS) {
00346             iiimp_message_delete(ph->data_s, pmes);
00347            IIIMCF_UNLOCK_HANDLE(ph);
00348            return st;
00349        }
00350     }
00351 
00352     st = iiimcf_send_message(ph, pmes, 1);
00353     if (st == IIIMF_STATUS_SUCCESS) {
00354        st = iiimcf_wait_message(ph, NULL, opcode, ppmes);
00355     }
00356     IIIMCF_UNLOCK_HANDLE(ph);
00357 
00358     return st;
00359 }
00360 
00361 /* Local Variables: */
00362 /* c-file-style: "iiim-project" */
00363 /* End: */