Mercurial > hg > xemacs-beta
comparison src/event-msw.c @ 219:262b8bb4a523 r20-4b8
Import from CVS: tag r20-4b8
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:09:35 +0200 |
parents | 78f53ef88e17 |
children | 2c611d1463a6 |
comparison
equal
deleted
inserted
replaced
218:c9f226976f56 | 219:262b8bb4a523 |
---|---|
45 | 45 |
46 #include "event-msw.h" | 46 #include "event-msw.h" |
47 | 47 |
48 static struct event_stream *mswindows_event_stream; | 48 static struct event_stream *mswindows_event_stream; |
49 static Lisp_Object mswindows_dispatch_event_queue, mswindows_dispatch_event_queue_tail; | 49 static Lisp_Object mswindows_dispatch_event_queue, mswindows_dispatch_event_queue_tail; |
50 static mswindows_waitable_count=0; | |
51 CRITICAL_SECTION mswindows_dispatch_crit; | 50 CRITICAL_SECTION mswindows_dispatch_crit; |
52 | |
53 static Lisp_Object mswindows_dequeue_dispatch_event (void); | |
54 | 51 |
55 /* | 52 /* |
56 * List of mswindows waitable handles. | 53 * List of mswindows waitable handles. |
57 * Apart from the dispatch queue semaphore, all of these handles may be waited | 54 * Apart from the dispatch queue semaphore, all of these handles may be waited |
58 * on multiple times in emacs_mswindows_next_event before being processed and so must | 55 * on multiple times in emacs_mswindows_next_event before being processed and so |
59 * be manual-reset events. | 56 * must be manual-reset events. |
60 */ | 57 */ |
61 static HANDLE mswindows_waitable[MAX_WAITABLE]; | 58 static HANDLE mswindows_waitable[MAX_WAITABLE]; |
62 | 59 |
63 /* random emacs info associated with each of the wait handles */ | 60 /* random emacs info associated with each of the wait handles */ |
64 static mswindows_waitable_info_type mswindows_waitable_info[MAX_WAITABLE]; | 61 static mswindows_waitable_info_type mswindows_waitable_info[MAX_WAITABLE]; |
65 | 62 |
63 /* Number of wait handles */ | |
64 static mswindows_waitable_count=0; | |
65 | |
66 /* | |
67 * Add an emacs event to the dispatch queue and increment the semaphore | |
68 */ | |
66 void | 69 void |
67 mswindows_enqueue_dispatch_event (Lisp_Object event) | 70 mswindows_enqueue_dispatch_event (Lisp_Object event) |
68 { | 71 { |
69 assert(mswindows_waitable_count); | 72 enqueue_event (event, &mswindows_dispatch_event_queue, |
70 // EnterCriticalSection (&mswindows_dispatch_crit); | 73 &mswindows_dispatch_event_queue_tail); |
71 enqueue_event (event, &mswindows_dispatch_event_queue, &mswindows_dispatch_event_queue_tail); | |
72 ReleaseSemaphore(mswindows_waitable[0], 1, NULL); | 74 ReleaseSemaphore(mswindows_waitable[0], 1, NULL); |
73 // LeaveCriticalSection (&mswindows_dispatch_crit); | 75 } |
74 } | 76 |
75 | 77 /* |
78 * Remove and return the first emacs event on the dispatch queue. Don't | |
79 * decrement the queue's semaphore because it will be decremented by being | |
80 * waited on. | |
81 */ | |
76 static Lisp_Object | 82 static Lisp_Object |
77 mswindows_dequeue_dispatch_event (void) | 83 mswindows_dequeue_dispatch_event (void) |
78 { | 84 { |
79 Lisp_Object event; | 85 Lisp_Object event; |
80 assert(mswindows_waitable_count); | 86 event = dequeue_event (&mswindows_dispatch_event_queue, |
81 // EnterCriticalSection (&mswindows_dispatch_crit); | 87 &mswindows_dispatch_event_queue_tail); |
82 event = dequeue_event (&mswindows_dispatch_event_queue, &mswindows_dispatch_event_queue_tail); | |
83 // LeaveCriticalSection (&mswindows_dispatch_crit); | |
84 return event; | 88 return event; |
89 } | |
90 | |
91 /* | |
92 * Remove and return the first emacs event on the dispatch queue that matches | |
93 * the supplied event and decrement the queue's semaphore. | |
94 * Only supports timeout events. | |
95 */ | |
96 Lisp_Object | |
97 mswindows_cancel_dispatch_event (Lisp_Object match_event) | |
98 { | |
99 Lisp_Object event; | |
100 Lisp_Object previous_event=Qnil; | |
101 struct Lisp_Event *match = XEVENT(match_event); | |
102 | |
103 assert (match->event_type == timeout_event); | |
104 | |
105 EVENT_CHAIN_LOOP (event, mswindows_dispatch_event_queue) | |
106 if (XEVENT_TYPE (event) == match->event_type) | |
107 { | |
108 /* We only handle timeouts */ | |
109 if (XEVENT(event)->event.timeout.interval_id == | |
110 match->event.timeout.interval_id) | |
111 { | |
112 if (NILP (previous_event)) | |
113 dequeue_event (&mswindows_dispatch_event_queue, | |
114 &mswindows_dispatch_event_queue_tail); | |
115 else | |
116 { | |
117 XSET_EVENT_NEXT (previous_event, XEVENT_NEXT (event)); | |
118 if (EQ (mswindows_dispatch_event_queue_tail, event)) | |
119 mswindows_dispatch_event_queue_tail = previous_event; | |
120 } | |
121 | |
122 /* Decrement the dispatch queue counter */ | |
123 WaitForSingleObject(mswindows_waitable[0], INFINITE); | |
124 return event; | |
125 } | |
126 } | |
127 else | |
128 previous_event = event; | |
129 | |
130 return Qnil; | |
85 } | 131 } |
86 | 132 |
87 /* | 133 /* |
88 * Find a free waitable slot | 134 * Find a free waitable slot |
89 */ | 135 */ |
194 { | 240 { |
195 mswindows_request_type request = { (void *) id }; | 241 mswindows_request_type request = { (void *) id }; |
196 mswindows_make_request(WM_XEMACS_KILLTIMER, 0, &request); | 242 mswindows_make_request(WM_XEMACS_KILLTIMER, 0, &request); |
197 } | 243 } |
198 | 244 |
245 /* If `user_p' is false, then return whether there are any win32, timeout, | |
246 * or subprocess events pending (that is, whether | |
247 * emacs_mswindows_next_event() would return immediately without blocking). | |
248 * | |
249 * if `user_p' is true, then return whether there are any *user generated* | |
250 * events available (that is, whether there are keyboard or mouse-click | |
251 * events ready to be read). This also implies that | |
252 * emacs_mswindows_next_event() would not block. | |
253 */ | |
199 static int | 254 static int |
200 emacs_mswindows_event_pending_p (int user_p) | 255 emacs_mswindows_event_pending_p (int user_p) |
201 { | 256 { |
202 return 0; | 257 if (user_p) |
258 { | |
259 /* Iterate over the dispatch queue looking for user-events */ | |
260 int found = 0; | |
261 Lisp_Object event; | |
262 | |
263 EnterCriticalSection (&mswindows_dispatch_crit); | |
264 EVENT_CHAIN_LOOP (event, mswindows_dispatch_event_queue) | |
265 if (command_event_p (event)) | |
266 found = 1; | |
267 LeaveCriticalSection (&mswindows_dispatch_crit); | |
268 return found; | |
269 } | |
270 else | |
271 { | |
272 /* Check for any kind of input, including the dispatch queue */ | |
273 #if 0 | |
274 /* Want do do the following, but it's not clear whether this would | |
275 * cause the waitables to become unsignalled */ | |
276 return (WaitForMultipleObjects (mswindows_waitable_count, | |
277 mswindows_waitable, FALSE, 0) | |
278 != WAIT_TIMEOUT); | |
279 #else | |
280 return !NILP (mswindows_dispatch_event_queue); | |
281 #endif | |
282 } | |
203 } | 283 } |
204 | 284 |
205 static struct console * | 285 static struct console * |
206 find_console_from_fd (int fd) | 286 find_console_from_fd (int fd) |
207 { | 287 { |
309 else | 389 else |
310 { | 390 { |
311 /* If we're uniconified, our size may or may not have changed */ | 391 /* If we're uniconified, our size may or may not have changed */ |
312 int columns, rows; | 392 int columns, rows; |
313 int was_visible = FRAME_VISIBLE_P (f); | 393 int was_visible = FRAME_VISIBLE_P (f); |
394 | |
395 FRAME_VISIBLE_P (f) = 1; | |
396 FRAME_PIXWIDTH(f) = rect->right; | |
397 FRAME_PIXHEIGHT(f) = rect->bottom; | |
398 | |
314 pixel_to_char_size (f, rect->right, rect->bottom, &columns, &rows); | 399 pixel_to_char_size (f, rect->right, rect->bottom, &columns, &rows); |
315 | 400 change_frame_size (f, rows, columns, 0); |
316 FRAME_VISIBLE_P (f) = 1; | |
317 if (f->height!=rows || f->width!=columns || f->size_change_pending) | |
318 { | |
319 /* Size changed */ | |
320 f->pixwidth = rect->right; | |
321 f->pixheight = rect->bottom; | |
322 change_frame_size (f, rows, columns, 0); | |
323 /* MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); /* XXX Too extreme? */ | 401 /* MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); /* XXX Too extreme? */ |
324 } | |
325 | 402 |
326 if (!was_visible) | 403 if (!was_visible) |
327 va_run_hook_with_args (Qmap_frame_hook, 1, frame); | 404 va_run_hook_with_args (Qmap_frame_hook, 1, frame); |
328 | 405 |
329 } | 406 } |
330 break; | 407 break; |
331 | 408 |
332 case WM_PAINT: | 409 case WM_PAINT: |
333 mswindows_redraw_exposed_area(f, rect->left, rect->top, | 410 mswindows_redraw_exposed_area(f, rect->left, rect->top, |
334 rect->right, rect->bottom); | 411 rect->right, rect->bottom); |
412 break; | |
413 | |
414 case WM_CLOSE: | |
415 enqueue_misc_user_event (frame, Qeval, list3 (Qdelete_frame, frame, Qt)); | |
335 break; | 416 break; |
336 | 417 |
337 default: | 418 default: |
338 assert(0); | 419 assert(0); |
339 } | 420 } |