home *** CD-ROM | disk | FTP | other *** search
- /* Title: tbevent.c
- * Purpose: dispatching toolbox events.
- * Author: IDJ
- * History: 19-Jun-94: IDJ: created
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "messagetrans.h"
-
- #include "tbevent.h"
- #include "trace.h"
- #include "riscos.h"
- #include "x.h"
-
- static event_toolbox_handler_item *Handlers[256];
-
- static event_toolbox_handler_item *All_Handlers = 0;
-
- static int Hash (int word)
-
- { /* hashing algorithm: add ascending bytes, with carry, and use lower byte as result */
-
- int temp = (word & 0xff) + (word >> 8 & 0xff) + (word >> 16 & 0xff) +
- (word >> 24 & 0xff);
-
- return temp + (temp >> 8) & 0xff;
- }
-
- #define MATCHES(h, object_id, event_code, handler, handle) h->object_id == (object_id)\
- && h->event_code == (event_code)\
- && h->handler == (handler)\
- && h->handle == (handle)
-
-
- /* ------------------------------------ dispatching toolbox events -------------------------------- */
-
- static int Matches (int event_code, event_toolbox_handler_item *h, toolbox_block *id_block)
- {
- /*
- * first look to see if interested in all objects of all classes,
- * then interest in this object.
- */
-
- if (h->event_code != event_code && h->event_code != -1)
- return 0;
-
- if (h->object_id == event_ANY) /* all objects */
- return 1;
- else if (h->object_id == id_block->this_obj) /* this object */
- return 1;
-
- return 0;
- }
-
- static bool Call (event_toolbox_handler_item *h,
- wimp_block *poll_block, toolbox_block *id_block)
-
- { toolbox_action *action = (toolbox_action *) poll_block->reserved;
-
- for (; h != NULL; h = h->next)
- if (Matches (action->action_no, h, id_block) &&
- h->handler != NULL)
- { tracef ("call the handler: id_block 0x%X\n" _ id_block);
- if (h->handler (action->action_no, action,
- id_block, h->handle))
- return TRUE;
- }
-
- return FALSE;
- }
-
- extern void tbevent_dispatch (wimp_block *poll_block,
- toolbox_block *id_block)
-
- { toolbox_action *action = (toolbox_action *) poll_block->reserved;
-
- tracef ("tbevent_dispatch\n");
- tracef ("id_block 0x%X\n" _ id_block);
-
- if (!Call (Handlers [Hash (action->action_no)], poll_block, id_block))
- Call (All_Handlers, poll_block, id_block);
- }
-
- /* -------------------------- registering handlers for toolbox events ------------------------------ */
-
- void tbevent_register_toolbox_handler (toolbox_o object_id, int
- event_code, event_toolbox_handler *handler, void *handle)
-
- { event_toolbox_handler_item *h, *new_h;
- int elem;
-
- /*
- * start looking down the linked list which hangs off the array element for this toolbox event
- */
-
- elem = Hash(event_code);
-
- if (event_code == -1)
- h = All_Handlers;
- else
- h = Handlers[elem];
-
- while (h != NULL)
- {
- /*
- * if there's already a handler, just return.
- */
-
- if (MATCHES (h, object_id, event_code, handler, handle))
- return;
-
- h = h->next;
- }
-
- /*
- * make a new entry in the list for this event
- */
-
- new_h = x_ALLOC (sizeof *new_h);
- new_h->object_id = object_id;
- new_h->event_code = event_code;
- new_h->handler = handler;
- new_h->handle = handle;
-
- if (event_code == -1)
- {
- new_h->next = All_Handlers;
- All_Handlers = new_h;
- }
- else
- {
- new_h->next = Handlers[elem];
- Handlers[elem] = new_h;
- }
- }
-
-
-
- /* --------------------------- deregistering toolbox event handlers --------------------------------- */
-
- void tbevent_deregister_toolbox_handler (toolbox_o object_id,
- int event_code, event_toolbox_handler *handler, void *handle)
-
- {
- event_toolbox_handler_item *h, *prev_h;
- event_toolbox_handler_item **listhead;
- int elem;
-
- /*
- * see if handler registered, and if so delete it.
- */
-
- /*
- * start looking down the linked list which hangs off the array element for this event
- */
-
- elem = Hash(event_code);
-
- if (event_code == -1)
- {
- h = prev_h = Handlers[elem];
- listhead = &Handlers[elem];
- }
- else
- {
- h = prev_h = All_Handlers;
- listhead = &All_Handlers;
- }
-
- while (h != NULL)
- {
- /*
- * see if there's a handler, which matches.
- */
-
- if (MATCHES (h, object_id, event_code, handler, handle))
- break;
-
- prev_h = h;
- h = h->next;
- }
-
-
- /*
- * delete the handler from the list
- */
-
- if (h != NULL)
- {
- if (h == *listhead)
- *listhead = h->next;
- else
- prev_h->next = h->next;
-
- x_FREE (h, sizeof *h);
- }
- }
-