Mercurial > hg > xemacs-beta
comparison src/event-msw.c @ 440:8de8e3f6228a r21-2-28
Import from CVS: tag r21-2-28
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:33:38 +0200 |
parents | 84b14dcb0985 |
children | abe6d1db359e |
comparison
equal
deleted
inserted
replaced
439:357dd071b03c | 440:8de8e3f6228a |
---|---|
88 #define FAKE_MOD_QUIT 0x80 | 88 #define FAKE_MOD_QUIT 0x80 |
89 | 89 |
90 /* Timer ID used for button2 emulation */ | 90 /* Timer ID used for button2 emulation */ |
91 #define BUTTON_2_TIMER_ID 1 | 91 #define BUTTON_2_TIMER_ID 1 |
92 | 92 |
93 extern Lisp_Object | |
94 mswindows_get_toolbar_button_text (struct frame* f, int command_id); | |
95 extern Lisp_Object | |
96 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id); | |
97 extern Lisp_Object | |
98 mswindows_handle_gui_wm_command (struct frame* f, HWND ctrl, WORD id); | |
99 | |
100 static Lisp_Object mswindows_find_frame (HWND hwnd); | 93 static Lisp_Object mswindows_find_frame (HWND hwnd); |
101 static Lisp_Object mswindows_find_console (HWND hwnd); | 94 static Lisp_Object mswindows_find_console (HWND hwnd); |
102 static Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods, | 95 static Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods, |
103 int extendedp); | 96 int extendedp); |
104 static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); | 97 static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); |
858 /************************************************************************/ | 851 /************************************************************************/ |
859 /* Dispatch queue management */ | 852 /* Dispatch queue management */ |
860 /************************************************************************/ | 853 /************************************************************************/ |
861 | 854 |
862 static int | 855 static int |
863 mswindows_user_event_p (struct Lisp_Event* sevt) | 856 mswindows_user_event_p (Lisp_Event* sevt) |
864 { | 857 { |
865 return (sevt->event_type == key_press_event | 858 return (sevt->event_type == key_press_event |
866 || sevt->event_type == button_press_event | 859 || sevt->event_type == button_press_event |
867 || sevt->event_type == button_release_event | 860 || sevt->event_type == button_release_event |
868 || sevt->event_type == misc_user_event); | 861 || sevt->event_type == misc_user_event); |
894 void | 887 void |
895 mswindows_enqueue_misc_user_event (Lisp_Object channel, Lisp_Object function, | 888 mswindows_enqueue_misc_user_event (Lisp_Object channel, Lisp_Object function, |
896 Lisp_Object object) | 889 Lisp_Object object) |
897 { | 890 { |
898 Lisp_Object event = Fmake_event (Qnil, Qnil); | 891 Lisp_Object event = Fmake_event (Qnil, Qnil); |
899 struct Lisp_Event* e = XEVENT (event); | 892 Lisp_Event* e = XEVENT (event); |
900 | 893 |
901 e->event_type = misc_user_event; | 894 e->event_type = misc_user_event; |
902 e->channel = channel; | 895 e->channel = channel; |
896 e->timestamp = GetTickCount (); | |
903 e->event.misc.function = function; | 897 e->event.misc.function = function; |
904 e->event.misc.object = object; | 898 e->event.misc.object = object; |
905 | 899 |
906 mswindows_enqueue_dispatch_event (event); | 900 mswindows_enqueue_dispatch_event (event); |
907 } | 901 } |
908 | 902 |
909 void | 903 void |
910 mswindows_enqueue_magic_event (HWND hwnd, UINT message) | 904 mswindows_enqueue_magic_event (HWND hwnd, UINT msg) |
911 { | 905 { |
912 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 906 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
913 struct Lisp_Event* event = XEVENT (emacs_event); | 907 Lisp_Event* event = XEVENT (emacs_event); |
914 | 908 |
915 event->channel = hwnd ? mswindows_find_frame (hwnd) : Qnil; | 909 event->channel = hwnd ? mswindows_find_frame (hwnd) : Qnil; |
916 event->timestamp = GetMessageTime(); | 910 event->timestamp = GetMessageTime(); |
917 event->event_type = magic_event; | 911 event->event_type = magic_event; |
918 EVENT_MSWINDOWS_MAGIC_TYPE (event) = message; | 912 EVENT_MSWINDOWS_MAGIC_TYPE (event) = msg; |
919 | 913 |
920 mswindows_enqueue_dispatch_event (emacs_event); | 914 mswindows_enqueue_dispatch_event (emacs_event); |
921 } | 915 } |
922 | 916 |
923 static void | 917 static void |
924 mswindows_enqueue_process_event (struct Lisp_Process* p) | 918 mswindows_enqueue_process_event (Lisp_Process* p) |
925 { | 919 { |
926 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 920 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
927 struct Lisp_Event* event = XEVENT (emacs_event); | 921 Lisp_Event* event = XEVENT (emacs_event); |
928 Lisp_Object process; | 922 Lisp_Object process; |
929 XSETPROCESS (process, p); | 923 XSETPROCESS (process, p); |
930 | 924 |
931 event->event_type = process_event; | 925 event->event_type = process_event; |
932 event->timestamp = GetTickCount (); | 926 event->timestamp = GetTickCount (); |
934 | 928 |
935 mswindows_enqueue_dispatch_event (emacs_event); | 929 mswindows_enqueue_dispatch_event (emacs_event); |
936 } | 930 } |
937 | 931 |
938 static void | 932 static void |
939 mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWORD when) | 933 mswindows_enqueue_mouse_button_event (HWND hwnd, UINT msg, POINTS where, DWORD when) |
940 { | 934 { |
941 | 935 |
942 /* We always use last message time, because mouse button | 936 /* We always use last message time, because mouse button |
943 events may get delayed, and XEmacs double click | 937 events may get delayed, and XEmacs double click |
944 recognition will fail */ | 938 recognition will fail */ |
945 | 939 |
946 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 940 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
947 struct Lisp_Event* event = XEVENT(emacs_event); | 941 Lisp_Event* event = XEVENT(emacs_event); |
948 | 942 |
949 event->channel = mswindows_find_frame(hwnd); | 943 event->channel = mswindows_find_frame(hwnd); |
950 event->timestamp = when; | 944 event->timestamp = when; |
951 event->event.button.button = | 945 event->event.button.button = |
952 (message==WM_LBUTTONDOWN || message==WM_LBUTTONUP) ? 1 : | 946 (msg==WM_LBUTTONDOWN || msg==WM_LBUTTONUP) ? 1 : |
953 ((message==WM_RBUTTONDOWN || message==WM_RBUTTONUP) ? 3 : 2); | 947 ((msg==WM_RBUTTONDOWN || msg==WM_RBUTTONUP) ? 3 : 2); |
954 event->event.button.x = where.x; | 948 event->event.button.x = where.x; |
955 event->event.button.y = where.y; | 949 event->event.button.y = where.y; |
956 event->event.button.modifiers = mswindows_modifier_state (NULL, 0); | 950 event->event.button.modifiers = mswindows_modifier_state (NULL, 0); |
957 | 951 |
958 if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN || | 952 if (msg==WM_LBUTTONDOWN || msg==WM_MBUTTONDOWN || |
959 message==WM_RBUTTONDOWN) | 953 msg==WM_RBUTTONDOWN) |
960 { | 954 { |
961 event->event_type = button_press_event; | 955 event->event_type = button_press_event; |
962 SetCapture (hwnd); | 956 SetCapture (hwnd); |
963 /* we need this to make sure the main window regains the focus | 957 /* we need this to make sure the main window regains the focus |
964 from control subwindows */ | 958 from control subwindows */ |
979 | 973 |
980 static void | 974 static void |
981 mswindows_enqueue_keypress_event (HWND hwnd, Lisp_Object keysym, int mods) | 975 mswindows_enqueue_keypress_event (HWND hwnd, Lisp_Object keysym, int mods) |
982 { | 976 { |
983 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 977 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
984 struct Lisp_Event* event = XEVENT(emacs_event); | 978 Lisp_Event* event = XEVENT(emacs_event); |
985 | 979 |
986 event->channel = mswindows_find_console(hwnd); | 980 event->channel = mswindows_find_console(hwnd); |
987 event->timestamp = GetMessageTime(); | 981 event->timestamp = GetMessageTime(); |
988 event->event_type = key_press_event; | 982 event->event_type = key_press_event; |
989 event->event.key.keysym = keysym; | 983 event->event.key.keysym = keysym; |
997 */ | 991 */ |
998 static Lisp_Object | 992 static Lisp_Object |
999 mswindows_dequeue_dispatch_event () | 993 mswindows_dequeue_dispatch_event () |
1000 { | 994 { |
1001 Lisp_Object event; | 995 Lisp_Object event; |
1002 struct Lisp_Event* sevt; | 996 Lisp_Event* sevt; |
1003 | 997 |
1004 assert (!NILP(mswindows_u_dispatch_event_queue) || | 998 assert (!NILP(mswindows_u_dispatch_event_queue) || |
1005 !NILP(mswindows_s_dispatch_event_queue)); | 999 !NILP(mswindows_s_dispatch_event_queue)); |
1006 | 1000 |
1007 event = dequeue_event ( | 1001 event = dequeue_event ( |
1031 * event in the queue and that of the given event is non-zero. | 1025 * event in the queue and that of the given event is non-zero. |
1032 * For all other event types, this function aborts. | 1026 * For all other event types, this function aborts. |
1033 */ | 1027 */ |
1034 | 1028 |
1035 Lisp_Object | 1029 Lisp_Object |
1036 mswindows_cancel_dispatch_event (struct Lisp_Event *match) | 1030 mswindows_cancel_dispatch_event (Lisp_Event *match) |
1037 { | 1031 { |
1038 Lisp_Object event; | 1032 Lisp_Object event; |
1039 Lisp_Object previous_event = Qnil; | 1033 Lisp_Object previous_event = Qnil; |
1040 int user_p = mswindows_user_event_p (match); | 1034 int user_p = mswindows_user_event_p (match); |
1041 Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue : | 1035 Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue : |
1046 assert (match->event_type == timeout_event | 1040 assert (match->event_type == timeout_event |
1047 || match->event_type == key_press_event); | 1041 || match->event_type == key_press_event); |
1048 | 1042 |
1049 EVENT_CHAIN_LOOP (event, *head) | 1043 EVENT_CHAIN_LOOP (event, *head) |
1050 { | 1044 { |
1051 struct Lisp_Event *e = XEVENT (event); | 1045 Lisp_Event *e = XEVENT (event); |
1052 if ((e->event_type == match->event_type) && | 1046 if ((e->event_type == match->event_type) && |
1053 ((e->event_type == timeout_event) ? | 1047 ((e->event_type == timeout_event) ? |
1054 (e->event.timeout.interval_id == match->event.timeout.interval_id) : | 1048 (e->event.timeout.interval_id == match->event.timeout.interval_id) : |
1055 /* Must be key_press_event */ | 1049 /* Must be key_press_event */ |
1056 ((e->event.key.modifiers & match->event.key.modifiers) != 0))) | 1050 ((e->event.key.modifiers & match->event.key.modifiers) != 0))) |
1229 result = mswindows_protect_modal_loop (mswindows_unsafe_pump_events, Qnil); | 1223 result = mswindows_protect_modal_loop (mswindows_unsafe_pump_events, Qnil); |
1230 UNGCPRO; | 1224 UNGCPRO; |
1231 return result; | 1225 return result; |
1232 } | 1226 } |
1233 | 1227 |
1228 /* | |
1229 * KEYBOARD_ONLY_P is set to non-zero when we are called from | |
1230 * QUITP, and are interesting in keyboard messages only. | |
1231 */ | |
1234 static void | 1232 static void |
1235 mswindows_drain_windows_queue () | 1233 mswindows_drain_windows_queue (int keyboard_only_till_quit_char_p) |
1236 { | 1234 { |
1237 MSG msg; | 1235 MSG msg; |
1238 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) | 1236 |
1239 { | 1237 /* Minimize the hassle of misordered events by not fetching |
1240 /* we have to translate messages that are not sent to the main | 1238 past quit char if called from QUITP; */ |
1241 window. this is so that key presses work ok in things like | 1239 while (!(keyboard_only_till_quit_char_p && |
1242 edit fields. however, we *musn't* translate message for the | 1240 mswindows_quit_chars_count > 0) && |
1241 PeekMessage (&msg, NULL, | |
1242 keyboard_only_till_quit_char_p ? WM_KEYFIRST : 0, | |
1243 keyboard_only_till_quit_char_p ? WM_KEYLAST : 0, | |
1244 PM_REMOVE)) | |
1245 { | |
1246 /* We have to translate messages that are not sent to the main | |
1247 window. This is so that key presses work ok in things like | |
1248 edit fields. However, we *musn't* translate message for the | |
1243 main window as this is handled in the wnd proc. */ | 1249 main window as this is handled in the wnd proc. */ |
1244 if ( GetWindowLong (msg.hwnd, GWL_STYLE) & WS_CHILD ) | 1250 if (GetWindowLong (msg.hwnd, GWL_STYLE) & WS_CHILD) |
1245 { | 1251 { |
1246 TranslateMessage (&msg); | 1252 TranslateMessage (&msg); |
1247 } | 1253 } |
1248 DispatchMessage (&msg); | 1254 DispatchMessage (&msg); |
1249 mswindows_unmodalize_signal_maybe (); | 1255 mswindows_unmodalize_signal_maybe (); |
1306 { | 1312 { |
1307 mswindows_need_event_in_modal_loop (badly_p); | 1313 mswindows_need_event_in_modal_loop (badly_p); |
1308 return; | 1314 return; |
1309 } | 1315 } |
1310 | 1316 |
1317 #if 0 | |
1311 /* Have to drain Windows message queue first, otherwise, we may miss | 1318 /* Have to drain Windows message queue first, otherwise, we may miss |
1312 quit char when called from quit_p */ | 1319 quit char when called from quit_p */ |
1320 /* #### This is, ehm, not quite true -- this function is not | |
1321 called from quit_p. --kkm */ | |
1313 mswindows_drain_windows_queue (); | 1322 mswindows_drain_windows_queue (); |
1323 #endif | |
1314 | 1324 |
1315 while (NILP (mswindows_u_dispatch_event_queue) | 1325 while (NILP (mswindows_u_dispatch_event_queue) |
1316 && NILP (mswindows_s_dispatch_event_queue)) | 1326 && NILP (mswindows_s_dispatch_event_queue)) |
1317 { | 1327 { |
1318 #ifdef HAVE_MSG_SELECT | 1328 #ifdef HAVE_MSG_SELECT |
1339 } | 1349 } |
1340 else if (active > 0) | 1350 else if (active > 0) |
1341 { | 1351 { |
1342 if (FD_ISSET (windows_fd, &temp_mask)) | 1352 if (FD_ISSET (windows_fd, &temp_mask)) |
1343 { | 1353 { |
1344 mswindows_drain_windows_queue (); | 1354 mswindows_drain_windows_queue (0); |
1345 } | 1355 } |
1346 #ifdef HAVE_TTY | 1356 #ifdef HAVE_TTY |
1347 /* Look for a TTY event */ | 1357 /* Look for a TTY event */ |
1348 for (i = 0; i < MAXDESC-1; i++) | 1358 for (i = 0; i < MAXDESC-1; i++) |
1349 { | 1359 { |
1352 user events ahead of process events. */ | 1362 user events ahead of process events. */ |
1353 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &tty_only_mask)) | 1363 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &tty_only_mask)) |
1354 { | 1364 { |
1355 struct console *c = tty_find_console_from_fd (i); | 1365 struct console *c = tty_find_console_from_fd (i); |
1356 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 1366 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
1357 struct Lisp_Event* event = XEVENT (emacs_event); | 1367 Lisp_Event* event = XEVENT (emacs_event); |
1358 | 1368 |
1359 assert (c); | 1369 assert (c); |
1360 if (read_event_from_tty_or_stream_desc (event, c, i)) | 1370 if (read_event_from_tty_or_stream_desc (event, c, i)) |
1361 { | 1371 { |
1362 mswindows_enqueue_dispatch_event (emacs_event); | 1372 mswindows_enqueue_dispatch_event (emacs_event); |
1370 { | 1380 { |
1371 if (FD_ISSET (i, &temp_mask)) | 1381 if (FD_ISSET (i, &temp_mask)) |
1372 { | 1382 { |
1373 if (FD_ISSET (i, &process_only_mask)) | 1383 if (FD_ISSET (i, &process_only_mask)) |
1374 { | 1384 { |
1375 struct Lisp_Process *p = | 1385 Lisp_Process *p = |
1376 get_process_from_usid (FD_TO_USID(i)); | 1386 get_process_from_usid (FD_TO_USID(i)); |
1377 | 1387 |
1378 mswindows_enqueue_process_event (p); | 1388 mswindows_enqueue_process_event (p); |
1379 } | 1389 } |
1380 else | 1390 else |
1420 return; | 1430 return; |
1421 } | 1431 } |
1422 else if (active == WAIT_OBJECT_0 + mswindows_waitable_count) | 1432 else if (active == WAIT_OBJECT_0 + mswindows_waitable_count) |
1423 { | 1433 { |
1424 /* Got your message, thanks */ | 1434 /* Got your message, thanks */ |
1425 mswindows_drain_windows_queue (); | 1435 mswindows_drain_windows_queue (0); |
1426 } | 1436 } |
1427 else | 1437 else |
1428 { | 1438 { |
1429 int ix = active - WAIT_OBJECT_0; | 1439 int ix = active - WAIT_OBJECT_0; |
1430 /* First, try to find which process' output has signaled */ | 1440 /* First, try to find which process' output has signaled */ |
1431 struct Lisp_Process *p = | 1441 Lisp_Process *p = |
1432 get_process_from_usid (HANDLE_TO_USID (mswindows_waitable_handles[ix])); | 1442 get_process_from_usid (HANDLE_TO_USID (mswindows_waitable_handles[ix])); |
1433 if (p != NULL) | 1443 if (p != NULL) |
1434 { | 1444 { |
1435 /* Found a signaled process input handle */ | 1445 /* Found a signaled process input handle */ |
1436 mswindows_enqueue_process_event (p); | 1446 mswindows_enqueue_process_event (p); |
1461 */ | 1471 */ |
1462 static void CALLBACK | 1472 static void CALLBACK |
1463 mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime) | 1473 mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime) |
1464 { | 1474 { |
1465 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 1475 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
1466 struct Lisp_Event *event = XEVENT (emacs_event); | 1476 Lisp_Event *event = XEVENT (emacs_event); |
1467 | 1477 |
1468 if (KillTimer (NULL, id_timer)) | 1478 if (KillTimer (NULL, id_timer)) |
1469 --mswindows_pending_timers_count; | 1479 --mswindows_pending_timers_count; |
1470 | 1480 |
1471 event->channel = Qnil; | 1481 event->channel = Qnil; |
1519 char *filename; | 1529 char *filename; |
1520 struct gcpro gcpro1, gcpro2; | 1530 struct gcpro gcpro1, gcpro2; |
1521 Lisp_Object l_dndlist = Qnil; | 1531 Lisp_Object l_dndlist = Qnil; |
1522 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); | 1532 Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); |
1523 Lisp_Object frmcons, devcons, concons; | 1533 Lisp_Object frmcons, devcons, concons; |
1524 struct Lisp_Event *event = XEVENT (emacs_event); | 1534 Lisp_Event *event = XEVENT (emacs_event); |
1525 | 1535 |
1526 DdeGetData (hdata, cmd, len, 0); | 1536 DdeGetData (hdata, cmd, len, 0); |
1527 cmd[len] = '\0'; | 1537 cmd[len] = '\0'; |
1528 DdeFreeDataHandle (hdata); | 1538 DdeFreeDataHandle (hdata); |
1529 | 1539 |
1597 } | 1607 } |
1598 } | 1608 } |
1599 #endif | 1609 #endif |
1600 | 1610 |
1601 /* | 1611 /* |
1612 * Returns 1 if a key is a real modifier or special key, which | |
1613 * is better handled by DefWindowProc | |
1614 */ | |
1615 static int | |
1616 key_needs_default_processing_p (UINT vkey) | |
1617 { | |
1618 if (mswindows_meta_activates_menu && vkey == VK_MENU) | |
1619 return 1; | |
1620 | |
1621 return 0; | |
1622 } | |
1623 | |
1624 /* | |
1602 * The windows procedure for the window class XEMACS_CLASS | 1625 * The windows procedure for the window class XEMACS_CLASS |
1603 */ | 1626 */ |
1604 LRESULT WINAPI | 1627 LRESULT WINAPI |
1605 mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | 1628 mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) |
1606 { | 1629 { |
1607 /* Note: Remember to initialize emacs_event and event before use. | 1630 /* Note: Remember to initialize emacs_event and event before use. |
1608 This code calls code that can GC. You must GCPRO before calling such code. */ | 1631 This code calls code that can GC. You must GCPRO before calling such code. */ |
1609 Lisp_Object emacs_event = Qnil; | 1632 Lisp_Object emacs_event = Qnil; |
1610 Lisp_Object fobj = Qnil; | 1633 Lisp_Object fobj = Qnil; |
1611 | 1634 |
1612 struct Lisp_Event *event; | 1635 Lisp_Event *event; |
1613 struct frame *frame; | 1636 struct frame *frame; |
1614 struct mswindows_frame* msframe; | 1637 struct mswindows_frame* msframe; |
1615 | 1638 |
1616 switch (message) | 1639 switch (message) |
1617 { | 1640 { |
1651 GetKeyboardState (keymap); | 1674 GetKeyboardState (keymap); |
1652 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80; | 1675 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80; |
1653 SetKeyboardState (keymap); | 1676 SetKeyboardState (keymap); |
1654 } | 1677 } |
1655 }; | 1678 }; |
1656 goto defproc; | 1679 if (key_needs_default_processing_p (wParam)) |
1680 goto defproc; | |
1681 else | |
1682 break; | |
1657 | 1683 |
1658 case WM_KEYDOWN: | 1684 case WM_KEYDOWN: |
1659 case WM_SYSKEYDOWN: | 1685 case WM_SYSKEYDOWN: |
1660 /* In some locales the right-hand Alt key is labelled AltGr. This key | 1686 /* In some locales the right-hand Alt key is labelled AltGr. This key |
1661 * should produce alternative charcaters when combined with another key. | 1687 * should produce alternative charcaters when combined with another key. |
1707 mods &= ~MOD_SHIFT; | 1733 mods &= ~MOD_SHIFT; |
1708 | 1734 |
1709 /* Clear control and alt modifiers unless AltGr is pressed */ | 1735 /* Clear control and alt modifiers unless AltGr is pressed */ |
1710 keymap [VK_RCONTROL] = 0; | 1736 keymap [VK_RCONTROL] = 0; |
1711 keymap [VK_LMENU] = 0; | 1737 keymap [VK_LMENU] = 0; |
1712 if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80)) | 1738 if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) |
1739 || !(keymap [VK_RMENU] & 0x80)) | |
1713 { | 1740 { |
1714 keymap [VK_LCONTROL] = 0; | 1741 keymap [VK_LCONTROL] = 0; |
1715 keymap [VK_CONTROL] = 0; | 1742 keymap [VK_CONTROL] = 0; |
1716 keymap [VK_RMENU] = 0; | 1743 keymap [VK_RMENU] = 0; |
1717 keymap [VK_MENU] = 0; | 1744 keymap [VK_MENU] = 0; |
1743 mswindows_enqueue_keypress_event (hwnd, make_char(ch), mods1); | 1770 mswindows_enqueue_keypress_event (hwnd, make_char(ch), mods1); |
1744 } /* while */ | 1771 } /* while */ |
1745 SetKeyboardState (keymap_orig); | 1772 SetKeyboardState (keymap_orig); |
1746 } /* else */ | 1773 } /* else */ |
1747 } | 1774 } |
1748 /* F10 causes menu activation by default. We do not want this */ | 1775 if (key_needs_default_processing_p (wParam)) |
1749 if (wParam != VK_F10 && (mswindows_meta_activates_menu || wParam != VK_MENU)) | |
1750 goto defproc; | 1776 goto defproc; |
1751 break; | 1777 else |
1778 break; | |
1752 | 1779 |
1753 case WM_MBUTTONDOWN: | 1780 case WM_MBUTTONDOWN: |
1754 case WM_MBUTTONUP: | 1781 case WM_MBUTTONUP: |
1755 /* Real middle mouse button has nothing to do with emulated one: | 1782 /* Real middle mouse button has nothing to do with emulated one: |
1756 if one wants to exercise fingers playing chords on the mouse, | 1783 if one wants to exercise fingers playing chords on the mouse, |
1962 | 1989 |
1963 if (!NILP(btext)) | 1990 if (!NILP(btext)) |
1964 { | 1991 { |
1965 /* I think this is safe since the text will only go away | 1992 /* I think this is safe since the text will only go away |
1966 when the toolbar does...*/ | 1993 when the toolbar does...*/ |
1967 GET_C_STRING_EXT_DATA_ALLOCA (btext, FORMAT_OS, | 1994 TO_EXTERNAL_FORMAT (LISP_STRING, btext, |
1968 tttext->lpszText); | 1995 C_STRING_ALLOCA, tttext->lpszText, |
1996 Qnative); | |
1969 } | 1997 } |
1970 #endif | 1998 #endif |
1971 } | 1999 } |
1972 /* handle tree view callbacks */ | 2000 /* handle tree view callbacks */ |
1973 else if (nmhdr->code == TVN_SELCHANGED) | 2001 else if (nmhdr->code == TVN_SELCHANGED) |
1978 } | 2006 } |
1979 /* handle tab control callbacks */ | 2007 /* handle tab control callbacks */ |
1980 else if (nmhdr->code == TCN_SELCHANGE) | 2008 else if (nmhdr->code == TCN_SELCHANGE) |
1981 { | 2009 { |
1982 TC_ITEM item; | 2010 TC_ITEM item; |
1983 int index = SendMessage (nmhdr->hwndFrom, TCM_GETCURSEL, 0, 0); | 2011 int idx = SendMessage (nmhdr->hwndFrom, TCM_GETCURSEL, 0, 0); |
1984 frame = XFRAME (mswindows_find_frame (hwnd)); | 2012 frame = XFRAME (mswindows_find_frame (hwnd)); |
1985 | 2013 |
1986 item.mask = TCIF_PARAM; | 2014 item.mask = TCIF_PARAM; |
1987 SendMessage (nmhdr->hwndFrom, TCM_GETITEM, (WPARAM)index, | 2015 SendMessage (nmhdr->hwndFrom, TCM_GETITEM, (WPARAM)idx, |
1988 (LPARAM)&item); | 2016 (LPARAM)&item); |
1989 | 2017 |
1990 mswindows_handle_gui_wm_command (frame, 0, item.lParam); | 2018 mswindows_handle_gui_wm_command (frame, 0, item.lParam); |
1991 } | 2019 } |
1992 } | 2020 } |
2613 } | 2641 } |
2614 | 2642 |
2615 static void | 2643 static void |
2616 emacs_mswindows_remove_timeout (int id) | 2644 emacs_mswindows_remove_timeout (int id) |
2617 { | 2645 { |
2618 struct Lisp_Event match_against; | 2646 Lisp_Event match_against; |
2619 Lisp_Object emacs_event; | 2647 Lisp_Object emacs_event; |
2620 | 2648 |
2621 if (KillTimer (NULL, id)) | 2649 if (KillTimer (NULL, id)) |
2622 --mswindows_pending_timers_count; | 2650 --mswindows_pending_timers_count; |
2623 | 2651 |
2649 | 2677 |
2650 /* | 2678 /* |
2651 * Return the next event | 2679 * Return the next event |
2652 */ | 2680 */ |
2653 static void | 2681 static void |
2654 emacs_mswindows_next_event (struct Lisp_Event *emacs_event) | 2682 emacs_mswindows_next_event (Lisp_Event *emacs_event) |
2655 { | 2683 { |
2656 Lisp_Object event, event2; | 2684 Lisp_Object event, event2; |
2657 | 2685 |
2658 mswindows_need_event (1); | 2686 mswindows_need_event (1); |
2659 | 2687 |
2665 | 2693 |
2666 /* | 2694 /* |
2667 * Handle a magic event off the dispatch queue. | 2695 * Handle a magic event off the dispatch queue. |
2668 */ | 2696 */ |
2669 static void | 2697 static void |
2670 emacs_mswindows_handle_magic_event (struct Lisp_Event *emacs_event) | 2698 emacs_mswindows_handle_magic_event (Lisp_Event *emacs_event) |
2671 { | 2699 { |
2672 switch (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event)) | 2700 switch (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event)) |
2673 { | 2701 { |
2674 case XM_BUMPQUEUE: | 2702 case XM_BUMPQUEUE: |
2675 break; | 2703 break; |
2719 } | 2747 } |
2720 } | 2748 } |
2721 | 2749 |
2722 #ifndef HAVE_MSG_SELECT | 2750 #ifndef HAVE_MSG_SELECT |
2723 static HANDLE | 2751 static HANDLE |
2724 get_process_input_waitable (struct Lisp_Process *process) | 2752 get_process_input_waitable (Lisp_Process *process) |
2725 { | 2753 { |
2726 Lisp_Object instr, outstr, p; | 2754 Lisp_Object instr, outstr, p; |
2727 XSETPROCESS (p, process); | 2755 XSETPROCESS (p, process); |
2728 get_process_streams (process, &instr, &outstr); | 2756 get_process_streams (process, &instr, &outstr); |
2729 assert (!NILP (instr)); | 2757 assert (!NILP (instr)); |
2735 return get_ntpipe_input_stream_waitable (XLSTREAM (instr)); | 2763 return get_ntpipe_input_stream_waitable (XLSTREAM (instr)); |
2736 #endif | 2764 #endif |
2737 } | 2765 } |
2738 | 2766 |
2739 static void | 2767 static void |
2740 emacs_mswindows_select_process (struct Lisp_Process *process) | 2768 emacs_mswindows_select_process (Lisp_Process *process) |
2741 { | 2769 { |
2742 HANDLE hev = get_process_input_waitable (process); | 2770 HANDLE hev = get_process_input_waitable (process); |
2743 | 2771 |
2744 if (!add_waitable_handle (hev)) | 2772 if (!add_waitable_handle (hev)) |
2745 error ("Too many active processes"); | 2773 error ("Too many active processes"); |
2760 } | 2788 } |
2761 #endif | 2789 #endif |
2762 } | 2790 } |
2763 | 2791 |
2764 static void | 2792 static void |
2765 emacs_mswindows_unselect_process (struct Lisp_Process *process) | 2793 emacs_mswindows_unselect_process (Lisp_Process *process) |
2766 { | 2794 { |
2767 /* Process handle is removed in the event loop as soon | 2795 /* Process handle is removed in the event loop as soon |
2768 as it is signaled, so don't bother here about it */ | 2796 as it is signaled, so don't bother here about it */ |
2769 HANDLE hev = get_process_input_waitable (process); | 2797 HANDLE hev = get_process_input_waitable (process); |
2770 remove_waitable_handle (hev); | 2798 remove_waitable_handle (hev); |
2794 } | 2822 } |
2795 | 2823 |
2796 static void | 2824 static void |
2797 emacs_mswindows_quit_p (void) | 2825 emacs_mswindows_quit_p (void) |
2798 { | 2826 { |
2799 MSG msg; | |
2800 | |
2801 /* Quit cannot happen in modal loop: all program | 2827 /* Quit cannot happen in modal loop: all program |
2802 input is dedicated to Windows. */ | 2828 input is dedicated to Windows. */ |
2803 if (mswindows_in_modal_loop) | 2829 if (mswindows_in_modal_loop) |
2804 return; | 2830 return; |
2805 | 2831 |
2806 /* Drain windows queue. This sets up number of quit characters in the queue | 2832 /* Drain windows queue. This sets up number of quit characters in |
2807 * (and also processes wm focus change, move, resize, etc messages). | 2833 the queue */ |
2808 * We don't want to process WM_PAINT messages because this function can be | 2834 mswindows_drain_windows_queue (1); |
2809 * called from almost anywhere and the windows' states may be changing. */ | |
2810 while (PeekMessage (&msg, NULL, 0, WM_PAINT-1, PM_REMOVE) || | |
2811 PeekMessage (&msg, NULL, WM_PAINT+1, WM_USER-1, PM_REMOVE)) | |
2812 DispatchMessage (&msg); | |
2813 | 2835 |
2814 if (mswindows_quit_chars_count > 0) | 2836 if (mswindows_quit_chars_count > 0) |
2815 { | 2837 { |
2816 /* Yes there's a hidden one... Throw it away */ | 2838 /* Yes there's a hidden one... Throw it away */ |
2817 struct Lisp_Event match_against; | 2839 Lisp_Event match_against; |
2818 Lisp_Object emacs_event; | 2840 Lisp_Object emacs_event; |
2841 int critical_p = 0; | |
2819 | 2842 |
2820 match_against.event_type = key_press_event; | 2843 match_against.event_type = key_press_event; |
2821 match_against.event.key.modifiers = FAKE_MOD_QUIT; | 2844 match_against.event.key.modifiers = FAKE_MOD_QUIT; |
2822 | 2845 |
2823 emacs_event = mswindows_cancel_dispatch_event (&match_against); | 2846 while (mswindows_quit_chars_count-- > 0) |
2824 assert (!NILP (emacs_event)); | 2847 { |
2825 | 2848 emacs_event = mswindows_cancel_dispatch_event (&match_against); |
2826 Vquit_flag = (XEVENT(emacs_event)->event.key.modifiers & MOD_SHIFT | 2849 assert (!NILP (emacs_event)); |
2827 ? Qcritical : Qt); | 2850 |
2828 | 2851 if (XEVENT(emacs_event)->event.key.modifiers & MOD_SHIFT) |
2829 Fdeallocate_event(emacs_event); | 2852 critical_p = 1; |
2830 --mswindows_quit_chars_count; | 2853 |
2854 Fdeallocate_event(emacs_event); | |
2855 } | |
2856 | |
2857 Vquit_flag = critical_p ? Qcritical : Qt; | |
2831 } | 2858 } |
2832 } | 2859 } |
2833 | 2860 |
2834 USID | 2861 USID |
2835 emacs_mswindows_create_stream_pair (void* inhandle, void* outhandle, | 2862 emacs_mswindows_create_stream_pair (void* inhandle, void* outhandle, |
2937 #ifndef HAVE_X_WINDOWS | 2964 #ifndef HAVE_X_WINDOWS |
2938 /* This is called from GC when a process object is about to be freed. | 2965 /* This is called from GC when a process object is about to be freed. |
2939 If we've still got pointers to it in this file, we're gonna lose hard. | 2966 If we've still got pointers to it in this file, we're gonna lose hard. |
2940 */ | 2967 */ |
2941 void | 2968 void |
2942 debug_process_finalization (struct Lisp_Process *p) | 2969 debug_process_finalization (Lisp_Process *p) |
2943 { | 2970 { |
2944 #if 0 /* #### */ | 2971 #if 0 /* #### */ |
2945 Lisp_Object instr, outstr; | 2972 Lisp_Object instr, outstr; |
2946 | 2973 |
2947 get_process_streams (p, &instr, &outstr); | 2974 get_process_streams (p, &instr, &outstr); |
2974 mswindows_event_stream->quit_p_cb = emacs_mswindows_quit_p; | 3001 mswindows_event_stream->quit_p_cb = emacs_mswindows_quit_p; |
2975 mswindows_event_stream->select_console_cb = emacs_mswindows_select_console; | 3002 mswindows_event_stream->select_console_cb = emacs_mswindows_select_console; |
2976 mswindows_event_stream->unselect_console_cb = emacs_mswindows_unselect_console; | 3003 mswindows_event_stream->unselect_console_cb = emacs_mswindows_unselect_console; |
2977 #ifdef HAVE_MSG_SELECT | 3004 #ifdef HAVE_MSG_SELECT |
2978 mswindows_event_stream->select_process_cb = | 3005 mswindows_event_stream->select_process_cb = |
2979 (void (*)(struct Lisp_Process*))event_stream_unixoid_select_process; | 3006 (void (*)(Lisp_Process*))event_stream_unixoid_select_process; |
2980 mswindows_event_stream->unselect_process_cb = | 3007 mswindows_event_stream->unselect_process_cb = |
2981 (void (*)(struct Lisp_Process*))event_stream_unixoid_unselect_process; | 3008 (void (*)(Lisp_Process*))event_stream_unixoid_unselect_process; |
2982 mswindows_event_stream->create_stream_pair_cb = event_stream_unixoid_create_stream_pair; | 3009 mswindows_event_stream->create_stream_pair_cb = event_stream_unixoid_create_stream_pair; |
2983 mswindows_event_stream->delete_stream_pair_cb = event_stream_unixoid_delete_stream_pair; | 3010 mswindows_event_stream->delete_stream_pair_cb = event_stream_unixoid_delete_stream_pair; |
2984 #else | 3011 #else |
2985 mswindows_event_stream->select_process_cb = emacs_mswindows_select_process; | 3012 mswindows_event_stream->select_process_cb = emacs_mswindows_select_process; |
2986 mswindows_event_stream->unselect_process_cb = emacs_mswindows_unselect_process; | 3013 mswindows_event_stream->unselect_process_cb = emacs_mswindows_unselect_process; |