comparison src/event-msw.c @ 373:6240c7796c7a r21-2b2

Import from CVS: tag r21-2b2
author cvs
date Mon, 13 Aug 2007 11:04:06 +0200
parents cc15677e0335
children 8626e4521993
comparison
equal deleted inserted replaced
372:49e1ed2d7ed8 373:6240c7796c7a
96 static struct event_stream *mswindows_event_stream; 96 static struct event_stream *mswindows_event_stream;
97 97
98 #ifdef HAVE_MSG_SELECT 98 #ifdef HAVE_MSG_SELECT
99 extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask; 99 extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask;
100 extern SELECT_TYPE process_only_mask, tty_only_mask; 100 extern SELECT_TYPE process_only_mask, tty_only_mask;
101 SELECT_TYPE zero_mask;
101 extern int signal_event_pipe_initialized; 102 extern int signal_event_pipe_initialized;
102 int windows_fd; 103 int windows_fd;
103 #endif 104 #endif
104 105
105 /* 106 /*
725 if (size == 0) 726 if (size == 0)
726 return 0; 727 return 0;
727 728
728 { 729 {
729 ResetEvent (str->ov.hEvent); 730 ResetEvent (str->ov.hEvent);
730 731
731 if (WriteFile ((HANDLE)str->s, data, size, NULL, &str->ov) 732 /* Docs indicate that 4th parameter to WriteFile can be NULL since this is
733 * an overlapped operation. This fails on Win95 with winsock 1.x so we
734 * supply a spare address which is ignored by Win95 anyway. Sheesh. */
735 if (WriteFile ((HANDLE)str->s, data, size, (LPDWORD)&str->buffer, &str->ov)
732 || GetLastError() == ERROR_IO_PENDING) 736 || GetLastError() == ERROR_IO_PENDING)
733 str->pending_p = 1; 737 str->pending_p = 1;
734 else 738 else
735 str->error_p = 1; 739 str->error_p = 1;
736 } 740 }
1292 { 1296 {
1293 EMACS_SET_SECS_USECS (sometime, 0, 0); 1297 EMACS_SET_SECS_USECS (sometime, 0, 0);
1294 EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block); 1298 EMACS_TIME_TO_SELECT_TIME (sometime, select_time_to_block);
1295 pointer_to_this = &select_time_to_block; 1299 pointer_to_this = &select_time_to_block;
1296 } 1300 }
1301
1302 /* select() is slow and buggy so if we don't have any processes
1303 just wait as normal */
1304 if (memcmp (&process_only_mask, &zero_mask, sizeof(SELECT_TYPE))==0)
1305 {
1306 /* Now try getting a message or process event */
1307 active = MsgWaitForMultipleObjects (0, mswindows_waitable_handles,
1308 FALSE, badly_p ? INFINITE : 0,
1309 QS_ALLINPUT);
1310
1311 if (active == WAIT_TIMEOUT)
1312 {
1313 /* No luck trying - just return what we've already got */
1314 return;
1315 }
1316 else if (active == WAIT_OBJECT_0)
1317 {
1318 /* Got your message, thanks */
1319 mswindows_drain_windows_queue ();
1320 continue;
1321 }
1322 }
1323
1297 active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this); 1324 active = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this);
1298 1325
1299 if (active == 0) 1326 if (active == 0)
1300 { 1327 {
1301 return; /* timeout */ 1328 return; /* timeout */
1570 case WM_CLOSE: 1597 case WM_CLOSE:
1571 fobj = mswindows_find_frame (hwnd); 1598 fobj = mswindows_find_frame (hwnd);
1572 mswindows_enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt)); 1599 mswindows_enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt));
1573 break; 1600 break;
1574 1601
1602 case WM_KEYUP:
1603 case WM_SYSKEYUP:
1604 /* See Win95 comment under WM_KEYDOWN */
1605 {
1606 BYTE keymap[256];
1607
1608 if (wParam == VK_CONTROL)
1609 {
1610 GetKeyboardState (keymap);
1611 keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] &= ~0x80;
1612 SetKeyboardState (keymap);
1613 }
1614 else if (wParam == VK_MENU)
1615 {
1616 GetKeyboardState (keymap);
1617 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] &= ~0x80;
1618 SetKeyboardState (keymap);
1619 }
1620 };
1621 goto defproc;
1622
1575 case WM_KEYDOWN: 1623 case WM_KEYDOWN:
1576 case WM_SYSKEYDOWN: 1624 case WM_SYSKEYDOWN:
1625 /* In some locales the right-hand Alt key is labelled AltGr. This key
1626 * should produce alternative charcaters when combined with another key.
1627 * eg on a German keyboard pressing AltGr+q should produce '@'.
1628 * AltGr generates exactly the same keystrokes as LCtrl+RAlt. But if
1629 * TranslateMessage() is called with *any* combination of Ctrl+Alt down,
1630 * it translates as if AltGr were down.
1631 * We get round this by removing all modifiers from the keymap before
1632 * calling TranslateMessage() unless AltGr is *really* down. */
1577 { 1633 {
1578 BYTE keymap[256]; 1634 BYTE keymap[256];
1579 int has_AltGr = mswindows_current_layout_has_AltGr (); 1635 int has_AltGr = mswindows_current_layout_has_AltGr ();
1580 int mods; 1636 int mods;
1581 Lisp_Object keysym; 1637 Lisp_Object keysym;
1582 1638
1583 GetKeyboardState (keymap); 1639 GetKeyboardState (keymap);
1584 mods = mswindows_modifier_state (keymap, has_AltGr); 1640 mods = mswindows_modifier_state (keymap, has_AltGr);
1585 1641
1586 /* Handle those keys that TranslateMessage won't generate a WM_CHAR for */ 1642 /* Handle those keys for which TranslateMessage won't generate a WM_CHAR */
1587 if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods))) 1643 if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods)))
1588 mswindows_enqueue_keypress_event (hwnd, keysym, mods); 1644 mswindows_enqueue_keypress_event (hwnd, keysym, mods);
1589 else 1645 else
1590 { 1646 {
1591 int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))); 1647 int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
1592 BYTE keymap_orig[256]; 1648 BYTE keymap_orig[256];
1593 MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) }; 1649 MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) };
1650
1651 /* GetKeyboardState() does not work as documented on Win95. We have
1652 * to loosely track Left and Right modifiers on behalf of the OS,
1653 * without screwing up Windows NT which tracks them properly. */
1654 if (wParam == VK_CONTROL)
1655 keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] |= 0x80;
1656 else if (wParam == VK_MENU)
1657 keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] |= 0x80;
1658
1594 memcpy (keymap_orig, keymap, 256); 1659 memcpy (keymap_orig, keymap, 256);
1595 1660
1596 /* Remove shift modifier from an ascii character */ 1661 /* Remove shift modifier from an ascii character */
1597 mods &= ~MOD_SHIFT; 1662 mods &= ~MOD_SHIFT;
1598 1663
1599 /* Clear control and alt modifiers out of the keymap */ 1664 /* Clear control and alt modifiers unless AltGr is pressed */
1600 keymap [VK_RCONTROL] = 0; 1665 keymap [VK_RCONTROL] = 0;
1601 keymap [VK_LMENU] = 0; 1666 keymap [VK_LMENU] = 0;
1602 if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80)) 1667 if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80))
1603 { 1668 {
1604 keymap [VK_LCONTROL] = 0; 1669 keymap [VK_LCONTROL] = 0;
1606 keymap [VK_RMENU] = 0; 1671 keymap [VK_RMENU] = 0;
1607 keymap [VK_MENU] = 0; 1672 keymap [VK_MENU] = 0;
1608 } 1673 }
1609 SetKeyboardState (keymap); 1674 SetKeyboardState (keymap);
1610 1675
1611 /* Have some WM_[SYS]CHARS in the queue */ 1676 /* Maybe generate some WM_[SYS]CHARs in the queue */
1612 TranslateMessage (&msg); 1677 TranslateMessage (&msg);
1613 1678
1614 while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE) 1679 while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE)
1615 || PeekMessage (&msg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE)) 1680 || PeekMessage (&msg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE))
1616 { 1681 {
2776 { 2841 {
2777 #ifdef HAVE_MSG_SELECT 2842 #ifdef HAVE_MSG_SELECT
2778 windows_fd = open("/dev/windows", O_RDONLY | O_NONBLOCK, 0); 2843 windows_fd = open("/dev/windows", O_RDONLY | O_NONBLOCK, 0);
2779 assert (windows_fd>=0); 2844 assert (windows_fd>=0);
2780 FD_SET (windows_fd, &input_wait_mask); 2845 FD_SET (windows_fd, &input_wait_mask);
2781 /* for some reason I get blocks on the signal event pipe, which is 2846 FD_ZERO(&zero_mask);
2782 bad...
2783 signal_event_pipe_initialized = 0; */
2784 #endif 2847 #endif
2785 2848
2786 event_stream = mswindows_event_stream; 2849 event_stream = mswindows_event_stream;
2787 2850
2788 mswindows_dynamic_frame_resize = !GetSystemMetrics (SM_SLOWMACHINE); 2851 mswindows_dynamic_frame_resize = !GetSystemMetrics (SM_SLOWMACHINE);