Mercurial > hg > xemacs-beta
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); |