1 /*
2 * Copyright 1993 Network Computing Devices, Inc.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name Network Computing Devices, Inc. not be
9 * used in advertising or publicity pertaining to distribution of this
10 * software without specific, written prior permission.
11 *
12 * THIS SOFTWARE IS PROVIDED 'AS-IS'. NETWORK COMPUTING DEVICES, INC.,
13 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
14 * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15 * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
16 * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
17 * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
18 * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
19 * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 *
22 * $NCDId: @(#)HandleEv.c,v 1.9 1993/08/11 17:01:58 greg Exp $
23 */
24
25 /*
26 * This file contains utilities contains an event handler takes care of
27 * dispatching the various events that might come into an application. The
28 * idea is to hide most of the mainline activity so that simple applications
29 * don't have to fuss with things.
30 *
31 * For example, an application that wants to play a sound from a file or memory
32 * buffer asynchronously needs to wait for events telling it when it can
33 * write to the ImportElement in the flow.
34 */
35
36 #include "Alibint.h"
37
38 void
AuHandleEvents(AuServer * aud)39 AuHandleEvents(AuServer *aud)
40 {
41 int nevents;
42 AuEvent event;
43
44 while (1)
45 {
46 /* do our best to find an event */
47 nevents = _AuEventsQueued(aud, AuEventsQueuedAlready);
48
49 if (!nevents)
50 {
51 nevents = _AuEventsQueued(aud, AuEventsQueuedAfterFlush);
52
53 if (!nevents)
54 {
55 nevents = _AuEventsQueued(aud, AuEventsQueuedAfterReading);
56
57 if (!nevents)
58 return;
59 }
60 }
61
62 /* got one, now do something with it */
63 for (; nevents > 0; nevents--)
64 {
65 AuNextEvent(aud, AuTrue, &event); /* dequeue the event */
66 (void) AuDispatchEvent(aud, &event); /* go deal with it */
67 }
68 }
69 }
70
71 AuBool
AuDispatchEvent(AuServer * aud,AuEvent * event)72 AuDispatchEvent(
73 AuServer *aud,
74 AuEvent *event
75 )
76 {
77 AuBool result = AuFalse;
78 AuEventHandlerRec *handler = NULL, *next;
79
80 do
81 {
82 if ((handler = AuLookupEventHandler(aud, event, handler))
83 != (AuEventHandlerRec *) NULL)
84 {
85 next = handler->next; /* could be removed by handler */
86 result |= (*(handler->callback)) (aud, event, handler);
87 handler = next;
88 }
89 } while (handler);
90
91 return result;
92 }
93
94 AuEventHandlerRec *
AuLookupEventHandler(AuServer * aud,AuEvent * event,AuEventHandlerRec * handler)95 AuLookupEventHandler(
96 AuServer *aud,
97 AuEvent *event,
98 AuEventHandlerRec *handler
99 )
100 {
101 /*
102 * From the given start location (NULL indicates beginning), walk down
103 * the handlers list looking for a match.
104 */
105 if (!handler)
106 handler = aud->eventhandlerq;
107
108 /*
109 * This could be done more efficiently than a linear lookup, but there
110 * are relatively few events in the audio protocol, so the overhead
111 * should be acceptable.
112 */
113 for (; handler; handler = handler->next)
114 {
115 if ((handler->mask & AuEventHandlerTypeMask) &&
116 (handler->type != event->type))
117 continue;
118
119 if ((handler->mask & AuEventHandlerIDMask) &&
120 (handler->id != event->auany.id))
121 continue;
122
123 break; /* got one! */
124 }
125
126 return handler;
127 }
128
129 AuEventHandlerRec *
AuRegisterEventHandler(AuServer * aud,AuMask mask,int type,AuID id,AuEventHandlerCallback callback,AuPointer data)130 AuRegisterEventHandler(
131 AuServer *aud,
132 AuMask mask,
133 int type,
134 AuID id,
135 AuEventHandlerCallback callback,
136 AuPointer data
137 )
138 {
139 AuEventHandlerRec *handler;
140
141 if (!(handler = (AuEventHandlerRec *) Aumalloc(sizeof(AuEventHandlerRec))))
142 return NULL;
143
144 handler->aud = aud;
145 handler->mask = mask;
146 handler->type = type;
147 handler->id = id;
148 handler->callback = callback;
149 handler->data = data;
150
151 _AuAddToLinkedList(aud->eventhandlerq, handler);
152
153 return handler;
154 }
155
156 void
AuUnregisterEventHandler(AuServer * aud,AuEventHandlerRec * handler)157 AuUnregisterEventHandler(
158 AuServer *aud,
159 AuEventHandlerRec *handler
160 )
161 {
162 _AuRemoveFromLinkedList(aud->eventhandlerq, handler);
163 Aufree(handler);
164 }
165