#include #include #include #include #include "input-method.h" #include "input-context.h" #include "handler.h" IIIMF_status iiimf_message_handler_entry_new( IIIMF_message_handler_entry *** entry_ret) { IIIMF_message_handler_entry ** entry; size_t size; int i; size = ((sizeof (IIIMF_message_handler_entry *)) * 128); entry = (IIIMF_message_handler_entry **)malloc(size); if (NULL == entry) return IIIMF_STATUS_MALLOC; for (i = 0; i < 128; i++) { *(entry + i) = NULL; } *entry_ret = entry; return IIIMF_STATUS_SUCCESS; } void iiimf_message_handler_entry_delete( IIIMF_message_handler_entry ** entry) { IIIMF_message_handler_entry * e; IIIMF_message_handler_entry * e_next; int i; for (i = 0; i < 128; i++) { for (e = *(entry + i); NULL != e; e = e_next) { e_next = e->next; iiimf_message_handler_entry_item_delete(e); } } free(entry); } IIIMF_message_handler_entry * iiimf_message_handler_entry_item_new( const char * name, IIIMF_message_handler proc) { IIIMF_message_handler_entry * entry; entry = (IIIMF_message_handler_entry *) malloc(sizeof (IIIMF_message_handler_entry)); if (NULL == entry) return NULL; entry->name = strdup(name); if (NULL == entry->name) { free(entry); return NULL; } entry->proc = proc; entry->next = NULL; return entry; } void iiimf_message_handler_entry_item_delete( IIIMF_message_handler_entry * entry) { free(entry->name); free(entry); } IIIMF_status iiimf_message_handler_register( IIIMF_im * im, int opcode, IIIMF_message_handler handler, const char * name, IIIMF_message_handler_register_place place, const char * anchor) { IIIMF_message_handler_entry * entry; IIIMF_message_handler_entry * entry_prev; IIIMF_message_handler_entry * entry_new; if (0x7f < opcode) return IIIMF_STATUS_OPCODE; entry_new = iiimf_message_handler_entry_item_new(name, handler); if (NULL == entry_new) return IIIMF_STATUS_MALLOC; entry = *(im->message_handler + opcode); switch (place) { case IIIMF_MESSAGE_HANDLER_REGISTER_PLACE_HEAD: entry = NULL; break; case IIIMF_MESSAGE_HANDLER_REGISTER_PLACE_TAIL: if (NULL != entry) { for (; NULL != entry->next; entry = entry->next) { } } break; case IIIMF_MESSAGE_HANDLER_REGISTER_PLACE_BEFORE: entry_prev = NULL; for (; NULL != entry; entry = entry->next) { if (0 == strcmp(entry->name, anchor)) break; entry_prev = entry; } if (NULL == entry) { iiimf_message_handler_entry_item_delete(entry_new); return IIIMF_STATUS_ARGUMENT; } entry = entry_prev; break; case IIIMF_MESSAGE_HANDLER_REGISTER_PLACE_AFTER: for (; NULL != entry; entry = entry->next) { if (0 == strcmp(entry->name, anchor)) break; } if (NULL == entry) { iiimf_message_handler_entry_item_delete(entry_new); return IIIMF_STATUS_ARGUMENT; } break; default: return IIIMF_STATUS_ARGUMENT; } if (NULL == entry) { entry_new->next = *(im->message_handler + opcode); *(im->message_handler + opcode) = entry_new; } else { entry_new->next = entry->next; entry->next = entry_new; } return IIIMF_STATUS_SUCCESS; } IIIMF_status iiimf_message_handler_unregister( IIIMF_im * im, int opcode, IIIMF_message_handler handler) { IIIMF_message_handler_entry * entry; IIIMF_message_handler_entry * entry_next; IIIMF_message_handler_entry * entry_prev; if (0x7f < opcode) return IIIMF_STATUS_OPCODE; entry = *(im->message_handler + opcode); if (NULL == entry->proc) return IIIMF_STATUS_ARGUMENT; if (handler == entry->proc) { entry_next = entry->next; if (NULL != entry_next) { entry->proc = entry_next->proc; entry->next = entry_next->next; free(entry_next); } return IIIMF_STATUS_SUCCESS; } for (entry_prev = entry, entry = entry->next; NULL != entry; entry_prev = entry, entry = entry->next) { if (handler == entry->proc) { entry_prev->proc = entry->next->proc; entry_prev->next = entry->next->next; free(entry); return IIIMF_STATUS_SUCCESS; } } return IIIMF_STATUS_ARGUMENT; } IIIMF_status iiimf_message_handler_unregister_name( IIIMF_im * im, const char * name) { IIIMF_status status; int opcode; IIIMF_message_handler_entry * entry; IIIMF_message_handler_entry * entry_prev; status = IIIMF_STATUS_FAIL; for (opcode = 0; opcode < 128; opcode++) { entry = *(im->message_handler + opcode); if (NULL == entry) continue; entry_prev = NULL; for (; NULL != entry; entry = entry->next) { if (0 == strcmp(entry->name, name)) break; entry_prev = entry; } if (NULL != entry) { if (NULL == entry_prev) { *(im->message_handler + opcode) = entry->next; } else { entry_prev->next = entry->next; } iiimf_message_handler_entry_item_delete(entry); status = IIIMF_STATUS_SUCCESS; } } return status; } IIIMF_status iiimf_message_handler_call( IIIMF_im * im, IIIMP_message * message) { IIIMF_ic * ic; IIIMF_message_handler_status status; IIIMF_message_handler_entry * entry; entry = *(im->message_handler + message->opcode); if ((NULL == entry) || (NULL == entry->proc)) { return IIIMF_STATUS_SUCCESS; } if (0 <= message->ic_id) { for (ic = im->ic_list; NULL != ic; ic = ic->next) { if ( message->ic_id == ic->ic_id) break; } if (NULL == ic) return IIIMF_STATUS_INVALID_ID; } else { ic = NULL; } for (; NULL != entry; entry = entry->next) { status = (*(entry->proc))(im, ic, message); if (IIIMF_MESSAGE_HANDLER_STATUS_NORMAL == status) { continue; } else if (IIIMF_MESSAGE_HANDLER_STATUS_STOP == status) { return IIIMF_STATUS_SUCCESS; } else { return IIIMF_STATUS_FAIL; } } return IIIMF_STATUS_SUCCESS; } /* Local Variables: */ /* c-file-style: "iiim-project" */ /* End: */