diff options
| author | Geoff Voelker | 1998-11-10 20:52:20 +0000 |
|---|---|---|
| committer | Geoff Voelker | 1998-11-10 20:52:20 +0000 |
| commit | 29a2c30ff67263ad887a15b2d6c728505ee656a0 (patch) | |
| tree | bfcf6925d09521412f1cee2686df587b99ac9759 /src | |
| parent | 0eaf592609ab8a3cd6a7836b28f0891740098ae8 (diff) | |
| download | emacs-29a2c30ff67263ad887a15b2d6c728505ee656a0.tar.gz emacs-29a2c30ff67263ad887a15b2d6c728505ee656a0.zip | |
Include w32term.h and w32heap.h.
(map_keypad_keys):
(Vw32_enable_caps_lock):
(Vw32_enable_num_lock):
(Vw32_pass_lwindow_to_system):
(Vw32_pass_rwindow_to_system):
(Vw32_lwindow_modifier):
(Vw32_rwindow_modifier):
(Vw32_apps_modifier):
(Vw32_scroll_lock_modifier):
(w32_key_to_modifier): Add externs.
(w32_kbd_mods_to_emacs): Recognize Windows keys, Apps key, and
Scroll Lock as potential modifiers; exclude numpad keys from
effect by CapsLock; act on Vw32_enable_caps_lock; remove obsolete
code.
(is_dead_key): Copy from w32fns.c.
(w32_kbd_patch_key): Comment attempt to improve handling of
dead-keys, and system bug relating to same on Windows NT. Work
around the bug by calling ToUnicode and then converting to the
correct codepage.
(map_virt_key): Removed obsolete variable.
(lispy_function_keys): Add extern.
(key_event): Major rework of keyboard input handling: optionally
recognize Windows keys and Apps key as modifiers; optionally treat
NumLock, CapsLock and ScrollLock as function keys; let system
translate keystrokes to characters to avoid system bugs relating
to dead-key handling; preserve shift distinction for control
characters. Remove some obsolete code.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32inevt.c | 443 |
1 files changed, 232 insertions, 211 deletions
diff --git a/src/w32inevt.c b/src/w32inevt.c index fdd3d792b03..f31f88edf09 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c | |||
| @@ -33,6 +33,8 @@ Boston, MA 02111-1307, USA. | |||
| 33 | #include "frame.h" | 33 | #include "frame.h" |
| 34 | #include "blockinput.h" | 34 | #include "blockinput.h" |
| 35 | #include "termhooks.h" | 35 | #include "termhooks.h" |
| 36 | #include "w32heap.h" | ||
| 37 | #include "w32term.h" | ||
| 36 | 38 | ||
| 37 | /* stdin, from ntterm */ | 39 | /* stdin, from ntterm */ |
| 38 | extern HANDLE keyboard_handle; | 40 | extern HANDLE keyboard_handle; |
| @@ -49,10 +51,20 @@ extern int change_frame_size (FRAME_PTR, int, int, int, int); | |||
| 49 | 51 | ||
| 50 | /* from w32fns.c */ | 52 | /* from w32fns.c */ |
| 51 | extern Lisp_Object Vw32_alt_is_meta; | 53 | extern Lisp_Object Vw32_alt_is_meta; |
| 54 | extern unsigned int map_keypad_keys (unsigned int, unsigned int); | ||
| 52 | 55 | ||
| 53 | /* from w32term */ | 56 | /* from w32term */ |
| 54 | extern Lisp_Object Vw32_capslock_is_shiftlock; | 57 | extern Lisp_Object Vw32_capslock_is_shiftlock; |
| 58 | extern Lisp_Object Vw32_enable_caps_lock; | ||
| 59 | extern Lisp_Object Vw32_enable_num_lock; | ||
| 55 | extern Lisp_Object Vw32_recognize_altgr; | 60 | extern Lisp_Object Vw32_recognize_altgr; |
| 61 | extern Lisp_Object Vw32_pass_lwindow_to_system; | ||
| 62 | extern Lisp_Object Vw32_pass_rwindow_to_system; | ||
| 63 | extern Lisp_Object Vw32_lwindow_modifier; | ||
| 64 | extern Lisp_Object Vw32_rwindow_modifier; | ||
| 65 | extern Lisp_Object Vw32_apps_modifier; | ||
| 66 | extern Lisp_Object Vw32_scroll_lock_modifier; | ||
| 67 | extern unsigned int w32_key_to_modifier (int key); | ||
| 56 | 68 | ||
| 57 | /* Event queue */ | 69 | /* Event queue */ |
| 58 | #define EVENT_QUEUE_SIZE 50 | 70 | #define EVENT_QUEUE_SIZE 50 |
| @@ -105,7 +117,7 @@ w32_kbd_mods_to_emacs (DWORD mods, WORD key) | |||
| 105 | int retval = 0; | 117 | int retval = 0; |
| 106 | 118 | ||
| 107 | /* If we recognize right-alt and left-ctrl as AltGr, and it has been | 119 | /* If we recognize right-alt and left-ctrl as AltGr, and it has been |
| 108 | pressed, remove the modifiers. */ | 120 | pressed, first remove those modifiers. */ |
| 109 | if (!NILP (Vw32_recognize_altgr) | 121 | if (!NILP (Vw32_recognize_altgr) |
| 110 | && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED)) | 122 | && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED)) |
| 111 | == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED)) | 123 | == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED)) |
| @@ -122,40 +134,57 @@ w32_kbd_mods_to_emacs (DWORD mods, WORD key) | |||
| 122 | retval |= meta_modifier; | 134 | retval |= meta_modifier; |
| 123 | } | 135 | } |
| 124 | 136 | ||
| 137 | if (mods & LEFT_WIN_PRESSED) | ||
| 138 | retval |= w32_key_to_modifier (VK_LWIN); | ||
| 139 | if (mods & RIGHT_WIN_PRESSED) | ||
| 140 | retval |= w32_key_to_modifier (VK_RWIN); | ||
| 141 | if (mods & APPS_PRESSED) | ||
| 142 | retval |= w32_key_to_modifier (VK_APPS); | ||
| 143 | if (mods & SCROLLLOCK_ON) | ||
| 144 | retval |= w32_key_to_modifier (VK_SCROLL); | ||
| 145 | |||
| 125 | /* Just in case someone wanted the original behaviour, make it | 146 | /* Just in case someone wanted the original behaviour, make it |
| 126 | optional by setting w32-capslock-is-shiftlock to t. */ | 147 | optional by setting w32-capslock-is-shiftlock to t. */ |
| 127 | if (NILP (Vw32_capslock_is_shiftlock) && | 148 | if (NILP (Vw32_capslock_is_shiftlock) |
| 128 | #if 1 | 149 | /* Keys that should _not_ be affected by CapsLock. */ |
| 129 | ( (key == VK_BACK) || | 150 | && ( (key == VK_BACK) |
| 130 | (key == VK_TAB) || | 151 | || (key == VK_TAB) |
| 131 | (key == VK_CLEAR) || | 152 | || (key == VK_CLEAR) |
| 132 | (key == VK_RETURN) || | 153 | || (key == VK_RETURN) |
| 133 | (key == VK_ESCAPE) || | 154 | || (key == VK_ESCAPE) |
| 134 | ( (key >= VK_SPACE) && (key <= VK_HELP)) || | 155 | || ((key >= VK_SPACE) && (key <= VK_HELP)) |
| 135 | ( (key >= VK_NUMPAD0) && (key <= VK_F24)) | 156 | || ((key >= VK_NUMPAD0) && (key <= VK_F24)) |
| 136 | ) | 157 | || ((key >= VK_NUMPAD_CLEAR) && (key <= VK_NUMPAD_DELETE)) |
| 137 | #else | 158 | )) |
| 138 | /* Perhaps easier to say which keys we *do* always want affected | ||
| 139 | by capslock. Not sure how this affects "alphabetic" keyboard | ||
| 140 | input in non-English languages though - what virtual key codes | ||
| 141 | are returned for accented letters, for instance? */ | ||
| 142 | !( (key >= '0' && key <= '9') || (key >= 'A' && key <= 'Z') ) | ||
| 143 | #endif | ||
| 144 | ) | ||
| 145 | { | 159 | { |
| 146 | if ( (mods & SHIFT_PRESSED) == SHIFT_PRESSED) | 160 | /* Only consider shift state. */ |
| 161 | if ((mods & SHIFT_PRESSED) != 0) | ||
| 147 | retval |= shift_modifier; | 162 | retval |= shift_modifier; |
| 148 | } | 163 | } |
| 149 | else | 164 | else |
| 150 | { | 165 | { |
| 151 | if (((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) == SHIFT_PRESSED) | 166 | /* Ignore CapsLock state if not enabled. */ |
| 152 | || ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) == CAPSLOCK_ON)) | 167 | if (NILP (Vw32_enable_caps_lock)) |
| 153 | retval |= shift_modifier; | 168 | mods &= ~CAPSLOCK_ON; |
| 169 | if ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) != 0) | ||
| 170 | retval |= shift_modifier; | ||
| 154 | } | 171 | } |
| 155 | 172 | ||
| 156 | return retval; | 173 | return retval; |
| 157 | } | 174 | } |
| 158 | 175 | ||
| 176 | #if 0 | ||
| 177 | /* Return nonzero if the virtual key is a dead key. */ | ||
| 178 | static int | ||
| 179 | is_dead_key (int wparam) | ||
| 180 | { | ||
| 181 | unsigned int code = MapVirtualKey (wparam, 2); | ||
| 182 | |||
| 183 | /* Windows 95 returns 0x8000, NT returns 0x80000000. */ | ||
| 184 | return (code & 0x80008000) ? 1 : 0; | ||
| 185 | } | ||
| 186 | #endif | ||
| 187 | |||
| 159 | /* The return code indicates key code size. */ | 188 | /* The return code indicates key code size. */ |
| 160 | int | 189 | int |
| 161 | w32_kbd_patch_key (KEY_EVENT_RECORD *event) | 190 | w32_kbd_patch_key (KEY_EVENT_RECORD *event) |
| @@ -176,6 +205,7 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event) | |||
| 176 | return 1; | 205 | return 1; |
| 177 | 206 | ||
| 178 | memset (keystate, 0, sizeof (keystate)); | 207 | memset (keystate, 0, sizeof (keystate)); |
| 208 | keystate[key_code] = 0x80; | ||
| 179 | if (mods & SHIFT_PRESSED) | 209 | if (mods & SHIFT_PRESSED) |
| 180 | keystate[VK_SHIFT] = 0x80; | 210 | keystate[VK_SHIFT] = 0x80; |
| 181 | if (mods & CAPSLOCK_ON) | 211 | if (mods & CAPSLOCK_ON) |
| @@ -191,235 +221,226 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event) | |||
| 191 | keystate[VK_RMENU] = 0x80; | 221 | keystate[VK_RMENU] = 0x80; |
| 192 | } | 222 | } |
| 193 | 223 | ||
| 194 | isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode, | 224 | #if 0 |
| 195 | keystate, (LPWORD) ansi_code, 0); | 225 | /* Because of an OS bug, ToAscii corrupts the stack when called to |
| 226 | convert a dead key in console mode on NT4. Unfortunately, trying | ||
| 227 | to check for dead keys using MapVirtualKey doesn't work either - | ||
| 228 | these functions apparently use internal information about keyboard | ||
| 229 | layout which doesn't get properly updated in console programs when | ||
| 230 | changing layout (though apparently it gets partly updated, | ||
| 231 | otherwise ToAscii wouldn't crash). */ | ||
| 232 | if (is_dead_key (event->wVirtualKeyCode)) | ||
| 233 | return 0; | ||
| 234 | #endif | ||
| 235 | |||
| 236 | /* On NT, call ToUnicode instead and then convert to the current | ||
| 237 | locale's default codepage. */ | ||
| 238 | if (os_subtype == OS_NT) | ||
| 239 | { | ||
| 240 | WCHAR buf[128]; | ||
| 241 | |||
| 242 | isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode, | ||
| 243 | keystate, buf, 128, 0); | ||
| 244 | if (isdead > 0) | ||
| 245 | { | ||
| 246 | char cp[20]; | ||
| 247 | int cpId; | ||
| 248 | |||
| 249 | GetLocaleInfo (GetThreadLocale (), | ||
| 250 | LOCALE_IDEFAULTANSICODEPAGE, cp, 20); | ||
| 251 | cpId = atoi (cp); | ||
| 252 | isdead = WideCharToMultiByte (cpId, 0, buf, isdead, | ||
| 253 | ansi_code, 4, NULL, NULL); | ||
| 254 | } | ||
| 255 | else | ||
| 256 | isdead = 0; | ||
| 257 | } | ||
| 258 | else | ||
| 259 | { | ||
| 260 | isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode, | ||
| 261 | keystate, (LPWORD) ansi_code, 0); | ||
| 262 | } | ||
| 263 | |||
| 196 | if (isdead == 0) | 264 | if (isdead == 0) |
| 197 | return 0; | 265 | return 0; |
| 198 | event->uChar.AsciiChar = ansi_code[0]; | 266 | event->uChar.AsciiChar = ansi_code[0]; |
| 199 | return isdead; | 267 | return isdead; |
| 200 | } | 268 | } |
| 201 | 269 | ||
| 202 | /* Map virtual key codes into: | ||
| 203 | -1 - Ignore this key | ||
| 204 | -2 - ASCII char | ||
| 205 | Other - Map non-ASCII keys into X keysyms so that they are looked up | ||
| 206 | correctly in keyboard.c | ||
| 207 | |||
| 208 | Return, escape and tab are mapped to ASCII rather than coming back | ||
| 209 | as non-ASCII to be more compatible with old-style keyboard support. */ | ||
| 210 | 270 | ||
| 211 | static int map_virt_key[256] = | 271 | extern char *lispy_function_keys[]; |
| 212 | { | ||
| 213 | #ifdef MULE | ||
| 214 | -3, | ||
| 215 | #else | ||
| 216 | -1, | ||
| 217 | #endif | ||
| 218 | -1, /* VK_LBUTTON */ | ||
| 219 | -1, /* VK_RBUTTON */ | ||
| 220 | 0x69, /* VK_CANCEL */ | ||
| 221 | -1, /* VK_MBUTTON */ | ||
| 222 | -1, -1, -1, | ||
| 223 | 8, /* VK_BACK */ | ||
| 224 | -2, /* VK_TAB */ | ||
| 225 | -1, -1, | ||
| 226 | 11, /* VK_CLEAR */ | ||
| 227 | -2, /* VK_RETURN */ | ||
| 228 | -1, -1, | ||
| 229 | -1, /* VK_SHIFT */ | ||
| 230 | -1, /* VK_CONTROL */ | ||
| 231 | -1, /* VK_MENU */ | ||
| 232 | 0x13, /* VK_PAUSE */ | ||
| 233 | -1, /* VK_CAPITAL */ | ||
| 234 | -1, -1, -1, -1, -1, -1, | ||
| 235 | -2, /* VK_ESCAPE */ | ||
| 236 | -1, -1, -1, -1, | ||
| 237 | -2, /* VK_SPACE */ | ||
| 238 | 0x55, /* VK_PRIOR */ | ||
| 239 | 0x56, /* VK_NEXT */ | ||
| 240 | 0x57, /* VK_END */ | ||
| 241 | 0x50, /* VK_HOME */ | ||
| 242 | 0x51, /* VK_LEFT */ | ||
| 243 | 0x52, /* VK_UP */ | ||
| 244 | 0x53, /* VK_RIGHT */ | ||
| 245 | 0x54, /* VK_DOWN */ | ||
| 246 | 0x60, /* VK_SELECT */ | ||
| 247 | 0x61, /* VK_PRINT */ | ||
| 248 | 0x62, /* VK_EXECUTE */ | ||
| 249 | -1, /* VK_SNAPSHOT */ | ||
| 250 | 0x63, /* VK_INSERT */ | ||
| 251 | 0xff, /* VK_DELETE */ | ||
| 252 | 0x6a, /* VK_HELP */ | ||
| 253 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, /* 0 - 9 */ | ||
| 254 | -1, -1, -1, -1, -1, -1, -1, | ||
| 255 | -2, -2, -2, -2, -2, -2, -2, -2, /* A - Z */ | ||
| 256 | -2, -2, -2, -2, -2, -2, -2, -2, | ||
| 257 | -2, -2, -2, -2, -2, -2, -2, -2, | ||
| 258 | -2, -2, | ||
| 259 | -1, -1, -1, -1, -1, | ||
| 260 | 0xb0, /* VK_NUMPAD0 */ | ||
| 261 | 0xb1, /* VK_NUMPAD1 */ | ||
| 262 | 0xb2, /* VK_NUMPAD2 */ | ||
| 263 | 0xb3, /* VK_NUMPAD3 */ | ||
| 264 | 0xb4, /* VK_NUMPAD4 */ | ||
| 265 | 0xb5, /* VK_NUMPAD5 */ | ||
| 266 | 0xb6, /* VK_NUMPAD6 */ | ||
| 267 | 0xb7, /* VK_NUMPAD7 */ | ||
| 268 | 0xb8, /* VK_NUMPAD8 */ | ||
| 269 | 0xb9, /* VK_NUMPAD9 */ | ||
| 270 | 0xaa, /* VK_MULTIPLY */ | ||
| 271 | 0xab, /* VK_ADD */ | ||
| 272 | 0xac, /* VK_SEPARATOR */ | ||
| 273 | 0xad, /* VK_SUBTRACT */ | ||
| 274 | 0xae, /* VK_DECIMAL */ | ||
| 275 | 0xaf, /* VK_DIVIDE */ | ||
| 276 | 0xbe, /* VK_F1 */ | ||
| 277 | 0xbf, /* VK_F2 */ | ||
| 278 | 0xc0, /* VK_F3 */ | ||
| 279 | 0xc1, /* VK_F4 */ | ||
| 280 | 0xc2, /* VK_F5 */ | ||
| 281 | 0xc3, /* VK_F6 */ | ||
| 282 | 0xc4, /* VK_F7 */ | ||
| 283 | 0xc5, /* VK_F8 */ | ||
| 284 | 0xc6, /* VK_F9 */ | ||
| 285 | 0xc7, /* VK_F10 */ | ||
| 286 | 0xc8, /* VK_F11 */ | ||
| 287 | 0xc9, /* VK_F12 */ | ||
| 288 | 0xca, /* VK_F13 */ | ||
| 289 | 0xcb, /* VK_F14 */ | ||
| 290 | 0xcc, /* VK_F15 */ | ||
| 291 | 0xcd, /* VK_F16 */ | ||
| 292 | 0xce, /* VK_F17 */ | ||
| 293 | 0xcf, /* VK_F18 */ | ||
| 294 | 0xd0, /* VK_F19 */ | ||
| 295 | 0xd1, /* VK_F20 */ | ||
| 296 | 0xd2, /* VK_F21 */ | ||
| 297 | 0xd3, /* VK_F22 */ | ||
| 298 | 0xd4, /* VK_F23 */ | ||
| 299 | 0xd5, /* VK_F24 */ | ||
| 300 | -1, -1, -1, -1, -1, -1, -1, -1, | ||
| 301 | 0x7f, /* VK_NUMLOCK */ | ||
| 302 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9f */ | ||
| 303 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xaf */ | ||
| 304 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb9 */ | ||
| 305 | -2, /* ; */ | ||
| 306 | -2, /* = */ | ||
| 307 | -2, /* , */ | ||
| 308 | -2, /* \ */ | ||
| 309 | -2, /* . */ | ||
| 310 | -2, /* / */ | ||
| 311 | -2, /* ` */ | ||
| 312 | -2, /* 0xc1: on Brazilian keyboards, this is the /(?) key. */ | ||
| 313 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xcf */ | ||
| 314 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xda */ | ||
| 315 | -2, -2, -2, -2, -2, /* 0xdf */ | ||
| 316 | -2, -2, -2, -2, -2, | ||
| 317 | -1, /* 0xe5 */ | ||
| 318 | -2, /* oxe6 */ | ||
| 319 | -1, -1, /* 0xe8 */ | ||
| 320 | -2, -2, -2, -2, -2, -2, -2, /* 0xef */ | ||
| 321 | -2, -2, -2, -2, -2, -2, | ||
| 322 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* 0xff */ | ||
| 323 | }; | ||
| 324 | 272 | ||
| 325 | /* return code -1 means that event_queue_ptr won't be incremented. | 273 | /* return code -1 means that event_queue_ptr won't be incremented. |
| 326 | In other word, this event makes two key codes. (by himi) */ | 274 | In other word, this event makes two key codes. (by himi) */ |
| 327 | int | 275 | int |
| 328 | key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead) | 276 | key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead) |
| 329 | { | 277 | { |
| 330 | int map; | 278 | static int faked_key = 0; |
| 331 | int key_flag = 0; | 279 | static int mod_key_state = 0; |
| 332 | static BOOL map_virt_key_init_done; | 280 | int wParam; |
| 333 | 281 | ||
| 334 | *isdead = 0; | 282 | *isdead = 0; |
| 335 | 283 | ||
| 336 | /* Skip key-up events. */ | 284 | /* Skip key-up events. */ |
| 337 | if (!event->bKeyDown) | 285 | if (!event->bKeyDown) |
| 338 | return 0; | ||
| 339 | |||
| 340 | if (event->wVirtualKeyCode > 0xff) | ||
| 341 | { | 286 | { |
| 342 | printf ("Unknown key code %d\n", event->wVirtualKeyCode); | 287 | switch (event->wVirtualKeyCode) |
| 288 | { | ||
| 289 | case VK_LWIN: | ||
| 290 | mod_key_state &= ~LEFT_WIN_PRESSED; | ||
| 291 | break; | ||
| 292 | case VK_RWIN: | ||
| 293 | mod_key_state &= ~RIGHT_WIN_PRESSED; | ||
| 294 | break; | ||
| 295 | case VK_APPS: | ||
| 296 | mod_key_state &= ~APPS_PRESSED; | ||
| 297 | break; | ||
| 298 | } | ||
| 343 | return 0; | 299 | return 0; |
| 344 | } | 300 | } |
| 345 | 301 | ||
| 346 | /* Patch needed for German keyboard. Ulrich Leodolter (1/11/95). */ | 302 | /* Ignore keystrokes we fake ourself; see below. */ |
| 347 | if (! map_virt_key_init_done) | 303 | if (faked_key == event->wVirtualKeyCode) |
| 348 | { | ||
| 349 | short vk; | ||
| 350 | |||
| 351 | if ((vk = VkKeyScan (0x3c)) >= 0 && vk < 256) map_virt_key[vk] = -2; /* less */ | ||
| 352 | if ((vk = VkKeyScan (0x3e)) >= 0 && vk < 256) map_virt_key[vk] = -2; /* greater */ | ||
| 353 | |||
| 354 | map_virt_key_init_done = TRUE; | ||
| 355 | } | ||
| 356 | |||
| 357 | /* BUGBUG - Ignores the repeat count | ||
| 358 | It's questionable whether we want to obey the repeat count anyway | ||
| 359 | since keys usually aren't repeated unless key events back up in | ||
| 360 | the queue. If they're backing up then we don't generally want | ||
| 361 | to honor them later since that leads to significant slop in | ||
| 362 | cursor motion when the system is under heavy load. */ | ||
| 363 | |||
| 364 | map = map_virt_key[event->wVirtualKeyCode]; | ||
| 365 | if (map == -1) | ||
| 366 | { | 304 | { |
| 305 | faked_key = 0; | ||
| 367 | return 0; | 306 | return 0; |
| 368 | } | 307 | } |
| 369 | else if (map == -2) | 308 | |
| 309 | /* To make it easier to debug this code, ignore modifier keys! */ | ||
| 310 | switch (event->wVirtualKeyCode) | ||
| 370 | { | 311 | { |
| 371 | /* ASCII */ | 312 | case VK_LWIN: |
| 372 | emacs_ev->kind = ascii_keystroke; | 313 | if (NILP (Vw32_pass_lwindow_to_system)) |
| 373 | key_flag = w32_kbd_patch_key (event); /* 95.7.25 by himi */ | 314 | { |
| 374 | if (key_flag == 0) | 315 | /* Prevent system from acting on keyup (which opens the Start |
| 316 | menu if no other key was pressed) by simulating a press of | ||
| 317 | Space which we will ignore. */ | ||
| 318 | if ((mod_key_state & LEFT_WIN_PRESSED) == 0) | ||
| 319 | { | ||
| 320 | faked_key = VK_SPACE; | ||
| 321 | keybd_event (VK_SPACE, (BYTE) MapVirtualKey (VK_SPACE, 0), 0, 0); | ||
| 322 | } | ||
| 323 | } | ||
| 324 | mod_key_state |= LEFT_WIN_PRESSED; | ||
| 325 | if (!NILP (Vw32_lwindow_modifier)) | ||
| 375 | return 0; | 326 | return 0; |
| 376 | if (key_flag < 0) | 327 | break; |
| 377 | *isdead = 1; | 328 | case VK_RWIN: |
| 378 | XSETINT (emacs_ev->code, event->uChar.AsciiChar); | 329 | if (NILP (Vw32_pass_rwindow_to_system)) |
| 330 | { | ||
| 331 | if ((mod_key_state & RIGHT_WIN_PRESSED) == 0) | ||
| 332 | { | ||
| 333 | faked_key = VK_SPACE; | ||
| 334 | keybd_event (VK_SPACE, (BYTE) MapVirtualKey (VK_SPACE, 0), 0, 0); | ||
| 335 | } | ||
| 336 | } | ||
| 337 | mod_key_state |= RIGHT_WIN_PRESSED; | ||
| 338 | if (!NILP (Vw32_rwindow_modifier)) | ||
| 339 | return 0; | ||
| 340 | break; | ||
| 341 | case VK_APPS: | ||
| 342 | mod_key_state |= APPS_PRESSED; | ||
| 343 | if (!NILP (Vw32_apps_modifier)) | ||
| 344 | return 0; | ||
| 345 | break; | ||
| 346 | case VK_CAPITAL: | ||
| 347 | /* Decide whether to treat as modifier or function key. */ | ||
| 348 | if (NILP (Vw32_enable_caps_lock)) | ||
| 349 | goto disable_lock_key; | ||
| 350 | return 0; | ||
| 351 | case VK_NUMLOCK: | ||
| 352 | /* Decide whether to treat as modifier or function key. */ | ||
| 353 | if (NILP (Vw32_enable_num_lock)) | ||
| 354 | goto disable_lock_key; | ||
| 355 | return 0; | ||
| 356 | case VK_SCROLL: | ||
| 357 | /* Decide whether to treat as modifier or function key. */ | ||
| 358 | if (NILP (Vw32_scroll_lock_modifier)) | ||
| 359 | goto disable_lock_key; | ||
| 360 | return 0; | ||
| 361 | disable_lock_key: | ||
| 362 | /* Ensure the appropriate lock key state is off (and the | ||
| 363 | indicator light as well). */ | ||
| 364 | wParam = event->wVirtualKeyCode; | ||
| 365 | if (GetAsyncKeyState (wParam) & 0x8000) | ||
| 366 | { | ||
| 367 | /* Fake another press of the relevant key. Apparently, this | ||
| 368 | really is the only way to turn off the indicator. */ | ||
| 369 | faked_key = wParam; | ||
| 370 | keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0), | ||
| 371 | KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); | ||
| 372 | keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0), | ||
| 373 | KEYEVENTF_EXTENDEDKEY | 0, 0); | ||
| 374 | keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0), | ||
| 375 | KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); | ||
| 376 | } | ||
| 377 | break; | ||
| 378 | case VK_MENU: | ||
| 379 | case VK_CONTROL: | ||
| 380 | case VK_SHIFT: | ||
| 381 | return 0; | ||
| 379 | } | 382 | } |
| 380 | #ifdef MULE | 383 | |
| 381 | /* for IME */ | 384 | /* Recognize state of Windows and Apps keys. */ |
| 382 | else if (map == -3) | 385 | event->dwControlKeyState |= mod_key_state; |
| 386 | |||
| 387 | /* Distinguish numeric keypad keys from extended keys. */ | ||
| 388 | event->wVirtualKeyCode = | ||
| 389 | map_keypad_keys (event->wVirtualKeyCode, | ||
| 390 | (event->dwControlKeyState & ENHANCED_KEY)); | ||
| 391 | |||
| 392 | if (lispy_function_keys[event->wVirtualKeyCode] == 0) | ||
| 383 | { | 393 | { |
| 384 | if ((event->dwControlKeyState & NLS_IME_CONVERSION) | 394 | emacs_ev->kind = ascii_keystroke; |
| 385 | && !(event->dwControlKeyState & RIGHT_ALT_PRESSED) | 395 | |
| 386 | && !(event->dwControlKeyState & LEFT_ALT_PRESSED) | 396 | if (!NILP (Vw32_recognize_altgr) |
| 387 | && !(event->dwControlKeyState & RIGHT_CTRL_PRESSED) | 397 | && (event->dwControlKeyState & LEFT_CTRL_PRESSED) |
| 388 | && !(event->dwControlKeyState & LEFT_CTRL_PRESSED)) | 398 | && (event->dwControlKeyState & RIGHT_ALT_PRESSED)) |
| 389 | { | 399 | { |
| 390 | emacs_ev->kind = ascii_keystroke; | 400 | /* Don't try to interpret AltGr key chords; ToAscii seems not |
| 391 | XSETINT (emacs_ev->code, event->uChar.AsciiChar); | 401 | to process them correctly. */ |
| 392 | } | 402 | } |
| 393 | else | 403 | /* Handle key chords including any modifiers other than shift |
| 404 | directly, in order to preserve as much modifier information as | ||
| 405 | possible. */ | ||
| 406 | else if (event->dwControlKeyState | ||
| 407 | & ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED | ||
| 408 | | RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED | ||
| 409 | | (!NILP (Vw32_lwindow_modifier) ? LEFT_WIN_PRESSED : 0) | ||
| 410 | | (!NILP (Vw32_rwindow_modifier) ? RIGHT_WIN_PRESSED : 0) | ||
| 411 | | (!NILP (Vw32_apps_modifier) ? APPS_PRESSED : 0) | ||
| 412 | | (!NILP (Vw32_scroll_lock_modifier) ? SCROLLLOCK_ON : 0))) | ||
| 413 | { | ||
| 414 | /* Don't translate modified alphabetic keystrokes, so the user | ||
| 415 | doesn't need to constantly switch layout to type control or | ||
| 416 | meta keystrokes when the normal layout translates | ||
| 417 | alphabetic characters to non-ascii characters. */ | ||
| 418 | if ('A' <= event->wVirtualKeyCode && event->wVirtualKeyCode <= 'Z') | ||
| 419 | { | ||
| 420 | event->uChar.AsciiChar = event->wVirtualKeyCode; | ||
| 421 | if ((event->dwControlKeyState & SHIFT_PRESSED) == 0) | ||
| 422 | event->uChar.AsciiChar += ('a' - 'A'); | ||
| 423 | } | ||
| 424 | /* Try to handle unrecognized keystrokes by determining the | ||
| 425 | base character (ie. translating the base key plus shift | ||
| 426 | modifier). */ | ||
| 427 | else if (event->uChar.AsciiChar == 0) | ||
| 428 | w32_kbd_patch_key (event); | ||
| 429 | } | ||
| 430 | if (event->uChar.AsciiChar == 0) | ||
| 394 | return 0; | 431 | return 0; |
| 432 | XSETINT (emacs_ev->code, event->uChar.AsciiChar); | ||
| 395 | } | 433 | } |
| 396 | #endif | ||
| 397 | else | 434 | else |
| 398 | { | 435 | { |
| 399 | /* non-ASCII */ | ||
| 400 | emacs_ev->kind = non_ascii_keystroke; | 436 | emacs_ev->kind = non_ascii_keystroke; |
| 401 | #ifdef HAVE_NTGUI | ||
| 402 | /* use Windows keysym map */ | ||
| 403 | XSETINT (emacs_ev->code, event->wVirtualKeyCode); | 437 | XSETINT (emacs_ev->code, event->wVirtualKeyCode); |
| 404 | #else | ||
| 405 | /* | ||
| 406 | * make_lispy_event () now requires non-ascii codes to have | ||
| 407 | * the full X keysym values (2nd byte is 0xff). add it on. | ||
| 408 | */ | ||
| 409 | map |= 0xff00; | ||
| 410 | XSETINT (emacs_ev->code, map); | ||
| 411 | #endif /* HAVE_NTGUI */ | ||
| 412 | } | 438 | } |
| 413 | /* for Mule 2.2 (Based on Emacs 19.28) */ | 439 | |
| 414 | #ifdef MULE | ||
| 415 | XSET (emacs_ev->frame_or_window, Lisp_Frame, get_frame ()); | ||
| 416 | #else | ||
| 417 | XSETFRAME (emacs_ev->frame_or_window, get_frame ()); | 440 | XSETFRAME (emacs_ev->frame_or_window, get_frame ()); |
| 418 | #endif | ||
| 419 | emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState, | 441 | emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState, |
| 420 | event->wVirtualKeyCode); | 442 | event->wVirtualKeyCode); |
| 421 | emacs_ev->timestamp = GetTickCount (); | 443 | emacs_ev->timestamp = GetTickCount (); |
| 422 | if (key_flag == 2) return -1; /* 95.7.25 by himi */ | ||
| 423 | return 1; | 444 | return 1; |
| 424 | } | 445 | } |
| 425 | 446 | ||