File: | NextEvent.c |
Location: | line 1004, column 6 |
Description: | Access to field 'input_max' 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); | ||
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 | } |