Mercurial > hg > xemacs-beta
comparison src/event-msw.c @ 371:cc15677e0335 r21-2b1
Import from CVS: tag r21-2b1
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:03:08 +0200 |
parents | a4f53d9b3154 |
children | 6240c7796c7a |
comparison
equal
deleted
inserted
replaced
370:bd866891f083 | 371:cc15677e0335 |
---|---|
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. | |
32 */ | 31 */ |
33 | 32 |
34 #include <config.h> | 33 #include <config.h> |
35 #include "lisp.h" | 34 #include "lisp.h" |
36 | 35 |
86 extern Lisp_Object | 85 extern Lisp_Object |
87 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id); | 86 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id); |
88 | 87 |
89 static Lisp_Object mswindows_find_frame (HWND hwnd); | 88 static Lisp_Object mswindows_find_frame (HWND hwnd); |
90 static Lisp_Object mswindows_find_console (HWND hwnd); | 89 static Lisp_Object mswindows_find_console (HWND hwnd); |
91 static Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods, | 90 static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods); |
92 int extendedp); | |
93 static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); | 91 static int mswindows_modifier_state (BYTE* keymap, int has_AltGr); |
94 static void mswindows_set_chord_timer (HWND hwnd); | 92 static void mswindows_set_chord_timer (HWND hwnd); |
95 static int mswindows_button2_near_enough (POINTS p1, POINTS p2); | 93 static int mswindows_button2_near_enough (POINTS p1, POINTS p2); |
96 static int mswindows_current_layout_has_AltGr (void); | 94 static int mswindows_current_layout_has_AltGr (void); |
97 | 95 |
98 static struct event_stream *mswindows_event_stream; | 96 static struct event_stream *mswindows_event_stream; |
99 | 97 |
100 #ifdef HAVE_MSG_SELECT | 98 #ifdef HAVE_MSG_SELECT |
101 extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask; | 99 extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask; |
102 extern SELECT_TYPE process_only_mask, tty_only_mask; | 100 extern SELECT_TYPE process_only_mask, tty_only_mask; |
103 SELECT_TYPE zero_mask; | |
104 extern int signal_event_pipe_initialized; | 101 extern int signal_event_pipe_initialized; |
105 int windows_fd; | 102 int windows_fd; |
106 #endif | 103 #endif |
107 | 104 |
108 /* | 105 /* |
450 /************************************************************************/ | 447 /************************************************************************/ |
451 | 448 |
452 #define NTPIPE_SHOVE_STREAM_DATA(stream) \ | 449 #define NTPIPE_SHOVE_STREAM_DATA(stream) \ |
453 LSTREAM_TYPE_DATA (stream, ntpipe_shove) | 450 LSTREAM_TYPE_DATA (stream, ntpipe_shove) |
454 | 451 |
455 #define MAX_SHOVE_BUFFER_SIZE 512 | 452 #define MAX_SHOVE_BUFFER_SIZE 128 |
456 | 453 |
457 struct ntpipe_shove_stream | 454 struct ntpipe_shove_stream |
458 { | 455 { |
459 LPARAM user_data; /* Any user data stored in the stream object */ | 456 LPARAM user_data; /* Any user data stored in the stream object */ |
460 HANDLE hev_thread; /* Our thread blocks on this, signaled by caller */ | 457 HANDLE hev_thread; /* Our thread blocks on this, signaled by caller */ |
483 | 480 |
484 /* Block on event and wait for a job */ | 481 /* Block on event and wait for a job */ |
485 InterlockedIncrement (&s->idle_p); | 482 InterlockedIncrement (&s->idle_p); |
486 WaitForSingleObject (s->hev_thread, INFINITE); | 483 WaitForSingleObject (s->hev_thread, INFINITE); |
487 | 484 |
488 /* Write passed buffer if any */ | 485 if (s->die_p) |
489 if (s->size > 0) | 486 break; |
487 | |
488 /* Write passed buffer */ | |
489 if (!WriteFile (s->hpipe, s->buffer, s->size, &bytes_written, NULL) | |
490 || bytes_written != s->size) | |
490 { | 491 { |
491 if (!WriteFile (s->hpipe, s->buffer, s->size, &bytes_written, NULL) | 492 s->error_p = TRUE; |
492 || bytes_written != s->size) | 493 InterlockedIncrement (&s->die_p); |
493 { | |
494 s->error_p = TRUE; | |
495 InterlockedIncrement (&s->die_p); | |
496 } | |
497 /* Set size to zero so we won't write it again if the closer sets | |
498 die_p and kicks us */ | |
499 s->size = 0; | |
500 } | 494 } |
501 | 495 |
502 if (s->die_p) | 496 if (s->die_p) |
503 break; | 497 break; |
504 } | 498 } |
527 { | 521 { |
528 Lstream_delete (lstr); | 522 Lstream_delete (lstr); |
529 return Qnil; | 523 return Qnil; |
530 } | 524 } |
531 | 525 |
532 /* Set the priority of the thread higher so we don't end up waiting | |
533 on it to send things. */ | |
534 if (!SetThreadPriority (s->hthread, THREAD_PRIORITY_HIGHEST)) | |
535 { | |
536 CloseHandle (s->hthread); | |
537 Lstream_delete (lstr); | |
538 return Qnil; | |
539 } | |
540 | |
541 /* hev_thread is an auto-reset event, initially nonsignaled */ | 526 /* hev_thread is an auto-reset event, initially nonsignaled */ |
542 s->hev_thread = CreateEvent (NULL, FALSE, FALSE, NULL); | 527 s->hev_thread = CreateEvent (NULL, FALSE, FALSE, NULL); |
543 | 528 |
544 /* Now let it go */ | 529 /* Now let it go */ |
545 ResumeThread (s->hthread); | 530 ResumeThread (s->hthread); |
593 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); | 578 struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream); |
594 | 579 |
595 /* Force thread stop */ | 580 /* Force thread stop */ |
596 InterlockedIncrement (&s->die_p); | 581 InterlockedIncrement (&s->die_p); |
597 | 582 |
598 /* Thread will end upon unblocking. If it's already unblocked this will | 583 /* Close pipe handle, possibly breaking it */ |
599 do nothing, but the thread won't look at die_p until it's written any | 584 CloseHandle (s->hpipe); |
600 pending output. */ | 585 |
586 /* Thread will end upon unblocking */ | |
601 SetEvent (s->hev_thread); | 587 SetEvent (s->hev_thread); |
602 | 588 |
603 /* Wait while thread terminates */ | 589 /* Wait while thread terminates */ |
604 WaitForSingleObject (s->hthread, INFINITE); | 590 WaitForSingleObject (s->hthread, INFINITE); |
605 | |
606 /* Close pipe handle, possibly breaking it */ | |
607 CloseHandle (s->hpipe); | |
608 | |
609 /* Close the thread handle */ | |
610 CloseHandle (s->hthread); | 591 CloseHandle (s->hthread); |
611 | 592 |
612 /* Destroy the event */ | 593 /* Destroy the event */ |
613 CloseHandle (s->hev_thread); | 594 CloseHandle (s->hev_thread); |
614 | 595 |
744 if (size == 0) | 725 if (size == 0) |
745 return 0; | 726 return 0; |
746 | 727 |
747 { | 728 { |
748 ResetEvent (str->ov.hEvent); | 729 ResetEvent (str->ov.hEvent); |
749 | 730 |
750 /* Docs indicate that 4th parameter to WriteFile can be NULL since this is | 731 if (WriteFile ((HANDLE)str->s, data, size, NULL, &str->ov) |
751 * an overlapped operation. This fails on Win95 with winsock 1.x so we | |
752 * supply a spare address which is ignored by Win95 anyway. Sheesh. */ | |
753 if (WriteFile ((HANDLE)str->s, data, size, (LPDWORD)&str->buffer, &str->ov) | |
754 || GetLastError() == ERROR_IO_PENDING) | 732 || GetLastError() == ERROR_IO_PENDING) |
755 str->pending_p = 1; | 733 str->pending_p = 1; |
756 else | 734 else |
757 str->error_p = 1; | 735 str->error_p = 1; |
758 } | 736 } |
1314 { | 1292 { |
1315 EMACS_SET_SECS_USECS (sometime, 0, 0); | 1293 EMACS_SET_SECS_USECS (sometime, 0, 0); |
1316 EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block); | 1294 EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block); |
1317 pointer_to_this = &select_time_to_block; | 1295 pointer_to_this = &select_time_to_block; |
1318 } | 1296 } |
1319 | |
1320 /* select() is slow and buggy so if we don't have any processes | |
1321 just wait as normal */ | |
1322 if (memcmp (&process_only_mask, &zero_mask, sizeof(SELECT_TYPE))==0) | |
1323 { | |
1324 /* Now try getting a message or process event */ | |
1325 active = MsgWaitForMultipleObjects (0, mswindows_waitable_handles, | |
1326 FALSE, badly_p ? INFINITE : 0, | |
1327 QS_ALLINPUT); | |
1328 | |
1329 if (active == WAIT_TIMEOUT) | |
1330 { | |
1331 /* No luck trying - just return what we've already got */ | |
1332 return; | |
1333 } | |
1334 else if (active == WAIT_OBJECT_0) | |
1335 { | |
1336 /* Got your message, thanks */ | |
1337 mswindows_drain_windows_queue (); | |
1338 continue; | |
1339 } | |
1340 } | |
1341 | |
1342 active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this); | 1297 active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this); |
1343 | 1298 |
1344 if (active == 0) | 1299 if (active == 0) |
1345 { | 1300 { |
1346 return; /* timeout */ | 1301 return; /* timeout */ |
1615 case WM_CLOSE: | 1570 case WM_CLOSE: |
1616 fobj = mswindows_find_frame (hwnd); | 1571 fobj = mswindows_find_frame (hwnd); |
1617 mswindows_enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt)); | 1572 mswindows_enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt)); |
1618 break; | 1573 break; |
1619 | 1574 |
1620 case WM_KEYUP: | |
1621 case WM_SYSKEYUP: | |
1622 /* See Win95 comment under WM_KEYDOWN */ | |
1623 { | |
1624 BYTE keymap[256]; | |
1625 | |
1626 if (wParam == VK_CONTROL) | |
1627 { | |
1628 GetKeyboardState (keymap); | |
1629 keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] &= ~0x80; | |
1630 SetKeyboardState (keymap); | |
1631 } | |
1632 else if (wParam == VK_MENU) | |
1633 { | |
1634 GetKeyboardState (keymap); | |
1635 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80; | |
1636 SetKeyboardState (keymap); | |
1637 } | |
1638 }; | |
1639 goto defproc; | |
1640 | |
1641 case WM_KEYDOWN: | 1575 case WM_KEYDOWN: |
1642 case WM_SYSKEYDOWN: | 1576 case WM_SYSKEYDOWN: |
1643 /* In some locales the right-hand Alt key is labelled AltGr. This key | |
1644 * should produce alternative charcaters when combined with another key. | |
1645 * eg on a German keyboard pressing AltGr+q should produce '@'. | |
1646 * AltGr generates exactly the same keystrokes as LCtrl+RAlt. But if | |
1647 * TranslateMessage() is called with *any* combination of Ctrl+Alt down, | |
1648 * it translates as if AltGr were down. | |
1649 * We get round this by removing all modifiers from the keymap before | |
1650 * calling TranslateMessage() unless AltGr is *really* down. */ | |
1651 { | 1577 { |
1652 BYTE keymap[256]; | 1578 BYTE keymap[256]; |
1653 int has_AltGr = mswindows_current_layout_has_AltGr (); | 1579 int has_AltGr = mswindows_current_layout_has_AltGr (); |
1654 int mods; | 1580 int mods; |
1655 int extendedp = lParam & 0x1000000; | |
1656 Lisp_Object keysym; | 1581 Lisp_Object keysym; |
1657 | 1582 |
1658 GetKeyboardState (keymap); | 1583 GetKeyboardState (keymap); |
1659 mods = mswindows_modifier_state (keymap, has_AltGr); | 1584 mods = mswindows_modifier_state (keymap, has_AltGr); |
1660 | 1585 |
1661 /* Handle non-printables */ | 1586 /* Handle those keys that TranslateMessage won't generate a WM_CHAR for */ |
1662 if (!NILP (keysym = mswindows_key_to_emacs_keysym (wParam, mods, | 1587 if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods))) |
1663 extendedp))) | |
1664 mswindows_enqueue_keypress_event (hwnd, keysym, mods); | 1588 mswindows_enqueue_keypress_event (hwnd, keysym, mods); |
1665 else /* Normal keys & modifiers */ | 1589 else |
1666 { | 1590 { |
1667 int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); | 1591 int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); |
1668 BYTE keymap_orig[256]; | 1592 BYTE keymap_orig[256]; |
1669 MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) }; | 1593 MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) }; |
1670 | |
1671 /* GetKeyboardState() does not work as documented on Win95. We have | |
1672 * to loosely track Left and Right modifiers on behalf of the OS, | |
1673 * without screwing up Windows NT which tracks them properly. */ | |
1674 if (wParam == VK_CONTROL) | |
1675 keymap [extendedp ? VK_RCONTROL : VK_LCONTROL] |= 0x80; | |
1676 else if (wParam == VK_MENU) | |
1677 keymap [extendedp ? VK_RMENU : VK_LMENU] |= 0x80; | |
1678 | |
1679 memcpy (keymap_orig, keymap, 256); | 1594 memcpy (keymap_orig, keymap, 256); |
1680 | 1595 |
1681 /* Remove shift modifier from an ascii character */ | 1596 /* Remove shift modifier from an ascii character */ |
1682 mods &= ~MOD_SHIFT; | 1597 mods &= ~MOD_SHIFT; |
1683 | 1598 |
1684 /* Clear control and alt modifiers unless AltGr is pressed */ | 1599 /* Clear control and alt modifiers out of the keymap */ |
1685 keymap [VK_RCONTROL] = 0; | 1600 keymap [VK_RCONTROL] = 0; |
1686 keymap [VK_LMENU] = 0; | 1601 keymap [VK_LMENU] = 0; |
1687 if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80)) | 1602 if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80)) |
1688 { | 1603 { |
1689 keymap [VK_LCONTROL] = 0; | 1604 keymap [VK_LCONTROL] = 0; |
1691 keymap [VK_RMENU] = 0; | 1606 keymap [VK_RMENU] = 0; |
1692 keymap [VK_MENU] = 0; | 1607 keymap [VK_MENU] = 0; |
1693 } | 1608 } |
1694 SetKeyboardState (keymap); | 1609 SetKeyboardState (keymap); |
1695 | 1610 |
1696 /* Maybe generate some WM_[SYS]CHARs in the queue */ | 1611 /* Have some WM_[SYS]CHARS in the queue */ |
1697 TranslateMessage (&msg); | 1612 TranslateMessage (&msg); |
1698 | 1613 |
1699 while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE) | 1614 while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE) |
1700 || PeekMessage (&msg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE)) | 1615 || PeekMessage (&msg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE)) |
1701 { | 1616 { |
2106 SendMessage (hwndScrollBar, WM_CANCELMODE, 0, 0); | 2021 SendMessage (hwndScrollBar, WM_CANCELMODE, 0, 0); |
2107 } | 2022 } |
2108 UNGCPRO; | 2023 UNGCPRO; |
2109 break; | 2024 break; |
2110 } | 2025 } |
2111 | |
2112 case WM_MOUSEWHEEL: | |
2113 { | |
2114 int keys = LOWORD (wParam); /* Modifier key flags */ | |
2115 int delta = (short) HIWORD (wParam); /* Wheel rotation amount */ | |
2116 struct gcpro gcpro1, gcpro2; | |
2117 | |
2118 if (mswindows_handle_mousewheel_event (mswindows_find_frame (hwnd), keys, delta)) | |
2119 { | |
2120 GCPRO2 (emacs_event, fobj); | |
2121 mswindows_pump_outstanding_events (); /* Can GC */ | |
2122 UNGCPRO; | |
2123 } | |
2124 else | |
2125 goto defproc; | |
2126 break; | |
2127 } | |
2128 #endif | 2026 #endif |
2129 | 2027 |
2130 #ifdef HAVE_MENUBARS | 2028 #ifdef HAVE_MENUBARS |
2131 case WM_INITMENU: | 2029 case WM_INITMENU: |
2132 if (UNBOUNDP (mswindows_handle_wm_initmenu ( | 2030 if (UNBOUNDP (mswindows_handle_wm_initmenu ( |
2328 | 2226 |
2329 /* | 2227 /* |
2330 * Translate a mswindows virtual key to a keysym. | 2228 * Translate a mswindows virtual key to a keysym. |
2331 * Only returns non-Qnil for keys that don't generate WM_CHAR messages | 2229 * Only returns non-Qnil for keys that don't generate WM_CHAR messages |
2332 * or whose ASCII codes (like space) xemacs doesn't like. | 2230 * or whose ASCII codes (like space) xemacs doesn't like. |
2231 * Virtual key values are defined in winresrc.h | |
2232 * XXX I'm not sure that KEYSYM("name") is the best thing to use here. | |
2333 */ | 2233 */ |
2334 Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods, | 2234 Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods) |
2335 int extendedp) | 2235 { |
2336 { | 2236 switch (mswindows_key) |
2337 if (extendedp) /* Keys not present on a 82 key keyboard */ | 2237 { |
2338 { | 2238 /* First the predefined ones */ |
2339 switch (mswindows_key) | 2239 case VK_BACK: return QKbackspace; |
2340 { | 2240 case VK_TAB: return QKtab; |
2341 case VK_CANCEL: return KEYSYM ("pause"); | 2241 case '\n': return QKlinefeed; /* No VK_LINEFEED in winresrc.h */ |
2342 case VK_RETURN: return KEYSYM ("kp-enter"); | 2242 case VK_RETURN: return QKreturn; |
2343 case VK_PRIOR: return KEYSYM ("prior"); | 2243 case VK_ESCAPE: return QKescape; |
2344 case VK_NEXT: return KEYSYM ("next"); | 2244 case VK_SPACE: return QKspace; |
2345 case VK_END: return KEYSYM ("end"); | 2245 case VK_DELETE: return QKdelete; |
2346 case VK_HOME: return KEYSYM ("home"); | 2246 |
2347 case VK_LEFT: return KEYSYM ("left"); | 2247 /* The rest */ |
2348 case VK_UP: return KEYSYM ("up"); | 2248 case VK_CLEAR: return KEYSYM ("clear"); /* Should do ^L ? */ |
2349 case VK_RIGHT: return KEYSYM ("right"); | 2249 case VK_PRIOR: return KEYSYM ("prior"); |
2350 case VK_DOWN: return KEYSYM ("down"); | 2250 case VK_NEXT: return KEYSYM ("next"); |
2351 case VK_INSERT: return KEYSYM ("insert"); | 2251 case VK_END: return KEYSYM ("end"); |
2352 case VK_DELETE: return QKdelete; | 2252 case VK_HOME: return KEYSYM ("home"); |
2353 #if 0 /* FSF Emacs allows these to return configurable syms/mods */ | 2253 case VK_LEFT: return KEYSYM ("left"); |
2354 case VK_LWIN return KEYSYM (""); | 2254 case VK_UP: return KEYSYM ("up"); |
2355 case VK_RWIN return KEYSYM (""); | 2255 case VK_RIGHT: return KEYSYM ("right"); |
2356 #endif | 2256 case VK_DOWN: return KEYSYM ("down"); |
2357 case VK_APPS: return KEYSYM ("menu"); | 2257 case VK_SELECT: return KEYSYM ("select"); |
2358 } | 2258 case VK_PRINT: return KEYSYM ("print"); |
2359 } | 2259 case VK_EXECUTE: return KEYSYM ("execute"); |
2360 else | 2260 case VK_SNAPSHOT: return KEYSYM ("print"); |
2361 { | 2261 case VK_INSERT: return KEYSYM ("insert"); |
2362 switch (mswindows_key) | 2262 case VK_HELP: return KEYSYM ("help"); |
2363 { | 2263 #if 0 /* XXX What are these supposed to do? */ |
2364 case VK_BACK: return QKbackspace; | 2264 case VK_LWIN return KEYSYM (""); |
2365 case VK_TAB: return QKtab; | 2265 case VK_RWIN return KEYSYM (""); |
2366 case '\n': return QKlinefeed; | 2266 #endif |
2367 case VK_CLEAR: return KEYSYM ("clear"); | 2267 case VK_APPS: return KEYSYM ("menu"); |
2368 case VK_RETURN: return QKreturn; | 2268 case VK_F1: return KEYSYM ("f1"); |
2369 case VK_PAUSE: return KEYSYM ("pause"); | 2269 case VK_F2: return KEYSYM ("f2"); |
2370 case VK_ESCAPE: return QKescape; | 2270 case VK_F3: return KEYSYM ("f3"); |
2371 case VK_SPACE: return QKspace; | 2271 case VK_F4: return KEYSYM ("f4"); |
2372 case VK_PRIOR: return KEYSYM ("kp-prior"); | 2272 case VK_F5: return KEYSYM ("f5"); |
2373 case VK_NEXT: return KEYSYM ("kp-next"); | 2273 case VK_F6: return KEYSYM ("f6"); |
2374 case VK_END: return KEYSYM ("kp-end"); | 2274 case VK_F7: return KEYSYM ("f7"); |
2375 case VK_HOME: return KEYSYM ("kp-home"); | 2275 case VK_F8: return KEYSYM ("f8"); |
2376 case VK_LEFT: return KEYSYM ("kp-left"); | 2276 case VK_F9: return KEYSYM ("f9"); |
2377 case VK_UP: return KEYSYM ("kp-up"); | 2277 case VK_F10: return KEYSYM ("f10"); |
2378 case VK_RIGHT: return KEYSYM ("kp-right"); | 2278 case VK_F11: return KEYSYM ("f11"); |
2379 case VK_DOWN: return KEYSYM ("kp-down"); | 2279 case VK_F12: return KEYSYM ("f12"); |
2380 case VK_SELECT: return KEYSYM ("select"); | 2280 case VK_F13: return KEYSYM ("f13"); |
2381 case VK_PRINT: return KEYSYM ("print"); | 2281 case VK_F14: return KEYSYM ("f14"); |
2382 case VK_EXECUTE: return KEYSYM ("execute"); | 2282 case VK_F15: return KEYSYM ("f15"); |
2383 case VK_SNAPSHOT: return KEYSYM ("print"); | 2283 case VK_F16: return KEYSYM ("f16"); |
2384 case VK_INSERT: return KEYSYM ("kp-insert"); | 2284 case VK_F17: return KEYSYM ("f17"); |
2385 case VK_DELETE: return KEYSYM ("kp-delete"); | 2285 case VK_F18: return KEYSYM ("f18"); |
2386 case VK_HELP: return KEYSYM ("help"); | 2286 case VK_F19: return KEYSYM ("f19"); |
2387 case VK_NUMPAD0: return KEYSYM ("kp-0"); | 2287 case VK_F20: return KEYSYM ("f20"); |
2388 case VK_NUMPAD1: return KEYSYM ("kp-1"); | 2288 case VK_F21: return KEYSYM ("f21"); |
2389 case VK_NUMPAD2: return KEYSYM ("kp-2"); | 2289 case VK_F22: return KEYSYM ("f22"); |
2390 case VK_NUMPAD3: return KEYSYM ("kp-3"); | 2290 case VK_F23: return KEYSYM ("f23"); |
2391 case VK_NUMPAD4: return KEYSYM ("kp-4"); | 2291 case VK_F24: return KEYSYM ("f24"); |
2392 case VK_NUMPAD5: return KEYSYM ("kp-5"); | 2292 } |
2393 case VK_NUMPAD6: return KEYSYM ("kp-6"); | |
2394 case VK_NUMPAD7: return KEYSYM ("kp-7"); | |
2395 case VK_NUMPAD8: return KEYSYM ("kp-8"); | |
2396 case VK_NUMPAD9: return KEYSYM ("kp-9"); | |
2397 case VK_MULTIPLY: return KEYSYM ("kp-multiply"); | |
2398 case VK_ADD: return KEYSYM ("kp-add"); | |
2399 case VK_SEPARATOR: return KEYSYM ("kp-separator"); | |
2400 case VK_SUBTRACT: return KEYSYM ("kp-subtract"); | |
2401 case VK_DECIMAL: return KEYSYM ("kp-decimal"); | |
2402 case VK_DIVIDE: return KEYSYM ("kp-divide"); | |
2403 case VK_F1: return KEYSYM ("f1"); | |
2404 case VK_F2: return KEYSYM ("f2"); | |
2405 case VK_F3: return KEYSYM ("f3"); | |
2406 case VK_F4: return KEYSYM ("f4"); | |
2407 case VK_F5: return KEYSYM ("f5"); | |
2408 case VK_F6: return KEYSYM ("f6"); | |
2409 case VK_F7: return KEYSYM ("f7"); | |
2410 case VK_F8: return KEYSYM ("f8"); | |
2411 case VK_F9: return KEYSYM ("f9"); | |
2412 case VK_F10: return KEYSYM ("f10"); | |
2413 case VK_F11: return KEYSYM ("f11"); | |
2414 case VK_F12: return KEYSYM ("f12"); | |
2415 case VK_F13: return KEYSYM ("f13"); | |
2416 case VK_F14: return KEYSYM ("f14"); | |
2417 case VK_F15: return KEYSYM ("f15"); | |
2418 case VK_F16: return KEYSYM ("f16"); | |
2419 case VK_F17: return KEYSYM ("f17"); | |
2420 case VK_F18: return KEYSYM ("f18"); | |
2421 case VK_F19: return KEYSYM ("f19"); | |
2422 case VK_F20: return KEYSYM ("f20"); | |
2423 case VK_F21: return KEYSYM ("f21"); | |
2424 case VK_F22: return KEYSYM ("f22"); | |
2425 case VK_F23: return KEYSYM ("f23"); | |
2426 case VK_F24: return KEYSYM ("f24"); | |
2427 } | |
2428 } | |
2429 return Qnil; | 2293 return Qnil; |
2430 } | 2294 } |
2431 | 2295 |
2432 /* | 2296 /* |
2433 * Find the console that matches the supplied mswindows window handle | 2297 * Find the console that matches the supplied mswindows window handle |
2648 } | 2512 } |
2649 | 2513 |
2650 static void | 2514 static void |
2651 emacs_mswindows_quit_p (void) | 2515 emacs_mswindows_quit_p (void) |
2652 { | 2516 { |
2653 MSG msg; | |
2654 | |
2655 /* Quit cannot happen in modal loop: all program | 2517 /* Quit cannot happen in modal loop: all program |
2656 input is dedicated to Windows. */ | 2518 input is dedicated to Windows. */ |
2657 if (mswindows_in_modal_loop) | 2519 if (mswindows_in_modal_loop) |
2658 return; | 2520 return; |
2659 | 2521 |
2660 /* Drain windows queue. This sets up number of quit characters in the queue | 2522 /* Drain windows queue. This sets up number of quit |
2661 * (and also processes wm focus change, move, resize, etc messages). | 2523 characters in in the queue */ |
2662 * We don't want to process WM_PAINT messages because this function can be | 2524 mswindows_drain_windows_queue (); |
2663 * called from almost anywhere and the windows' states may be changing. */ | |
2664 while (PeekMessage (&msg, NULL, 0, WM_PAINT-1, PM_REMOVE) || | |
2665 PeekMessage (&msg, NULL, WM_PAINT+1, WM_USER-1, PM_REMOVE)) | |
2666 DispatchMessage (&msg); | |
2667 | 2525 |
2668 if (mswindows_quit_chars_count > 0) | 2526 if (mswindows_quit_chars_count > 0) |
2669 { | 2527 { |
2670 /* Yes there's a hidden one... Throw it away */ | 2528 /* Yes there's a hidden one... Throw it away */ |
2671 struct Lisp_Event match_against; | 2529 struct Lisp_Event match_against; |
2918 { | 2776 { |
2919 #ifdef HAVE_MSG_SELECT | 2777 #ifdef HAVE_MSG_SELECT |
2920 windows_fd = open("/dev/windows", O_RDONLY | O_NONBLOCK, 0); | 2778 windows_fd = open("/dev/windows", O_RDONLY | O_NONBLOCK, 0); |
2921 assert (windows_fd>=0); | 2779 assert (windows_fd>=0); |
2922 FD_SET (windows_fd, &input_wait_mask); | 2780 FD_SET (windows_fd, &input_wait_mask); |
2923 FD_ZERO(&zero_mask); | 2781 /* for some reason I get blocks on the signal event pipe, which is |
2782 bad... | |
2783 signal_event_pipe_initialized = 0; */ | |
2924 #endif | 2784 #endif |
2925 | 2785 |
2926 event_stream = mswindows_event_stream; | 2786 event_stream = mswindows_event_stream; |
2927 | 2787 |
2928 mswindows_dynamic_frame_resize = !GetSystemMetrics (SM_SLOWMACHINE); | 2788 mswindows_dynamic_frame_resize = !GetSystemMetrics (SM_SLOWMACHINE); |