File: | NextEvent.c |
Location: | line 862, column 15 |
Description: | Access to field 'workQueue' 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 | } |