home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / oslib / examples / c / tbevent < prev    next >
Encoding:
Text File  |  1995-08-29  |  4.8 KB  |  202 lines

  1. /* Title:   tbevent.c
  2.  * Purpose: dispatching toolbox events.
  3.  * Author:  IDJ
  4.  * History: 19-Jun-94: IDJ: created
  5.  *
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. #include "messagetrans.h"
  13.  
  14. #include "tbevent.h"
  15. #include "trace.h"
  16. #include "riscos.h"
  17. #include "x.h"
  18.  
  19. static event_toolbox_handler_item *Handlers[256];
  20.  
  21. static event_toolbox_handler_item *All_Handlers = 0;
  22.  
  23. static int Hash (int word)
  24.  
  25. {  /* hashing algorithm: add ascending bytes, with carry, and use lower byte as result */
  26.  
  27.    int temp = (word & 0xff) + (word >> 8 & 0xff) + (word >> 16 & 0xff) +
  28.          (word >> 24 & 0xff);
  29.  
  30.    return temp + (temp >> 8) & 0xff;
  31. }
  32.  
  33. #define MATCHES(h, object_id, event_code, handler, handle)   h->object_id == (object_id)\
  34.                                                                  && h->event_code == (event_code)\
  35.                                                                  && h->handler == (handler)\
  36.                                                                  && h->handle == (handle)
  37.  
  38.  
  39. /* ------------------------------------ dispatching toolbox events -------------------------------- */
  40.  
  41. static int Matches (int event_code, event_toolbox_handler_item *h, toolbox_block *id_block)
  42. {
  43.     /*
  44.      * first look to see if interested in all objects of all classes,
  45.      * then interest in this object.
  46.      */
  47.  
  48.     if (h->event_code != event_code && h->event_code != -1)
  49.         return 0;
  50.  
  51.     if (h->object_id == event_ANY)      /* all objects */
  52.         return 1;
  53.     else if (h->object_id == id_block->this_obj)    /* this object */
  54.         return 1;
  55.  
  56.     return 0;
  57. }
  58.  
  59. static bool Call (event_toolbox_handler_item *h,
  60.       wimp_block *poll_block, toolbox_block *id_block)
  61.  
  62. {  toolbox_action *action = (toolbox_action *) poll_block->reserved;
  63.  
  64.    for (; h != NULL; h = h->next)
  65.       if (Matches (action->action_no, h, id_block) &&
  66.             h->handler != NULL)
  67.       {  tracef ("call the handler: id_block 0x%X\n" _ id_block);
  68.          if (h->handler (action->action_no, action,
  69.                id_block, h->handle))
  70.             return TRUE;
  71.       }
  72.  
  73.    return FALSE;
  74. }
  75.  
  76. extern void tbevent_dispatch (wimp_block *poll_block,
  77.       toolbox_block *id_block)
  78.  
  79. {  toolbox_action *action = (toolbox_action *) poll_block->reserved;
  80.  
  81.    tracef ("tbevent_dispatch\n");
  82.    tracef ("id_block 0x%X\n" _ id_block);
  83.  
  84.    if (!Call (Handlers [Hash (action->action_no)], poll_block, id_block))
  85.       Call (All_Handlers, poll_block, id_block);
  86. }
  87.  
  88. /* -------------------------- registering handlers for toolbox events ------------------------------ */
  89.  
  90. void tbevent_register_toolbox_handler (toolbox_o object_id, int
  91.       event_code, event_toolbox_handler *handler, void *handle)
  92.  
  93. {   event_toolbox_handler_item *h, *new_h;
  94.     int elem;
  95.  
  96.     /*
  97.      * start looking down the linked list which hangs off the array element for this toolbox event
  98.      */
  99.  
  100.     elem = Hash(event_code);
  101.  
  102.     if (event_code == -1)
  103.         h =  All_Handlers;
  104.     else
  105.         h = Handlers[elem];
  106.  
  107.     while (h != NULL)
  108.     {
  109.         /*
  110.          * if there's already a handler, just return.
  111.          */
  112.  
  113.         if (MATCHES (h, object_id, event_code, handler, handle))
  114.             return;
  115.  
  116.         h = h->next;
  117.     }
  118.  
  119.     /*
  120.      * make a new entry in the list for this event
  121.      */
  122.  
  123.    new_h = x_ALLOC (sizeof *new_h);
  124.    new_h->object_id  = object_id;
  125.    new_h->event_code = event_code;
  126.    new_h->handler    = handler;
  127.    new_h->handle     = handle;
  128.  
  129.    if (event_code == -1)
  130.    {
  131.       new_h->next           = All_Handlers;
  132.       All_Handlers = new_h;
  133.    }
  134.    else
  135.    {
  136.       new_h->next             = Handlers[elem];
  137.       Handlers[elem] = new_h;
  138.    }
  139. }
  140.  
  141.  
  142.  
  143. /* --------------------------- deregistering toolbox event handlers --------------------------------- */
  144.  
  145. void tbevent_deregister_toolbox_handler (toolbox_o object_id,
  146.       int event_code, event_toolbox_handler *handler, void *handle)
  147.  
  148. {
  149.     event_toolbox_handler_item *h, *prev_h;
  150.     event_toolbox_handler_item **listhead;
  151.     int                      elem;
  152.  
  153.     /*
  154.      * see if handler registered, and if so delete it.
  155.      */
  156.  
  157.     /*
  158.      * start looking down the linked list which hangs off the array element for this event
  159.      */
  160.  
  161.     elem = Hash(event_code);
  162.  
  163.     if (event_code == -1)
  164.     {
  165.         h = prev_h = Handlers[elem];
  166.         listhead   = &Handlers[elem];
  167.     }
  168.     else
  169.     {
  170.         h = prev_h = All_Handlers;
  171.         listhead   = &All_Handlers;
  172.     }
  173.  
  174.     while (h != NULL)
  175.     {
  176.         /*
  177.          * see if there's a handler, which matches.
  178.          */
  179.  
  180.         if (MATCHES (h, object_id, event_code, handler, handle))
  181.             break;
  182.  
  183.         prev_h = h;
  184.         h = h->next;
  185.     }
  186.  
  187.  
  188.     /*
  189.      * delete the handler from the list
  190.      */
  191.  
  192.     if (h != NULL)
  193.     {
  194.         if (h == *listhead)
  195.             *listhead = h->next;
  196.         else
  197.             prev_h->next = h->next;
  198.  
  199.         x_FREE (h, sizeof *h);
  200.     }
  201. }
  202.