X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fevent-msw.c;h=f3e77271f35f8239ee9aae95fff4157a04bfa002;hp=2a9b919b841bbdc8566f1ecfd1becca37f8c4af6;hb=afa9772e3fcbb4e80e3e4cfd1a40b4fccc6d08b8;hpb=1c97bf160520f9e0b193236a902eb4b73d59d134 diff --git a/src/event-msw.c b/src/event-msw.c index 2a9b919..f3e7727 100644 --- a/src/event-msw.c +++ b/src/event-msw.c @@ -73,11 +73,7 @@ typedef unsigned int SOCKET; #include #if defined (__CYGWIN32__) && !defined (CYGWIN_VERSION_DLL_MAJOR) -typedef struct tagNMHDR { - HWND hwndFrom; - UINT idFrom; - UINT code; -} NMHDR, *PNMHDR, *LPNMHDR; +typedef NMHDR *LPNMHDR; #endif #ifdef HAVE_MENUBARS @@ -93,7 +89,7 @@ typedef struct tagNMHDR { /* Timer ID used for button2 emulation */ #define BUTTON_2_TIMER_ID 1 -extern Lisp_Object +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); @@ -102,7 +98,8 @@ 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); @@ -148,6 +145,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; @@ -201,7 +199,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 @@ -273,7 +271,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. */ @@ -362,11 +360,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) @@ -375,7 +373,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); @@ -426,7 +424,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; @@ -435,11 +433,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 */ @@ -471,7 +469,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 */ @@ -498,7 +496,7 @@ shove_thread (LPVOID vparam) for (;;) { - DWORD bytes_written; + DWORD bytes_written; /* Block on event and wait for a job */ InterlockedIncrement (&s->idle_p); @@ -535,7 +533,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); @@ -564,7 +562,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); @@ -673,7 +671,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); @@ -706,7 +704,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); @@ -719,7 +717,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); @@ -747,7 +745,7 @@ winsock_writer (Lstream *stream, CONST unsigned char *data, size_t size) if (size == 0) return 0; - + { ResetEvent (str->ov.hEvent); @@ -869,7 +867,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 @@ -877,7 +875,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); @@ -955,7 +953,7 @@ mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWO 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) { @@ -974,7 +972,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); } @@ -1006,10 +1004,10 @@ mswindows_dequeue_dispatch_event () !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); @@ -1039,9 +1037,9 @@ mswindows_cancel_dispatch_event (struct 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 @@ -1064,7 +1062,7 @@ mswindows_cancel_dispatch_event (struct Lisp_Event *match) if (EQ (*tail, event)) *tail = previous_event; } - + return event; } previous_event = event; @@ -1105,7 +1103,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 */ @@ -1129,7 +1127,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); @@ -1153,7 +1151,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 @@ -1177,7 +1175,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; @@ -1225,14 +1223,14 @@ 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 +static void mswindows_drain_windows_queue () { MSG msg; @@ -1251,7 +1249,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 @@ -1284,7 +1282,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); @@ -1321,7 +1319,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 @@ -1332,7 +1330,7 @@ mswindows_need_event (int badly_p) } active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this); - + if (active == 0) { assert (!badly_p); @@ -1344,7 +1342,7 @@ mswindows_need_event (int badly_p) { mswindows_drain_windows_queue (); } -#ifdef HAVE_TTY +#ifdef HAVE_TTY /* Look for a TTY event */ for (i = 0; i < MAXDESC-1; i++) { @@ -1356,7 +1354,7 @@ 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); - + assert (c); if (read_event_from_tty_or_stream_desc (event, c, i)) { @@ -1375,7 +1373,7 @@ mswindows_need_event (int badly_p) { struct Lisp_Process *p = get_process_from_usid (FD_TO_USID(i)); - + mswindows_enqueue_process_event (p); } else @@ -1414,7 +1412,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 */ @@ -1429,7 +1427,7 @@ mswindows_need_event (int badly_p) { int ix = active - WAIT_OBJECT_0; /* First, try to find which process' output has signaled */ - struct Lisp_Process *p = + struct Lisp_Process *p = get_process_from_usid (HANDLE_TO_USID (mswindows_waitable_handles[ix])); if (p != NULL) { @@ -1457,7 +1455,7 @@ mswindows_need_event (int badly_p) /* Event generators */ /************************************************************************/ -/* +/* * Callback procedure for synchronous timer messages */ static void CALLBACK @@ -1479,7 +1477,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 @@ -1490,9 +1488,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; @@ -1509,7 +1507,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)) @@ -1590,12 +1588,12 @@ 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 @@ -1663,21 +1661,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; @@ -1689,9 +1689,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); @@ -1738,7 +1738,7 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } /* else */ } /* F10 causes menu activation by default. We do not want this */ - if (wParam != VK_F10) + if (wParam != VK_F10 && (mswindows_meta_activates_menu || wParam != VK_MENU)) goto defproc; break; @@ -1750,7 +1750,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(); @@ -1872,7 +1872,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) { @@ -1921,7 +1921,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; @@ -1946,9 +1946,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; @@ -1956,7 +1956,7 @@ 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, + GET_C_STRING_EXT_DATA_ALLOCA (btext, FORMAT_OS, tttext->lpszText); } #endif @@ -1974,25 +1974,47 @@ mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TC_ITEM item; int index = SendMessage (nmhdr->hwndFrom, TCM_GETCURSEL, 0, 0); frame = XFRAME (mswindows_find_frame (hwnd)); + + item.mask = TCIF_PARAM; SendMessage (nmhdr->hwndFrom, TCM_GETITEM, (WPARAM)index, (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; + + 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; + } - BeginPaint (hwnd, &paintStruct); - mswindows_redraw_exposed_area (frame, - paintStruct.rcPaint.left, paintStruct.rcPaint.top, - paintStruct.rcPaint.right, paintStruct.rcPaint.bottom); - EndPaint (hwnd, &paintStruct); + EndPaint (hwnd, &paintStruct); + } + else + goto defproc; } break; @@ -2035,8 +2057,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. */ @@ -2051,7 +2073,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 (); } @@ -2142,7 +2164,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 @@ -2216,7 +2255,7 @@ 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))) @@ -2227,27 +2266,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; @@ -2419,67 +2458,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; } @@ -2595,7 +2667,7 @@ emacs_mswindows_handle_magic_event (struct Lisp_Event *emacs_event) { case XM_BUMPQUEUE: break; - + case WM_SETFOCUS: case WM_KILLFOCUS: { @@ -2623,13 +2695,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 : @@ -2879,20 +2951,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; @@ -2907,9 +2969,9 @@ 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 = + mswindows_event_stream->select_process_cb = (void (*)(struct Lisp_Process*))event_stream_unixoid_select_process; - mswindows_event_stream->unselect_process_cb = + mswindows_event_stream->unselect_process_cb = (void (*)(struct 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; @@ -2919,6 +2981,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_u_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 @@ -2964,6 +3051,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