Back to index

im-sdk  12.3.91
handler.c
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <string.h>
00003 #include <sys/types.h>
00004 
00005 #include <iiimp.h>
00006 
00007 #include "input-method.h"
00008 #include "input-context.h"
00009 #include "handler.h"
00010 
00011 
00012 IIIMF_status
00013 iiimf_message_handler_entry_new(
00014     IIIMF_message_handler_entry ***       entry_ret)
00015 {
00016     IIIMF_message_handler_entry ** entry;
00017     size_t                         size;
00018     int                                   i;
00019 
00020     size = ((sizeof (IIIMF_message_handler_entry *)) * 128);
00021 
00022     entry = (IIIMF_message_handler_entry **)malloc(size);
00023     if (NULL == entry) return IIIMF_STATUS_MALLOC;
00024 
00025     for (i = 0; i < 128; i++) {
00026        *(entry + i) = NULL;
00027     }
00028 
00029     *entry_ret = entry;
00030 
00031     return IIIMF_STATUS_SUCCESS;
00032 }
00033 
00034 
00035 void
00036 iiimf_message_handler_entry_delete(
00037     IIIMF_message_handler_entry ** entry)
00038 {
00039     IIIMF_message_handler_entry *  e;
00040     IIIMF_message_handler_entry *  e_next;
00041     int                                   i;
00042 
00043     for (i = 0; i < 128; i++) {
00044        for (e = *(entry + i); NULL != e; e = e_next) {
00045            e_next = e->next;
00046            iiimf_message_handler_entry_item_delete(e);
00047        }
00048     }
00049 
00050     free(entry);
00051 }
00052 
00053 
00054 IIIMF_message_handler_entry *
00055 iiimf_message_handler_entry_item_new(
00056     const char *            name,
00057     IIIMF_message_handler   proc)
00058 {
00059     IIIMF_message_handler_entry *  entry;
00060 
00061     entry = (IIIMF_message_handler_entry *)
00062        malloc(sizeof (IIIMF_message_handler_entry));
00063     if (NULL == entry) return NULL;
00064 
00065     entry->name = strdup(name);
00066     if (NULL == entry->name) {
00067        free(entry);
00068        return NULL;
00069     }
00070 
00071     entry->proc = proc;
00072     entry->next = NULL;
00073 
00074     return entry;
00075 }
00076 
00077 
00078 void
00079 iiimf_message_handler_entry_item_delete(
00080     IIIMF_message_handler_entry *  entry)
00081 {
00082     free(entry->name);
00083     free(entry);
00084 }
00085 
00086 
00087 IIIMF_status
00088 iiimf_message_handler_register(
00089     IIIMF_im *                                   im,
00090     int                                          opcode,
00091     IIIMF_message_handler                 handler,
00092     const char *                          name,
00093     IIIMF_message_handler_register_place  place,
00094     const char *                          anchor)
00095 {
00096     IIIMF_message_handler_entry *  entry;
00097     IIIMF_message_handler_entry *  entry_prev;
00098     IIIMF_message_handler_entry *  entry_new;
00099 
00100     if (0x7f < opcode) return IIIMF_STATUS_OPCODE;
00101 
00102     entry_new = iiimf_message_handler_entry_item_new(name, handler);
00103     if (NULL == entry_new) return IIIMF_STATUS_MALLOC;
00104 
00105     entry = *(im->message_handler + opcode);
00106 
00107     switch (place) {
00108     case IIIMF_MESSAGE_HANDLER_REGISTER_PLACE_HEAD:
00109        entry = NULL;
00110        break;
00111     case IIIMF_MESSAGE_HANDLER_REGISTER_PLACE_TAIL:
00112        if (NULL != entry) {
00113            for (; NULL != entry->next; entry = entry->next) {
00114            }
00115        }
00116        break;
00117     case IIIMF_MESSAGE_HANDLER_REGISTER_PLACE_BEFORE:
00118        entry_prev = NULL;
00119        for (; NULL != entry; entry = entry->next) {
00120            if (0 == strcmp(entry->name, anchor)) break;
00121            entry_prev = entry;
00122        }
00123        if (NULL == entry) {
00124            iiimf_message_handler_entry_item_delete(entry_new);
00125            return IIIMF_STATUS_ARGUMENT;
00126        }
00127        entry = entry_prev;
00128        break;
00129     case IIIMF_MESSAGE_HANDLER_REGISTER_PLACE_AFTER:
00130        for (; NULL != entry; entry = entry->next) {
00131            if (0 == strcmp(entry->name, anchor)) break;
00132        }
00133        if (NULL == entry) {
00134            iiimf_message_handler_entry_item_delete(entry_new);
00135            return IIIMF_STATUS_ARGUMENT;
00136        }
00137        break;
00138     default:
00139        return IIIMF_STATUS_ARGUMENT;
00140     }
00141 
00142     if (NULL == entry) {
00143        entry_new->next = *(im->message_handler + opcode);
00144        *(im->message_handler + opcode) = entry_new;
00145     } else {
00146        entry_new->next = entry->next;
00147        entry->next = entry_new;
00148     }
00149 
00150     return IIIMF_STATUS_SUCCESS;
00151 }
00152 
00153 
00154 IIIMF_status
00155 iiimf_message_handler_unregister(
00156     IIIMF_im *                     im,
00157     int                            opcode,
00158     IIIMF_message_handler   handler)
00159 {
00160     IIIMF_message_handler_entry *  entry;
00161     IIIMF_message_handler_entry *  entry_next;
00162     IIIMF_message_handler_entry *  entry_prev;
00163 
00164     if (0x7f < opcode) return IIIMF_STATUS_OPCODE;
00165 
00166     entry = *(im->message_handler + opcode);
00167 
00168     if (NULL == entry->proc) return IIIMF_STATUS_ARGUMENT;
00169 
00170     if (handler == entry->proc) {
00171        entry_next = entry->next;
00172        if (NULL != entry_next) {
00173            entry->proc = entry_next->proc;
00174            entry->next = entry_next->next;
00175            free(entry_next);
00176        }
00177        return IIIMF_STATUS_SUCCESS;
00178     }
00179 
00180     for (entry_prev = entry, entry = entry->next;
00181         NULL != entry;
00182         entry_prev = entry, entry = entry->next) {
00183        if (handler == entry->proc) {
00184            entry_prev->proc = entry->next->proc;
00185            entry_prev->next = entry->next->next;
00186            free(entry);
00187            return IIIMF_STATUS_SUCCESS;
00188        }
00189     }
00190 
00191     return IIIMF_STATUS_ARGUMENT;
00192 }
00193 
00194 
00195 IIIMF_status
00196 iiimf_message_handler_unregister_name(
00197     IIIMF_im *              im,
00198     const char *     name)
00199 {
00200     IIIMF_status                   status;
00201     int                                   opcode;
00202     IIIMF_message_handler_entry *  entry;
00203     IIIMF_message_handler_entry *  entry_prev;
00204 
00205     status = IIIMF_STATUS_FAIL;
00206 
00207     for (opcode = 0; opcode < 128; opcode++) {
00208        entry = *(im->message_handler + opcode);
00209        if (NULL == entry) continue;
00210 
00211        entry_prev = NULL;
00212        for (; NULL != entry; entry = entry->next) {
00213            if (0 == strcmp(entry->name, name)) break;
00214            entry_prev = entry;
00215        }
00216        if (NULL != entry) {
00217            if (NULL == entry_prev) {
00218               *(im->message_handler + opcode) = entry->next;
00219            } else {
00220               entry_prev->next = entry->next;
00221            }
00222            iiimf_message_handler_entry_item_delete(entry);
00223            status = IIIMF_STATUS_SUCCESS;
00224        }
00225     }
00226 
00227     return status;
00228 }
00229 
00230 
00231 IIIMF_status
00232 iiimf_message_handler_call(
00233     IIIMF_im *              im,
00234     IIIMP_message *  message)
00235 {
00236     IIIMF_ic *                            ic;
00237     IIIMF_message_handler_status   status;
00238     IIIMF_message_handler_entry *  entry;
00239 
00240     entry = *(im->message_handler + message->opcode);
00241     if ((NULL == entry) || (NULL == entry->proc)) {
00242        return IIIMF_STATUS_SUCCESS;
00243     }
00244 
00245     if (0 <= message->ic_id) {
00246        for (ic = im->ic_list; NULL != ic; ic = ic->next) {
00247            if ( message->ic_id == ic->ic_id) break;
00248        }
00249        if (NULL == ic) return IIIMF_STATUS_INVALID_ID;
00250     } else {
00251        ic = NULL;
00252     }
00253 
00254     for (; NULL != entry; entry = entry->next) {
00255        status = (*(entry->proc))(im, ic, message);
00256        if (IIIMF_MESSAGE_HANDLER_STATUS_NORMAL == status) {
00257            continue;
00258        } else if (IIIMF_MESSAGE_HANDLER_STATUS_STOP == status) {
00259            return IIIMF_STATUS_SUCCESS;
00260        } else {
00261            return IIIMF_STATUS_FAIL;
00262        }
00263     }
00264 
00265     return IIIMF_STATUS_SUCCESS;
00266 }
00267 
00268 
00269 /* Local Variables: */
00270 /* c-file-style: "iiim-project" */
00271 /* End: */