home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / curve / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  4.0 KB  |  173 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    event.c
  19.  *    A more rational way to handle reading the event queue
  20.  * Written by Wade Olsen
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <device.h>
  25. #include "event.h"
  26.  
  27.  
  28. typedef struct event_s
  29. {
  30.     int        window, device, state;
  31.     void (*func)(void *, int);
  32.     char *arg;
  33.     struct event_s    *next;
  34. } event_t, *event_p;
  35.  
  36. typedef struct update_s
  37. {
  38.     int *flag;
  39.     void (*ufunc)(void *);
  40.     char *arg;
  41.     struct update_s *next;
  42. } update_t, *update_p;
  43.  
  44.  
  45. static event_p        event_list;
  46. static update_p    update_list;
  47.  
  48. /*
  49.  * This routine adds an event to be checked for to the event queue.
  50.  * window should be the wid of the window to respond in, or ANY if
  51.  * this event applies to all windows.  device is the device, and state
  52.  * is the device's value (e.g.  ANY, UP, DOWN, the window id (for
  53.  * REDRAW), etc).  Func is the function that will be called, with
  54.  * arguments 'arg' and the device's value.
  55.  * 
  56.  * NOTE:  the device must be queued for it to be found by the event()
  57.  * routine-- add_event DOES NOT qdevice(device).
  58.  */
  59. void
  60. add_event(window, device, state, func, arg)
  61. int    window, device, state;
  62. void (*func)(void *, int);
  63. char *arg;
  64. {
  65.     event_p new_guy;
  66.  
  67.     new_guy = (event_p)malloc(sizeof(event_t));
  68.     new_guy->window = window;
  69.     new_guy->device = device;
  70.     new_guy->state  = state;
  71.     new_guy->func   = func;
  72.     new_guy->arg    = arg;
  73.     new_guy->next   = event_list;
  74.     event_list = new_guy;
  75. }
  76.  
  77. /*
  78.  *    Specify a function to be called if there is nothing in the queue
  79.  * and (*flag) is non-zero.  If no update function is active, or
  80.  * (*flag) is 0, then event() will block on a qread.  If there is an
  81.  * active update function, event() will continuously call the update
  82.  * function, hogging the cpu.
  83.  */
  84. void
  85. add_update(flag, ufunc, arg)
  86. int    *flag;
  87. void (*ufunc)(void *);
  88. char *arg;
  89. {
  90.     update_p    new_guy;
  91.  
  92.     new_guy = (update_p)malloc(sizeof(update_t));
  93.     new_guy->flag = flag;
  94.     new_guy->ufunc = ufunc;
  95.     new_guy->arg  = arg;
  96.     new_guy->next = update_list;
  97.     update_list = new_guy;
  98. }
  99.  
  100. /*
  101.  * The main Event.  Call this repeatedly to automagically handle
  102.  * reading the queue, and calling your functions to handle what
  103.  * appears there.
  104.  */
  105. void
  106. event()
  107. {
  108.     void find_event(void), event_inputchange(void);
  109.     int find_update(void);
  110.     static int initialized = 0;
  111.     
  112.     if (initialized == 0)
  113.     {
  114.         add_event(ANY, INPUTCHANGE, ANY, event_inputchange, NULL);
  115.         qdevice(INPUTCHANGE);
  116.         initialized = 1;
  117.     }
  118.  
  119.     /* Something in the queue?  Handle it */
  120.     if (qtest())
  121.         find_event();
  122.     /*
  123.      * Or, if there's no update function, wait for something to appear
  124.      */
  125.     else if (find_update() == 0)
  126.         find_event();
  127. }
  128.  
  129. int
  130. find_update()
  131. {
  132.     update_p    scan;
  133.     int        updated = 0;
  134.  
  135.     for (scan = update_list; scan && updated == 0; scan = scan->next)
  136.     {
  137.         if (*scan->flag)
  138.         {
  139.             (*scan->ufunc)(scan->arg);
  140.             updated = 1;
  141.         }
  142.     }
  143.  
  144.     return(updated);
  145. }
  146.  
  147. int context, state, device;
  148.  
  149. void
  150. event_inputchange()
  151. {
  152.     context = winget();
  153. }
  154.  
  155. void
  156. find_event()
  157. {
  158.     event_p scan;
  159.     short    s;
  160.  
  161.     device = qread(&s);
  162.     state = s;
  163.     for (scan = event_list; scan; scan = scan->next)
  164.     {
  165.         if ( ((scan->window == ANY) || (context == scan->window))
  166.             && ((scan->device == ANY) ||(device == scan->device))
  167.             && ((scan->state == ANY) || (state == scan->state)))
  168.         {
  169.             (*scan->func)(scan->arg, state);
  170.         }
  171.     }
  172. }
  173.