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);