1 /*
2  * Copyright 1993 Network Computing Devices, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that 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: @(#)ScanEvents.c,v 1.5 1993/01/29 20:47:28 lemke Exp $
23  */
24 
25 /* Portions derived from */
26 /* $XConsortium: XChkIfEv.c,v 11.11 91/01/06 11:44:28 rws Exp $ */
27 /* Copyright    Massachusetts Institute of Technology    1985, 1987	*/
28 
29 #include "Alibint.h"
30 
31 /*
32  * AuScanEvents - Walk the queue of events (refilling if necessary) looking
33  * for an event that matches a caller-specified predicate.  If one is found,
34  * the search stops and the event is optionally dequeued.  The mode argument
35  * indicates how far the routine should keep scanning looking for a match:
36  *
37  *     AuEventsQueuedAlready		Only those events in the queue are
38  * 					are scaned.
39  *
40  *     AuEventsQueuedAfterReading	If no match is found from the queue,
41  * 					a read is attempted see if there are
42  * 					any pending.
43  *
44  *     AuEventsQueuedAfterFlush		If no match is found after reading,
45  * 					the output buffer is flushed.
46  */
47 
AuScanEvents(AuServer * aud,int mode,AuBool dequeue,AuBool (* predicate)(AuServer *,AuEvent *,AuPointer),AuPointer arg,AuEvent * event)48 AuBool AuScanEvents (
49                      AuServer *aud,
50                      int mode,
51                      AuBool dequeue,
52                      AuBool (*predicate)(
53                                          AuServer *, /* server */
54                                          AuEvent *, /* event */
55                                          AuPointer /* arg */
56                                          ), /* function to call */
57                      AuPointer arg,
58                      AuEvent *event		/* AuEvent to be filled in. */
59                      )
60 {
61     _AuQEvent *prev, *qelt;
62     int n;			/* time through count */
63 
64     if (mode > AuEventsQueuedAfterFlush)
65 	return AuFalse;
66 
67     _AuLockServer();
68     prev = NULL;
69     for (n = AuEventsQueuedAlready; n <= mode; n++) {
70 	switch (n) {
71 	  case AuEventsQueuedAfterReading:
72 	    (void) _AuEventsQueued (aud, AuEventsQueuedAfterReading);
73 	    break;
74 
75 	  case AuEventsQueuedAfterFlush:
76 	    _AuFlush (aud);
77 	    break;
78 	}
79 
80 	for (qelt = prev ? prev->next : aud->head; qelt;
81 	     prev = qelt, qelt = qelt->next) {
82 	    if ((*predicate)(aud, &qelt->event, arg)) {	   /* found a match */
83 		*event = qelt->event;
84 		if (dequeue) {
85 		    if (prev) {
86 			if ((prev->next = qelt->next) == NULL)
87 			    aud->tail = prev;
88 		    } else {
89 			if ((aud->head = qelt->next) == NULL)
90 			    aud->tail = NULL;
91 		    }
92 		    qelt->next = aud->qfree;
93 		    aud->qfree = qelt;
94 		    aud->qlen--;
95 		}
96 		_AuUnlockServer();
97 		return AuTrue;
98 	    }
99 	}
100     }
101     _AuUnlockServer();
102     return AuFalse;
103 }
104