Mercurial > hg > xemacs-beta
comparison src/event-msw.c @ 384:bbff43aa5eb7 r21-2-7
Import from CVS: tag r21-2-7
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:08:24 +0200 |
parents | 064ab7fed2e0 |
children | aabb7f5b1c81 |
comparison
equal
deleted
inserted
replaced
383:6a50c6a581a5 | 384:bbff43aa5eb7 |
---|---|
26 /* Authorship: | 26 /* Authorship: |
27 | 27 |
28 Ultimately based on FSF. | 28 Ultimately based on FSF. |
29 Rewritten by Ben Wing. | 29 Rewritten by Ben Wing. |
30 Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0. | 30 Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0. |
31 Subprocess and modal loop support by Kirill M. Katsnelson. | |
31 */ | 32 */ |
32 | 33 |
33 #include <config.h> | 34 #include <config.h> |
34 #include "lisp.h" | 35 #include "lisp.h" |
35 | 36 |
48 #endif | 49 #endif |
49 | 50 |
50 #include "device.h" | 51 #include "device.h" |
51 #include "events.h" | 52 #include "events.h" |
52 #include "frame.h" | 53 #include "frame.h" |
54 #include "buffer.h" | |
55 #include "faces.h" | |
53 #include "lstream.h" | 56 #include "lstream.h" |
54 #include "process.h" | 57 #include "process.h" |
55 #include "redisplay.h" | 58 #include "redisplay.h" |
56 #include "sysproc.h" | 59 #include "sysproc.h" |
57 #include "syswait.h" | 60 #include "syswait.h" |
58 #include "systime.h" | 61 #include "systime.h" |
59 #include "sysdep.h" | 62 #include "sysdep.h" |
63 #include "objects-msw.h" | |
60 | 64 |
61 #include "events-mod.h" | 65 #include "events-mod.h" |
62 #ifdef HAVE_MSG_SELECT | 66 #ifdef HAVE_MSG_SELECT |
63 #include "sysfile.h" | 67 #include "sysfile.h" |
64 #elif defined(__CYGWIN32__) | 68 #elif defined(__CYGWIN32__) |
82 | 86 |
83 extern Lisp_Object | 87 extern Lisp_Object |
84 mswindows_get_toolbar_button_text (struct frame* f, int command_id); | 88 mswindows_get_toolbar_button_text (struct frame* f, int command_id); |
85 extern Lisp_Object | 89 extern Lisp_Object |
86 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id); | 90 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id); |
91 extern Lisp_Object | |
92 mswindows_handle_gui_wm_command (struct frame* f, HWND ctrl, WORD id); | |
87 | 93 |
88 static Lisp_Object mswindows_find_frame (HWND hwnd); | 94 static Lisp_Object mswindows_find_frame (HWND hwnd); |
89 static Lisp_Object mswindows_find_console (HWND hwnd); | 95 static Lisp_Object mswindows_find_console (HWND hwnd); |
90 static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods); | 96 static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods); |
91 static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); | 97 static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); |
116 #define MAX_WAITABLE (MAXIMUM_WAIT_OBJECTS - 1) | 122 #define MAX_WAITABLE (MAXIMUM_WAIT_OBJECTS - 1) |
117 | 123 |
118 /* List of mswindows waitable handles. */ | 124 /* List of mswindows waitable handles. */ |
119 static HANDLE mswindows_waitable_handles[MAX_WAITABLE]; | 125 static HANDLE mswindows_waitable_handles[MAX_WAITABLE]; |
120 | 126 |
127 #ifndef HAVE_MSG_SELECT | |
121 /* Number of wait handles */ | 128 /* Number of wait handles */ |
122 static int mswindows_waitable_count=0; | 129 static int mswindows_waitable_count=0; |
130 #endif /* HAVE_MSG_SELECT */ | |
131 /* Brush for painting widgets */ | |
132 static HBRUSH widget_brush = 0; | |
133 static LONG last_widget_brushed = 0; | |
123 | 134 |
124 /* Count of quit chars currently in the queue */ | 135 /* Count of quit chars currently in the queue */ |
125 /* Incremented in WM_[SYS]KEYDOWN handler in the mswindows_wnd_proc() | 136 /* Incremented in WM_[SYS]KEYDOWN handler in the mswindows_wnd_proc() |
126 Decremented in mswindows_dequeue_dispatch_event() */ | 137 Decremented in mswindows_dequeue_dispatch_event() */ |
127 int mswindows_quit_chars_count = 0; | 138 int mswindows_quit_chars_count = 0; |
468 }; | 479 }; |
469 | 480 |
470 DEFINE_LSTREAM_IMPLEMENTATION ("ntpipe-output", lstream_ntpipe_shove, | 481 DEFINE_LSTREAM_IMPLEMENTATION ("ntpipe-output", lstream_ntpipe_shove, |
471 sizeof (struct ntpipe_shove_stream)); | 482 sizeof (struct ntpipe_shove_stream)); |
472 | 483 |
484 #ifndef HAVE_MSG_SELECT | |
473 static DWORD WINAPI | 485 static DWORD WINAPI |
474 shove_thread (LPVOID vparam) | 486 shove_thread (LPVOID vparam) |
475 { | 487 { |
476 struct ntpipe_shove_stream *s = (struct ntpipe_shove_stream*) vparam; | 488 struct ntpipe_shove_stream *s = (struct ntpipe_shove_stream*) vparam; |
477 | 489 |
539 get_ntpipe_output_stream_param (Lstream *stream) | 551 get_ntpipe_output_stream_param (Lstream *stream) |
540 { | 552 { |
541 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); | 553 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); |
542 return s->user_data; | 554 return s->user_data; |
543 } | 555 } |
556 #endif | |
544 | 557 |
545 static int | 558 static int |
546 ntpipe_shove_writer (Lstream *stream, const unsigned char *data, size_t size) | 559 ntpipe_shove_writer (Lstream *stream, const unsigned char *data, size_t size) |
547 { | 560 { |
548 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); | 561 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); |
937 if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN || | 950 if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN || |
938 message==WM_RBUTTONDOWN) | 951 message==WM_RBUTTONDOWN) |
939 { | 952 { |
940 event->event_type = button_press_event; | 953 event->event_type = button_press_event; |
941 SetCapture (hwnd); | 954 SetCapture (hwnd); |
955 /* we need this to make sure the main window regains the focus | |
956 from control subwindows */ | |
957 if (GetFocus() != hwnd) | |
958 { | |
959 SetFocus (hwnd); | |
960 mswindows_enqueue_magic_event (hwnd, WM_SETFOCUS); | |
961 } | |
942 } | 962 } |
943 else | 963 else |
944 { | 964 { |
945 event->event_type = button_release_event; | 965 event->event_type = button_release_event; |
946 ReleaseCapture (); | 966 ReleaseCapture (); |
995 return event; | 1015 return event; |
996 } | 1016 } |
997 | 1017 |
998 /* | 1018 /* |
999 * Remove and return the first emacs event on the dispatch queue that matches | 1019 * Remove and return the first emacs event on the dispatch queue that matches |
1000 * the supplied event | 1020 * the supplied event. |
1001 * Timeout event matches if interval_id equals to that of the given event. | 1021 * Timeout event matches if interval_id is equal to that of the given event. |
1002 * Keypress event matches if logical AND between modifiers bitmask of the | 1022 * Keypress event matches if logical AND between modifiers bitmask of the |
1003 * event in the queue and that of the given event is non-zero | 1023 * event in the queue and that of the given event is non-zero. |
1004 * For all other event types, this function asserts. | 1024 * For all other event types, this function aborts. |
1005 */ | 1025 */ |
1006 | 1026 |
1007 Lisp_Object | 1027 Lisp_Object |
1008 mswindows_cancel_dispatch_event (struct Lisp_Event* match) | 1028 mswindows_cancel_dispatch_event (struct Lisp_Event *match) |
1009 { | 1029 { |
1010 Lisp_Object event; | 1030 Lisp_Object event; |
1011 Lisp_Object previous_event=Qnil; | 1031 Lisp_Object previous_event = Qnil; |
1012 int user_p = mswindows_user_event_p (match); | 1032 int user_p = mswindows_user_event_p (match); |
1013 Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue : | 1033 Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue : |
1014 &mswindows_s_dispatch_event_queue; | 1034 &mswindows_s_dispatch_event_queue; |
1015 Lisp_Object* tail = user_p ? &mswindows_u_dispatch_event_queue_tail : | 1035 Lisp_Object* tail = user_p ? &mswindows_u_dispatch_event_queue_tail : |
1016 &mswindows_s_dispatch_event_queue_tail; | 1036 &mswindows_s_dispatch_event_queue_tail; |
1018 assert (match->event_type == timeout_event | 1038 assert (match->event_type == timeout_event |
1019 || match->event_type == key_press_event); | 1039 || match->event_type == key_press_event); |
1020 | 1040 |
1021 EVENT_CHAIN_LOOP (event, *head) | 1041 EVENT_CHAIN_LOOP (event, *head) |
1022 { | 1042 { |
1023 int found = 1; | 1043 struct Lisp_Event *e = XEVENT (event); |
1024 if (XEVENT_TYPE (event) != match->event_type) | 1044 if ((e->event_type == match->event_type) && |
1025 found = 0; | 1045 ((e->event_type == timeout_event) ? |
1026 if (found && match->event_type == timeout_event | 1046 (e->event.timeout.interval_id == match->event.timeout.interval_id) : |
1027 && (XEVENT(event)->event.timeout.interval_id != | 1047 /* Must be key_press_event */ |
1028 match->event.timeout.interval_id)) | 1048 ((e->event.key.modifiers & match->event.key.modifiers) != 0))) |
1029 found = 0; | |
1030 if (found && match->event_type == key_press_event | |
1031 && ((XEVENT(event)->event.key.modifiers & | |
1032 match->event.key.modifiers) == 0)) | |
1033 found = 0; | |
1034 | |
1035 if (found) | |
1036 { | 1049 { |
1037 if (NILP (previous_event)) | 1050 if (NILP (previous_event)) |
1038 dequeue_event (head, tail); | 1051 dequeue_event (head, tail); |
1039 else | 1052 else |
1040 { | 1053 { |
1048 previous_event = event; | 1061 previous_event = event; |
1049 } | 1062 } |
1050 return Qnil; | 1063 return Qnil; |
1051 } | 1064 } |
1052 | 1065 |
1066 #ifndef HAVE_MSG_SELECT | |
1053 /************************************************************************/ | 1067 /************************************************************************/ |
1054 /* Waitable handles manipulation */ | 1068 /* Waitable handles manipulation */ |
1055 /************************************************************************/ | 1069 /************************************************************************/ |
1056 static int | 1070 static int |
1057 find_waitable_handle (HANDLE h) | 1071 find_waitable_handle (HANDLE h) |
1083 return; | 1097 return; |
1084 | 1098 |
1085 mswindows_waitable_handles [ix] = | 1099 mswindows_waitable_handles [ix] = |
1086 mswindows_waitable_handles [--mswindows_waitable_count]; | 1100 mswindows_waitable_handles [--mswindows_waitable_count]; |
1087 } | 1101 } |
1102 #endif /* HAVE_MSG_SELECT */ | |
1088 | 1103 |
1089 | 1104 |
1090 /************************************************************************/ | 1105 /************************************************************************/ |
1091 /* Event pump */ | 1106 /* Event pump */ |
1092 /************************************************************************/ | 1107 /************************************************************************/ |
1212 mswindows_drain_windows_queue () | 1227 mswindows_drain_windows_queue () |
1213 { | 1228 { |
1214 MSG msg; | 1229 MSG msg; |
1215 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) | 1230 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) |
1216 { | 1231 { |
1232 /* we have to translate messages that are not sent to the main | |
1233 window. this is so that key presses work ok in things like | |
1234 edit fields. however, we *musn't* translate message for the | |
1235 main window as this is handled in the wnd proc. */ | |
1236 if ( GetWindowLong (msg.hwnd, GWL_STYLE) & WS_CHILD ) | |
1237 { | |
1238 TranslateMessage (&msg); | |
1239 } | |
1217 DispatchMessage (&msg); | 1240 DispatchMessage (&msg); |
1218 mswindows_unmodalize_signal_maybe (); | 1241 mswindows_unmodalize_signal_maybe (); |
1219 } | 1242 } |
1220 } | 1243 } |
1221 | 1244 |
1646 mswindows_enqueue_keypress_event (hwnd, keysym, mods); | 1669 mswindows_enqueue_keypress_event (hwnd, keysym, mods); |
1647 else | 1670 else |
1648 { | 1671 { |
1649 int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); | 1672 int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); |
1650 BYTE keymap_orig[256]; | 1673 BYTE keymap_orig[256]; |
1651 MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) }; | 1674 POINT pnt = { LOWORD (GetMessagePos()), HIWORD (GetMessagePos()) }; |
1675 MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), pnt }; | |
1652 | 1676 |
1653 /* GetKeyboardState() does not work as documented on Win95. We have | 1677 /* GetKeyboardState() does not work as documented on Win95. We have |
1654 * to loosely track Left and Right modifiers on behalf of the OS, | 1678 * to loosely track Left and Right modifiers on behalf of the OS, |
1655 * without screwing up Windows NT which tracks them properly. */ | 1679 * without screwing up Windows NT which tracks them properly. */ |
1656 if (wParam == VK_CONTROL) | 1680 if (wParam == VK_CONTROL) |
1916 | 1940 |
1917 if (!NILP(btext)) | 1941 if (!NILP(btext)) |
1918 { | 1942 { |
1919 /* I think this is safe since the text will only go away | 1943 /* I think this is safe since the text will only go away |
1920 when the toolbar does...*/ | 1944 when the toolbar does...*/ |
1921 tttext->lpszText=XSTRING_DATA (btext); | 1945 GET_C_STRING_EXT_DATA_ALLOCA (btext, FORMAT_OS, |
1946 tttext->lpszText); | |
1922 } | 1947 } |
1923 #if 0 | 1948 #if 0 |
1924 tttext->uFlags |= TTF_DI_SETITEM; | 1949 tttext->uFlags |= TTF_DI_SETITEM; |
1925 #endif | 1950 #endif |
1926 } | 1951 } |
2113 #endif /* HAVE_MENUBARS */ | 2138 #endif /* HAVE_MENUBARS */ |
2114 | 2139 |
2115 case WM_COMMAND: | 2140 case WM_COMMAND: |
2116 { | 2141 { |
2117 WORD id = LOWORD (wParam); | 2142 WORD id = LOWORD (wParam); |
2143 WORD nid = HIWORD (wParam); | |
2118 HWND cid = (HWND)lParam; | 2144 HWND cid = (HWND)lParam; |
2119 frame = XFRAME (mswindows_find_frame (hwnd)); | 2145 frame = XFRAME (mswindows_find_frame (hwnd)); |
2120 | 2146 |
2121 #ifdef HAVE_TOOLBARS | 2147 #ifdef HAVE_TOOLBARS |
2122 if (!NILP (mswindows_handle_toolbar_wm_command (frame, cid, id))) | 2148 if (!NILP (mswindows_handle_toolbar_wm_command (frame, cid, id))) |
2123 break; | 2149 break; |
2124 #endif | 2150 #endif |
2125 | 2151 /* widgets in a buffer only eval a callback for suitable events.*/ |
2152 switch (nid) | |
2153 { | |
2154 case BN_CLICKED: | |
2155 case EN_CHANGE: | |
2156 case CBN_EDITCHANGE: | |
2157 case CBN_SELCHANGE: | |
2158 if (!NILP (mswindows_handle_gui_wm_command (frame, cid, id))) | |
2159 return 0; | |
2160 default: /* do nothing */ | |
2161 } | |
2162 /* menubars always must come last since the hashtables do not | |
2163 always exist*/ | |
2126 #ifdef HAVE_MENUBARS | 2164 #ifdef HAVE_MENUBARS |
2127 if (!NILP (mswindows_handle_wm_command (frame, id))) | 2165 if (!NILP (mswindows_handle_wm_command (frame, id))) |
2128 break; | 2166 break; |
2129 #endif | 2167 #endif |
2130 | 2168 |
2131 /* Bite me - a spurious command. This cannot happen. */ | 2169 return DefWindowProc (hwnd, message, wParam, lParam); |
2132 error ("XEMACS BUG: Cannot decode command message"); | 2170 /* Bite me - a spurious command. This used to not be able to |
2171 happen but with the introduction of widgets its now | |
2172 possible. */ | |
2133 } | 2173 } |
2134 break; | 2174 break; |
2175 | |
2176 case WM_CTLCOLORBTN: | |
2177 case WM_CTLCOLORLISTBOX: | |
2178 case WM_CTLCOLOREDIT: | |
2179 case WM_CTLCOLORSTATIC: | |
2180 case WM_CTLCOLORSCROLLBAR: | |
2181 { | |
2182 /* if we get an opportunity to paint a widget then do so if | |
2183 there is an appropriate face */ | |
2184 HWND crtlwnd = (HWND)lParam; | |
2185 LONG ii = GetWindowLong (crtlwnd, GWL_USERDATA); | |
2186 if (ii) | |
2187 { | |
2188 Lisp_Object image_instance; | |
2189 VOID_TO_LISP (image_instance, ii); | |
2190 if (IMAGE_INSTANCEP (image_instance) | |
2191 && | |
2192 IMAGE_INSTANCE_TYPE_P (image_instance, IMAGE_WIDGET) | |
2193 && | |
2194 !NILP (XIMAGE_INSTANCE_WIDGET_FACE (image_instance))) | |
2195 { | |
2196 /* set colors for the buttons */ | |
2197 HDC hdc = (HDC)wParam; | |
2198 if (last_widget_brushed != ii) | |
2199 { | |
2200 if (widget_brush) | |
2201 DeleteObject (widget_brush); | |
2202 widget_brush = CreateSolidBrush | |
2203 (COLOR_INSTANCE_MSWINDOWS_COLOR | |
2204 (XCOLOR_INSTANCE | |
2205 (FACE_BACKGROUND | |
2206 (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | |
2207 XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); | |
2208 } | |
2209 last_widget_brushed = ii; | |
2210 SetTextColor | |
2211 (hdc, | |
2212 COLOR_INSTANCE_MSWINDOWS_COLOR | |
2213 (XCOLOR_INSTANCE | |
2214 (FACE_FOREGROUND | |
2215 (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | |
2216 XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); | |
2217 SetBkMode (hdc, OPAQUE); | |
2218 SetBkColor | |
2219 (hdc, | |
2220 COLOR_INSTANCE_MSWINDOWS_COLOR | |
2221 (XCOLOR_INSTANCE | |
2222 (FACE_BACKGROUND | |
2223 (XIMAGE_INSTANCE_WIDGET_FACE (image_instance), | |
2224 XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance))))); | |
2225 return (LRESULT)widget_brush; | |
2226 } | |
2227 } | |
2228 } | |
2229 goto defproc; | |
2135 | 2230 |
2136 #ifdef HAVE_DRAGNDROP | 2231 #ifdef HAVE_DRAGNDROP |
2137 case WM_DROPFILES: /* implementation ripped-off from event-Xt.c */ | 2232 case WM_DROPFILES: /* implementation ripped-off from event-Xt.c */ |
2138 { | 2233 { |
2139 UINT filecount, i, len; | 2234 UINT filecount, i, len; |
2516 default: | 2611 default: |
2517 assert(0); | 2612 assert(0); |
2518 } | 2613 } |
2519 } | 2614 } |
2520 | 2615 |
2616 #ifndef HAVE_MSG_SELECT | |
2521 static HANDLE | 2617 static HANDLE |
2522 get_process_input_waitable (struct Lisp_Process *process) | 2618 get_process_input_waitable (struct Lisp_Process *process) |
2523 { | 2619 { |
2524 Lisp_Object instr, outstr, p; | 2620 Lisp_Object instr, outstr, p; |
2525 XSETPROCESS (p, process); | 2621 XSETPROCESS (p, process); |
2565 /* Process handle is removed in the event loop as soon | 2661 /* Process handle is removed in the event loop as soon |
2566 as it is signaled, so don't bother here about it */ | 2662 as it is signaled, so don't bother here about it */ |
2567 HANDLE hev = get_process_input_waitable (process); | 2663 HANDLE hev = get_process_input_waitable (process); |
2568 remove_waitable_handle (hev); | 2664 remove_waitable_handle (hev); |
2569 } | 2665 } |
2666 #endif /* HAVE_MSG_SELECT */ | |
2570 | 2667 |
2571 static void | 2668 static void |
2572 emacs_mswindows_select_console (struct console *con) | 2669 emacs_mswindows_select_console (struct console *con) |
2573 { | 2670 { |
2574 } | 2671 } |
2579 } | 2676 } |
2580 | 2677 |
2581 static void | 2678 static void |
2582 emacs_mswindows_quit_p (void) | 2679 emacs_mswindows_quit_p (void) |
2583 { | 2680 { |
2681 MSG msg; | |
2682 | |
2584 /* Quit cannot happen in modal loop: all program | 2683 /* Quit cannot happen in modal loop: all program |
2585 input is dedicated to Windows. */ | 2684 input is dedicated to Windows. */ |
2586 if (mswindows_in_modal_loop) | 2685 if (mswindows_in_modal_loop) |
2587 return; | 2686 return; |
2588 | 2687 |
2589 /* Drain windows queue. This sets up number of quit | 2688 /* Drain windows queue. This sets up number of quit characters in the queue |
2590 characters in in the queue */ | 2689 * (and also processes wm focus change, move, resize, etc messages). |
2591 mswindows_drain_windows_queue (); | 2690 * We don't want to process WM_PAINT messages because this function can be |
2691 * called from almost anywhere and the windows' states may be changing. */ | |
2692 while (PeekMessage (&msg, NULL, 0, WM_PAINT-1, PM_REMOVE) || | |
2693 PeekMessage (&msg, NULL, WM_PAINT+1, WM_USER-1, PM_REMOVE)) | |
2694 DispatchMessage (&msg); | |
2592 | 2695 |
2593 if (mswindows_quit_chars_count > 0) | 2696 if (mswindows_quit_chars_count > 0) |
2594 { | 2697 { |
2595 /* Yes there's a hidden one... Throw it away */ | 2698 /* Yes there's a hidden one... Throw it away */ |
2596 struct Lisp_Event match_against; | 2699 struct Lisp_Event match_against; |