Back to index

im-sdk  12.3.91
event.c
Go to the documentation of this file.
00001 /*
00002   event.c
00003 */
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include "iiimcfint.h"
00007 
00008 #define IIIMCF_EVENT_QUEUE_INITIAL_SLOTS_SIZE 4
00009 #define IIIMCF_EVENT_STACK_INITIAL_SLOTS_SIZE 4
00010 
00011 /* #define IIIMCF_EVENT_STACK */
00012 
00013 enum IIIMCF_EVENT_STATE_FLAGS {
00014        IIIMCF_EVENT_STATE_MUSTIGNORE = (1 << 0),
00015        IIIMCF_EVENT_STATE_DISPATCHING = (1 << 1),
00016        IIIMCF_EVENT_STATE_INQUEUE = (1 << 2),
00017        IIIMCF_EVENT_STATE_BROADCASTING = (1 << 3)
00018 };
00019 #define IIIMCF_EVENT_SET_STATE(pe, flag) ((pe)->state |= (flag))
00020 #define IIIMCF_EVENT_RESET_STATE(pe, flag) ((pe)->state &= (~(flag)))
00021 #define IIIMCF_EVENT_IS_DISCARDABLE(pe) ((pe)->state == 0)
00022 
00023 static void
00024 delete_event(
00025     IIIMCF_event_rec *pe
00026 )
00027 {
00028     switch (pe->type) {
00029       case IIIMCF_EVENT_TYPE_AUX_START:
00030       case IIIMCF_EVENT_TYPE_AUX_SETVALUES:
00031       case IIIMCF_EVENT_TYPE_AUX_GETVALUES:
00032       case IIIMCF_EVENT_TYPE_AUX_DRAW:
00033       case IIIMCF_EVENT_TYPE_AUX_DONE:
00034        iiimcf_delete_aux_event(pe);
00035        break;
00036 
00037       default:
00038        break;
00039     }
00040     free(pe);
00041 }
00042 
00043 /********************************************************************************
00044                          event queue and stack
00045 ********************************************************************************/
00046 
00047 static int
00048 expand_event_queue(
00049     IIIMCF_context_rec *pc
00050 )
00051 {
00052     int nsize;
00053     IIIMCF_event_rec **ppev;
00054     if (pc->evqueue_size == 0) {
00055        nsize = IIIMCF_EVENT_QUEUE_INITIAL_SLOTS_SIZE;
00056        ppev = (IIIMCF_event_rec**) malloc(sizeof(*ppev) * nsize);
00057        if (!ppev) return 0;
00058        memset(ppev, 0, sizeof(*ppev) * nsize);
00059        pc->ppevqueue = ppev;
00060        pc->ppev_pro = ppev;
00061        pc->ppev_con = ppev;
00062     } else {
00063        int osize = pc->evqueue_size;
00064        IIIMCF_event_rec **ppev_ncon, **ppev_npro;
00065 
00066        nsize = osize * 2;
00067        ppev = (IIIMCF_event_rec**) realloc(pc->ppevqueue, sizeof(*ppev) * nsize);
00068        if (!ppev) return 0;
00069        if (pc->ppev_con == (pc->ppev_pro + 1)) {
00070            /*       p c                               p         c
00071                    v v                               v         v
00072              +-----------------------+         +-------------------------------+
00073              |X|X|X|X|X|X|X|X|X|X|X|X|   ==>   |X|X|X|X| | | | |X|X|X|X|X|X|X|X|
00074              +-----------------------+            +-------------------------------+
00075                                                  ^               ^
00076                                                  ppev            ppev + nsize
00077                                                              - (osize - (ppev_con - ppevqueue))
00078            */
00079            ppev_ncon = ppev + nsize - (osize - (pc->ppev_con - pc->ppevqueue));
00080            ppev_npro = ppev + (pc->ppev_pro - pc->ppevqueue);
00081            memmove(ppev_ncon, ppev_npro + 1, sizeof(*ppev) * (nsize - (ppev_ncon - ppev)));
00082            memset(ppev_npro + 1, 0, sizeof(*ppev) * (ppev_ncon - ppev_npro - 1));
00083        } else if ((pc->ppev_pro == pc->ppevqueue + osize)
00084                  && (pc->ppev_con == pc->ppevqueue)) {
00085            /* c                       p         c                       p
00086               v                       v         v                       v
00087              +-----------------------+         +-------------------------------+
00088              |X|X|X|X|X|X|X|X|X|X|X|X|   ==>   |X|X|X|X|X|X|X|X|X|X|X|X| | | | |
00089              +-----------------------+         +-------------------------------+
00090            */
00091            ppev_ncon = ppev;
00092            ppev_npro = ppev + osize;
00093            memset(ppev_npro, 0, sizeof(*ppev) * (nsize - osize));
00094        } else {
00095            /* queue has still some empty rooms!!! */
00096            abort();
00097        }
00098        pc->ppevqueue = ppev;
00099        pc->ppev_pro = ppev_npro;
00100        pc->ppev_con = ppev_ncon;
00101     }
00102 
00103     pc->evqueue_size = nsize;
00104     return 1;
00105 }
00106 
00107 IIIMF_status
00108 iiimcf_store_event(
00109     IIIMCF_context_rec *pc,
00110     IIIMCF_event_rec *pe
00111 )
00112 {
00113     int size = pc->evqueue_size;
00114 
00115     if ((!pc->ppevqueue)
00116        || ((pc->ppev_pro + 1) == pc->ppev_con)) {
00117        if (!expand_event_queue(pc))
00118            return IIIMF_STATUS_MALLOC;
00119     }
00120     *pc->ppev_pro = pe;
00121     pc->ppev_pro++;
00122     if (pc->ppev_pro == pc->ppevqueue + size) {
00123        if (pc->ppev_con == pc->ppevqueue) {
00124            if (!expand_event_queue(pc))
00125               return IIIMF_STATUS_MALLOC;
00126        } else {
00127            pc->ppev_pro = pc->ppevqueue;
00128        }
00129     }
00130 
00131     return IIIMF_STATUS_SUCCESS;
00132 }
00133 
00134 IIIMCF_event_rec*
00135 iiimcf_get_event(
00136     IIIMCF_context_rec *pc,
00137     int removep
00138 )
00139 {
00140     IIIMCF_event_rec *pe;
00141 
00142     if (pc->ppev_con == pc->ppev_pro) return NULL;
00143 
00144     pe = *pc->ppev_con;
00145 
00146     if (removep) {
00147        *pc->ppev_con = NULL;
00148        if (pc->ppev_con == (pc->ppevqueue + pc->evqueue_size - 1))
00149            pc->ppev_con = pc->ppevqueue;
00150        else
00151            pc->ppev_con++;
00152     }
00153 
00154     return pe;
00155 }
00156 
00157 #ifdef IIIMCF_EVENT_STACK
00158 
00159 static int
00160 expand_event_stack(
00161     IIIMCF_context_rec *pc
00162 )
00163 {
00164     int nsize = pc->evstack_size;
00165     IIIMCF_event_rec **ppev;
00166 
00167     ASSERT((pc->ppevstack + nsize)  == pc->ppev_sp);
00168 
00169     if (nsize == 0) nsize = IIIMCF_EVENT_STACK_INITIAL_SLOTS_SIZE;
00170     else nsize *= 2;
00171 
00172     ppev = (IIIMCF_event_rec**) realloc(pc->ppevstack, sizeof(*ppev) * nsize);
00173     if (!ppev) return 0;
00174     memset(ppev + pc->evstack_size, 0, sizeof(*ppev) * (nsize - pc->evstack_size));
00175     pc->ppev_sp = ppev + pc->evstack_size;
00176     pc->ppevstack = ppev;
00177     pc->evstack_size = nsize;
00178 
00179     return 1;
00180 }
00181 
00182 IIIMF_status
00183 iiimcf_push_event(
00184     IIIMCF_context_rec *pc,
00185     IIIMCF_event_rec *pe
00186 )
00187 {
00188     int nsize = pc->evstack_size;
00189 
00190     if (pc->ppev_sp == (pc->ppevstack + nsize)) {
00191        if (!expand_event_stack(pc))
00192            return IIIMF_STATUS_MALLOC;
00193     }
00194     *pc->ppev_sp = pe;
00195     pc->ppev_sp++;
00196 
00197     return IIIMF_STATUS_SUCCESS;
00198 }
00199 
00200 IIIMCF_event_rec*
00201 iiimcf_pop_event(
00202     IIIMCF_context_rec *pc
00203 )
00204 {
00205     IIIMCF_event_rec *pe;
00206 
00207     if (pc->ppevstack == pc->ppev_sp) return NULL;
00208 
00209     --pc->ppev_sp;
00210     pe = *pc->ppev_sp;
00211     *pc->ppev_sp = NULL;
00212 
00213     return pe;
00214 }
00215 
00216 #endif /* IIIMCF_EVENT_STACK */
00217 
00218 /********************************************************************************
00219                          internal services
00220 ********************************************************************************/
00221 
00222 IIIMCF_event_rec*
00223 iiimcf_make_event(
00224     IIIMCF_event_type type
00225 )
00226 {
00227     IIIMCF_event_rec *pe;
00228 
00229     pe = (IIIMCF_event_rec*) malloc(sizeof(*pe));
00230     if (!pe) return NULL;
00231 
00232     memset(pe, 0, sizeof(*pe));
00233     pe->type = type;
00234 
00235     return pe;
00236 }
00237 
00238 IIIMF_status
00239 iiimcf_store_simple_event(
00240     IIIMCF_context_rec *pc,
00241     IIIMCF_event_type type
00242 )
00243 {
00244     IIIMCF_event_rec *pe;
00245 
00246     pe = iiimcf_make_event(type);
00247     if (!pe) return IIIMF_STATUS_MALLOC;
00248 
00249     return iiimcf_store_event(pc, pe);
00250 }
00251 
00252 
00253 IIIMF_status
00254 iiimcf_delete_event_storage(
00255     IIIMCF_context_rec *pc
00256 )
00257 {
00258     int i;
00259     IIIMCF_event_rec **ppe;
00260 
00261     if (pc->ppevqueue) {
00262        for (ppe = pc->ppevqueue, i = 0; i < pc->evqueue_size; i++, ppe++) {
00263            if (*ppe) delete_event(*ppe);
00264        }
00265        free(pc->ppevqueue);
00266        pc->ppevqueue = pc->ppev_pro = pc->ppev_con = NULL;
00267        pc->evqueue_size = 0;
00268     }
00269 #ifdef IIIMCF_EVENT_STACK
00270     if (pc->ppevstack) {
00271        for (ppe = ppevstack; ppe < pc->ppev_sp; ppe++) {
00272            if (*ppe) delete_event(*ppe);
00273        }
00274        free(pc->ppevstack);
00275        pc->ppevstack = pc->ppev_sp = NULL;
00276        pc->evstack_size = 0;
00277     }
00278 #endif
00279 
00280     return IIIMF_STATUS_SUCCESS;
00281 }
00282 
00283 static IIIMF_status
00284 broadcast(
00285     IIIMCF_context_rec *pc,
00286     IIIMCF_event_rec *pe,
00287     IIIMCF_component_rec *pcom,
00288     IIIMCF_component_rec *pcom_parent
00289 )
00290 {
00291     IIIMF_status st1, st2;
00292 
00293     st2 = IIIMF_STATUS_SUCCESS;
00294     for (; pcom; pcom = pcom->pnext) {
00295        st1 = (*pcom->func)(pc, pe, pcom, pcom_parent);
00296        if ((st1 != IIIMF_STATUS_SUCCESS)
00297            && (st1 != IIIMF_STATUS_COMPONENT_INDIFFERENT))
00298            st2 = st1;
00299        if (pcom->pchild) {
00300            st1 = broadcast(pc, pe, pcom->pchild, pcom);
00301            if ((st1 != IIIMF_STATUS_SUCCESS)
00302               && (st1 != IIIMF_STATUS_COMPONENT_INDIFFERENT))
00303               st2 = st1;
00304        }
00305     }
00306     return st2;
00307 }
00308 
00309 IIIMF_status
00310 iiimcf_broadcast_event(
00311     IIIMCF_context_rec *pc,
00312     IIIMCF_event_rec *pe
00313 )
00314 {
00315     IIIMF_status st;
00316 
00317     IIIMCF_EVENT_SET_STATE(pe, IIIMCF_EVENT_STATE_BROADCASTING);
00318     IIIMCF_SET_STATE(pc, IIIMCF_CONTEXT_BROADCASTING);
00319     st = broadcast(pc, pe, pc->ph->proot_component, NULL);
00320     IIIMCF_RESET_STATE(pc, IIIMCF_CONTEXT_BROADCASTING);
00321     IIIMCF_EVENT_RESET_STATE(pe, IIIMCF_EVENT_STATE_BROADCASTING);
00322 
00323     if (IIIMCF_EVENT_IS_DISCARDABLE(pe)) delete_event(pe);
00324 
00325     return st;
00326 }
00327 
00328 /********************************************************************************
00329                                  APIs
00330 ********************************************************************************/
00331 
00332 IIIMF_status
00333 iiimcf_get_event_type(
00334     IIIMCF_event event,
00335     IIIMCF_event_type *pevent_type
00336 )
00337 {
00338     IIIMCF_event_rec *pe = (IIIMCF_event_rec*) event;
00339  
00340    *pevent_type = pe->type;
00341     return IIIMF_STATUS_SUCCESS;
00342 }
00343 
00344 IIIMF_status
00345 iiimcf_create_keyevent(
00346     const IIIMCF_keyevent *pkeyevent,
00347     IIIMCF_event *pevent
00348 )
00349 {
00350     IIIMCF_event_rec *pe;
00351 
00352     pe = iiimcf_make_event(IIIMCF_EVENT_TYPE_KEYEVENT);
00353     if (!pe) return IIIMF_STATUS_MALLOC;
00354 
00355     pe->v.keyevent = *pkeyevent;
00356 
00357     *pevent = pe;
00358 
00359     return IIIMF_STATUS_SUCCESS;
00360 }
00361 
00362 IIIMF_status
00363 iiimcf_get_keyevent_value(
00364     IIIMCF_event event,
00365     IIIMCF_keyevent *pkeyevent
00366 )
00367 {
00368     IIIMCF_event_rec *pe = (IIIMCF_event_rec*) event;
00369     if (pe->type != IIIMCF_EVENT_TYPE_KEYEVENT)
00370        return IIIMF_STATUS_ARGUMENT;
00371 
00372     *pkeyevent = pe->v.keyevent;
00373     return IIIMF_STATUS_SUCCESS;
00374 }
00375 
00376 static IIIMF_status
00377 forward_keyevent(
00378     IIIMCF_context_rec *pc,
00379     IIIMCF_event_rec *pe
00380 )
00381 {
00382     IIIMF_status st;
00383     IIIMCF_handle_rec *ph = pc->ph;
00384     IIIMP_data_s *pds = ph->data_s;
00385     IIIMCF_keyevent *pk = &pe->v.keyevent;
00386     IIIMP_keyevent ikev;
00387     IIIMP_keyevent_list *pikl;
00388     IIIMP_contents *pcon;
00389     IIIMP_message *pmes;
00390 
00391     if (IIIMCF_IS_ENABLED(pc, IIIMCF_CONTEXT_AUTOMATIC_TRIGGER_NOTIFY)) {
00392         if (ph->server_protocol_version >= 3)
00393          st = iiimcf_process_hotkey_keyevent(pc, pk);
00394         else if (ph->server_protocol_version < 3)
00395          st = iiimcf_process_trigger_keyevent(pc, pk);
00396        if (st == IIIMF_STATUS_SUCCESS) return st;
00397        if (st != IIIMF_STATUS_NOT_TRIGGER_KEY) return st;
00398     }
00399 
00400     if (!IIIMCF_IS_STATIC_EVENT_FLOW(ph)
00401        && !IIIMCF_IS_ENABLED(pc, IIIMCF_CONTEXT_CONVERSION_MODE))
00402          return IIIMF_STATUS_EVENT_NOT_FORWARDED;
00403 
00404     ikev.keycode = pk->keycode;
00405     ikev.keychar = pk->keychar;
00406     ikev.modifier = pk->modifier;
00407     ikev.time_stamp = pk->time_stamp;
00408 
00409     pikl = iiimp_keyevent_list_new(pds, 1, &ikev);
00410     if (!pikl) return IIIMF_STATUS_MALLOC;
00411 
00412     pcon = iiimp_contents_keyevent_list_new(pds, pikl);
00413     if (!pcon) {
00414        iiimp_keyevent_list_delete(pds, pikl);
00415        return IIIMF_STATUS_MALLOC;
00416     }
00417 
00418     pmes = iiimp_forward_event_new(pds, ph->im_id, pc->ic_id, pcon);
00419     if (!pmes) {
00420        iiimp_contents_delete(pds, pcon);
00421        return IIIMF_STATUS_MALLOC;
00422     }
00423     st = iiimcf_request_message(ph, pmes, pc, IM_FORWARD_EVENT_REPLY, NULL);
00424     
00425     return st;
00426 }
00427 
00428 static IIIMF_status
00429 forward_seticfocus(
00430     IIIMCF_context_rec *pc
00431 )
00432 {
00433     IIIMF_status st;
00434     IIIMCF_handle_rec *ph = pc->ph;
00435     IIIMP_data_s *pds = ph->data_s;
00436     IIIMP_message *pmes;
00437 
00438     pmes = iiimp_seticfocus_new(pds, ph->im_id, pc->ic_id);
00439     if (!pmes) return IIIMF_STATUS_MALLOC;
00440     st = iiimcf_request_message(ph, pmes, pc, IM_SETICFOCUS_REPLY, NULL);
00441     
00442     return st;
00443 }
00444 
00445 IIIMF_status
00446 iiimcf_create_seticfocus_event(
00447     IIIMCF_event *pevent
00448 )
00449 {
00450     IIIMCF_event_rec *pe;
00451 
00452     pe = iiimcf_make_event(IIIMCF_EVENT_TYPE_SETICFOCUS);
00453     if (!pe) return IIIMF_STATUS_MALLOC;
00454     *pevent = pe;
00455 
00456     return IIIMF_STATUS_SUCCESS;
00457 }
00458 
00459 static IIIMF_status
00460 forward_unseticfocus(
00461     IIIMCF_context_rec *pc
00462 )
00463 {
00464     IIIMF_status st;
00465     IIIMCF_handle_rec *ph = pc->ph;
00466     IIIMP_data_s *pds = ph->data_s;
00467     IIIMP_message *pmes;
00468 
00469     pmes = iiimp_unseticfocus_new(pds, ph->im_id, pc->ic_id);
00470     if (!pmes) return IIIMF_STATUS_MALLOC;
00471     st = iiimcf_request_message(ph, pmes, pc, IM_UNSETICFOCUS_REPLY, NULL);
00472     
00473     return st;
00474 }
00475 
00476 IIIMF_status
00477 iiimcf_create_unseticfocus_event(
00478     IIIMCF_event *pevent
00479 )
00480 {
00481     IIIMCF_event_rec *pe;
00482 
00483     pe = iiimcf_make_event(IIIMCF_EVENT_TYPE_UNSETICFOCUS);
00484     if (!pe) return IIIMF_STATUS_MALLOC;
00485     *pevent = pe;
00486 
00487     return IIIMF_STATUS_SUCCESS;
00488 }
00489 
00490 /*
00491  * Forwarding Event to IIIMSF.
00492  * event is deleted unless its state is marked as DISCARDABLE
00493  */
00494 IIIMF_status
00495 iiimcf_forward_event(
00496     IIIMCF_context context,
00497     IIIMCF_event event
00498 )
00499 {
00500     IIIMF_status st;
00501     IIIMCF_context_rec *pc = (IIIMCF_context_rec*) context;
00502     IIIMCF_event_rec *pe = (IIIMCF_event_rec*) event;
00503 
00504     if (IIIMCF_IS_IC_INVALID(pc)) {
00505        st = iiimcf_enable_context(pc);
00506        if (st != IIIMF_STATUS_SUCCESS) {
00507             if (IIIMCF_EVENT_IS_DISCARDABLE(pe)) delete_event(pe);
00508            return IIIMF_STATUS_IC_INVALID;
00509         }
00510     }
00511 
00512     IIIMCF_RESET_STATE_CHANGE(pc,
00513                            IIIMCF_STATE_PREEDIT_CHANGED
00514                            | IIIMCF_STATE_LOOKUP_CHOICE_CHANGED
00515                            | IIIMCF_STATE_STATUS_CHANGED
00516                            | IIIMCF_STATE_COMMIT_REQUIRED);
00517     switch (pe->type) {
00518       case IIIMCF_EVENT_TYPE_KEYEVENT:
00519        st = forward_keyevent(pc, pe);
00520        break;
00521       case IIIMCF_EVENT_TYPE_TRIGGER_NOTIFY:
00522        st = iiimcf_forward_trigger_notify(pc, pe->v.number);
00523        break;
00524       case IIIMCF_EVENT_TYPE_AUX_SETVALUES:
00525        st = iiimcf_forward_aux_setvalues(pc, pe);
00526        break;
00527       case IIIMCF_EVENT_TYPE_AUX_GETVALUES:
00528        st = iiimcf_forward_aux_getvalues(pc, pe);
00529        break;
00530       case IIIMCF_EVENT_TYPE_SETICFOCUS:
00531        st = forward_seticfocus(pc);
00532        break;
00533       case IIIMCF_EVENT_TYPE_UNSETICFOCUS:
00534        st = forward_unseticfocus(pc);
00535        break;
00536       default:
00537        st = IIIMF_STATUS_EVENT_NOT_FORWARDED;
00538     }
00539     if (IIIMCF_EVENT_IS_DISCARDABLE(pe)) delete_event(pe);
00540 
00541     return st;
00542 }
00543 
00544 IIIMF_status
00545 iiimcf_receive_forwarded_event(
00546     IIIMCF_context_rec *pc,
00547     IIIMP_message *pmes
00548 )
00549 {
00550     IIIMF_status st;
00551     IIIMP_contents *pcon = pmes->v.forward_event.contents;
00552     ASSERT(pmes->opcode == IM_FORWARD_EVENT);
00553 
00554     switch (pcon->type) {
00555       case IIIMP_CONTENTS_KEYEVENT:
00556       {
00557          int i, n;
00558          IIIMCF_event_rec *pev;
00559          IIIMCF_keyevent kev;
00560          IIIMP_keyevent_list *pkl = pcon->value.keyevent_list;
00561          IIIMP_keyevent *pimkev = pkl->keyevent;
00562          
00563          n = pkl->count;
00564          for (i = 0; i < n; i++, pimkev++) {
00565              kev.keycode = pimkev->keycode;
00566              kev.keychar = pimkev->keychar;
00567              kev.modifier = pimkev->modifier;
00568              kev.time_stamp = pimkev->time_stamp;
00569              st = iiimcf_create_keyevent(&kev, (IIIMCF_event*) &pev);
00570              if (st != IIIMF_STATUS_SUCCESS) return st;
00571              st = iiimcf_store_event(pc, pev);
00572              if (st != IIIMF_STATUS_SUCCESS) {
00573                     delete_event(pev);
00574                     return st;
00575              }
00576          }
00577       }
00578 
00579       case IIIMP_CONTENTS_STRING:
00580       case IIIMP_CONTENTS_TEXT:
00581        /* currently ignore */
00582        break;
00583       default:
00584        abort();
00585     }
00586 
00587     return IIIMF_STATUS_SUCCESS;
00588 }
00589 
00590 IIIMF_status
00591 iiimcf_dispatch_event(
00592     IIIMCF_context context,
00593     IIIMCF_event event
00594 )
00595 {
00596     IIIMF_status st1, st2;
00597     IIIMCF_context_rec *pc = (IIIMCF_context_rec*) context;
00598     IIIMCF_event_rec *pe = (IIIMCF_event_rec*) event;
00599     IIIMCF_component_rec *pcom, *pcom_parent;
00600 
00601     /* When broadcasting event, event dispatchment
00602        must be inhibited because if we allow it, a component
00603        may receive the same broadcasting event more than once.
00604        Eventually, we return immediately with success.  */
00605     if (IIIMCF_IS_BROADCASTING(pc)) {
00606        if (IIIMCF_EVENT_IS_DISCARDABLE(pe)) delete_event(pe);
00607        return IIIMF_STATUS_SUCCESS;
00608     }
00609 
00610     pcom_parent = pc->pcurrent_component;
00611     if (pcom_parent) pcom = pcom_parent->pchild;
00612     else pcom = pc->ph->proot_component;
00613 
00614     IIIMCF_EVENT_SET_STATE(pe, IIIMCF_EVENT_STATE_DISPATCHING);
00615 
00616     st2 = IIIMF_STATUS_COMPONENT_INDIFFERENT;
00617     for (; pcom; pcom = pcom->pnext) {
00618        pc->pcurrent_component = pcom;
00619        st1 = (*pcom->func)(pc, pe, pcom, pcom_parent);
00620        if (st1 == IIIMF_STATUS_SUCCESS) {
00621            if (st2 == IIIMF_STATUS_COMPONENT_INDIFFERENT) {
00622               st2 = IIIMF_STATUS_SUCCESS;
00623            }
00624        } else if (st1 == IIIMF_STATUS_COMPONENT_FAIL) {
00625            st2 = st1;
00626        } else if (st1 != IIIMF_STATUS_COMPONENT_INDIFFERENT) {
00627            /* fatal error.  immediately quit.*/
00628            st2 = st1;
00629            break;
00630        }
00631     }
00632     pc->pcurrent_component = pcom_parent;
00633 
00634     IIIMCF_EVENT_RESET_STATE(pe, IIIMCF_EVENT_STATE_DISPATCHING);
00635 
00636     if (IIIMCF_EVENT_IS_DISCARDABLE(pe)) delete_event(pe);
00637 
00638     return st2;
00639 }
00640 
00641 IIIMF_status
00642 iiimcf_get_next_event(
00643     IIIMCF_context context,
00644     IIIMCF_event *pevent
00645 )
00646 {
00647     IIIMCF_context_rec *pc = (IIIMCF_context_rec*) context;
00648     IIIMCF_event_rec *pe;
00649 
00650     pe = iiimcf_get_event(pc, 1);
00651     if (!pe) return IIIMF_STATUS_NO_EVENT;
00652     *pevent = pe;
00653     IIIMCF_EVENT_RESET_STATE(pe, IIIMCF_EVENT_STATE_INQUEUE);
00654     IIIMCF_EVENT_SET_STATE(pe, IIIMCF_EVENT_STATE_MUSTIGNORE);
00655 
00656     return IIIMF_STATUS_SUCCESS;
00657 }
00658 
00659 IIIMF_status
00660 iiimcf_peek_next_event(
00661     IIIMCF_context context,
00662     IIIMCF_event *pevent
00663 )
00664 {
00665     IIIMCF_context_rec *pc = (IIIMCF_context_rec*) context;
00666     IIIMCF_event_rec *pe;
00667 
00668     pe = iiimcf_get_event(pc, 0);
00669     if (!pe) return IIIMF_STATUS_NO_EVENT;
00670     *pevent = pe;
00671     IIIMCF_EVENT_SET_STATE(pe, IIIMCF_EVENT_STATE_INQUEUE);
00672 
00673     return IIIMF_STATUS_SUCCESS;
00674 }
00675 
00676 IIIMF_status
00677 iiimcf_ignore_event(
00678     IIIMCF_event event
00679 )
00680 {
00681     IIIMCF_event_rec *pe = (IIIMCF_event_rec*) event;
00682 
00683     IIIMCF_EVENT_RESET_STATE(pe, IIIMCF_EVENT_STATE_MUSTIGNORE);
00684     if (IIIMCF_EVENT_IS_DISCARDABLE(pe)) delete_event(pe);
00685 
00686     return IIIMF_STATUS_SUCCESS;
00687 }
00688 
00689 /* Local Variables: */
00690 /* c-file-style: "iiim-project" */
00691 /* End: */