home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 1 / RISC_DISC_1.iso / pd_share / code / desklib / Libraries / Event / c / Event next >
Encoding:
Text File  |  1994-05-29  |  21.0 KB  |  797 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for 
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #                                      
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    Event.c
  12.     Author:  Copyright © 1992, 1993, 1994 John Winters
  13.              (mucked about by Jason Williams and Tim Browse)
  14.     Version: 1.07 (30 May 1994)
  15.     Purpose: High-level WIMP event dispatch to a hierarchy of user event
  16.              handling functions.
  17.  
  18.     PJC:     Added Event_Initialise3 and allowed support for the
  19.              NonZero Poll Word event
  20.  
  21.     JCW:     Fixed incorrect releasing of NULL events on event_ANY release.
  22. */
  23.  
  24.  
  25. #include <stdlib.h>
  26. #include <stdarg.h>
  27. #include "string.h"
  28.  
  29. #include "EventDefs.h"
  30. #include "Error.h"
  31. #include "WimpSWIs.h"
  32.  
  33.  
  34. /* Error message definitions.
  35.    These are ALL the messages produced by this module, and have been defined
  36.    here so that it is easier for you to alter them or replace them with
  37.    msgtrans tags.
  38.    Error numbers are also included: Currently, the error number is unused
  39.    so they are defined starting from ERRBASE. If you wish to use the error
  40.    number in your Error reporting code, then you will have to set ERRBASE to
  41.    a suitable value to ensure that all errors produced have unique numbers.
  42. */
  43. #define ERRBASE  1
  44. #define ERR1     ERRBASE+0
  45. #define ERRMESS1 "Can't allocate memory for an icon record"
  46. #define ERR2     ERRBASE+1
  47. #define ERRMESS2 "Can't allocate memory for a window record"
  48. #define ERR3     ERRBASE+2
  49. #define ERRMESS3 "Can't allocate memory to record an event claim"
  50. #define ERR4     ERRBASE+3
  51. #define ERRMESS4 "Attempt to claim invalid event type"
  52. #define ERR5     ERRBASE+4
  53. #define ERRMESS5 "Can't trace event claim"
  54.  
  55.  
  56. event_pollmask  event_mask = 0;
  57. event_pollblock event_lastevent;
  58. task_handle     event_taskhandle  = 0;
  59. unsigned int    event_wimpversion = 0;
  60. char            event_taskname[40];
  61.  
  62. static short usagecounts[wimp_NUMBEROFEVENTS]= {
  63.   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  64.   0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  65. };
  66.  
  67. /*
  68.    PJC: needed to remove the 'const' declaration so that
  69.    the list can be altered on the fly
  70. */
  71. static event_class eventclass [event_MAXEVENTS] =
  72. {
  73.     notrelated,     /* NULL             */
  74.     windowrelated,  /* redraw           */
  75.     windowrelated,  /* open window      */
  76.     windowrelated,  /* close window     */
  77.     windowrelated,  /* pointer leave    */
  78.     windowrelated,  /* pointer enter    */
  79.     iconrelated,    /* Mouse click      */
  80.     notrelated,     /* drag finished    */
  81.     iconrelated,    /* keypress         */
  82.     notrelated,     /* menu selection   */
  83.     windowrelated,  /* scroll           */
  84.     iconrelated,    /* lose caret       */
  85.     iconrelated,    /* gain caret       */
  86.     notrelated,     /* nonzero pollword */
  87.     nonexistent,    /* 14               */
  88.     nonexistent,    /* 15               */
  89.     nonexistent,    /* 16               */
  90.     notrelated,     /* Message          */
  91.     notrelated,     /* Message recorded */
  92.     notrelated      /* Message ack      */
  93. };
  94.  
  95. static linklist_header catchalls = {NULL, NULL};
  96.  
  97. static linklist_header eventqueues[event_MAXEVENTS] =
  98. {
  99.   {NULL, NULL},
  100.   {NULL, NULL},
  101.   {NULL, NULL},
  102.   {NULL, NULL},
  103.   {NULL, NULL},
  104.   {NULL, NULL},
  105.   {NULL, NULL},
  106.   {NULL, NULL},
  107.   {NULL, NULL},
  108.   {NULL, NULL},
  109.   {NULL, NULL},
  110.   {NULL, NULL},
  111.   {NULL, NULL},
  112.   {NULL, NULL},
  113.   {NULL, NULL},
  114.   {NULL, NULL},
  115.   {NULL, NULL},
  116.   {NULL, NULL},
  117.   {NULL, NULL},
  118.   {NULL, NULL}
  119. };
  120.  
  121.  
  122. static linklist_header window_anchor = {NULL, NULL};
  123. static void *currentscan = NULL;
  124.  
  125.  
  126. /* prototypes for the 3 handler functions used in the event_handlers list */
  127. static BOOL DispatchIconEvents(event_pollblock *event, void *reference);
  128. static BOOL DispatchWindowEvents(event_pollblock *event, void *reference);
  129. static BOOL DispatchMiscEvents(event_pollblock *event, void *reference);
  130.  
  131. static event_handler event_handlers[wimp_NUMBEROFEVENTS] = {
  132.     DispatchMiscEvents,
  133.     DispatchWindowEvents,
  134.     DispatchWindowEvents,
  135.     DispatchWindowEvents,
  136.     DispatchWindowEvents,
  137.     DispatchWindowEvents,
  138.     DispatchIconEvents,
  139.     DispatchMiscEvents,
  140.     DispatchIconEvents,
  141.     DispatchMiscEvents,
  142.     DispatchWindowEvents,
  143.     DispatchIconEvents,
  144.     DispatchIconEvents,
  145.     NULL,
  146.     NULL,
  147.     NULL,
  148.     NULL,
  149.     DispatchMiscEvents,
  150.     DispatchMiscEvents,
  151.     DispatchMiscEvents
  152. };
  153.  
  154.  
  155. /* which events can be masked out? */
  156. static const char event_masks[event_MAXEVENTS] = {
  157.   TRUE,          /* Null             */
  158.   FALSE,         /* Redraw Window    */
  159.   FALSE,         /* Open Window      */
  160.   FALSE,         /* Close Window     */
  161.   TRUE,          /* Pointer Leaving  */
  162.   TRUE,          /* Pointer Entering */
  163.   FALSE,         /* Click            */
  164.   FALSE,         /* Drag finish      */
  165.   FALSE,         /* Key              */
  166.   FALSE,         /* Menu Selection   */
  167.   FALSE,         /* Scroll           */
  168.   TRUE,          /* Lose caret       */
  169.   TRUE,          /* Gain caret       */
  170.   TRUE,          /* NonZero PollWord */
  171.   FALSE,         /* Reserved         */
  172.   FALSE,         /* Reserved         */
  173.   FALSE,         /* Reserved         */
  174.   FALSE,         /* Message          */
  175.   TRUE,          /* Message Recorded */
  176.   TRUE           /* Message Ack      */
  177. };
  178.  
  179.  
  180. /* =========================================================================
  181.    Functions
  182.    ========================================================================= */
  183.  
  184.  
  185.  
  186. static void IncrementUsage(event_type event)
  187. {
  188.   if ((usagecounts[event])++ == 0)      /* increment count: if not used b4...*/
  189.   {
  190.     event_mask.value &= ~(1 << event);  /* then stop masking event out       */
  191.  
  192.     /* PJC: if NZPW event type, also set bit 22 */
  193.     if (event == event_NONZEROPOLLWORD)
  194.       event_mask.data.r3ispollwordptr = TRUE;
  195.   }
  196. }
  197.  
  198.  
  199.  
  200. static void DecrementUsage(event_type event)
  201. {
  202.   if (--(usagecounts[event]) == 0)      /* decrement count: if not used now..*/
  203.   {
  204.     if (event_masks[event])             /* then mask the event out           */
  205.       event_mask.value |= 1 << event;
  206.  
  207.     /* PJC: if NZPW event type, also clear bit 22 */
  208.     if (event == event_NONZEROPOLLWORD)
  209.       event_mask.data.r3ispollwordptr = FALSE;
  210.   }
  211. }
  212.  
  213.  
  214.  
  215. static event_iconrecord *CreateIconRecord(event_windowrecord *windowrecord,
  216.                                           icon_handle        icon)
  217. {
  218.   event_iconrecord *current;
  219.  
  220.   current = malloc(sizeof(event_iconrecord));
  221.   if (current == NULL)
  222.     Error_ReportInternal(ERR1, ERRMESS1);
  223.   else
  224.   {
  225.     current->icon = icon;
  226.     LinkList_Init(&(current->claimlist));
  227.     LinkList_AddToTail(&(windowrecord->iconlist), &(current->header));
  228.   }
  229.  
  230.   return(current);
  231. }
  232.  
  233.  
  234.  
  235. static event_windowrecord *CreateWindowRecord(window_handle window)
  236. {
  237.   event_windowrecord *current;
  238.  
  239.   current = malloc(sizeof(event_windowrecord));
  240.   if (current == NULL)
  241.     Error_ReportInternal(ERR2, ERRMESS2);
  242.   else
  243.   {
  244.     current->window = window;
  245.     LinkList_Init(&(current->iconlist));
  246.     LinkList_Init(&(current->claimlist));
  247.     LinkList_AddToTail(&window_anchor, &(current->header));
  248.   }
  249.   return(current);
  250. }
  251.  
  252.  
  253.  
  254. static event_iconrecord *FindIcon(event_windowrecord *windowrecord,
  255.                                   icon_handle        icon)
  256. {
  257.   event_iconrecord *current;
  258.  
  259.   current = LinkList_FirstItem(&(windowrecord->iconlist));
  260.   while (current != NULL)
  261.   {
  262.     if (current->icon == icon)
  263.       break;
  264.     current = LinkList_NextItem(&(current->header));
  265.   }
  266.   return(current);
  267. }
  268.  
  269.  
  270.  
  271. static event_windowrecord *FindWindow(window_handle window)
  272. {
  273.   event_windowrecord *current;
  274.  
  275.   current = LinkList_FirstItem(&window_anchor);
  276.   while (current != NULL)
  277.   {
  278.     if (current->window == window)
  279.       break;
  280.     current = LinkList_NextItem(&(current->header));
  281.   }
  282.  
  283.   return(current);
  284. }
  285.  
  286.  
  287.  
  288. extern BOOL Event_Claim(event_type eventtype,
  289.                         window_handle window,  icon_handle icon,
  290.                         event_handler handler, void *reference)
  291. {
  292.   event_claimrecord  *record;
  293.   event_iconrecord   *iconrecord;
  294.   event_windowrecord *windowrecord;
  295.   int                index;
  296.   BOOL               result;
  297.  
  298.   result = FALSE;
  299.   if ((eventtype == event_ANY) ||
  300.        ((eventtype >= 0) && (eventtype < wimp_NUMBEROFEVENTS) &&
  301.         (eventclass[eventtype] != nonexistent)))
  302.   {
  303.     record = malloc(sizeof(event_claimrecord));
  304.     if (record == NULL)
  305.     {
  306.       Error_ReportInternal(ERR3, ERRMESS3);
  307.       return(TRUE);
  308.     }
  309.  
  310.     record->eventtype = eventtype;
  311.     record->handler   = handler;
  312.     record->reference = reference;
  313.  
  314.     if (window == event_ANY)
  315.     {
  316.       if (eventtype == event_ANY)
  317.       {
  318.         /* Any events to any window (lowest level of hierarchy) */
  319.         LinkList_AddToHead(&catchalls, &(record->header));
  320.         result = TRUE;
  321.  
  322.         for (index = 1; index < event_MAXEVENTS; index++)
  323.           if (eventclass[index] != nonexistent)
  324.             IncrementUsage(index);
  325.       }
  326.       else
  327.       {
  328.         /* Specific event to any window */
  329.         LinkList_AddToHead(&(eventqueues[eventtype]), &(record->header));
  330.         result = TRUE;
  331.  
  332.         IncrementUsage(eventtype);
  333.       }
  334.     }
  335.     else
  336.     {
  337.       /* Claims for specific windows... */
  338.       windowrecord = FindWindow(window);/* Find/Make claim record for window */
  339.       if (windowrecord == NULL)
  340.         windowrecord = CreateWindowRecord(window);
  341.  
  342.       if (windowrecord != NULL)
  343.       {
  344.         if (icon == event_ANY)
  345.         {
  346.           /* Specific window, any icon */
  347.           if (eventtype == event_ANY)
  348.           {
  349.             /* Specific window, any icon, any event */
  350.             LinkList_AddToTail(&(windowrecord->claimlist), &(record->header));
  351.             result = TRUE;
  352.  
  353.             /* NULL events are not included in "event_ANY", so start from 1 */
  354.             for (index = 1; index < event_MAXEVENTS; index++)
  355.               if (eventclass[index] != nonexistent)
  356.                 IncrementUsage (index);
  357.           }
  358.           else
  359.           {
  360.             /* specific window, any icon, specific event */
  361.             LinkList_AddToHead(&(windowrecord->claimlist), &(record->header));
  362.             result = TRUE;
  363.  
  364.             IncrementUsage(eventtype);
  365.           }
  366.  
  367.         }
  368.         else
  369.         {
  370.           /* Specific window, specific icon */
  371.           iconrecord = FindIcon(windowrecord, icon);
  372.           if (iconrecord == NULL)
  373.               iconrecord = CreateIconRecord(windowrecord, icon);
  374.  
  375.           if (iconrecord != NULL)
  376.           {
  377.             if (eventtype == event_ANY)
  378.             {
  379.               /* specific window, specific icon, any event */
  380.               LinkList_AddToTail(&(iconrecord->claimlist),&(record->header));
  381.               result = TRUE;
  382.  
  383.               /* NULL events are not included in "event_ANY" so start from 1 */
  384.               for (index = 1; index < event_MAXEVENTS; index++)
  385.                 if (eventclass[index] != nonexistent)
  386.                   IncrementUsage(index);
  387.             }
  388.             else
  389.             {
  390.               /* specific window, specific icon, specific event */
  391.               LinkList_AddToHead(&(iconrecord->claimlist), &(record->header));
  392.               result = TRUE;
  393.  
  394.               IncrementUsage(eventtype);
  395.             }
  396.           }
  397.         }
  398.       }
  399.     }
  400.     if (result == FALSE)
  401.         free (record);
  402.   }
  403.   else
  404.     Error_ReportInternal(ERR4, ERRMESS4);
  405.  
  406.   return(result);
  407. }
  408.  
  409.  
  410.  
  411. static void LoseClaim(linklist_header *listheader,
  412.                       event_claimrecord *claimrecord)
  413. {
  414.   int index;
  415.  
  416.   if (claimrecord->eventtype == event_ANY)
  417.   {
  418.     /* "event_ANY" does not include event_NULL, so start from 1 */
  419.     for (index = 1; index < wimp_NUMBEROFEVENTS; index++)
  420.       if (eventclass[index] != nonexistent)
  421.               DecrementUsage(index);
  422.   }
  423.   else
  424.     DecrementUsage(claimrecord->eventtype);
  425.  
  426.   if (claimrecord == currentscan)
  427.     currentscan = NULL; /* Make other routines aware we have deleted the item
  428.                            that they are currently scanning                  */
  429.  
  430.   LinkList_Unlink(listheader, &(claimrecord->header));
  431.  
  432.   free(claimrecord);
  433. }
  434.  
  435.  
  436.  
  437. static BOOL RemoveClaim(linklist_header *header,
  438.                         event_type      eventtype,
  439.                         event_handler   handler, void *reference,
  440.                         int             *lastone)
  441. /* Returns TRUE if it found and removed the claim.
  442.  * If it did, it also returns a flag: lastone == TRUE if no more claims left
  443.  * on this event
  444.  */
  445. {
  446.   event_claimrecord *claimrecord;
  447.   BOOL result;
  448.  
  449.   result = FALSE;
  450.   claimrecord = LinkList_FirstItem(header);
  451.  
  452.   while (claimrecord != NULL)
  453.   {
  454.     if ((claimrecord->eventtype == eventtype) &&
  455.         (claimrecord->handler   == handler)   &&
  456.         (claimrecord->reference == reference))
  457.     {
  458.       LoseClaim(header, claimrecord);
  459.       result = TRUE;
  460.       break;
  461.     }
  462.  
  463.     claimrecord = LinkList_NextItem(&(claimrecord->header));
  464.   }
  465.  
  466.   if ((result) && (lastone != NULL))
  467.     *lastone = (LinkList_FirstItem(header) == NULL);    /* return the result */
  468.  
  469.   return(result);
  470. }
  471.  
  472.  
  473.  
  474. static void LoseIcon(linklist_header *list, event_iconrecord *iconrecord)
  475. {
  476.   event_claimrecord *claimrecord;
  477.  
  478.   while ((claimrecord = LinkList_FirstItem(&(iconrecord->claimlist))) != NULL)
  479.     LoseClaim(&(iconrecord->claimlist), claimrecord);
  480.  
  481.   LinkList_Unlink(list, &(iconrecord->header));
  482.   free(iconrecord);
  483. }
  484.  
  485.  
  486.  
  487. static void LoseWindow(event_windowrecord *windowrecord)
  488. {
  489.   LinkList_Unlink(&window_anchor, &(windowrecord->header));
  490.   free(windowrecord);
  491. }
  492.  
  493.  
  494.  
  495. extern BOOL Event_Release(event_type event,
  496.                           window_handle  window, icon_handle icon,
  497.                           event_handler handler, void *reference)
  498. {
  499.   event_windowrecord *windowrecord;
  500.   event_iconrecord *iconrecord;
  501.   int  lastone;
  502.   BOOL result;
  503.  
  504.   result = FALSE;
  505.  
  506.   if (window == event_ANY)
  507.   {
  508.     if (event == event_ANY)
  509.       result = RemoveClaim(&catchalls, event, handler, reference, NULL);
  510.     else
  511.       result = RemoveClaim (&(eventqueues[event]),
  512.                                event, handler, reference, NULL);
  513.   }
  514.   else
  515.   {
  516.     windowrecord = FindWindow(window);
  517.     if (windowrecord != NULL)
  518.     {
  519.       if (icon == event_ANY)
  520.         result = RemoveClaim(&(windowrecord->claimlist),
  521.                                  event, handler, reference, NULL);
  522.       else
  523.       {
  524.         iconrecord = FindIcon(windowrecord, icon);
  525.         if (iconrecord != NULL)
  526.         {
  527.           if (RemoveClaim(&(iconrecord->claimlist),
  528.                                       event, handler, reference, &lastone))
  529.           {
  530.             result = TRUE;
  531.             if (lastone)
  532.               LoseIcon(&(windowrecord->iconlist), iconrecord);
  533.           }
  534.         }
  535.       }
  536.  
  537.       if (result)
  538.       {
  539.         if ((LinkList_FirstItem(&(windowrecord->iconlist)) == NULL) &&
  540.             (LinkList_FirstItem(&(windowrecord->claimlist)) == NULL))
  541.           LoseWindow(windowrecord);
  542.       }
  543.     }
  544.   }
  545.  
  546.   if (!result)
  547.     Error_ReportInternal(ERR5, ERRMESS5);
  548.  
  549.   return (result) ;
  550. }
  551.  
  552.  
  553.  
  554. extern void Event_ReleaseWindow(window_handle window)
  555. {
  556.   event_claimrecord  *claimrecord;
  557.   event_iconrecord   *iconrecord;
  558.   event_windowrecord *windowrecord;
  559.  
  560.   windowrecord = FindWindow(window);
  561.   if (windowrecord != NULL)
  562.   {
  563.     while ((claimrecord = LinkList_FirstItem(&(windowrecord->claimlist)))
  564.            != NULL)
  565.       LoseClaim(&(windowrecord->claimlist), claimrecord) ;
  566.  
  567.     while ((iconrecord = LinkList_FirstItem(&(windowrecord->iconlist)))
  568.            != NULL)
  569.       LoseIcon(&(windowrecord->iconlist), iconrecord);
  570.  
  571.     LoseWindow(windowrecord);
  572.   }
  573. }
  574.  
  575.  
  576.  
  577. /* Event dispatchers. These functions take in an event, and find the highest-
  578.  * priority user event handler, which is then called to process the event
  579.  */
  580.  
  581. static BOOL ScanMiscQueue(linklist_header *queue, event_pollblock *event)
  582. {
  583.   event_claimrecord *current;
  584.  
  585.   current = LinkList_FirstItem(queue);
  586.   while (current != NULL)
  587.   {
  588.     currentscan = current;
  589.     if (current->handler(event, current->reference))
  590.       return(TRUE);                    /* User handler has handled the event */
  591.  
  592.     if (currentscan == current)
  593.       current = LinkList_NextItem(&(current->header));
  594.     else
  595.       current = LinkList_FirstItem(queue);/* item deleted out from under us! */
  596.   }
  597.   return(FALSE);
  598. }
  599.  
  600.  
  601.  
  602. static BOOL DispatchMiscEvents(event_pollblock *event, void *reference)
  603. /* Processes any general event that either is non-window-specific, or has not
  604.  * been processed by any higher-level handlers. If NO handler at this level
  605.  * manages to handle the event, then only default action is to check for the
  606.  * QUIT message, and quit if necessary.
  607.  */
  608. {
  609.   BOOL dummy;
  610.   linklist_header *queue;
  611.  
  612.   queue = &eventqueues[event->type];          /* Try specific event handlers */
  613.   dummy = ScanMiscQueue(queue, event);
  614.  
  615.   if (!dummy)
  616.     dummy = ScanMiscQueue(&catchalls, event);      /* Try catch-all handlers */
  617.  
  618.   /* User handlers haven't processed event, so check for QUIT message */
  619.   if (!dummy)
  620.     if (((event->type == event_USERMESSAGE) ||
  621.          (event->type == event_USERMESSAGERECORDED)) &&
  622.          (event->data.message.header.action == message_QUIT))
  623.       exit(0);          /* Just die. atexit() handlers should tidy up for us */
  624.  
  625.   return(TRUE);   /* Always assume we have handled the event, because we are
  626.                      the last event handler that will ever be called...      */
  627. }
  628.  
  629.  
  630.  
  631. static BOOL ScanWindowQueue(linklist_header *queue, event_pollblock *event)
  632. {
  633.   event_claimrecord *current;
  634.  
  635.   current = LinkList_FirstItem(queue);
  636.   while (current != NULL)
  637.   {
  638.     currentscan = current ;
  639.     if ((current->eventtype == event->type) ||
  640.         (current->eventtype == event_ANY))
  641.       if (current->handler(event, current->reference))
  642.         return(TRUE);                      /* User handler has handled event */
  643.  
  644.     if (currentscan == current)
  645.       current = LinkList_NextItem(&(current->header));
  646.     else
  647.       current = LinkList_FirstItem(queue);/* item deleted out from under us! */
  648.   }
  649.   return(FALSE);
  650. }
  651.  
  652.  
  653.  
  654. static BOOL DispatchIconEvents(event_pollblock *event, void *reference)
  655. {
  656.   icon_handle        icon;
  657.   event_iconrecord   *iconrecord;
  658.   window_handle      window;
  659.   event_windowrecord *windowrecord;
  660.  
  661.   if (event->type == event_CLICK)
  662.     window = event->data.mouse.window;
  663.   else
  664.     window = event->data.openblock.window;
  665.  
  666.   windowrecord = FindWindow(window);
  667.   if (windowrecord != NULL)
  668.   {
  669.     switch (event->type)
  670.     {
  671.       case event_CLICK:
  672.         icon = event->data.mouse.icon;
  673.         break;
  674.  
  675.       case event_KEY:
  676.         icon = event->data.key.caret.icon;
  677.         break;
  678.  
  679.       case event_LOSECARET:
  680.       case event_GAINCARET:
  681.         icon = event->data.caret.icon;
  682.         break;
  683.  
  684.       default:
  685.         icon = -1;
  686.         break;
  687.     }
  688.  
  689.     if (icon != -1)
  690.     {
  691.       iconrecord = FindIcon(windowrecord, icon);
  692.       if (iconrecord != NULL)
  693.         if (ScanWindowQueue(&(iconrecord->claimlist), event))
  694.           return(TRUE);  /* event handled */
  695.     }
  696.  
  697.     if (ScanWindowQueue(&(windowrecord->claimlist), event))
  698.       return(TRUE);  /* event handled */
  699.   }
  700.  
  701. /* Unable to find a highlevel handler for this event, so fallback to the
  702.  * low-level handlers...
  703.  */
  704.  
  705.   return(DispatchMiscEvents(event, NULL));
  706. }
  707.  
  708.  
  709.  
  710. static BOOL DispatchWindowEvents(event_pollblock *event, void *reference)
  711. {
  712.   window_handle      window;
  713.   event_windowrecord *windowrecord;
  714.  
  715.   window = event->data.openblock.window;
  716.   windowrecord = FindWindow(window);
  717.  
  718.   if (windowrecord != NULL)
  719.     if (ScanWindowQueue(&(windowrecord->claimlist), event))
  720.       return(TRUE);  /* Window handler has dealt with the event */
  721.  
  722. /* Unable to find a highlevel handler for this event, so fallback to the
  723.  * low-level handlers...
  724.  */
  725.  
  726.   return(DispatchMiscEvents(event, NULL));
  727. }
  728.  
  729.  
  730.  
  731. void ExitFunction(void)
  732. /* This function is called at exit, to tidy up as we quit */
  733. {
  734.   if (event_taskhandle != 0)
  735.     Wimp_CloseDown(event_taskhandle);
  736. }
  737.  
  738.  
  739.  
  740. /* And now, ladies and gentlemen, the routines you have all been waiting
  741.  * for... I give you... the amazing Eventi brothers...
  742.  */
  743.  
  744. extern void Event_Initialise(char *taskname)
  745. {
  746.   Event_Initialise3(taskname, 200, NULL);
  747. }
  748.  
  749.  
  750. extern void Event_Initialise3(char *taskname, int version, int *messages)
  751. {
  752.   int index;
  753.  
  754.   atexit(ExitFunction);
  755.   for (index = 0; index < event_MAXEVENTS; index++)
  756.   {
  757.     if (event_masks[index])
  758.       event_mask.value |= 1 << index;
  759.   }  
  760.  
  761.   if (version >= 300)
  762.   {
  763.     eventclass[event_NONZEROPOLLWORD] = notrelated;
  764.     event_handlers[event_NONZEROPOLLWORD] = DispatchMiscEvents;
  765.   }
  766.  
  767.   event_wimpversion = version;
  768.   Error_CheckFatal(Wimp_Initialise(&event_wimpversion,
  769.                                      taskname, &event_taskhandle, messages));
  770.   strncpy(event_taskname, taskname, 39);
  771.   event_taskname[39] = 0;
  772. }
  773.  
  774.  
  775. extern void Event_Process(event_pollblock *event)
  776. {
  777.   event_handler handler;
  778.  
  779.   handler = (event_handler) (event_handlers[event->type]);
  780.   handler(event, NULL);
  781. }
  782.  
  783.  
  784.  
  785. extern void Event_Poll(void)
  786. {
  787.   Wimp_Poll(event_mask, &event_lastevent);
  788.   Event_Process(&event_lastevent);
  789. }
  790.  
  791.  
  792.  
  793. extern void Event_CloseDown(void)
  794. {
  795.   exit(0);  /* Wimp_CloseDown is handled by the ExitFunction */
  796. }
  797.