X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fevent-msw.c;h=c5c3d2fef1d228652bcb335571b8de6d0ce78519;hp=49a2446b33ba367a5fb01676dcc9ab7c65e23120;hb=716cfba952c1dc0d2cf5c968971f3780ba728a89;hpb=937bb3ce20f4819a75e8234cb91a1acaa19847f8 diff --git a/src/event-msw.c b/src/event-msw.c index 49a2446..c5c3d2f 100644 --- a/src/event-msw.c +++ b/src/event-msw.c @@ -56,6 +56,7 @@ Boston, MA 02111-1307, USA. */ #include "lstream.h" #include "process.h" #include "redisplay.h" +#include "select.h" #include "sysproc.h" #include "syswait.h" #include "systime.h" @@ -72,7 +73,7 @@ typedef unsigned int SOCKET; #include #include -#if defined (__CYGWIN32__) && !defined (CYGWIN_VERSION_DLL_MAJOR) +#if defined (__CYGWIN32__) && (CYGWIN_VERSION_DLL_MAJOR < 20) typedef NMHDR *LPNMHDR; #endif @@ -89,16 +90,10 @@ typedef NMHDR *LPNMHDR; /* Timer ID used for button2 emulation */ #define BUTTON_2_TIMER_ID 1 -extern Lisp_Object -mswindows_get_toolbar_button_text (struct frame* f, int command_id); -extern Lisp_Object -mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id); -extern Lisp_Object -mswindows_handle_gui_wm_command (struct frame* f, HWND ctrl, WORD id); - static Lisp_Object mswindows_find_frame (HWND hwnd); static Lisp_Object mswindows_find_console (HWND hwnd); -static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods); +static Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods, + int extendedp); static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); static void mswindows_set_chord_timer (HWND hwnd); static int mswindows_button2_near_enough (POINTS p1, POINTS p2); @@ -144,6 +139,7 @@ int mswindows_quit_chars_count = 0; /* These are Lisp integers; see DEFVARS in this file for description. */ int mswindows_dynamic_frame_resize; +int mswindows_meta_activates_menu; int mswindows_num_mouse_buttons; int mswindows_mouse_button_max_skew_x; int mswindows_mouse_button_max_skew_y; @@ -197,7 +193,7 @@ struct ntpipe_slurp_stream_shared_data }; #define MAX_SLURP_STREAMS 32 -struct ntpipe_slurp_stream_shared_data +struct ntpipe_slurp_stream_shared_data shared_data_block[MAX_SLURP_STREAMS]={{0}}; struct ntpipe_slurp_stream @@ -269,7 +265,7 @@ slurp_thread (LPVOID vparam) /* Now we got something to notify caller, either a byte or an error/eof indication. Before we do, allow internal pipe - buffer to accumulate little bit more data. + buffer to accumulate little bit more data. Reader function pulses this event before waiting for a character, to avoid pipe delay, and to get the byte immediately. */ @@ -358,11 +354,11 @@ get_ntpipe_input_stream_waitable (Lstream *stream) return s->thread_data->hev_caller; } -static int +static ssize_t ntpipe_slurp_reader (Lstream *stream, unsigned char *data, size_t size) { /* This function must be called from the main thread only */ - struct ntpipe_slurp_stream_shared_data* s = + struct ntpipe_slurp_stream_shared_data* s = NTPIPE_SLURP_STREAM_DATA(stream)->thread_data; if (!s->die_p) @@ -371,7 +367,7 @@ ntpipe_slurp_reader (Lstream *stream, unsigned char *data, size_t size) /* Disallow pipe read delay for the thread: we need a character ASAP */ SetEvent (s->hev_unsleep); - + /* Check if we have a character ready. Give it a short delay, for the thread to awake from pipe delay, just ion case*/ wait_result = WaitForSingleObject (s->hev_caller, 2); @@ -422,7 +418,7 @@ ntpipe_slurp_reader (Lstream *stream, unsigned char *data, size_t size) ReadFile (s->hpipe, data, min (bytes_available, size), &bytes_read, NULL); } - + /* Now we can unblock thread, so it attempts to read more */ SetEvent (s->hev_thread); return bytes_read + 1; @@ -431,11 +427,11 @@ ntpipe_slurp_reader (Lstream *stream, unsigned char *data, size_t size) return 0; } -static int +static int ntpipe_slurp_closer (Lstream *stream) { /* This function must be called from the main thread only */ - struct ntpipe_slurp_stream_shared_data* s = + struct ntpipe_slurp_stream_shared_data* s = NTPIPE_SLURP_STREAM_DATA(stream)->thread_data; /* Force thread to stop */ @@ -467,7 +463,7 @@ init_slurp_stream (void) LSTREAM_TYPE_DATA (stream, ntpipe_shove) #define MAX_SHOVE_BUFFER_SIZE 128 - + struct ntpipe_shove_stream { LPARAM user_data; /* Any user data stored in the stream object */ @@ -494,7 +490,7 @@ shove_thread (LPVOID vparam) for (;;) { - DWORD bytes_written; + DWORD bytes_written; /* Block on event and wait for a job */ InterlockedIncrement (&s->idle_p); @@ -531,7 +527,7 @@ make_ntpipe_output_stream (HANDLE hpipe, LPARAM param) s->hpipe = hpipe; s->user_data = param; - /* Create reader thread. This could fail, so do not + /* Create reader thread. This could fail, so do not create the event until thread is created */ s->hthread = CreateThread (NULL, 0, shove_thread, (LPVOID)s, CREATE_SUSPENDED, &thread_id_unused); @@ -560,7 +556,7 @@ get_ntpipe_output_stream_param (Lstream *stream) } #endif -static int +static ssize_t ntpipe_shove_writer (Lstream *stream, const unsigned char *data, size_t size) { struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); @@ -669,7 +665,7 @@ winsock_initiate_read (struct winsock_stream *str) str->eof_p = 1; } -static int +static ssize_t winsock_reader (Lstream *stream, unsigned char *data, size_t size) { struct winsock_stream *str = WINSOCK_STREAM_DATA (stream); @@ -702,7 +698,7 @@ winsock_reader (Lstream *stream, unsigned char *data, size_t size) return 0; if (str->error_p) return -1; - + /* Return as much of buffer as we have */ size = min (size, (size_t) (str->bufsize - str->bufpos)); memcpy (data, (void*)((BYTE*)str->buffer + str->bufpos), size); @@ -715,7 +711,7 @@ winsock_reader (Lstream *stream, unsigned char *data, size_t size) return size; } -static int +static ssize_t winsock_writer (Lstream *stream, CONST unsigned char *data, size_t size) { struct winsock_stream *str = WINSOCK_STREAM_DATA (stream); @@ -743,7 +739,7 @@ winsock_writer (Lstream *stream, CONST unsigned char *data, size_t size) if (size == 0) return 0; - + { ResetEvent (str->ov.hEvent); @@ -857,7 +853,7 @@ init_winsock_stream (void) /************************************************************************/ static int -mswindows_user_event_p (struct Lisp_Event* sevt) +mswindows_user_event_p (Lisp_Event* sevt) { return (sevt->event_type == key_press_event || sevt->event_type == button_press_event @@ -865,7 +861,7 @@ mswindows_user_event_p (struct Lisp_Event* sevt) || sevt->event_type == misc_user_event); } -/* +/* * Add an emacs event to the proper dispatch queue */ static void @@ -873,7 +869,7 @@ mswindows_enqueue_dispatch_event (Lisp_Object event) { int user_p = mswindows_user_event_p (XEVENT(event)); enqueue_event (event, - user_p ? &mswindows_u_dispatch_event_queue : + user_p ? &mswindows_u_dispatch_event_queue : &mswindows_s_dispatch_event_queue, user_p ? &mswindows_u_dispatch_event_queue_tail : &mswindows_s_dispatch_event_queue_tail); @@ -893,10 +889,11 @@ mswindows_enqueue_misc_user_event (Lisp_Object channel, Lisp_Object function, Lisp_Object object) { Lisp_Object event = Fmake_event (Qnil, Qnil); - struct Lisp_Event* e = XEVENT (event); + Lisp_Event* e = XEVENT (event); e->event_type = misc_user_event; e->channel = channel; + e->timestamp = GetTickCount (); e->event.misc.function = function; e->event.misc.object = object; @@ -904,24 +901,24 @@ mswindows_enqueue_misc_user_event (Lisp_Object channel, Lisp_Object function, } void -mswindows_enqueue_magic_event (HWND hwnd, UINT message) +mswindows_enqueue_magic_event (HWND hwnd, UINT msg) { Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event* event = XEVENT (emacs_event); + Lisp_Event* event = XEVENT (emacs_event); event->channel = hwnd ? mswindows_find_frame (hwnd) : Qnil; event->timestamp = GetMessageTime(); event->event_type = magic_event; - EVENT_MSWINDOWS_MAGIC_TYPE (event) = message; + EVENT_MSWINDOWS_MAGIC_TYPE (event) = msg; mswindows_enqueue_dispatch_event (emacs_event); } static void -mswindows_enqueue_process_event (struct Lisp_Process* p) +mswindows_enqueue_process_event (Lisp_Process* p) { Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event* event = XEVENT (emacs_event); + Lisp_Event* event = XEVENT (emacs_event); Lisp_Object process; XSETPROCESS (process, p); @@ -933,7 +930,7 @@ mswindows_enqueue_process_event (struct Lisp_Process* p) } static void -mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWORD when) +mswindows_enqueue_mouse_button_event (HWND hwnd, UINT msg, POINTS where, DWORD when) { /* We always use last message time, because mouse button @@ -941,19 +938,19 @@ mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWO recognition will fail */ Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event* event = XEVENT(emacs_event); + Lisp_Event* event = XEVENT(emacs_event); event->channel = mswindows_find_frame(hwnd); event->timestamp = when; event->event.button.button = - (message==WM_LBUTTONDOWN || message==WM_LBUTTONUP) ? 1 : - ((message==WM_RBUTTONDOWN || message==WM_RBUTTONUP) ? 3 : 2); + (msg==WM_LBUTTONDOWN || msg==WM_LBUTTONUP) ? 1 : + ((msg==WM_RBUTTONDOWN || msg==WM_RBUTTONUP) ? 3 : 2); event->event.button.x = where.x; event->event.button.y = where.y; event->event.button.modifiers = mswindows_modifier_state (NULL, 0); - - if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN || - message==WM_RBUTTONDOWN) + + if (msg==WM_LBUTTONDOWN || msg==WM_MBUTTONDOWN || + msg==WM_RBUTTONDOWN) { event->event_type = button_press_event; SetCapture (hwnd); @@ -970,7 +967,7 @@ mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWO event->event_type = button_release_event; ReleaseCapture (); } - + mswindows_enqueue_dispatch_event (emacs_event); } @@ -978,7 +975,7 @@ static void mswindows_enqueue_keypress_event (HWND hwnd, Lisp_Object keysym, int mods) { Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event* event = XEVENT(emacs_event); + Lisp_Event* event = XEVENT(emacs_event); event->channel = mswindows_find_console(hwnd); event->timestamp = GetMessageTime(); @@ -996,16 +993,16 @@ static Lisp_Object mswindows_dequeue_dispatch_event () { Lisp_Object event; - struct Lisp_Event* sevt; + Lisp_Event* sevt; assert (!NILP(mswindows_u_dispatch_event_queue) || !NILP(mswindows_s_dispatch_event_queue)); event = dequeue_event ( - NILP(mswindows_u_dispatch_event_queue) ? - &mswindows_s_dispatch_event_queue : + NILP(mswindows_u_dispatch_event_queue) ? + &mswindows_s_dispatch_event_queue : &mswindows_u_dispatch_event_queue, - NILP(mswindows_u_dispatch_event_queue) ? + NILP(mswindows_u_dispatch_event_queue) ? &mswindows_s_dispatch_event_queue_tail : &mswindows_u_dispatch_event_queue_tail); @@ -1030,14 +1027,14 @@ mswindows_dequeue_dispatch_event () */ Lisp_Object -mswindows_cancel_dispatch_event (struct Lisp_Event *match) +mswindows_cancel_dispatch_event (Lisp_Event *match) { Lisp_Object event; Lisp_Object previous_event = Qnil; int user_p = mswindows_user_event_p (match); - Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue : + Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue : &mswindows_s_dispatch_event_queue; - Lisp_Object* tail = user_p ? &mswindows_u_dispatch_event_queue_tail : + Lisp_Object* tail = user_p ? &mswindows_u_dispatch_event_queue_tail : &mswindows_s_dispatch_event_queue_tail; assert (match->event_type == timeout_event @@ -1045,7 +1042,7 @@ mswindows_cancel_dispatch_event (struct Lisp_Event *match) EVENT_CHAIN_LOOP (event, *head) { - struct Lisp_Event *e = XEVENT (event); + Lisp_Event *e = XEVENT (event); if ((e->event_type == match->event_type) && ((e->event_type == timeout_event) ? (e->event.timeout.interval_id == match->event.timeout.interval_id) : @@ -1060,7 +1057,7 @@ mswindows_cancel_dispatch_event (struct Lisp_Event *match) if (EQ (*tail, event)) *tail = previous_event; } - + return event; } previous_event = event; @@ -1101,7 +1098,7 @@ remove_waitable_handle (HANDLE h) if (ix < 0) return; - mswindows_waitable_handles [ix] = + mswindows_waitable_handles [ix] = mswindows_waitable_handles [--mswindows_waitable_count]; } #endif /* HAVE_MSG_SELECT */ @@ -1125,7 +1122,7 @@ mswindows_protect_modal_loop (Lisp_Object (*bfun) (Lisp_Object barg), { Lisp_Object tmp; - ++mswindows_in_modal_loop; + ++mswindows_in_modal_loop; tmp = condition_case_1 (Qt, bfun, barg, mswindows_modal_loop_error_handler, Qnil); @@ -1149,7 +1146,7 @@ mswindows_unmodalize_signal_maybe (void) } /* - * This is an unsafe part of event pump, guarded by + * This is an unsafe part of event pump, guarded by * condition_case. See mswindows_pump_outstanding_events */ static Lisp_Object @@ -1173,7 +1170,7 @@ mswindows_unsafe_pump_events (Lisp_Object u_n_u_s_e_d) Fdeallocate_event (event); UNGCPRO; - + /* Qt becomes return value of mswindows_pump_outstanding_events once we get here */ return Qt; @@ -1221,24 +1218,36 @@ mswindows_pump_outstanding_events (void) Lisp_Object result = Qt; struct gcpro gcpro1; GCPRO1 (result); - + if (NILP(mswindows_error_caught_in_modal_loop)) result = mswindows_protect_modal_loop (mswindows_unsafe_pump_events, Qnil); UNGCPRO; return result; } -static void -mswindows_drain_windows_queue () +/* + * KEYBOARD_ONLY_P is set to non-zero when we are called from + * QUITP, and are interesting in keyboard messages only. + */ +static void +mswindows_drain_windows_queue (int keyboard_only_till_quit_char_p) { MSG msg; - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + + /* Minimize the hassle of misordered events by not fetching + past quit char if called from QUITP; */ + while (!(keyboard_only_till_quit_char_p && + mswindows_quit_chars_count > 0) && + PeekMessage (&msg, NULL, + keyboard_only_till_quit_char_p ? WM_KEYFIRST : 0, + keyboard_only_till_quit_char_p ? WM_KEYLAST : 0, + PM_REMOVE)) { - /* we have to translate messages that are not sent to the main - window. this is so that key presses work ok in things like - edit fields. however, we *musn't* translate message for the + /* We have to translate messages that are not sent to the main + window. This is so that key presses work ok in things like + edit fields. However, we *musn't* translate message for the main window as this is handled in the wnd proc. */ - if ( GetWindowLong (msg.hwnd, GWL_STYLE) & WS_CHILD ) + if (GetWindowLong (msg.hwnd, GWL_STYLE) & WS_CHILD) { TranslateMessage (&msg); } @@ -1247,7 +1256,7 @@ mswindows_drain_windows_queue () } } -/* +/* * This is a special flavor of the mswindows_need_event function, * used while in event pump. Actually, there is only kind of events * allowed while in event pump: a timer. An attempt to fetch any @@ -1280,7 +1289,7 @@ mswindows_need_event_in_modal_loop (int badly_p) /* We'll deadlock if go waiting */ if (mswindows_pending_timers_count == 0) error ("Deadlock due to an attempt to call next-event in a wrong context"); - + /* Fetch and dispatch any pending timers */ GetMessage (&msg, NULL, WM_TIMER, WM_TIMER); DispatchMessage (&msg); @@ -1305,9 +1314,13 @@ mswindows_need_event (int badly_p) return; } +#if 0 /* Have to drain Windows message queue first, otherwise, we may miss quit char when called from quit_p */ + /* #### This is, ehm, not quite true -- this function is not + called from quit_p. --kkm */ mswindows_drain_windows_queue (); +#endif while (NILP (mswindows_u_dispatch_event_queue) && NILP (mswindows_s_dispatch_event_queue)) @@ -1317,7 +1330,7 @@ mswindows_need_event (int badly_p) SELECT_TYPE temp_mask = input_wait_mask; EMACS_TIME sometime; EMACS_SELECT_TIME select_time_to_block, *pointer_to_this; - + if (badly_p) pointer_to_this = 0; else @@ -1328,7 +1341,7 @@ mswindows_need_event (int badly_p) } active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this); - + if (active == 0) { assert (!badly_p); @@ -1338,9 +1351,9 @@ mswindows_need_event (int badly_p) { if (FD_ISSET (windows_fd, &temp_mask)) { - mswindows_drain_windows_queue (); + mswindows_drain_windows_queue (0); } -#ifdef HAVE_TTY +#ifdef HAVE_TTY /* Look for a TTY event */ for (i = 0; i < MAXDESC-1; i++) { @@ -1351,8 +1364,8 @@ mswindows_need_event (int badly_p) { struct console *c = tty_find_console_from_fd (i); Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event* event = XEVENT (emacs_event); - + Lisp_Event* event = XEVENT (emacs_event); + assert (c); if (read_event_from_tty_or_stream_desc (event, c, i)) { @@ -1369,9 +1382,9 @@ mswindows_need_event (int badly_p) { if (FD_ISSET (i, &process_only_mask)) { - struct Lisp_Process *p = + Lisp_Process *p = get_process_from_usid (FD_TO_USID(i)); - + mswindows_enqueue_process_event (p); } else @@ -1410,7 +1423,7 @@ mswindows_need_event (int badly_p) assert ((!badly_p && active == WAIT_TIMEOUT) || (active >= WAIT_OBJECT_0 && active <= WAIT_OBJECT_0 + mswindows_waitable_count)); - + if (active == WAIT_TIMEOUT) { /* No luck trying - just return what we've already got */ @@ -1419,13 +1432,13 @@ mswindows_need_event (int badly_p) else if (active == WAIT_OBJECT_0 + mswindows_waitable_count) { /* Got your message, thanks */ - mswindows_drain_windows_queue (); + mswindows_drain_windows_queue (0); } else { int ix = active - WAIT_OBJECT_0; /* First, try to find which process' output has signaled */ - struct Lisp_Process *p = + Lisp_Process *p = get_process_from_usid (HANDLE_TO_USID (mswindows_waitable_handles[ix])); if (p != NULL) { @@ -1453,14 +1466,14 @@ mswindows_need_event (int badly_p) /* Event generators */ /************************************************************************/ -/* +/* * Callback procedure for synchronous timer messages */ static void CALLBACK mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime) { Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); - struct Lisp_Event *event = XEVENT (emacs_event); + Lisp_Event *event = XEVENT (emacs_event); if (KillTimer (NULL, id_timer)) --mswindows_pending_timers_count; @@ -1475,7 +1488,7 @@ mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime) mswindows_enqueue_dispatch_event (emacs_event); } -/* +/* * Callback procedure for dde messages * * We execute a dde Open("file") by simulating a file drop, so dde support @@ -1486,9 +1499,9 @@ HDDEDATA CALLBACK mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv, HSZ hszTopic, HSZ hszItem, HDDEDATA hdata, DWORD dwData1, DWORD dwData2) -{ +{ switch (uType) - { + { case XTYP_CONNECT: if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)) return (HDDEDATA)TRUE; @@ -1505,7 +1518,7 @@ mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv, return (DdeCreateDataHandle (mswindows_dde_mlid, (LPBYTE)pairs, sizeof (pairs), 0L, 0, uFmt, 0)); } - return (HDDEDATA)NULL; + return (HDDEDATA)NULL; case XTYP_EXECUTE: if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)) @@ -1518,7 +1531,7 @@ mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv, Lisp_Object l_dndlist = Qnil; Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); Lisp_Object frmcons, devcons, concons; - struct Lisp_Event *event = XEVENT (emacs_event); + Lisp_Event *event = XEVENT (emacs_event); DdeGetData (hdata, cmd, len, 0); cmd[len] = '\0'; @@ -1586,16 +1599,29 @@ mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv, UNGCPRO; return (HDDEDATA) DDE_FACK; } - DdeFreeDataHandle (hdata); + DdeFreeDataHandle (hdata); return (HDDEDATA) DDE_FNOTPROCESSED; - default: - return (HDDEDATA) NULL; - } + default: + return (HDDEDATA) NULL; + } } #endif /* + * Returns 1 if a key is a real modifier or special key, which + * is better handled by DefWindowProc + */ +static int +key_needs_default_processing_p (UINT vkey) +{ + if (mswindows_meta_activates_menu && vkey == VK_MENU) + return 1; + + return 0; +} + +/* * The windows procedure for the window class XEMACS_CLASS */ LRESULT WINAPI @@ -1606,12 +1632,19 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) Lisp_Object emacs_event = Qnil; Lisp_Object fobj = Qnil; - struct Lisp_Event *event; + Lisp_Event *event; struct frame *frame; struct mswindows_frame* msframe; switch (message) { + case WM_DESTROYCLIPBOARD: + /* We own the clipboard and someone else wants it. Delete our + cached copy of the clipboard contents so we'll ask for it from + Windows again when someone does a paste. */ + handle_selection_clear(QCLIPBOARD); + break; + case WM_ERASEBKGND: /* Erase background only during non-dynamic sizing */ msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); @@ -1643,7 +1676,10 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SetKeyboardState (keymap); } }; - goto defproc; + if (key_needs_default_processing_p (wParam)) + goto defproc; + else + break; case WM_KEYDOWN: case WM_SYSKEYDOWN: @@ -1659,21 +1695,23 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) BYTE keymap[256]; int has_AltGr = mswindows_current_layout_has_AltGr (); int mods; + int extendedp = lParam & 0x1000000; Lisp_Object keysym; GetKeyboardState (keymap); mods = mswindows_modifier_state (keymap, has_AltGr); - /* Handle those keys for which TranslateMessage won't generate a WM_CHAR */ - if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods))) + /* Handle non-printables */ + if (!NILP (keysym = mswindows_key_to_emacs_keysym (wParam, mods, + extendedp))) mswindows_enqueue_keypress_event (hwnd, keysym, mods); - else + else /* Normal keys & modifiers */ { int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); BYTE keymap_orig[256]; POINT pnt = { LOWORD (GetMessagePos()), HIWORD (GetMessagePos()) }; MSG msg; - + msg.hwnd = hwnd; msg.message = message; msg.wParam = wParam; @@ -1685,9 +1723,9 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) * to loosely track Left and Right modifiers on behalf of the OS, * without screwing up Windows NT which tracks them properly. */ if (wParam == VK_CONTROL) - keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] |= 0x80; + keymap [extendedp ? VK_RCONTROL : VK_LCONTROL] |= 0x80; else if (wParam == VK_MENU) - keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] |= 0x80; + keymap [extendedp ? VK_RMENU : VK_LMENU] |= 0x80; memcpy (keymap_orig, keymap, 256); @@ -1697,7 +1735,8 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* Clear control and alt modifiers unless AltGr is pressed */ keymap [VK_RCONTROL] = 0; keymap [VK_LMENU] = 0; - if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80)) + if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) + || !(keymap [VK_RMENU] & 0x80)) { keymap [VK_LCONTROL] = 0; keymap [VK_CONTROL] = 0; @@ -1733,10 +1772,10 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SetKeyboardState (keymap_orig); } /* else */ } - /* F10 causes menu activation by default. We do not want this */ - if (wParam != VK_F10) + if (key_needs_default_processing_p (wParam)) goto defproc; - break; + else + break; case WM_MBUTTONDOWN: case WM_MBUTTONUP: @@ -1746,7 +1785,7 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) mswindows_enqueue_mouse_button_event (hwnd, message, MAKEPOINTS (lParam), GetMessageTime()); break; - + case WM_LBUTTONUP: msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); msframe->last_click_time = GetMessageTime(); @@ -1868,7 +1907,7 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } msframe->last_click_time = GetMessageTime(); break; - + case WM_TIMER: if (wParam == BUTTON_2_TIMER_ID) { @@ -1917,7 +1956,7 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) event->event.motion.x = MAKEPOINTS(lParam).x; event->event.motion.y = MAKEPOINTS(lParam).y; event->event.motion.modifiers = mswindows_modifier_state (NULL, 0); - + mswindows_enqueue_dispatch_event (emacs_event); } break; @@ -1942,9 +1981,9 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* find out which toolbar */ frame = XFRAME (mswindows_find_frame (hwnd)); - btext = mswindows_get_toolbar_button_text ( frame, + btext = mswindows_get_toolbar_button_text ( frame, nmhdr->idFrom ); - + tttext->lpszText = NULL; tttext->hinst = NULL; @@ -1952,8 +1991,9 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { /* I think this is safe since the text will only go away when the toolbar does...*/ - GET_C_STRING_EXT_DATA_ALLOCA (btext, FORMAT_OS, - tttext->lpszText); + TO_EXTERNAL_FORMAT (LISP_STRING, btext, + C_STRING_ALLOCA, tttext->lpszText, + Qnative); } #endif } @@ -1968,27 +2008,49 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) else if (nmhdr->code == TCN_SELCHANGE) { TC_ITEM item; - int index = SendMessage (nmhdr->hwndFrom, TCM_GETCURSEL, 0, 0); + int idx = SendMessage (nmhdr->hwndFrom, TCM_GETCURSEL, 0, 0); frame = XFRAME (mswindows_find_frame (hwnd)); - SendMessage (nmhdr->hwndFrom, TCM_GETITEM, (WPARAM)index, + + item.mask = TCIF_PARAM; + SendMessage (nmhdr->hwndFrom, TCM_GETITEM, (WPARAM)idx, (LPARAM)&item); - + mswindows_handle_gui_wm_command (frame, 0, item.lParam); } } break; - + case WM_PAINT: { - PAINTSTRUCT paintStruct; - - frame = XFRAME (mswindows_find_frame (hwnd)); + /* According to the docs we need to check GetUpdateRect() before + actually doing a WM_PAINT */ + if (GetUpdateRect (hwnd, NULL, FALSE)) + { + PAINTSTRUCT paintStruct; + int x, y, width, height; - BeginPaint (hwnd, &paintStruct); - mswindows_redraw_exposed_area (frame, - paintStruct.rcPaint.left, paintStruct.rcPaint.top, - paintStruct.rcPaint.right, paintStruct.rcPaint.bottom); - EndPaint (hwnd, &paintStruct); + frame = XFRAME (mswindows_find_frame (hwnd)); + + BeginPaint (hwnd, &paintStruct); + x = paintStruct.rcPaint.left; + y = paintStruct.rcPaint.top; + width = paintStruct.rcPaint.right - paintStruct.rcPaint.left; + height = paintStruct.rcPaint.bottom - paintStruct.rcPaint.top; + /* Normally we want to ignore expose events when child + windows are unmapped, however once we are in the guts of + WM_PAINT we need to make sure that we don't register + unmaps then because they will not actually occur. */ + if (!check_for_ignored_expose (frame, x, y, width, height)) + { + hold_ignored_expose_registration = 1; + mswindows_redraw_exposed_area (frame, x, y, width, height); + hold_ignored_expose_registration = 0; + } + + EndPaint (hwnd, &paintStruct); + } + else + goto defproc; } break; @@ -2031,8 +2093,8 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (FRAME_MSWINDOWS_TARGET_RECT (frame)) { /* Yes, we have to size again */ - mswindows_size_frame_internal ( frame, - FRAME_MSWINDOWS_TARGET_RECT + mswindows_size_frame_internal ( frame, + FRAME_MSWINDOWS_TARGET_RECT (frame)); /* Reset so we do not get here again. The SetWindowPos call in * mswindows_size_frame_internal can cause recursion here. */ @@ -2047,7 +2109,7 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!msframe->sizing && !FRAME_VISIBLE_P (frame)) mswindows_enqueue_magic_event (hwnd, XM_MAPFRAME); FRAME_VISIBLE_P (frame) = 1; - + if (!msframe->sizing || mswindows_dynamic_frame_resize) redisplay (); } @@ -2138,7 +2200,24 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage (hwndScrollBar, WM_CANCELMODE, 0, 0); } UNGCPRO; - break; + break; + } + + case WM_MOUSEWHEEL: + { + int keys = LOWORD (wParam); /* Modifier key flags */ + int delta = (short) HIWORD (wParam); /* Wheel rotation amount */ + struct gcpro gcpro1, gcpro2; + + if (mswindows_handle_mousewheel_event (mswindows_find_frame (hwnd), keys, delta)) + { + GCPRO2 (emacs_event, fobj); + mswindows_pump_outstanding_events (); /* Can GC */ + UNGCPRO; + } + else + goto defproc; + break; } #endif @@ -2212,10 +2291,8 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) Lisp_Object image_instance; VOID_TO_LISP (image_instance, ii); if (IMAGE_INSTANCEP (image_instance) - && - IMAGE_INSTANCE_TYPE_P (image_instance, IMAGE_WIDGET) && - !NILP (XIMAGE_INSTANCE_WIDGET_FACE (image_instance))) + IMAGE_INSTANCE_TYPE_P (image_instance, IMAGE_WIDGET)) { /* set colors for the buttons */ HDC hdc = (HDC)wParam; @@ -2223,27 +2300,27 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if (widget_brush) DeleteObject (widget_brush); - widget_brush = CreateSolidBrush - (COLOR_INSTANCE_MSWINDOWS_COLOR - (XCOLOR_INSTANCE - (FACE_BACKGROUND + widget_brush = CreateSolidBrush + (COLOR_INSTANCE_MSWINDOWS_COLOR + (XCOLOR_INSTANCE + (FACE_BACKGROUND (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); } last_widget_brushed = ii; SetTextColor (hdc, - COLOR_INSTANCE_MSWINDOWS_COLOR - (XCOLOR_INSTANCE - (FACE_FOREGROUND + COLOR_INSTANCE_MSWINDOWS_COLOR + (XCOLOR_INSTANCE + (FACE_FOREGROUND (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); SetBkMode (hdc, OPAQUE); SetBkColor (hdc, - COLOR_INSTANCE_MSWINDOWS_COLOR - (XCOLOR_INSTANCE - (FACE_BACKGROUND + COLOR_INSTANCE_MSWINDOWS_COLOR + (XCOLOR_INSTANCE + (FACE_BACKGROUND (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); return (LRESULT)widget_brush; @@ -2415,67 +2492,100 @@ int mswindows_modifier_state (BYTE* keymap, int has_AltGr) * Only returns non-Qnil for keys that don't generate WM_CHAR messages * or whose ASCII codes (like space) xemacs doesn't like. * Virtual key values are defined in winresrc.h - * XXX I'm not sure that KEYSYM("name") is the best thing to use here. */ -Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods) +Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods, + int extendedp) { - switch (mswindows_key) - { - /* First the predefined ones */ - case VK_BACK: return QKbackspace; - case VK_TAB: return QKtab; - case '\n': return QKlinefeed; /* No VK_LINEFEED in winresrc.h */ - case VK_RETURN: return QKreturn; - case VK_ESCAPE: return QKescape; - case VK_SPACE: return QKspace; - case VK_DELETE: return QKdelete; - - /* The rest */ - case VK_CLEAR: return KEYSYM ("clear"); /* Should do ^L ? */ - case VK_PRIOR: return KEYSYM ("prior"); - case VK_NEXT: return KEYSYM ("next"); - case VK_END: return KEYSYM ("end"); - case VK_HOME: return KEYSYM ("home"); - case VK_LEFT: return KEYSYM ("left"); - case VK_UP: return KEYSYM ("up"); - case VK_RIGHT: return KEYSYM ("right"); - case VK_DOWN: return KEYSYM ("down"); - case VK_SELECT: return KEYSYM ("select"); - case VK_PRINT: return KEYSYM ("print"); - case VK_EXECUTE: return KEYSYM ("execute"); - case VK_SNAPSHOT: return KEYSYM ("print"); - case VK_INSERT: return KEYSYM ("insert"); - case VK_HELP: return KEYSYM ("help"); -#if 0 /* XXX What are these supposed to do? */ - case VK_LWIN return KEYSYM (""); - case VK_RWIN return KEYSYM (""); + if (extendedp) /* Keys not present on a 82 key keyboard */ + { + switch (mswindows_key) + { + case VK_RETURN: return KEYSYM ("kp-enter"); + case VK_PRIOR: return KEYSYM ("prior"); + case VK_NEXT: return KEYSYM ("next"); + case VK_END: return KEYSYM ("end"); + case VK_HOME: return KEYSYM ("home"); + case VK_LEFT: return KEYSYM ("left"); + case VK_UP: return KEYSYM ("up"); + case VK_RIGHT: return KEYSYM ("right"); + case VK_DOWN: return KEYSYM ("down"); + case VK_INSERT: return KEYSYM ("insert"); + case VK_DELETE: return QKdelete; + } + } + else + { + switch (mswindows_key) + { + case VK_BACK: return QKbackspace; + case VK_TAB: return QKtab; + case '\n': return QKlinefeed; + case VK_CLEAR: return KEYSYM ("clear"); + case VK_RETURN: return QKreturn; + case VK_ESCAPE: return QKescape; + case VK_SPACE: return QKspace; + case VK_PRIOR: return KEYSYM ("kp-prior"); + case VK_NEXT: return KEYSYM ("kp-next"); + case VK_END: return KEYSYM ("kp-end"); + case VK_HOME: return KEYSYM ("kp-home"); + case VK_LEFT: return KEYSYM ("kp-left"); + case VK_UP: return KEYSYM ("kp-up"); + case VK_RIGHT: return KEYSYM ("kp-right"); + case VK_DOWN: return KEYSYM ("kp-down"); + case VK_SELECT: return KEYSYM ("select"); + case VK_PRINT: return KEYSYM ("print"); + case VK_EXECUTE: return KEYSYM ("execute"); + case VK_SNAPSHOT: return KEYSYM ("print"); + case VK_INSERT: return KEYSYM ("kp-insert"); + case VK_DELETE: return KEYSYM ("kp-delete"); + case VK_HELP: return KEYSYM ("help"); +#if 0 /* FSF Emacs allows these to return configurable syms/mods */ + case VK_LWIN return KEYSYM (""); + case VK_RWIN return KEYSYM (""); #endif - case VK_APPS: return KEYSYM ("menu"); - case VK_F1: return KEYSYM ("f1"); - case VK_F2: return KEYSYM ("f2"); - case VK_F3: return KEYSYM ("f3"); - case VK_F4: return KEYSYM ("f4"); - case VK_F5: return KEYSYM ("f5"); - case VK_F6: return KEYSYM ("f6"); - case VK_F7: return KEYSYM ("f7"); - case VK_F8: return KEYSYM ("f8"); - case VK_F9: return KEYSYM ("f9"); - case VK_F10: return KEYSYM ("f10"); - case VK_F11: return KEYSYM ("f11"); - case VK_F12: return KEYSYM ("f12"); - case VK_F13: return KEYSYM ("f13"); - case VK_F14: return KEYSYM ("f14"); - case VK_F15: return KEYSYM ("f15"); - case VK_F16: return KEYSYM ("f16"); - case VK_F17: return KEYSYM ("f17"); - case VK_F18: return KEYSYM ("f18"); - case VK_F19: return KEYSYM ("f19"); - case VK_F20: return KEYSYM ("f20"); - case VK_F21: return KEYSYM ("f21"); - case VK_F22: return KEYSYM ("f22"); - case VK_F23: return KEYSYM ("f23"); - case VK_F24: return KEYSYM ("f24"); - } + case VK_APPS: return KEYSYM ("menu"); + case VK_NUMPAD0: return KEYSYM ("kp-0"); + case VK_NUMPAD1: return KEYSYM ("kp-1"); + case VK_NUMPAD2: return KEYSYM ("kp-2"); + case VK_NUMPAD3: return KEYSYM ("kp-3"); + case VK_NUMPAD4: return KEYSYM ("kp-4"); + case VK_NUMPAD5: return KEYSYM ("kp-5"); + case VK_NUMPAD6: return KEYSYM ("kp-6"); + case VK_NUMPAD7: return KEYSYM ("kp-7"); + case VK_NUMPAD8: return KEYSYM ("kp-8"); + case VK_NUMPAD9: return KEYSYM ("kp-9"); + case VK_MULTIPLY: return KEYSYM ("kp-multiply"); + case VK_ADD: return KEYSYM ("kp-add"); + case VK_SEPARATOR: return KEYSYM ("kp-separator"); + case VK_SUBTRACT: return KEYSYM ("kp-subtract"); + case VK_DECIMAL: return KEYSYM ("kp-decimal"); + case VK_DIVIDE: return KEYSYM ("kp-divide"); + case VK_F1: return KEYSYM ("f1"); + case VK_F2: return KEYSYM ("f2"); + case VK_F3: return KEYSYM ("f3"); + case VK_F4: return KEYSYM ("f4"); + case VK_F5: return KEYSYM ("f5"); + case VK_F6: return KEYSYM ("f6"); + case VK_F7: return KEYSYM ("f7"); + case VK_F8: return KEYSYM ("f8"); + case VK_F9: return KEYSYM ("f9"); + case VK_F10: return KEYSYM ("f10"); + case VK_F11: return KEYSYM ("f11"); + case VK_F12: return KEYSYM ("f12"); + case VK_F13: return KEYSYM ("f13"); + case VK_F14: return KEYSYM ("f14"); + case VK_F15: return KEYSYM ("f15"); + case VK_F16: return KEYSYM ("f16"); + case VK_F17: return KEYSYM ("f17"); + case VK_F18: return KEYSYM ("f18"); + case VK_F19: return KEYSYM ("f19"); + case VK_F20: return KEYSYM ("f20"); + case VK_F21: return KEYSYM ("f21"); + case VK_F22: return KEYSYM ("f22"); + case VK_F23: return KEYSYM ("f23"); + case VK_F24: return KEYSYM ("f24"); + } + } return Qnil; } @@ -2533,7 +2643,7 @@ emacs_mswindows_add_timeout (EMACS_TIME thyme) static void emacs_mswindows_remove_timeout (int id) { - struct Lisp_Event match_against; + Lisp_Event match_against; Lisp_Object emacs_event; if (KillTimer (NULL, id)) @@ -2569,7 +2679,7 @@ emacs_mswindows_event_pending_p (int user_p) * Return the next event */ static void -emacs_mswindows_next_event (struct Lisp_Event *emacs_event) +emacs_mswindows_next_event (Lisp_Event *emacs_event) { Lisp_Object event, event2; @@ -2585,13 +2695,13 @@ emacs_mswindows_next_event (struct Lisp_Event *emacs_event) * Handle a magic event off the dispatch queue. */ static void -emacs_mswindows_handle_magic_event (struct Lisp_Event *emacs_event) +emacs_mswindows_handle_magic_event (Lisp_Event *emacs_event) { switch (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event)) { case XM_BUMPQUEUE: break; - + case WM_SETFOCUS: case WM_KILLFOCUS: { @@ -2619,13 +2729,13 @@ emacs_mswindows_handle_magic_event (struct Lisp_Event *emacs_event) case XM_UNMAPFRAME: { Lisp_Object frame = EVENT_CHANNEL (emacs_event); - va_run_hook_with_args (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event) + va_run_hook_with_args (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event) == XM_MAPFRAME ? - Qmap_frame_hook : Qunmap_frame_hook, + Qmap_frame_hook : Qunmap_frame_hook, 1, frame); } break; - + /* #### What about Enter & Leave */ #if 0 va_run_hook_with_args (in_p ? Qmouse_enter_frame_hook : @@ -2639,7 +2749,7 @@ emacs_mswindows_handle_magic_event (struct Lisp_Event *emacs_event) #ifndef HAVE_MSG_SELECT static HANDLE -get_process_input_waitable (struct Lisp_Process *process) +get_process_input_waitable (Lisp_Process *process) { Lisp_Object instr, outstr, p; XSETPROCESS (p, process); @@ -2655,7 +2765,7 @@ get_process_input_waitable (struct Lisp_Process *process) } static void -emacs_mswindows_select_process (struct Lisp_Process *process) +emacs_mswindows_select_process (Lisp_Process *process) { HANDLE hev = get_process_input_waitable (process); @@ -2680,7 +2790,7 @@ emacs_mswindows_select_process (struct Lisp_Process *process) } static void -emacs_mswindows_unselect_process (struct Lisp_Process *process) +emacs_mswindows_unselect_process (Lisp_Process *process) { /* Process handle is removed in the event loop as soon as it is signaled, so don't bother here about it */ @@ -2714,38 +2824,37 @@ emacs_mswindows_unselect_console (struct console *con) static void emacs_mswindows_quit_p (void) { - MSG msg; - /* Quit cannot happen in modal loop: all program input is dedicated to Windows. */ if (mswindows_in_modal_loop) return; - /* Drain windows queue. This sets up number of quit characters in the queue - * (and also processes wm focus change, move, resize, etc messages). - * We don't want to process WM_PAINT messages because this function can be - * called from almost anywhere and the windows' states may be changing. */ - while (PeekMessage (&msg, NULL, 0, WM_PAINT-1, PM_REMOVE) || - PeekMessage (&msg, NULL, WM_PAINT+1, WM_USER-1, PM_REMOVE)) - DispatchMessage (&msg); + /* Drain windows queue. This sets up number of quit characters in + the queue */ + mswindows_drain_windows_queue (1); if (mswindows_quit_chars_count > 0) { /* Yes there's a hidden one... Throw it away */ - struct Lisp_Event match_against; + Lisp_Event match_against; Lisp_Object emacs_event; + int critical_p = 0; match_against.event_type = key_press_event; match_against.event.key.modifiers = FAKE_MOD_QUIT; - emacs_event = mswindows_cancel_dispatch_event (&match_against); - assert (!NILP (emacs_event)); + while (mswindows_quit_chars_count-- > 0) + { + emacs_event = mswindows_cancel_dispatch_event (&match_against); + assert (!NILP (emacs_event)); + + if (XEVENT(emacs_event)->event.key.modifiers & MOD_SHIFT) + critical_p = 1; - Vquit_flag = (XEVENT(emacs_event)->event.key.modifiers & MOD_SHIFT - ? Qcritical : Qt); + Fdeallocate_event(emacs_event); + } - Fdeallocate_event(emacs_event); - --mswindows_quit_chars_count; + Vquit_flag = critical_p ? Qcritical : Qt; } } @@ -2857,7 +2966,7 @@ emacs_mswindows_delete_stream_pair (Lisp_Object instream, If we've still got pointers to it in this file, we're gonna lose hard. */ void -debug_process_finalization (struct Lisp_Process *p) +debug_process_finalization (Lisp_Process *p) { #if 0 /* #### */ Lisp_Object instr, outstr; @@ -2875,20 +2984,10 @@ debug_process_finalization (struct Lisp_Process *p) /************************************************************************/ /* initialization */ /************************************************************************/ - + void -vars_of_event_mswindows (void) +reinit_vars_of_event_mswindows (void) { - mswindows_u_dispatch_event_queue = Qnil; - staticpro (&mswindows_u_dispatch_event_queue); - mswindows_u_dispatch_event_queue_tail = Qnil; - - mswindows_s_dispatch_event_queue = Qnil; - staticpro (&mswindows_s_dispatch_event_queue); - mswindows_s_dispatch_event_queue_tail = Qnil; - - mswindows_error_caught_in_modal_loop = Qnil; - staticpro (&mswindows_error_caught_in_modal_loop); mswindows_in_modal_loop = 0; mswindows_pending_timers_count = 0; @@ -2903,10 +3002,10 @@ vars_of_event_mswindows (void) mswindows_event_stream->select_console_cb = emacs_mswindows_select_console; mswindows_event_stream->unselect_console_cb = emacs_mswindows_unselect_console; #ifdef HAVE_MSG_SELECT - mswindows_event_stream->select_process_cb = - (void (*)(struct Lisp_Process*))event_stream_unixoid_select_process; - mswindows_event_stream->unselect_process_cb = - (void (*)(struct Lisp_Process*))event_stream_unixoid_unselect_process; + mswindows_event_stream->select_process_cb = + (void (*)(Lisp_Process*))event_stream_unixoid_select_process; + mswindows_event_stream->unselect_process_cb = + (void (*)(Lisp_Process*))event_stream_unixoid_unselect_process; mswindows_event_stream->create_stream_pair_cb = event_stream_unixoid_create_stream_pair; mswindows_event_stream->delete_stream_pair_cb = event_stream_unixoid_delete_stream_pair; #else @@ -2915,6 +3014,31 @@ vars_of_event_mswindows (void) mswindows_event_stream->create_stream_pair_cb = emacs_mswindows_create_stream_pair; mswindows_event_stream->delete_stream_pair_cb = emacs_mswindows_delete_stream_pair; #endif +} + +void +vars_of_event_mswindows (void) +{ + reinit_vars_of_event_mswindows (); + + mswindows_u_dispatch_event_queue = Qnil; + staticpro (&mswindows_u_dispatch_event_queue); + mswindows_u_dispatch_event_queue_tail = Qnil; + pdump_wire (&mswindows_u_dispatch_event_queue_tail); + + mswindows_s_dispatch_event_queue = Qnil; + staticpro (&mswindows_s_dispatch_event_queue); + mswindows_s_dispatch_event_queue_tail = Qnil; + pdump_wire (&mswindows_s_dispatch_event_queue_tail); + + mswindows_error_caught_in_modal_loop = Qnil; + staticpro (&mswindows_error_caught_in_modal_loop); + + DEFVAR_BOOL ("mswindows-meta-activates-menu", &mswindows_meta_activates_menu /* +*Controls whether pressing and releasing the Meta (Alt) key should +activate the menubar. +Default is t. +*/ ); DEFVAR_BOOL ("mswindows-dynamic-frame-resize", &mswindows_dynamic_frame_resize /* *Controls redrawing frame contents during mouse-drag or keyboard resize @@ -2960,6 +3084,7 @@ If negative or zero, currently set system default is used instead. mswindows_mouse_button_max_skew_x = 0; mswindows_mouse_button_max_skew_y = 0; mswindows_mouse_button_tolerance = 0; + mswindows_meta_activates_menu = 1; } void