Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- a/src/event-msw.c Mon Aug 13 10:08:36 2007 +0200 +++ b/src/event-msw.c Mon Aug 13 10:09:35 2007 +0200 @@ -47,44 +47,90 @@ static struct event_stream *mswindows_event_stream; static Lisp_Object mswindows_dispatch_event_queue, mswindows_dispatch_event_queue_tail; -static mswindows_waitable_count=0; CRITICAL_SECTION mswindows_dispatch_crit; -static Lisp_Object mswindows_dequeue_dispatch_event (void); - /* * List of mswindows waitable handles. * Apart from the dispatch queue semaphore, all of these handles may be waited - * on multiple times in emacs_mswindows_next_event before being processed and so must - * be manual-reset events. + * on multiple times in emacs_mswindows_next_event before being processed and so + * must be manual-reset events. */ static HANDLE mswindows_waitable[MAX_WAITABLE]; /* random emacs info associated with each of the wait handles */ static mswindows_waitable_info_type mswindows_waitable_info[MAX_WAITABLE]; +/* Number of wait handles */ +static mswindows_waitable_count=0; + +/* + * Add an emacs event to the dispatch queue and increment the semaphore + */ void mswindows_enqueue_dispatch_event (Lisp_Object event) { - assert(mswindows_waitable_count); -// EnterCriticalSection (&mswindows_dispatch_crit); - enqueue_event (event, &mswindows_dispatch_event_queue, &mswindows_dispatch_event_queue_tail); + enqueue_event (event, &mswindows_dispatch_event_queue, + &mswindows_dispatch_event_queue_tail); ReleaseSemaphore(mswindows_waitable[0], 1, NULL); -// LeaveCriticalSection (&mswindows_dispatch_crit); } +/* + * Remove and return the first emacs event on the dispatch queue. Don't + * decrement the queue's semaphore because it will be decremented by being + * waited on. + */ static Lisp_Object mswindows_dequeue_dispatch_event (void) { Lisp_Object event; - assert(mswindows_waitable_count); -// EnterCriticalSection (&mswindows_dispatch_crit); - event = dequeue_event (&mswindows_dispatch_event_queue, &mswindows_dispatch_event_queue_tail); -// LeaveCriticalSection (&mswindows_dispatch_crit); + event = dequeue_event (&mswindows_dispatch_event_queue, + &mswindows_dispatch_event_queue_tail); return event; } /* + * Remove and return the first emacs event on the dispatch queue that matches + * the supplied event and decrement the queue's semaphore. + * Only supports timeout events. + */ +Lisp_Object +mswindows_cancel_dispatch_event (Lisp_Object match_event) +{ + Lisp_Object event; + Lisp_Object previous_event=Qnil; + struct Lisp_Event *match = XEVENT(match_event); + + assert (match->event_type == timeout_event); + + EVENT_CHAIN_LOOP (event, mswindows_dispatch_event_queue) + if (XEVENT_TYPE (event) == match->event_type) + { + /* We only handle timeouts */ + if (XEVENT(event)->event.timeout.interval_id == + match->event.timeout.interval_id) + { + if (NILP (previous_event)) + dequeue_event (&mswindows_dispatch_event_queue, + &mswindows_dispatch_event_queue_tail); + else + { + XSET_EVENT_NEXT (previous_event, XEVENT_NEXT (event)); + if (EQ (mswindows_dispatch_event_queue_tail, event)) + mswindows_dispatch_event_queue_tail = previous_event; + } + + /* Decrement the dispatch queue counter */ + WaitForSingleObject(mswindows_waitable[0], INFINITE); + return event; + } + } + else + previous_event = event; + + return Qnil; +} + +/* * Find a free waitable slot */ static int @@ -196,10 +242,44 @@ mswindows_make_request(WM_XEMACS_KILLTIMER, 0, &request); } +/* If `user_p' is false, then return whether there are any win32, timeout, + * or subprocess events pending (that is, whether + * emacs_mswindows_next_event() would return immediately without blocking). + * + * if `user_p' is true, then return whether there are any *user generated* + * events available (that is, whether there are keyboard or mouse-click + * events ready to be read). This also implies that + * emacs_mswindows_next_event() would not block. + */ static int emacs_mswindows_event_pending_p (int user_p) { - return 0; + if (user_p) + { + /* Iterate over the dispatch queue looking for user-events */ + int found = 0; + Lisp_Object event; + + EnterCriticalSection (&mswindows_dispatch_crit); + EVENT_CHAIN_LOOP (event, mswindows_dispatch_event_queue) + if (command_event_p (event)) + found = 1; + LeaveCriticalSection (&mswindows_dispatch_crit); + return found; + } + else + { + /* Check for any kind of input, including the dispatch queue */ +#if 0 + /* Want do do the following, but it's not clear whether this would + * cause the waitables to become unsignalled */ + return (WaitForMultipleObjects (mswindows_waitable_count, + mswindows_waitable, FALSE, 0) + != WAIT_TIMEOUT); +#else + return !NILP (mswindows_dispatch_event_queue); +#endif + } } static struct console * @@ -311,17 +391,14 @@ /* If we're uniconified, our size may or may not have changed */ int columns, rows; int was_visible = FRAME_VISIBLE_P (f); - pixel_to_char_size (f, rect->right, rect->bottom, &columns, &rows); FRAME_VISIBLE_P (f) = 1; - if (f->height!=rows || f->width!=columns || f->size_change_pending) - { - /* Size changed */ - f->pixwidth = rect->right; - f->pixheight = rect->bottom; - change_frame_size (f, rows, columns, 0); + FRAME_PIXWIDTH(f) = rect->right; + FRAME_PIXHEIGHT(f) = rect->bottom; + + pixel_to_char_size (f, rect->right, rect->bottom, &columns, &rows); + change_frame_size (f, rows, columns, 0); /* MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); /* XXX Too extreme? */ - } if (!was_visible) va_run_hook_with_args (Qmap_frame_hook, 1, frame); @@ -331,7 +408,11 @@ case WM_PAINT: mswindows_redraw_exposed_area(f, rect->left, rect->top, - rect->right, rect->bottom); + rect->right, rect->bottom); + break; + + case WM_CLOSE: + enqueue_misc_user_event (frame, Qeval, list3 (Qdelete_frame, frame, Qt)); break; default: