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 }