File: | NextEvent.c |
Location: | line 822, column 10 |
Description: | Access to field 'timerQueue' results in a dereference of a null pointer (loaded from variable 'app') |
1 | /*********************************************************** |
2 | Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. |
3 | |
4 | Permission is hereby granted, free of charge, to any person obtaining a |
5 | copy of this software and associated documentation files (the "Software"), |
6 | to deal in the Software without restriction, including without limitation |
7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | and/or sell copies of the Software, and to permit persons to whom the |
9 | Software is furnished to do so, subject to the following conditions: |
10 | |
11 | The above copyright notice and this permission notice (including the next |
12 | paragraph) shall be included in all copies or substantial portions of the |
13 | Software. |
14 | |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
21 | DEALINGS IN THE SOFTWARE. |
22 | |
23 | Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. |
24 | |
25 | All Rights Reserved |
26 | |
27 | Permission to use, copy, modify, and distribute this software and its |
28 | documentation for any purpose and without fee is hereby granted, |
29 | provided that the above copyright notice appear in all copies and that |
30 | both that copyright notice and this permission notice appear in |
31 | supporting documentation, and that the name of Digital not be |
32 | used in advertising or publicity pertaining to distribution of the |
33 | software without specific, written prior permission. |
34 | |
35 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING |
36 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL |
37 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR |
38 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
39 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
40 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
41 | SOFTWARE. |
42 | |
43 | ******************************************************************/ |
44 | |
45 | /* |
46 | |
47 | Copyright 1987, 1988, 1994, 1998, 2001 The Open Group |
48 | |
49 | Permission to use, copy, modify, distribute, and sell this software and its |
50 | documentation for any purpose is hereby granted without fee, provided that |
51 | the above copyright notice appear in all copies and that both that |
52 | copyright notice and this permission notice appear in supporting |
53 | documentation. |
54 | |
55 | The above copyright notice and this permission notice shall be included in |
56 | all copies or substantial portions of the Software. |
57 | |
58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
59 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
60 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
61 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
62 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
63 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
64 | |
65 | Except as contained in this notice, the name of The Open Group shall not be |
66 | used in advertising or otherwise to promote the sale, use or other dealings |
67 | in this Software without prior written authorization from The Open Group. |
68 | |
69 | */ |
70 | |
71 | #ifdef HAVE_CONFIG_H1 |
72 | #include <config.h> |
73 | #endif |
74 | #include "IntrinsicI.h" |
75 | #include <stdio.h> |
76 | #include <errno(*__errno_location ()).h> |
77 | |
78 | #ifdef __UNIXOS2__ |
79 | #include <sys/time.h> |
80 | #endif |
81 | |
82 | static TimerEventRec* freeTimerRecs; |
83 | static WorkProcRec* freeWorkRecs; |
84 | static SignalEventRec* freeSignalRecs; |
85 | |
86 | /* Some systems running NTP daemons are known to return strange usec |
87 | * values from gettimeofday. |
88 | */ |
89 | |
90 | #ifndef NEEDS_NTPD_FIXUP0 |
91 | # if defined(sun) || defined(MOTOROLA) || (defined(__osf__) && defined(__alpha)) |
92 | # define NEEDS_NTPD_FIXUP0 1 |
93 | # else |
94 | # define NEEDS_NTPD_FIXUP0 0 |
95 | # endif |
96 | #endif |
97 | |
98 | #if NEEDS_NTPD_FIXUP0 |
99 | #define FIXUP_TIMEVAL(t) { \ |
100 | while ((t).tv_usec >= 1000000) { \ |
101 | (t).tv_usec -= 1000000; \ |
102 | (t).tv_sec++; \ |
103 | } \ |
104 | while ((t).tv_usec < 0) { \ |
105 | if ((t).tv_sec > 0) { \ |
106 | (t).tv_usec += 1000000; \ |
107 | (t).tv_sec--; \ |
108 | } else { \ |
109 | (t).tv_usec = 0; \ |
110 | break; \ |
111 | } \ |
112 | }} |
113 | #else |
114 | #define FIXUP_TIMEVAL(t) |
115 | #endif /*NEEDS_NTPD_FIXUP*/ |
116 | |
117 | /* |
118 | * Private routines |
119 | */ |
120 | #define ADD_TIME(dest, src1, src2){ if(((dest).tv_usec = (src1).tv_usec + (src2).tv_usec) >= 1000000) { (dest).tv_usec -= 1000000; (dest).tv_sec = (src1) .tv_sec + (src2).tv_sec + 1 ; } else { (dest).tv_sec = (src1) .tv_sec + (src2).tv_sec ; if(((dest).tv_sec >= 1) && (((dest).tv_usec <0))) { (dest).tv_sec --;(dest).tv_usec += 1000000; } } } { \ |
121 | if(((dest).tv_usec = (src1).tv_usec + (src2).tv_usec) >= 1000000) {\ |
122 | (dest).tv_usec -= 1000000;\ |
123 | (dest).tv_sec = (src1).tv_sec + (src2).tv_sec + 1 ; \ |
124 | } else { (dest).tv_sec = (src1).tv_sec + (src2).tv_sec ; \ |
125 | if(((dest).tv_sec >= 1) && (((dest).tv_usec <0))) { \ |
126 | (dest).tv_sec --;(dest).tv_usec += 1000000; } } } |
127 | |
128 | |
129 | #define TIMEDELTA(dest, src1, src2){ if(((dest).tv_usec = (src1).tv_usec - (src2).tv_usec) < 0 ) { (dest).tv_usec += 1000000; (dest).tv_sec = (src1).tv_sec - (src2).tv_sec - 1; } else (dest).tv_sec = (src1).tv_sec - (src2 ).tv_sec; } { \ |
130 | if(((dest).tv_usec = (src1).tv_usec - (src2).tv_usec) < 0) {\ |
131 | (dest).tv_usec += 1000000;\ |
132 | (dest).tv_sec = (src1).tv_sec - (src2).tv_sec - 1;\ |
133 | } else (dest).tv_sec = (src1).tv_sec - (src2).tv_sec; } |
134 | |
135 | #define IS_AFTER(t1, t2)(((t2).tv_sec > (t1).tv_sec) || (((t2).tv_sec == (t1).tv_sec )&& ((t2).tv_usec > (t1).tv_usec))) (((t2).tv_sec > (t1).tv_sec) \ |
136 | || (((t2).tv_sec == (t1).tv_sec)&& ((t2).tv_usec > (t1).tv_usec))) |
137 | |
138 | #define IS_AT_OR_AFTER(t1, t2)(((t2).tv_sec > (t1).tv_sec) || (((t2).tv_sec == (t1).tv_sec )&& ((t2).tv_usec >= (t1).tv_usec))) (((t2).tv_sec > (t1).tv_sec) \ |
139 | || (((t2).tv_sec == (t1).tv_sec)&& ((t2).tv_usec >= (t1).tv_usec))) |
140 | |
141 | #ifdef USE_POLL1 |
142 | #ifndef XT_DEFAULT_FDLIST_SIZE32 |
143 | #define XT_DEFAULT_FDLIST_SIZE32 32 |
144 | #endif |
145 | #endif |
146 | |
147 | static void AdjustHowLong ( |
148 | unsigned long *howlong, |
149 | struct timeval *start_time) |
150 | { |
151 | struct timeval new_time, time_spent, lstart_time; |
152 | |
153 | lstart_time = *start_time; |
154 | X_GETTIMEOFDAY (&new_time)gettimeofday(&new_time, (struct timezone*)0); |
155 | FIXUP_TIMEVAL(new_time); |
156 | TIMEDELTA(time_spent, new_time, lstart_time){ if(((time_spent).tv_usec = (new_time).tv_usec - (lstart_time ).tv_usec) < 0) { (time_spent).tv_usec += 1000000; (time_spent ).tv_sec = (new_time).tv_sec - (lstart_time).tv_sec - 1; } else (time_spent).tv_sec = (new_time).tv_sec - (lstart_time).tv_sec ; }; |
157 | if(*howlong <= (unsigned long)(time_spent.tv_sec*1000+time_spent.tv_usec/1000)) |
158 | *howlong = (unsigned long)0; /* Timed out */ |
159 | else |
160 | *howlong -= (time_spent.tv_sec*1000+time_spent.tv_usec/1000); |
161 | } |
162 | |
163 | typedef struct { |
164 | struct timeval cur_time; |
165 | struct timeval start_time; |
166 | struct timeval wait_time; |
167 | struct timeval new_time; |
168 | struct timeval time_spent; |
169 | struct timeval max_wait_time; |
170 | #ifndef USE_POLL1 |
171 | struct timeval *wait_time_ptr; |
172 | #else |
173 | int poll_wait; |
174 | #endif |
175 | } wait_times_t, *wait_times_ptr_t; |
176 | |
177 | static struct timeval zero_time = { 0 , 0}; |
178 | #ifndef USE_POLL1 |
179 | static fd_set zero_fd; |
180 | #else |
181 | #define X_BLOCK-1 -1 |
182 | #define X_DONT_BLOCK0 0 |
183 | #endif |
184 | |
185 | static void InitTimes ( |
186 | Boolean block, |
187 | unsigned long* howlong, |
188 | wait_times_ptr_t wt) |
189 | { |
190 | if (block) { |
191 | X_GETTIMEOFDAY (&wt->cur_time)gettimeofday(&wt->cur_time, (struct timezone*)0); |
192 | FIXUP_TIMEVAL(wt->cur_time); |
193 | wt->start_time = wt->cur_time; |
194 | if(howlong == NULL((void*)0)) { /* special case for ever */ |
195 | #ifndef USE_POLL1 |
196 | wt->wait_time_ptr = NULL((void*)0); |
197 | #else |
198 | wt->poll_wait = X_BLOCK-1; |
199 | #endif |
200 | } else { /* block until at most */ |
201 | wt->max_wait_time.tv_sec = *howlong/1000; |
202 | wt->max_wait_time.tv_usec = (*howlong %1000)*1000; |
203 | #ifndef USE_POLL1 |
204 | wt->wait_time_ptr = &wt->max_wait_time; |
205 | #else |
206 | wt->poll_wait = *howlong; |
207 | #endif |
208 | } |
209 | } else { /* don't block */ |
210 | wt->max_wait_time = zero_time; |
211 | #ifndef USE_POLL1 |
212 | wt->wait_time_ptr = &wt->max_wait_time; |
213 | #else |
214 | wt->poll_wait = X_DONT_BLOCK0; |
215 | #endif |
216 | } |
217 | } |
218 | |
219 | typedef struct { |
220 | #ifndef USE_POLL1 |
221 | fd_set rmask, wmask, emask; |
222 | int nfds; |
223 | #else |
224 | struct pollfd* fdlist; |
225 | struct pollfd* stack; |
226 | int fdlistlen, num_dpys; |
227 | #endif |
228 | } wait_fds_t, *wait_fds_ptr_t; |
229 | |
230 | static void InitFds ( |
231 | XtAppContext app, |
232 | Boolean ignoreEvents, |
233 | Boolean ignoreInputs, |
234 | wait_fds_ptr_t wf) |
235 | { |
236 | int ii; |
237 | app->rebuild_fdlist = FALSE0; |
238 | #ifndef USE_POLL1 |
239 | wf->nfds = app->fds.nfds; |
240 | if( !ignoreInputs ) { |
241 | wf->rmask = app->fds.rmask; |
242 | wf->wmask = app->fds.wmask; |
243 | wf->emask = app->fds.emask; |
244 | } else |
245 | wf->rmask = wf->wmask = wf->emask = zero_fd; |
246 | |
247 | if (!ignoreEvents) |
248 | for (ii = 0; ii < app->count; ii++) { |
249 | FD_SET (ConnectionNumber(app->list[ii]), &wf->rmask)((void) (((&wf->rmask)->fds_bits)[(((((_XPrivDisplay )app->list[ii])->fd)) / (8 * (int) sizeof (__fd_mask))) ] |= ((__fd_mask) 1 << (((((_XPrivDisplay)app->list[ ii])->fd)) % (8 * (int) sizeof (__fd_mask)))))); |
250 | } |
251 | #else |
252 | #ifndef POLLRDNORM0x040 |
253 | #define POLLRDNORM0x040 0 |
254 | #endif |
255 | |
256 | #ifndef POLLRDBAND0x080 |
257 | #define POLLRDBAND0x080 0 |
258 | #endif |
259 | |
260 | #ifndef POLLWRNORM0x100 |
261 | #define POLLWRNORM0x100 0 |
262 | #endif |
263 | |
264 | #ifndef POLLWRBAND0x200 |
265 | #define POLLWRBAND0x200 0 |
266 | #endif |
267 | |
268 | #define XPOLL_READ(0x001|0x040|0x002|0x080) (POLLIN0x001|POLLRDNORM0x040|POLLPRI0x002|POLLRDBAND0x080) |
269 | #define XPOLL_WRITE(0x004|0x100|0x200) (POLLOUT0x004|POLLWRNORM0x100|POLLWRBAND0x200) |
270 | #define XPOLL_EXCEPT0 0 |
271 | |
272 | if (!ignoreEvents) |
273 | wf->fdlistlen = wf->num_dpys = app->count; |
274 | else |
275 | wf->fdlistlen = wf->num_dpys = 0; |
276 | |
277 | if (!ignoreInputs && app->input_list != NULL((void*)0)) { |
278 | int ii; |
279 | for (ii = 0; ii < (int) app->input_max; ii++) |
280 | if (app->input_list[ii] != NULL((void*)0)) |
281 | wf->fdlistlen++; |
282 | } |
283 | |
284 | if (!wf->fdlist || wf->fdlist == wf->stack) { |
285 | wf->fdlist = (struct pollfd*) |
286 | XtStackAlloc (sizeof (struct pollfd) * wf->fdlistlen, wf->stack)((sizeof (struct pollfd) * wf->fdlistlen) <= sizeof(wf-> stack) ? (XtPointer)(wf->stack) : XtMalloc((unsigned)(sizeof (struct pollfd) * wf->fdlistlen))); |
287 | } else { |
288 | wf->fdlist = (struct pollfd*) |
289 | XtRealloc ((char*) wf->fdlist, |
290 | sizeof (struct pollfd) * wf->fdlistlen); |
291 | } |
292 | |
293 | if (wf->fdlistlen) { |
294 | struct pollfd* fdlp = wf->fdlist; |
295 | InputEvent* iep; |
296 | |
297 | if (!ignoreEvents) |
298 | for (ii = 0 ; ii < wf->num_dpys; ii++, fdlp++) { |
299 | fdlp->fd = ConnectionNumber (app->list[ii])(((_XPrivDisplay)app->list[ii])->fd); |
300 | fdlp->events = POLLIN0x001; |
301 | } |
302 | if (!ignoreInputs && app->input_list != NULL((void*)0)) |
303 | for (ii = 0; ii < app->input_max; ii++) |
304 | if (app->input_list[ii] != NULL((void*)0)) { |
305 | iep = app->input_list[ii]; |
306 | fdlp->fd = ii; |
307 | fdlp->events = 0; |
308 | for ( ; iep; iep = iep->ie_next) { |
309 | if (iep->ie_condition & XtInputReadMask(1L<<0)) |
310 | fdlp->events |= XPOLL_READ(0x001|0x040|0x002|0x080); |
311 | if (iep->ie_condition & XtInputWriteMask(1L<<1)) |
312 | fdlp->events |= XPOLL_WRITE(0x004|0x100|0x200); |
313 | if (iep->ie_condition & XtInputExceptMask(1L<<2)) |
314 | fdlp->events |= XPOLL_EXCEPT0; |
315 | } |
316 | fdlp++; |
317 | } |
318 | } |
319 | #endif |
320 | } |
321 | |
322 | static void AdjustTimes ( |
323 | XtAppContext app, |
324 | Boolean block, |
325 | unsigned long* howlong, |
326 | Boolean ignoreTimers, |
327 | wait_times_ptr_t wt) |
328 | { |
329 | if (app->timerQueue != NULL((void*)0) && !ignoreTimers && block) { |
330 | if (IS_AFTER (wt->cur_time, app->timerQueue->te_timer_value)(((app->timerQueue->te_timer_value).tv_sec > (wt-> cur_time).tv_sec) || (((app->timerQueue->te_timer_value ).tv_sec == (wt->cur_time).tv_sec)&& ((app->timerQueue ->te_timer_value).tv_usec > (wt->cur_time).tv_usec)) )) { |
331 | TIMEDELTA (wt->wait_time, app->timerQueue->te_timer_value, wt->cur_time){ if(((wt->wait_time).tv_usec = (app->timerQueue->te_timer_value ).tv_usec - (wt->cur_time).tv_usec) < 0) { (wt->wait_time ).tv_usec += 1000000; (wt->wait_time).tv_sec = (app->timerQueue ->te_timer_value).tv_sec - (wt->cur_time).tv_sec - 1; } else (wt->wait_time).tv_sec = (app->timerQueue->te_timer_value ).tv_sec - (wt->cur_time).tv_sec; }; |
332 | if (howlong == NULL((void*)0) || IS_AFTER (wt->wait_time, wt->max_wait_time)(((wt->max_wait_time).tv_sec > (wt->wait_time).tv_sec ) || (((wt->max_wait_time).tv_sec == (wt->wait_time).tv_sec )&& ((wt->max_wait_time).tv_usec > (wt->wait_time ).tv_usec)))) |
333 | #ifndef USE_POLL1 |
334 | wt->wait_time_ptr = &wt->wait_time; |
335 | else |
336 | wt->wait_time_ptr = &wt->max_wait_time; |
337 | } else |
338 | wt->wait_time_ptr = &zero_time; |
339 | } |
340 | #else |
341 | wt->poll_wait = wt->wait_time.tv_sec * 1000 + wt->wait_time.tv_usec / 1000; |
342 | else |
343 | wt->poll_wait = wt->max_wait_time.tv_sec * 1000 + wt->max_wait_time.tv_usec / 1000; |
344 | } else |
345 | wt->poll_wait = X_DONT_BLOCK0; |
346 | } |
347 | #endif |
348 | } |
349 | |
350 | |
351 | static int IoWait ( |
352 | wait_times_ptr_t wt, |
353 | wait_fds_ptr_t wf) |
354 | { |
355 | #ifndef USE_POLL1 |
356 | return Select (wf->nfds, &wf->rmask, &wf->wmask, &wf->emask, |
357 | wt->wait_time_ptr); |
358 | #else |
359 | return poll (wf->fdlist, wf->fdlistlen, wt->poll_wait); |
360 | #endif |
361 | } |
362 | |
363 | |
364 | static void FindInputs ( |
365 | XtAppContext app, |
366 | wait_fds_ptr_t wf, |
367 | int nfds, |
368 | Boolean ignoreEvents, |
369 | Boolean ignoreInputs, |
370 | int* dpy_no, |
371 | int* found_input) |
372 | { |
373 | XtInputMask condition; |
374 | InputEvent *ep; |
375 | int ii; |
376 | #ifndef USE_POLL1 /* { check ready file descriptors block */ |
377 | #ifdef XTHREADS1 |
378 | fd_set rmask; |
379 | #endif |
380 | int dd; |
381 | *dpy_no = -1; |
382 | *found_input = False0; |
383 | |
384 | #ifdef XTHREADS1 |
385 | rmask = app->fds.rmask; |
386 | for (dd = app->count; dd-- > 0; ) |
387 | FD_SET (ConnectionNumber (app->list[dd]), &rmask)((void) (((&rmask)->fds_bits)[(((((_XPrivDisplay)app-> list[dd])->fd)) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask ) 1 << (((((_XPrivDisplay)app->list[dd])->fd)) % ( 8 * (int) sizeof (__fd_mask)))))); |
388 | #endif |
389 | |
390 | for (ii = 0; ii < wf->nfds && nfds > 0; ii++) { |
391 | condition = 0; |
392 | if (FD_ISSET (ii, &wf->rmask)((((&wf->rmask)->fds_bits)[((ii) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((ii) % (8 * (int ) sizeof (__fd_mask))))) != 0) |
393 | #ifdef XTHREADS1 |
394 | && FD_ISSET (ii, &rmask)((((&rmask)->fds_bits)[((ii) / (8 * (int) sizeof (__fd_mask )))] & ((__fd_mask) 1 << ((ii) % (8 * (int) sizeof ( __fd_mask))))) != 0) |
395 | #endif |
396 | ) { |
397 | nfds--; |
398 | if (!ignoreEvents) { |
399 | for (dd = 0; dd < app->count; dd++) { |
400 | if (ii == ConnectionNumber (app->list[dd])(((_XPrivDisplay)app->list[dd])->fd)) { |
401 | if (*dpy_no == -1) { |
402 | if (XEventsQueued (app->list[dd], QueuedAfterReading1 )) |
403 | *dpy_no = dd; |
404 | /* |
405 | * An error event could have arrived |
406 | * without any real events, or events |
407 | * could have been swallowed by Xlib, |
408 | * or the connection may be broken. |
409 | * We can't tell the difference, so |
410 | * assume Xlib will eventually discover |
411 | * a broken connection. |
412 | */ |
413 | } |
414 | goto ENDILOOP; |
415 | } |
416 | } |
417 | } |
418 | condition = XtInputReadMask(1L<<0); |
419 | } |
420 | if (FD_ISSET (ii, &wf->wmask)((((&wf->wmask)->fds_bits)[((ii) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((ii) % (8 * (int ) sizeof (__fd_mask))))) != 0) |
421 | #ifdef XTHREADS1 |
422 | && FD_ISSET (ii, &app->fds.wmask)((((&app->fds.wmask)->fds_bits)[((ii) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((ii) % (8 * (int ) sizeof (__fd_mask))))) != 0) |
423 | #endif |
424 | ) { |
425 | condition |= XtInputWriteMask(1L<<1); |
426 | nfds--; |
427 | } |
428 | if (FD_ISSET (ii, &wf->emask)((((&wf->emask)->fds_bits)[((ii) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((ii) % (8 * (int ) sizeof (__fd_mask))))) != 0) |
429 | #ifdef XTHREADS1 |
430 | && FD_ISSET (ii, &app->fds.emask)((((&app->fds.emask)->fds_bits)[((ii) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((ii) % (8 * (int ) sizeof (__fd_mask))))) != 0) |
431 | #endif |
432 | ) { |
433 | condition |= XtInputExceptMask(1L<<2); |
434 | nfds--; |
435 | } |
436 | if (condition) { |
437 | for (ep = app->input_list[ii]; ep; ep = ep->ie_next) |
438 | if (condition & ep->ie_condition) { |
439 | /* make sure this input isn't already marked outstanding */ |
440 | InputEvent *oq; |
441 | for (oq = app->outstandingQueue; oq; oq = oq->ie_oq) |
442 | if (oq == ep) |
443 | break; |
444 | if (!oq) |
445 | { |
446 | ep->ie_oq = app->outstandingQueue; |
447 | app->outstandingQueue = ep; |
448 | } |
449 | } |
450 | *found_input = True1; |
451 | } |
452 | ENDILOOP: ; |
453 | } /* endfor */ |
454 | #else /* }{ */ |
455 | struct pollfd* fdlp; |
456 | |
457 | *dpy_no = -1; |
458 | *found_input = False0; |
459 | |
460 | if (!ignoreEvents) { |
461 | fdlp = wf->fdlist; |
462 | for (ii = 0; ii < wf->num_dpys; ii++, fdlp++) { |
463 | if (*dpy_no == -1 && fdlp->revents & (POLLIN0x001|POLLHUP0x010|POLLERR0x008) && |
464 | #ifdef XTHREADS1 |
465 | !(fdlp->revents & POLLNVAL0x020) && |
466 | #endif |
467 | XEventsQueued (app->list[ii], QueuedAfterReading1)) { |
468 | *dpy_no = ii; |
469 | break; |
470 | } |
471 | } |
472 | } |
473 | |
474 | if (!ignoreInputs) { |
475 | fdlp = &wf->fdlist[wf->num_dpys]; |
476 | for (ii = wf->num_dpys; ii < wf->fdlistlen; ii++, fdlp++) { |
477 | condition = 0; |
478 | if (fdlp->revents) { |
479 | if (fdlp->revents & (XPOLL_READ(0x001|0x040|0x002|0x080)|POLLHUP0x010|POLLERR0x008) |
480 | #ifdef XTHREADS1 |
481 | && !(fdlp->revents & POLLNVAL0x020) |
482 | #endif |
483 | ) |
484 | condition = XtInputReadMask(1L<<0); |
485 | if (fdlp->revents & XPOLL_WRITE(0x004|0x100|0x200)) |
486 | condition |= XtInputWriteMask(1L<<1); |
487 | if (fdlp->revents & XPOLL_EXCEPT0) |
488 | condition |= XtInputExceptMask(1L<<2); |
489 | } |
490 | if (condition) { |
491 | *found_input = True1; |
492 | for (ep = app->input_list[fdlp->fd]; ep; ep = ep->ie_next) |
493 | if (condition & ep->ie_condition) { |
494 | InputEvent *oq; |
495 | /* make sure this input isn't already marked outstanding */ |
496 | for (oq = app->outstandingQueue; oq; oq = oq->ie_oq) |
497 | if (oq == ep) |
498 | break; |
499 | if (!oq) |
500 | { |
501 | ep->ie_oq = app->outstandingQueue; |
502 | app->outstandingQueue = ep; |
503 | } |
504 | } |
505 | } |
506 | } |
507 | } |
508 | #endif /* } */ |
509 | } |
510 | |
511 | /* |
512 | * Routine to block in the toolkit. This should be the only call to select. |
513 | * |
514 | * This routine returns when there is something to be done. |
515 | * |
516 | * Before calling this with ignoreInputs==False, app->outstandingQueue should |
517 | * be checked; this routine will not verify that an alternate input source |
518 | * has not already been enqueued. |
519 | * |
520 | * |
521 | * _XtWaitForSomething( appContext, |
522 | * ignoreEvent, ignoreTimers, ignoreInputs, ignoreSignals, |
523 | * block, drop_lock, howlong) |
524 | * XtAppContext app; (Displays to check wait on) |
525 | * |
526 | * Boolean ignoreEvents; (Don't return if XEvents are available |
527 | * Also implies forget XEvents exist) |
528 | * |
529 | * Boolean ignoreTimers; (Ditto for timers) |
530 | * |
531 | * Boolean ignoreInputs; (Ditto for input callbacks ) |
532 | * |
533 | * Boolean ignoreSignals; (Ditto for signals) |
534 | * |
535 | * Boolean block; (Okay to block) |
536 | * |
537 | * Boolean drop_lock (drop lock before going into select/poll) |
538 | * |
539 | * TimeVal howlong; (howlong to wait for if blocking and not |
540 | * doing Timers... Null means forever. |
541 | * Maybe should mean shortest of both) |
542 | * Returns display for which input is available, if any |
543 | * and if ignoreEvents==False, else returns -1 |
544 | * |
545 | * if ignoring everything && block=True && howlong=NULL, you'll have |
546 | * lots of time for coffee; better not try it! In fact, it probably |
547 | * makes little sense to do this regardless of the value of howlong |
548 | * (bottom line is, we don't bother checking here). |
549 | * |
550 | * If drop_lock is FALSE, the app->lock->mutex is not unlocked before |
551 | * entering select/poll. It is illegal for drop_lock to be FALSE if |
552 | * ignoreTimers, ignoreInputs, or ignoreSignals is FALSE. |
553 | */ |
554 | int _XtWaitForSomething( |
555 | XtAppContext app, |
556 | _XtBooleanBoolean ignoreEvents, |
557 | _XtBooleanBoolean ignoreTimers, |
558 | _XtBooleanBoolean ignoreInputs, |
559 | _XtBooleanBoolean ignoreSignals, |
560 | _XtBooleanBoolean block, |
561 | #ifdef XTHREADS1 |
562 | _XtBooleanBoolean drop_lock, |
563 | #endif |
564 | unsigned long *howlong) |
565 | { |
566 | wait_times_t wt; |
567 | wait_fds_t wf; |
568 | int nfds, dpy_no, found_input, dd; |
569 | #ifdef XTHREADS1 |
570 | Boolean push_thread = TRUE1; |
571 | Boolean pushed_thread = FALSE0; |
572 | int level = 0; |
573 | #endif |
574 | #ifdef USE_POLL1 |
575 | struct pollfd fdlist[XT_DEFAULT_FDLIST_SIZE32]; |
576 | #endif |
577 | |
578 | #ifdef XTHREADS1 |
579 | /* assert ((ignoreTimers && ignoreInputs && ignoreSignals) || drop_lock); */ |
580 | /* If not multi-threaded, never drop lock */ |
581 | if (app->lock == (ThreadAppProc) NULL((void*)0)) |
582 | drop_lock = FALSE0; |
583 | #endif |
584 | |
585 | InitTimes (block, howlong, &wt); |
586 | |
587 | #ifdef USE_POLL1 |
588 | wf.fdlist = NULL((void*)0); |
589 | wf.stack = fdlist; |
590 | wf.fdlistlen = wf.num_dpys = 0; |
591 | #endif |
592 | |
593 | WaitLoop: |
594 | app->rebuild_fdlist = TRUE1; |
595 | |
596 | while (1) { |
597 | AdjustTimes (app, block, howlong, ignoreTimers, &wt); |
598 | |
599 | if (block && app->block_hook_list) { |
600 | BlockHook hook; |
601 | for (hook = app->block_hook_list; |
602 | hook != NULL((void*)0); |
603 | hook = hook->next) |
604 | (*hook->proc) (hook->closure); |
605 | |
606 | if (!ignoreEvents) |
607 | /* see if the hook(s) generated any protocol */ |
608 | for (dd = 0; dd < app->count; dd++) |
609 | if (XEventsQueued(app->list[dd], QueuedAlready0)) { |
610 | #ifdef USE_POLL1 |
611 | XtStackFree ((XtPointer) wf.fdlist, fdlist){ if (((XtPointer) wf.fdlist) != ((XtPointer)(fdlist))) XtFree ((XtPointer) wf.fdlist); }; |
612 | #endif |
613 | return dd; |
614 | } |
615 | } |
616 | |
617 | if (app->rebuild_fdlist) |
618 | InitFds (app, ignoreEvents, ignoreInputs, &wf); |
619 | |
620 | #ifdef XTHREADS1 /* { */ |
621 | if (drop_lock) { |
622 | YIELD_APP_LOCK(app, &push_thread, &pushed_thread, &level)if(app && app->yield_lock) (*app->yield_lock)(app ,&push_thread,&pushed_thread,&level); |
623 | nfds = IoWait (&wt, &wf); |
624 | RESTORE_APP_LOCK(app, level, &pushed_thread)if(app && app->restore_lock) (*app->restore_lock )(app,level,&pushed_thread); |
625 | } else |
626 | #endif /* } */ |
627 | nfds = IoWait (&wt, &wf); |
628 | if (nfds == -1) { |
629 | /* |
630 | * interrupt occured recalculate time value and wait again. |
631 | */ |
632 | if (errno(*__errno_location ()) == EINTR4 || errno(*__errno_location ()) == EAGAIN11) { |
633 | if (errno(*__errno_location ()) == EAGAIN11) { |
634 | errno(*__errno_location ()) = 0; /* errno is not self reseting */ |
635 | continue; |
636 | } |
637 | errno(*__errno_location ()) = 0; /* errno is not self reseting */ |
638 | |
639 | /* was it interrupted by a signal that we care about? */ |
640 | if (!ignoreSignals && app->signalQueue != NULL((void*)0)) { |
641 | SignalEventRec *se_ptr = app->signalQueue; |
642 | while (se_ptr != NULL((void*)0)) { |
643 | if (se_ptr->se_notice) { |
644 | if (block && howlong != NULL((void*)0)) |
645 | AdjustHowLong (howlong, &wt.start_time); |
646 | #ifdef USE_POLL1 |
647 | XtStackFree ((XtPointer) wf.fdlist, fdlist){ if (((XtPointer) wf.fdlist) != ((XtPointer)(fdlist))) XtFree ((XtPointer) wf.fdlist); }; |
648 | #endif |
649 | return -1; |
650 | } |
651 | se_ptr = se_ptr->se_next; |
652 | } |
653 | } |
654 | |
655 | if (!ignoreEvents) |
656 | /* get Xlib to detect a bad connection */ |
657 | for (dd = 0; dd < app->count; dd++) |
658 | if (XEventsQueued(app->list[dd], QueuedAfterReading1)) { |
659 | #ifdef USE_POLL1 |
660 | XtStackFree ((XtPointer) wf.fdlist, fdlist){ if (((XtPointer) wf.fdlist) != ((XtPointer)(fdlist))) XtFree ((XtPointer) wf.fdlist); }; |
661 | #endif |
662 | return dd; |
663 | } |
664 | |
665 | if (block) { |
666 | #ifndef USE_POLL1 |
667 | if (wt.wait_time_ptr == NULL((void*)0)) |
668 | #else |
669 | if (wt.poll_wait == X_BLOCK-1) |
670 | #endif |
671 | continue; |
672 | X_GETTIMEOFDAY (&wt.new_time)gettimeofday(&wt.new_time, (struct timezone*)0); |
673 | FIXUP_TIMEVAL (wt.new_time); |
674 | TIMEDELTA (wt.time_spent, wt.new_time, wt.cur_time){ if(((wt.time_spent).tv_usec = (wt.new_time).tv_usec - (wt.cur_time ).tv_usec) < 0) { (wt.time_spent).tv_usec += 1000000; (wt. time_spent).tv_sec = (wt.new_time).tv_sec - (wt.cur_time).tv_sec - 1; } else (wt.time_spent).tv_sec = (wt.new_time).tv_sec - ( wt.cur_time).tv_sec; }; |
675 | wt.cur_time = wt.new_time; |
676 | #ifndef USE_POLL1 |
677 | if (IS_AFTER (wt.time_spent, *wt.wait_time_ptr)(((*wt.wait_time_ptr).tv_sec > (wt.time_spent).tv_sec) || ( ((*wt.wait_time_ptr).tv_sec == (wt.time_spent).tv_sec)&& ((*wt.wait_time_ptr).tv_usec > (wt.time_spent).tv_usec)))) { |
678 | TIMEDELTA (wt.wait_time, *wt.wait_time_ptr, wt.time_spent){ if(((wt.wait_time).tv_usec = (*wt.wait_time_ptr).tv_usec - ( wt.time_spent).tv_usec) < 0) { (wt.wait_time).tv_usec += 1000000 ; (wt.wait_time).tv_sec = (*wt.wait_time_ptr).tv_sec - (wt.time_spent ).tv_sec - 1; } else (wt.wait_time).tv_sec = (*wt.wait_time_ptr ).tv_sec - (wt.time_spent).tv_sec; }; |
679 | wt.wait_time_ptr = &wt.wait_time; |
680 | continue; |
681 | } else |
682 | #else |
683 | if ((wt.time_spent.tv_sec * 1000 + wt.time_spent.tv_usec / 1000) < wt.poll_wait) { |
684 | wt.poll_wait -= (wt.time_spent.tv_sec * 1000 + wt.time_spent.tv_usec / 1000); |
685 | continue; |
686 | } else |
687 | #endif |
688 | nfds = 0; |
689 | } |
690 | } else { |
691 | char Errno[12]; |
692 | String param = Errno; |
693 | Cardinal param_count = 1; |
694 | |
695 | sprintf( Errno, "%d", errno(*__errno_location ())); |
696 | XtAppWarningMsg(app, "communicationError","select", |
697 | XtCXtToolkitError,"Select failed; error code %s", |
698 | ¶m, ¶m_count); |
699 | continue; |
700 | } |
701 | } /* timed out or input available */ |
702 | break; |
703 | } |
704 | |
705 | if (nfds == 0) { |
706 | /* Timed out */ |
707 | if (howlong) |
708 | *howlong = (unsigned long)0; |
709 | #ifdef USE_POLL1 |
710 | XtStackFree ((XtPointer) wf.fdlist, fdlist){ if (((XtPointer) wf.fdlist) != ((XtPointer)(fdlist))) XtFree ((XtPointer) wf.fdlist); }; |
711 | #endif |
712 | return -1; |
713 | } |
714 | |
715 | if (block && howlong != NULL((void*)0)) |
716 | AdjustHowLong (howlong, &wt.start_time); |
717 | |
718 | if (ignoreInputs && ignoreEvents) { |
719 | #ifdef USE_POLL1 |
720 | XtStackFree ((XtPointer) wf.fdlist, fdlist){ if (((XtPointer) wf.fdlist) != ((XtPointer)(fdlist))) XtFree ((XtPointer) wf.fdlist); }; |
721 | #endif |
722 | return -1; |
723 | } else |
724 | FindInputs (app, &wf, nfds, |
725 | ignoreEvents, ignoreInputs, |
726 | &dpy_no, &found_input); |
727 | |
728 | if (dpy_no >= 0 || found_input) { |
729 | #ifdef USE_POLL1 |
730 | XtStackFree ((XtPointer) wf.fdlist, fdlist){ if (((XtPointer) wf.fdlist) != ((XtPointer)(fdlist))) XtFree ((XtPointer) wf.fdlist); }; |
731 | #endif |
732 | return dpy_no; |
733 | } |
734 | if (block) |
735 | goto WaitLoop; |
736 | else { |
737 | #ifdef USE_POLL1 |
738 | XtStackFree ((XtPointer) wf.fdlist, fdlist){ if (((XtPointer) wf.fdlist) != ((XtPointer)(fdlist))) XtFree ((XtPointer) wf.fdlist); }; |
739 | #endif |
740 | return -1; |
741 | } |
742 | } |
743 | |
744 | #define IeCallProc(ptr)(*ptr->ie_proc) (ptr->ie_closure, &ptr->ie_source , (XtInputId*)&ptr); \ |
745 | (*ptr->ie_proc) (ptr->ie_closure, &ptr->ie_source, (XtInputId*)&ptr); |
746 | |
747 | #define TeCallProc(ptr)(*ptr->te_proc) (ptr->te_closure, (XtIntervalId*)&ptr ); \ |
748 | (*ptr->te_proc) (ptr->te_closure, (XtIntervalId*)&ptr); |
749 | |
750 | #define SeCallProc(ptr)(*ptr->se_proc) (ptr->se_closure, (XtSignalId*)&ptr ); \ |
751 | (*ptr->se_proc) (ptr->se_closure, (XtSignalId*)&ptr); |
752 | |
753 | /* |
754 | * Public Routines |
755 | */ |
756 | |
757 | XtIntervalId XtAddTimeOut( |
758 | unsigned long interval, |
759 | XtTimerCallbackProc proc, |
760 | XtPointer closure) |
761 | { |
762 | return XtAppAddTimeOut(_XtDefaultAppContext(), |
763 | interval, proc, closure); |
764 | } |
765 | |
766 | static void QueueTimerEvent( |
767 | XtAppContext app, |
768 | TimerEventRec *ptr) |
769 | { |
770 | TimerEventRec *t,**tt; |
771 | tt = &app->timerQueue; |
772 | t = *tt; |
773 | while (t != NULL((void*)0) && |
774 | IS_AFTER(t->te_timer_value, ptr->te_timer_value)(((ptr->te_timer_value).tv_sec > (t->te_timer_value) .tv_sec) || (((ptr->te_timer_value).tv_sec == (t->te_timer_value ).tv_sec)&& ((ptr->te_timer_value).tv_usec > (t ->te_timer_value).tv_usec)))) { |
775 | tt = &t->te_next; |
776 | t = *tt; |
777 | } |
778 | ptr->te_next = t; |
779 | *tt = ptr; |
780 | } |
781 | |
782 | XtIntervalId XtAppAddTimeOut( |
783 | XtAppContext app, |
784 | unsigned long interval, |
785 | XtTimerCallbackProc proc, |
786 | XtPointer closure) |
787 | { |
788 | TimerEventRec *tptr; |
789 | struct timeval current_time; |
790 | |
791 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
792 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
793 | if (freeTimerRecs) { |
794 | tptr = freeTimerRecs; |
795 | freeTimerRecs = tptr->te_next; |
796 | } |
797 | else tptr = XtNew(TimerEventRec)((TimerEventRec *) XtMalloc((unsigned) sizeof(TimerEventRec)) ); |
798 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
799 | |
800 | tptr->te_next = NULL((void*)0); |
801 | tptr->te_closure = closure; |
802 | tptr->te_proc = proc; |
803 | tptr->app = app; |
804 | tptr->te_timer_value.tv_sec = interval/1000; |
805 | tptr->te_timer_value.tv_usec = (interval%1000)*1000; |
806 | X_GETTIMEOFDAY (¤t_time)gettimeofday(¤t_time, (struct timezone*)0); |
807 | FIXUP_TIMEVAL(current_time); |
808 | ADD_TIME(tptr->te_timer_value,tptr->te_timer_value,current_time){ if(((tptr->te_timer_value).tv_usec = (tptr->te_timer_value ).tv_usec + (current_time).tv_usec) >= 1000000) { (tptr-> te_timer_value).tv_usec -= 1000000; (tptr->te_timer_value) .tv_sec = (tptr->te_timer_value).tv_sec + (current_time).tv_sec + 1 ; } else { (tptr->te_timer_value).tv_sec = (tptr-> te_timer_value).tv_sec + (current_time).tv_sec ; if(((tptr-> te_timer_value).tv_sec >= 1) && (((tptr->te_timer_value ).tv_usec <0))) { (tptr->te_timer_value).tv_sec --;(tptr ->te_timer_value).tv_usec += 1000000; } } }; |
809 | QueueTimerEvent(app, tptr); |
810 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
811 | return( (XtIntervalId) tptr); |
812 | } |
813 | |
814 | void XtRemoveTimeOut( |
815 | XtIntervalId id) |
816 | { |
817 | TimerEventRec *t, *last, *tid = (TimerEventRec *) id; |
818 | XtAppContext app = tid->app; |
819 | |
820 | /* find it */ |
821 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
822 | for(t = app->timerQueue, last = NULL((void*)0); |
Access to field 'timerQueue' results in a dereference of a null pointer (loaded from variable 'app') | |
823 | t != NULL((void*)0) && t != tid; |
824 | t = t->te_next) last = t; |
825 | |
826 | if (t == NULL((void*)0)) { |
827 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
828 | return; /* couldn't find it */ |
829 | } |
830 | if(last == NULL((void*)0)) { /* first one on the list */ |
831 | app->timerQueue = t->te_next; |
832 | } else last->te_next = t->te_next; |
833 | |
834 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
835 | t->te_next = freeTimerRecs; |
836 | freeTimerRecs = t; |
837 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
838 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
839 | } |
840 | |
841 | XtWorkProcId XtAddWorkProc( |
842 | XtWorkProc proc, |
843 | XtPointer closure) |
844 | { |
845 | return XtAppAddWorkProc(_XtDefaultAppContext(), proc, closure); |
846 | } |
847 | |
848 | XtWorkProcId XtAppAddWorkProc( |
849 | XtAppContext app, |
850 | XtWorkProc proc, |
851 | XtPointer closure) |
852 | { |
853 | WorkProcRec *wptr; |
854 | |
855 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
856 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
857 | if (freeWorkRecs) { |
858 | wptr = freeWorkRecs; |
859 | freeWorkRecs = wptr->next; |
860 | } else wptr = XtNew(WorkProcRec)((WorkProcRec *) XtMalloc((unsigned) sizeof(WorkProcRec))); |
861 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
862 | wptr->next = app->workQueue; |
863 | wptr->closure = closure; |
864 | wptr->proc = proc; |
865 | wptr->app = app; |
866 | app->workQueue = wptr; |
867 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
868 | return (XtWorkProcId) wptr; |
869 | } |
870 | |
871 | void XtRemoveWorkProc( |
872 | XtWorkProcId id) |
873 | { |
874 | WorkProcRec *wid= (WorkProcRec *) id, *w, *last; |
875 | XtAppContext app = wid->app; |
876 | |
877 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
878 | /* find it */ |
879 | for(w = app->workQueue, last = NULL((void*)0); |
880 | w != NULL((void*)0) && w != wid; w = w->next) last = w; |
881 | |
882 | if (w == NULL((void*)0)) { |
883 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
884 | return; /* couldn't find it */ |
885 | } |
886 | |
887 | if(last == NULL((void*)0)) app->workQueue = w->next; |
888 | else last->next = w->next; |
889 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
890 | w->next = freeWorkRecs; |
891 | freeWorkRecs = w; |
892 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
893 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
894 | } |
895 | |
896 | XtSignalId XtAddSignal( |
897 | XtSignalCallbackProc proc, |
898 | XtPointer closure) |
899 | { |
900 | return XtAppAddSignal(_XtDefaultAppContext(), proc, closure); |
901 | } |
902 | |
903 | XtSignalId XtAppAddSignal( |
904 | XtAppContext app, |
905 | XtSignalCallbackProc proc, |
906 | XtPointer closure) |
907 | { |
908 | SignalEventRec *sptr; |
909 | |
910 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
911 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
912 | if (freeSignalRecs) { |
913 | sptr = freeSignalRecs; |
914 | freeSignalRecs = sptr->se_next; |
915 | } else |
916 | sptr = XtNew(SignalEventRec)((SignalEventRec *) XtMalloc((unsigned) sizeof(SignalEventRec ))); |
917 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
918 | sptr->se_next = app->signalQueue; |
919 | sptr->se_closure = closure; |
920 | sptr->se_proc = proc; |
921 | sptr->app = app; |
922 | sptr->se_notice = FALSE0; |
923 | app->signalQueue = sptr; |
924 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
925 | return (XtSignalId) sptr; |
926 | } |
927 | |
928 | void XtRemoveSignal( |
929 | XtSignalId id) |
930 | { |
931 | SignalEventRec *sid = (SignalEventRec*) id, *s, *last = NULL((void*)0); |
932 | XtAppContext app = sid->app; |
933 | |
934 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
935 | for (s = app->signalQueue; s != NULL((void*)0) && s != sid; s = s->se_next) |
936 | last = s; |
937 | if (s == NULL((void*)0)) { |
938 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
939 | return; |
940 | } |
941 | if (last == NULL((void*)0)) |
942 | app->signalQueue = s->se_next; |
943 | else |
944 | last->se_next = s->se_next; |
945 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
946 | s->se_next = freeSignalRecs; |
947 | freeSignalRecs = s; |
948 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
949 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
950 | } |
951 | |
952 | void XtNoticeSignal( |
953 | XtSignalId id) |
954 | { |
955 | /* |
956 | * It would be overkill to lock the app to set this flag. |
957 | * In the worst case, 2..n threads would be modifying this |
958 | * flag. The last one wins. Since signals occur asynchronously |
959 | * anyway, this can occur with or without threads. |
960 | * |
961 | * The other issue is that thread t1 sets the flag in a |
962 | * signalrec that has been deleted in thread t2. We rely |
963 | * on a detail of the implementation, i.e. free'd signalrecs |
964 | * aren't really free'd, they're just moved to a list of |
965 | * free recs, so deref'ing one won't hurt anything. |
966 | * |
967 | * Lastly, and perhaps most importantly, since POSIX threads |
968 | * says that the handling of asynchronous signals in a synchronous |
969 | * threads environment is undefined. Therefor it would be an |
970 | * error for both signals and threads to be in use in the same |
971 | * program. |
972 | */ |
973 | SignalEventRec *sid = (SignalEventRec*) id; |
974 | sid->se_notice = TRUE1; |
975 | } |
976 | |
977 | XtInputId XtAddInput( |
978 | int source, |
979 | XtPointer Condition, |
980 | XtInputCallbackProc proc, |
981 | XtPointer closure) |
982 | { |
983 | return XtAppAddInput(_XtDefaultAppContext(), |
984 | source, Condition, proc, closure); |
985 | } |
986 | |
987 | XtInputId XtAppAddInput( |
988 | XtAppContext app, |
989 | int source, |
990 | XtPointer Condition, |
991 | XtInputCallbackProc proc, |
992 | XtPointer closure) |
993 | { |
994 | InputEvent* sptr; |
995 | XtInputMask condition = (XtInputMask) Condition; |
996 | |
997 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
998 | if (!condition || |
999 | condition & ~(XtInputReadMask(1L<<0)|XtInputWriteMask(1L<<1)|XtInputExceptMask(1L<<2))) |
1000 | XtAppErrorMsg(app,"invalidParameter","xtAddInput",XtCXtToolkitError, |
1001 | "invalid condition passed to XtAppAddInput", |
1002 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); |
1003 | |
1004 | if (app->input_max <= source) { |
1005 | Cardinal n = source + 1; |
1006 | int ii; |
1007 | app->input_list = (InputEvent**)XtRealloc((char*) app->input_list, |
1008 | n * sizeof(InputEvent*)); |
1009 | for (ii = app->input_max; ii < (int) n; ii++) |
1010 | app->input_list[ii] = (InputEvent*) NULL((void*)0); |
1011 | app->input_max = n; |
1012 | } |
1013 | sptr = XtNew(InputEvent)((InputEvent *) XtMalloc((unsigned) sizeof(InputEvent))); |
1014 | sptr->ie_proc = proc; |
1015 | sptr->ie_closure = closure; |
1016 | sptr->app = app; |
1017 | sptr->ie_oq = NULL((void*)0); |
1018 | sptr->ie_source = source; |
1019 | sptr->ie_condition = condition; |
1020 | sptr->ie_next = app->input_list[source]; |
1021 | app->input_list[source] = sptr; |
1022 | |
1023 | #ifndef USE_POLL1 |
1024 | if (condition & XtInputReadMask(1L<<0)) FD_SET(source, &app->fds.rmask)((void) (((&app->fds.rmask)->fds_bits)[((source) / ( 8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << (( source) % (8 * (int) sizeof (__fd_mask)))))); |
1025 | if (condition & XtInputWriteMask(1L<<1)) FD_SET(source, &app->fds.wmask)((void) (((&app->fds.wmask)->fds_bits)[((source) / ( 8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << (( source) % (8 * (int) sizeof (__fd_mask)))))); |
1026 | if (condition & XtInputExceptMask(1L<<2)) FD_SET(source, &app->fds.emask)((void) (((&app->fds.emask)->fds_bits)[((source) / ( 8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << (( source) % (8 * (int) sizeof (__fd_mask)))))); |
1027 | |
1028 | if (app->fds.nfds < (source+1)) app->fds.nfds = source+1; |
1029 | #else |
1030 | if (sptr->ie_next == NULL((void*)0)) |
1031 | app->fds.nfds++; |
1032 | #endif |
1033 | app->input_count++; |
1034 | app->rebuild_fdlist = TRUE1; |
1035 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1036 | return((XtInputId)sptr); |
1037 | } |
1038 | |
1039 | void XtRemoveInput( |
1040 | register XtInputId id) |
1041 | { |
1042 | register InputEvent *sptr, *lptr; |
1043 | XtAppContext app = ((InputEvent *)id)->app; |
1044 | register int source = ((InputEvent *)id)->ie_source; |
1045 | Boolean found = False0; |
1046 | |
1047 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1048 | sptr = app->outstandingQueue; |
1049 | lptr = NULL((void*)0); |
1050 | for (; sptr != NULL((void*)0); sptr = sptr->ie_oq) { |
1051 | if (sptr == (InputEvent *)id) { |
1052 | if (lptr == NULL((void*)0)) app->outstandingQueue = sptr->ie_oq; |
1053 | else lptr->ie_oq = sptr->ie_oq; |
1054 | } |
1055 | lptr = sptr; |
1056 | } |
1057 | |
1058 | if(app->input_list && (sptr = app->input_list[source]) != NULL((void*)0)) { |
1059 | for( lptr = NULL((void*)0) ; sptr; sptr = sptr->ie_next ){ |
1060 | if(sptr == (InputEvent *) id) { |
1061 | #ifndef USE_POLL1 |
1062 | XtInputMask condition = 0; |
1063 | #endif |
1064 | if(lptr == NULL((void*)0)) { |
1065 | app->input_list[source] = sptr->ie_next; |
1066 | } else { |
1067 | lptr->ie_next = sptr->ie_next; |
1068 | } |
1069 | #ifndef USE_POLL1 |
1070 | for (lptr = app->input_list[source]; |
1071 | lptr; lptr = lptr->ie_next) |
1072 | condition |= lptr->ie_condition; |
1073 | if ((sptr->ie_condition & XtInputReadMask(1L<<0)) && |
1074 | !(condition & XtInputReadMask(1L<<0))) |
1075 | FD_CLR(source, &app->fds.rmask)((void) (((&app->fds.rmask)->fds_bits)[((source) / ( 8 * (int) sizeof (__fd_mask)))] &= ~((__fd_mask) 1 << ((source) % (8 * (int) sizeof (__fd_mask)))))); |
1076 | if ((sptr->ie_condition & XtInputWriteMask(1L<<1)) && |
1077 | !(condition & XtInputWriteMask(1L<<1))) |
1078 | FD_CLR(source, &app->fds.wmask)((void) (((&app->fds.wmask)->fds_bits)[((source) / ( 8 * (int) sizeof (__fd_mask)))] &= ~((__fd_mask) 1 << ((source) % (8 * (int) sizeof (__fd_mask)))))); |
1079 | if ((sptr->ie_condition & XtInputExceptMask(1L<<2)) && |
1080 | !(condition & XtInputExceptMask(1L<<2))) |
1081 | FD_CLR(source, &app->fds.emask)((void) (((&app->fds.emask)->fds_bits)[((source) / ( 8 * (int) sizeof (__fd_mask)))] &= ~((__fd_mask) 1 << ((source) % (8 * (int) sizeof (__fd_mask)))))); |
1082 | #endif |
1083 | XtFree((char *) sptr); |
1084 | found = True1; |
1085 | break; |
1086 | } |
1087 | lptr = sptr; |
1088 | } |
1089 | } |
1090 | |
1091 | if (found) { |
1092 | app->input_count--; |
1093 | #ifdef USE_POLL1 |
1094 | if (app->input_list[source] == NULL((void*)0)) |
1095 | app->fds.nfds--; |
1096 | #endif |
1097 | app->rebuild_fdlist = TRUE1; |
1098 | } else |
1099 | XtAppWarningMsg(app, "invalidProcedure","inputHandler", |
1100 | XtCXtToolkitError, |
1101 | "XtRemoveInput: Input handler not found", |
1102 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); |
1103 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1104 | } |
1105 | |
1106 | void _XtRemoveAllInputs( |
1107 | XtAppContext app) |
1108 | { |
1109 | int i; |
1110 | for (i = 0; i < app->input_max; i++) { |
1111 | InputEvent* ep = app->input_list[i]; |
1112 | while (ep) { |
1113 | InputEvent *next = ep->ie_next; |
1114 | XtFree( (char*)ep ); |
1115 | ep = next; |
1116 | } |
1117 | } |
1118 | XtFree((char *) app->input_list); |
1119 | } |
1120 | |
1121 | /* Do alternate input and timer callbacks if there are any */ |
1122 | |
1123 | static void DoOtherSources( |
1124 | XtAppContext app) |
1125 | { |
1126 | TimerEventRec *te_ptr; |
1127 | InputEvent *ie_ptr; |
1128 | struct timeval cur_time; |
1129 | |
1130 | #define DrainQueue() \ |
1131 | for (ie_ptr = app->outstandingQueue; ie_ptr != NULL((void*)0);) { \ |
1132 | app->outstandingQueue = ie_ptr->ie_oq; \ |
1133 | ie_ptr ->ie_oq = NULL((void*)0); \ |
1134 | IeCallProc(ie_ptr)(*ie_ptr->ie_proc) (ie_ptr->ie_closure, &ie_ptr-> ie_source, (XtInputId*)&ie_ptr);; \ |
1135 | ie_ptr = app->outstandingQueue; \ |
1136 | } |
1137 | /*enddef*/ |
1138 | DrainQueue(); |
1139 | if (app->input_count > 0) { |
1140 | /* Call _XtWaitForSomething to get input queued up */ |
1141 | (void) _XtWaitForSomething (app, |
1142 | TRUE1, TRUE1, FALSE0, TRUE1, |
1143 | FALSE0, |
1144 | #ifdef XTHREADS1 |
1145 | TRUE1, |
1146 | #endif |
1147 | (unsigned long *)NULL((void*)0)); |
1148 | DrainQueue(); |
1149 | } |
1150 | if (app->timerQueue != NULL((void*)0)) { /* check timeout queue */ |
1151 | X_GETTIMEOFDAY (&cur_time)gettimeofday(&cur_time, (struct timezone*)0); |
1152 | FIXUP_TIMEVAL(cur_time); |
1153 | while(IS_AT_OR_AFTER (app->timerQueue->te_timer_value, cur_time)(((cur_time).tv_sec > (app->timerQueue->te_timer_value ).tv_sec) || (((cur_time).tv_sec == (app->timerQueue->te_timer_value ).tv_sec)&& ((cur_time).tv_usec >= (app->timerQueue ->te_timer_value).tv_usec)))) { |
1154 | te_ptr = app->timerQueue; |
1155 | app->timerQueue = te_ptr->te_next; |
1156 | te_ptr->te_next = NULL((void*)0); |
1157 | if (te_ptr->te_proc != NULL((void*)0)) |
1158 | TeCallProc(te_ptr)(*te_ptr->te_proc) (te_ptr->te_closure, (XtIntervalId*) &te_ptr);; |
1159 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1160 | te_ptr->te_next = freeTimerRecs; |
1161 | freeTimerRecs = te_ptr; |
1162 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1163 | if (app->timerQueue == NULL((void*)0)) break; |
1164 | } |
1165 | } |
1166 | if (app->signalQueue != NULL((void*)0)) { |
1167 | SignalEventRec *se_ptr = app->signalQueue; |
1168 | while (se_ptr != NULL((void*)0)) { |
1169 | if (se_ptr->se_notice) { |
1170 | se_ptr->se_notice = FALSE0; |
1171 | if (se_ptr->se_proc != NULL((void*)0)) |
1172 | SeCallProc(se_ptr)(*se_ptr->se_proc) (se_ptr->se_closure, (XtSignalId*)& se_ptr);; |
1173 | } |
1174 | se_ptr = se_ptr->se_next; |
1175 | } |
1176 | } |
1177 | #undef DrainQueue |
1178 | } |
1179 | |
1180 | /* If there are any work procs, call them. Return whether we did so */ |
1181 | |
1182 | static Boolean CallWorkProc( |
1183 | XtAppContext app) |
1184 | { |
1185 | register WorkProcRec *w = app->workQueue; |
1186 | Boolean delete; |
1187 | |
1188 | if (w == NULL((void*)0)) return FALSE0; |
1189 | |
1190 | app->workQueue = w->next; |
1191 | |
1192 | delete = (*(w->proc)) (w->closure); |
1193 | |
1194 | if (delete) { |
1195 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1196 | w->next = freeWorkRecs; |
1197 | freeWorkRecs = w; |
1198 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1199 | } |
1200 | else { |
1201 | w->next = app->workQueue; |
1202 | app->workQueue = w; |
1203 | } |
1204 | return TRUE1; |
1205 | } |
1206 | |
1207 | /* |
1208 | * XtNextEvent() |
1209 | * return next event; |
1210 | */ |
1211 | |
1212 | void XtNextEvent( |
1213 | XEvent *event) |
1214 | { |
1215 | XtAppNextEvent(_XtDefaultAppContext(), event); |
1216 | } |
1217 | |
1218 | void _XtRefreshMapping( |
1219 | XEvent* event, |
1220 | _XtBooleanBoolean dispatch) |
1221 | { |
1222 | XtPerDisplay pd; |
1223 | |
1224 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1225 | pd = _XtGetPerDisplay(event->xmapping.display); |
1226 | if (event->xmapping.request != MappingPointer2 && |
1227 | pd && pd->keysyms && (event->xmapping.serial >= pd->keysyms_serial)) |
1228 | _XtBuildKeysymTables( event->xmapping.display, pd ); |
1229 | XRefreshKeyboardMapping(&event->xmapping); |
1230 | if (dispatch && pd && pd->mapping_callbacks) |
1231 | XtCallCallbackList((Widget) NULL((void*)0), |
1232 | (XtCallbackList)pd->mapping_callbacks, |
1233 | (XtPointer)event ); |
1234 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1235 | } |
1236 | |
1237 | void XtAppNextEvent( |
1238 | XtAppContext app, |
1239 | XEvent *event) |
1240 | { |
1241 | int i, d; |
1242 | |
1243 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1244 | for (;;) { |
1245 | if (app->count == 0) |
1246 | DoOtherSources(app); |
1247 | else { |
1248 | for (i = 1; i <= app->count; i++) { |
1249 | d = (i + app->last) % app->count; |
1250 | if (d == 0) DoOtherSources(app); |
1251 | if (XEventsQueued(app->list[d], QueuedAfterReading1)) |
1252 | goto GotEvent; |
1253 | } |
1254 | for (i = 1; i <= app->count; i++) { |
1255 | d = (i + app->last) % app->count; |
1256 | if (XEventsQueued(app->list[d], QueuedAfterFlush2)) |
1257 | goto GotEvent; |
1258 | } |
1259 | } |
1260 | |
1261 | /* We're ready to wait...if there is a work proc, call it */ |
1262 | if (CallWorkProc(app)) continue; |
1263 | |
1264 | d = _XtWaitForSomething (app, |
1265 | FALSE0, FALSE0, FALSE0, FALSE0, |
1266 | TRUE1, |
1267 | #ifdef XTHREADS1 |
1268 | TRUE1, |
1269 | #endif |
1270 | (unsigned long *) NULL((void*)0)); |
1271 | |
1272 | if (d != -1) { |
1273 | GotEvent: |
1274 | XNextEvent (app->list[d], event); |
1275 | #ifdef XTHREADS1 |
1276 | /* assert(app->list[d] == event->xany.display); */ |
1277 | #endif |
1278 | app->last = d; |
1279 | if (event->xany.type == MappingNotify34) |
1280 | _XtRefreshMapping(event, False0); |
1281 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1282 | return; |
1283 | } |
1284 | |
1285 | } /* for */ |
1286 | } |
1287 | |
1288 | void XtProcessEvent( |
1289 | XtInputMask mask) |
1290 | { |
1291 | XtAppProcessEvent(_XtDefaultAppContext(), mask); |
1292 | } |
1293 | |
1294 | void XtAppProcessEvent( |
1295 | XtAppContext app, |
1296 | XtInputMask mask) |
1297 | { |
1298 | int i, d; |
1299 | XEvent event; |
1300 | struct timeval cur_time; |
1301 | |
1302 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1303 | if (mask == 0) { |
1304 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1305 | return; |
1306 | } |
1307 | |
1308 | for (;;) { |
1309 | |
1310 | if (mask & XtIMSignal8 && app->signalQueue != NULL((void*)0)) { |
1311 | SignalEventRec *se_ptr = app->signalQueue; |
1312 | while (se_ptr != NULL((void*)0)) { |
1313 | if (se_ptr->se_notice) { |
1314 | se_ptr->se_notice = FALSE0; |
1315 | SeCallProc(se_ptr)(*se_ptr->se_proc) (se_ptr->se_closure, (XtSignalId*)& se_ptr);; |
1316 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1317 | return; |
1318 | } |
1319 | se_ptr = se_ptr->se_next; |
1320 | } |
1321 | } |
1322 | |
1323 | if (mask & XtIMTimer2 && app->timerQueue != NULL((void*)0)) { |
1324 | X_GETTIMEOFDAY (&cur_time)gettimeofday(&cur_time, (struct timezone*)0); |
1325 | FIXUP_TIMEVAL(cur_time); |
1326 | if (IS_AT_OR_AFTER(app->timerQueue->te_timer_value, cur_time)(((cur_time).tv_sec > (app->timerQueue->te_timer_value ).tv_sec) || (((cur_time).tv_sec == (app->timerQueue->te_timer_value ).tv_sec)&& ((cur_time).tv_usec >= (app->timerQueue ->te_timer_value).tv_usec)))){ |
1327 | TimerEventRec *te_ptr = app->timerQueue; |
1328 | app->timerQueue = app->timerQueue->te_next; |
1329 | te_ptr->te_next = NULL((void*)0); |
1330 | if (te_ptr->te_proc != NULL((void*)0)) |
1331 | TeCallProc(te_ptr)(*te_ptr->te_proc) (te_ptr->te_closure, (XtIntervalId*) &te_ptr);; |
1332 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1333 | te_ptr->te_next = freeTimerRecs; |
1334 | freeTimerRecs = te_ptr; |
1335 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1336 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1337 | return; |
1338 | } |
1339 | } |
1340 | |
1341 | if (mask & XtIMAlternateInput4) { |
1342 | if (app->input_count > 0 && app->outstandingQueue == NULL((void*)0)) { |
1343 | /* Call _XtWaitForSomething to get input queued up */ |
1344 | (void) _XtWaitForSomething (app, |
1345 | TRUE1, TRUE1, FALSE0, TRUE1, |
1346 | FALSE0, |
1347 | #ifdef XTHREADS1 |
1348 | TRUE1, |
1349 | #endif |
1350 | (unsigned long *)NULL((void*)0)); |
1351 | } |
1352 | if (app->outstandingQueue != NULL((void*)0)) { |
1353 | InputEvent *ie_ptr = app->outstandingQueue; |
1354 | app->outstandingQueue = ie_ptr->ie_oq; |
1355 | ie_ptr->ie_oq = NULL((void*)0); |
1356 | IeCallProc(ie_ptr)(*ie_ptr->ie_proc) (ie_ptr->ie_closure, &ie_ptr-> ie_source, (XtInputId*)&ie_ptr);; |
1357 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1358 | return; |
1359 | } |
1360 | } |
1361 | |
1362 | if (mask & XtIMXEvent1) { |
1363 | for (i = 1; i <= app->count; i++) { |
1364 | d = (i + app->last) % app->count; |
1365 | if (XEventsQueued(app->list[d], QueuedAfterReading1)) |
1366 | goto GotEvent; |
1367 | } |
1368 | for (i = 1; i <= app->count; i++) { |
1369 | d = (i + app->last) % app->count; |
1370 | if (XEventsQueued(app->list[d], QueuedAfterFlush2)) |
1371 | goto GotEvent; |
1372 | } |
1373 | } |
1374 | |
1375 | /* Nothing to do...wait for something */ |
1376 | |
1377 | if (CallWorkProc(app)) continue; |
1378 | |
1379 | d = _XtWaitForSomething (app, |
1380 | (mask & XtIMXEvent1 ? FALSE0 : TRUE1), |
1381 | (mask & XtIMTimer2 ? FALSE0 : TRUE1), |
1382 | (mask & XtIMAlternateInput4 ? FALSE0 : TRUE1), |
1383 | (mask & XtIMSignal8 ? FALSE0 : TRUE1), |
1384 | TRUE1, |
1385 | #ifdef XTHREADS1 |
1386 | TRUE1, |
1387 | #endif |
1388 | (unsigned long *) NULL((void*)0)); |
1389 | |
1390 | if (mask & XtIMXEvent1 && d != -1) { |
1391 | GotEvent: |
1392 | XNextEvent(app->list[d], &event); |
1393 | #ifdef XTHREADS1 |
1394 | /* assert(app->list[d] == event.xany.display); */ |
1395 | #endif |
1396 | app->last = d; |
1397 | if (event.xany.type == MappingNotify34) { |
1398 | _XtRefreshMapping(&event, False0); |
1399 | } |
1400 | XtDispatchEvent(&event); |
1401 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1402 | return; |
1403 | } |
1404 | |
1405 | } |
1406 | } |
1407 | |
1408 | Boolean XtPending(void) |
1409 | { |
1410 | return (XtAppPending(_XtDefaultAppContext()) != 0); |
1411 | } |
1412 | |
1413 | XtInputMask XtAppPending( |
1414 | XtAppContext app) |
1415 | { |
1416 | struct timeval cur_time; |
1417 | int d; |
1418 | XtInputMask ret = 0; |
1419 | |
1420 | /* |
1421 | * Check for pending X events |
1422 | */ |
1423 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1424 | for (d = 0; d < app->count; d++) { |
1425 | if (XEventsQueued(app->list[d], QueuedAfterReading1)) { |
1426 | ret = XtIMXEvent1; |
1427 | break; |
1428 | } |
1429 | } |
1430 | if (ret == 0) { |
1431 | for (d = 0; d < app->count; d++) { |
1432 | if (XEventsQueued(app->list[d], QueuedAfterFlush2)) { |
1433 | ret = XtIMXEvent1; |
1434 | break; |
1435 | } |
1436 | } |
1437 | } |
1438 | |
1439 | if (app->signalQueue != NULL((void*)0)) { |
1440 | SignalEventRec *se_ptr = app->signalQueue; |
1441 | while (se_ptr != NULL((void*)0)) { |
1442 | if (se_ptr->se_notice) { |
1443 | ret |= XtIMSignal8; |
1444 | break; |
1445 | } |
1446 | se_ptr = se_ptr->se_next; |
1447 | } |
1448 | } |
1449 | |
1450 | /* |
1451 | * Check for pending alternate input |
1452 | */ |
1453 | if (app->timerQueue != NULL((void*)0)) { /* check timeout queue */ |
1454 | X_GETTIMEOFDAY (&cur_time)gettimeofday(&cur_time, (struct timezone*)0); |
1455 | FIXUP_TIMEVAL(cur_time); |
1456 | if ((IS_AT_OR_AFTER(app->timerQueue->te_timer_value, cur_time)(((cur_time).tv_sec > (app->timerQueue->te_timer_value ).tv_sec) || (((cur_time).tv_sec == (app->timerQueue->te_timer_value ).tv_sec)&& ((cur_time).tv_usec >= (app->timerQueue ->te_timer_value).tv_usec)))) && |
1457 | (app->timerQueue->te_proc != NULL((void*)0))) { |
1458 | ret |= XtIMTimer2; |
1459 | } |
1460 | } |
1461 | |
1462 | if (app->outstandingQueue != NULL((void*)0)) ret |= XtIMAlternateInput4; |
1463 | else { |
1464 | /* This won't cause a wait, but will enqueue any input */ |
1465 | |
1466 | if(_XtWaitForSomething (app, |
1467 | FALSE0, TRUE1, FALSE0, TRUE1, |
1468 | FALSE0, |
1469 | #ifdef XTHREADS1 |
1470 | TRUE1, |
1471 | #endif |
1472 | (unsigned long *) NULL((void*)0)) != -1) |
1473 | ret |= XtIMXEvent1; |
1474 | if (app->outstandingQueue != NULL((void*)0)) ret |= XtIMAlternateInput4; |
1475 | } |
1476 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1477 | return ret; |
1478 | } |
1479 | |
1480 | /* Peek at alternate input and timer callbacks if there are any */ |
1481 | |
1482 | static Boolean PeekOtherSources( |
1483 | XtAppContext app) |
1484 | { |
1485 | struct timeval cur_time; |
1486 | |
1487 | if (app->outstandingQueue != NULL((void*)0)) return TRUE1; |
1488 | |
1489 | if (app->signalQueue != NULL((void*)0)) { |
1490 | SignalEventRec *se_ptr = app->signalQueue; |
1491 | while (se_ptr != NULL((void*)0)) { |
1492 | if (se_ptr->se_notice) |
1493 | return TRUE1; |
1494 | se_ptr = se_ptr->se_next; |
1495 | } |
1496 | } |
1497 | |
1498 | if (app->input_count > 0) { |
1499 | /* Call _XtWaitForSomething to get input queued up */ |
1500 | (void) _XtWaitForSomething (app, |
1501 | TRUE1, TRUE1, FALSE0, TRUE1, |
1502 | FALSE0, |
1503 | #ifdef XTHREADS1 |
1504 | TRUE1, |
1505 | #endif |
1506 | (unsigned long *)NULL((void*)0)); |
1507 | if (app->outstandingQueue != NULL((void*)0)) return TRUE1; |
1508 | } |
1509 | |
1510 | if (app->timerQueue != NULL((void*)0)) { /* check timeout queue */ |
1511 | X_GETTIMEOFDAY (&cur_time)gettimeofday(&cur_time, (struct timezone*)0); |
1512 | FIXUP_TIMEVAL(cur_time); |
1513 | if (IS_AT_OR_AFTER (app->timerQueue->te_timer_value, cur_time)(((cur_time).tv_sec > (app->timerQueue->te_timer_value ).tv_sec) || (((cur_time).tv_sec == (app->timerQueue->te_timer_value ).tv_sec)&& ((cur_time).tv_usec >= (app->timerQueue ->te_timer_value).tv_usec)))) |
1514 | return TRUE1; |
1515 | } |
1516 | |
1517 | return FALSE0; |
1518 | } |
1519 | |
1520 | Boolean XtPeekEvent( |
1521 | XEvent *event) |
1522 | { |
1523 | return XtAppPeekEvent(_XtDefaultAppContext(), event); |
1524 | } |
1525 | |
1526 | Boolean XtAppPeekEvent_SkipTimer; |
1527 | |
1528 | Boolean XtAppPeekEvent( |
1529 | XtAppContext app, |
1530 | XEvent *event) |
1531 | { |
1532 | int i, d; |
1533 | Boolean foundCall = FALSE0; |
1534 | |
1535 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); |
1536 | for (i = 1; i <= app->count; i++) { |
1537 | d = (i + app->last) % app->count; |
1538 | if (d == 0) foundCall = PeekOtherSources(app); |
1539 | if (XEventsQueued(app->list[d], QueuedAfterReading1)) |
1540 | goto GotEvent; |
1541 | } |
1542 | for (i = 1; i <= app->count; i++) { |
1543 | d = (i + app->last) % app->count; |
1544 | if (XEventsQueued(app->list[d], QueuedAfterFlush2)) |
1545 | goto GotEvent; |
1546 | } |
1547 | |
1548 | if (foundCall) { |
1549 | event->xany.type = 0; |
1550 | event->xany.display = NULL((void*)0); |
1551 | event->xany.window = 0; |
1552 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1553 | return FALSE0; |
1554 | } |
1555 | |
1556 | while (1) { |
1557 | d = _XtWaitForSomething (app, |
1558 | FALSE0, FALSE0, FALSE0, FALSE0, |
1559 | TRUE1, |
1560 | #ifdef XTHREADS1 |
1561 | TRUE1, |
1562 | #endif |
1563 | (unsigned long *) NULL((void*)0)); |
1564 | |
1565 | if (d != -1) { /* event */ |
1566 | GotEvent: |
1567 | XPeekEvent(app->list[d], event); |
1568 | app->last = (d == 0 ? app->count : d) - 1; |
1569 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1570 | return TRUE1; |
1571 | } |
1572 | else { /* input or timer or signal */ |
1573 | /* |
1574 | * Check to see why a -1 was returned, if a timer expired, |
1575 | * call it and block some more |
1576 | */ |
1577 | if ((app->timerQueue != NULL((void*)0)) && ! XtAppPeekEvent_SkipTimer) { /* timer */ |
1578 | struct timeval cur_time; |
1579 | Boolint did_timer = False0; |
1580 | |
1581 | X_GETTIMEOFDAY (&cur_time)gettimeofday(&cur_time, (struct timezone*)0); |
1582 | FIXUP_TIMEVAL(cur_time); |
1583 | while (IS_AT_OR_AFTER(app->timerQueue->te_timer_value, cur_time)(((cur_time).tv_sec > (app->timerQueue->te_timer_value ).tv_sec) || (((cur_time).tv_sec == (app->timerQueue->te_timer_value ).tv_sec)&& ((cur_time).tv_usec >= (app->timerQueue ->te_timer_value).tv_usec)))) { |
1584 | TimerEventRec *te_ptr = app->timerQueue; |
1585 | app->timerQueue = app->timerQueue->te_next; |
1586 | te_ptr->te_next = NULL((void*)0); |
1587 | if (te_ptr->te_proc != NULL((void*)0)) { |
1588 | TeCallProc(te_ptr)(*te_ptr->te_proc) (te_ptr->te_closure, (XtIntervalId*) &te_ptr);; |
1589 | did_timer = True1; |
1590 | } |
1591 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); |
1592 | te_ptr->te_next = freeTimerRecs; |
1593 | freeTimerRecs = te_ptr; |
1594 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); |
1595 | if (app->timerQueue == NULL((void*)0)) break; |
1596 | } |
1597 | if (did_timer) |
1598 | { |
1599 | for (d = 0; d < app->count; d++) |
1600 | /* the timer's procedure may have caused an event */ |
1601 | if (XEventsQueued(app->list[d], QueuedAfterFlush2)) { |
1602 | goto GotEvent; |
1603 | } |
1604 | continue; /* keep blocking */ |
1605 | } |
1606 | } |
1607 | /* |
1608 | * spec is vague here; we'll assume signals also return FALSE, |
1609 | * of course to determine whether a signal is pending requires |
1610 | * walking the signalQueue looking for se_notice flags which |
1611 | * this code doesn't do. |
1612 | */ |
1613 | #if 0 |
1614 | if (app->signalQueue != NULL((void*)0)) { /* signal */ |
1615 | event->xany.type = 0; |
1616 | event->xany.display = NULL((void*)0); |
1617 | event->xany.window = 0; |
1618 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1619 | return FALSE0; |
1620 | } |
1621 | else |
1622 | #endif |
1623 | { /* input */ |
1624 | event->xany.type = 0; |
1625 | event->xany.display = NULL((void*)0); |
1626 | event->xany.window = 0; |
1627 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); |
1628 | return FALSE0; |
1629 | } |
1630 | } |
1631 | } /* end while */ |
1632 | } |