Mercurial > emacs
comparison src/w32fns.c @ 23681:af0276da2059
(Vw32_pass_optional_keys_to_system): Variable removed.
(Vw32_pass_lwindow_to_system):
(Vw32_pass_rwindow_to_system):
(Vw32_lwindow_modifier):
(Vw32_rwindow_modifier):
(Vw32_apps_modifier):
(Vw32_enable_num_lock):
(Vw32_enable_caps_lock):
(Vw32_scroll_lock_modifier): New variables.
(modifier_set): Return toggle state for Scroll Lock.
(w32_key_to_modifier): New function. Returns chosen modifier bit
for given key.
(w32_get_modifiers): Returns modifier flags for
non-keyboard input events.
(construct_console_modifiers): Renamed from construct_modifiers;
recognize Windows and Apps keys as modifiers.
(w32_get_key_modifiers): New function. Returns modifier flags for
keyboard input events.
(map_keypad_keys): Make non-static. Use second arg as extended
flag.
(w32_grabbed_keys): New variable.
(HOTKEY, HOTKEY_ID, HOTKEY_VK_CODE, HOTKEY_MODIFIERS): New macros.
(register_hot_keys):
(unregister_hot_keys):
(lookup_vk_code):
(w32_parse_hot_key):
(Fw32_register_hot_key):
(Fw32_unregister_hot_key):
(Fw32_registered_hot_keys):
(Fw32_reconstruct_hot_key): New functions to support hotkeys.
(post_character_message): New function.
(w32_msg_pump): Handle new messages for using hotkeys and changing
keyboard layout/language.
(w32_wnd_proc): 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; forward keyboard
layout/language changes to lisp; detect and convert hot-key events
to normal keystrokes.
(syms_of_w32fns): Register new functions and variables.
(w32_last_error): New function for use in debugging.
author | Geoff Voelker <voelker@cs.washington.edu> |
---|---|
date | Tue, 10 Nov 1998 20:54:46 +0000 |
parents | 54b22e0a1f7b |
children | 119fd94ae526 |
comparison
equal
deleted
inserted
replaced
23680:02e5da32da56 | 23681:af0276da2059 |
---|---|
48 extern void abort (); | 48 extern void abort (); |
49 extern void free_frame_menubar (); | 49 extern void free_frame_menubar (); |
50 extern struct scroll_bar *x_window_to_scroll_bar (); | 50 extern struct scroll_bar *x_window_to_scroll_bar (); |
51 extern int quit_char; | 51 extern int quit_char; |
52 | 52 |
53 extern char *lispy_function_keys[]; | |
54 | |
53 /* The colormap for converting color names to RGB values */ | 55 /* The colormap for converting color names to RGB values */ |
54 Lisp_Object Vw32_color_map; | 56 Lisp_Object Vw32_color_map; |
55 | 57 |
56 /* Non nil if alt key presses are passed on to Windows. */ | 58 /* Non nil if alt key presses are passed on to Windows. */ |
57 Lisp_Object Vw32_pass_alt_to_system; | 59 Lisp_Object Vw32_pass_alt_to_system; |
58 | 60 |
59 /* Non nil if alt key is translated to meta_modifier, nil if it is translated | 61 /* Non nil if alt key is translated to meta_modifier, nil if it is translated |
60 to alt_modifier. */ | 62 to alt_modifier. */ |
61 Lisp_Object Vw32_alt_is_meta; | 63 Lisp_Object Vw32_alt_is_meta; |
62 | 64 |
63 /* Non nil if left window, right window, and application key events | 65 /* Non nil if left window key events are passed on to Windows (this only |
64 are passed on to Windows. */ | 66 affects whether "tapping" the key opens the Start menu). */ |
65 Lisp_Object Vw32_pass_optional_keys_to_system; | 67 Lisp_Object Vw32_pass_lwindow_to_system; |
68 | |
69 /* Non nil if right window key events are passed on to Windows (this | |
70 only affects whether "tapping" the key opens the Start menu). */ | |
71 Lisp_Object Vw32_pass_rwindow_to_system; | |
72 | |
73 /* Modifier associated with the left "Windows" key, or nil to act as a | |
74 normal key. */ | |
75 Lisp_Object Vw32_lwindow_modifier; | |
76 | |
77 /* Modifier associated with the right "Windows" key, or nil to act as a | |
78 normal key. */ | |
79 Lisp_Object Vw32_rwindow_modifier; | |
80 | |
81 /* Modifier associated with the "Apps" key, or nil to act as a normal | |
82 key. */ | |
83 Lisp_Object Vw32_apps_modifier; | |
84 | |
85 /* Value is nil if Num Lock acts as a function key. */ | |
86 Lisp_Object Vw32_enable_num_lock; | |
87 | |
88 /* Value is nil if Caps Lock acts as a function key. */ | |
89 Lisp_Object Vw32_enable_caps_lock; | |
90 | |
91 /* Modifier associated with Scroll Lock, or nil to act as a normal key. */ | |
92 Lisp_Object Vw32_scroll_lock_modifier; | |
66 | 93 |
67 /* Switch to control whether we inhibit requests for italicised fonts (which | 94 /* Switch to control whether we inhibit requests for italicised fonts (which |
68 are synthesized, look ugly, and are trashed by cursor movement under NT). */ | 95 are synthesized, look ugly, and are trashed by cursor movement under NT). */ |
69 Lisp_Object Vw32_enable_italics; | 96 Lisp_Object Vw32_enable_italics; |
70 | 97 |
203 extern Lisp_Object last_mouse_scroll_bar; | 230 extern Lisp_Object last_mouse_scroll_bar; |
204 extern int last_mouse_scroll_bar_pos; | 231 extern int last_mouse_scroll_bar_pos; |
205 | 232 |
206 /* From w32term.c. */ | 233 /* From w32term.c. */ |
207 extern Lisp_Object Vw32_num_mouse_buttons; | 234 extern Lisp_Object Vw32_num_mouse_buttons; |
235 extern Lisp_Object Vw32_recognize_altgr; | |
208 | 236 |
209 | 237 |
210 /* Error if we are not connected to MS-Windows. */ | 238 /* Error if we are not connected to MS-Windows. */ |
211 void | 239 void |
212 check_w32 () | 240 check_w32 () |
2957 /* Do this to discard the default setting specified by our parent. */ | 2985 /* Do this to discard the default setting specified by our parent. */ |
2958 ShowWindow (hwnd, SW_HIDE); | 2986 ShowWindow (hwnd, SW_HIDE); |
2959 } | 2987 } |
2960 } | 2988 } |
2961 | 2989 |
2962 /* Convert between the modifier bits W32 uses and the modifier bits | |
2963 Emacs uses. */ | |
2964 unsigned int | |
2965 w32_get_modifiers () | |
2966 { | |
2967 return (((GetKeyState (VK_SHIFT)&0x8000) ? shift_modifier : 0) | | |
2968 ((GetKeyState (VK_CONTROL)&0x8000) ? ctrl_modifier : 0) | | |
2969 ((GetKeyState (VK_MENU)&0x8000) ? | |
2970 ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier) : 0)); | |
2971 } | |
2972 | |
2973 void | 2990 void |
2974 my_post_msg (wmsg, hwnd, msg, wParam, lParam) | 2991 my_post_msg (wmsg, hwnd, msg, wParam, lParam) |
2975 W32Msg * wmsg; | 2992 W32Msg * wmsg; |
2976 HWND hwnd; | 2993 HWND hwnd; |
2977 UINT msg; | 2994 UINT msg; |
3114 } | 3131 } |
3115 | 3132 |
3116 static int | 3133 static int |
3117 modifier_set (int vkey) | 3134 modifier_set (int vkey) |
3118 { | 3135 { |
3119 if (vkey == VK_CAPITAL) | 3136 if (vkey == VK_CAPITAL || vkey == VK_SCROLL) |
3120 return (GetKeyState (vkey) & 0x1); | 3137 return (GetKeyState (vkey) & 0x1); |
3121 if (!modifiers_recorded) | 3138 if (!modifiers_recorded) |
3122 return (GetKeyState (vkey) & 0x8000); | 3139 return (GetKeyState (vkey) & 0x8000); |
3123 | 3140 |
3124 switch (vkey) | 3141 switch (vkey) |
3129 return modifiers[EMACS_RCONTROL]; | 3146 return modifiers[EMACS_RCONTROL]; |
3130 case VK_LMENU: | 3147 case VK_LMENU: |
3131 return modifiers[EMACS_LMENU]; | 3148 return modifiers[EMACS_LMENU]; |
3132 case VK_RMENU: | 3149 case VK_RMENU: |
3133 return modifiers[EMACS_RMENU]; | 3150 return modifiers[EMACS_RMENU]; |
3151 } | |
3152 return (GetKeyState (vkey) & 0x8000); | |
3153 } | |
3154 | |
3155 /* Convert between the modifier bits W32 uses and the modifier bits | |
3156 Emacs uses. */ | |
3157 | |
3158 unsigned int | |
3159 w32_key_to_modifier (int key) | |
3160 { | |
3161 Lisp_Object key_mapping; | |
3162 | |
3163 switch (key) | |
3164 { | |
3165 case VK_LWIN: | |
3166 key_mapping = Vw32_lwindow_modifier; | |
3167 break; | |
3168 case VK_RWIN: | |
3169 key_mapping = Vw32_rwindow_modifier; | |
3170 break; | |
3171 case VK_APPS: | |
3172 key_mapping = Vw32_apps_modifier; | |
3173 break; | |
3174 case VK_SCROLL: | |
3175 key_mapping = Vw32_scroll_lock_modifier; | |
3176 break; | |
3134 default: | 3177 default: |
3135 break; | 3178 key_mapping = Qnil; |
3136 } | 3179 } |
3137 return (GetKeyState (vkey) & 0x8000); | 3180 |
3181 if (EQ (key_mapping, intern ("hyper"))) | |
3182 return hyper_modifier; | |
3183 if (EQ (key_mapping, intern ("super"))) | |
3184 return super_modifier; | |
3185 if (EQ (key_mapping, intern ("meta"))) | |
3186 return meta_modifier; | |
3187 if (EQ (key_mapping, intern ("alt"))) | |
3188 return alt_modifier; | |
3189 if (EQ (key_mapping, intern ("ctrl"))) | |
3190 return ctrl_modifier; | |
3191 if (EQ (key_mapping, intern ("control"))) /* synonym for ctrl */ | |
3192 return ctrl_modifier; | |
3193 if (EQ (key_mapping, intern ("shift"))) | |
3194 return shift_modifier; | |
3195 | |
3196 /* Don't generate any modifier if not explicitly requested. */ | |
3197 return 0; | |
3198 } | |
3199 | |
3200 unsigned int | |
3201 w32_get_modifiers () | |
3202 { | |
3203 return ((modifier_set (VK_SHIFT) ? shift_modifier : 0) | | |
3204 (modifier_set (VK_CONTROL) ? ctrl_modifier : 0) | | |
3205 (modifier_set (VK_LWIN) ? w32_key_to_modifier (VK_LWIN) : 0) | | |
3206 (modifier_set (VK_RWIN) ? w32_key_to_modifier (VK_RWIN) : 0) | | |
3207 (modifier_set (VK_APPS) ? w32_key_to_modifier (VK_APPS) : 0) | | |
3208 (modifier_set (VK_SCROLL) ? w32_key_to_modifier (VK_SCROLL) : 0) | | |
3209 (modifier_set (VK_MENU) ? | |
3210 ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier) : 0)); | |
3138 } | 3211 } |
3139 | 3212 |
3140 /* We map the VK_* modifiers into console modifier constants | 3213 /* We map the VK_* modifiers into console modifier constants |
3141 so that we can use the same routines to handle both console | 3214 so that we can use the same routines to handle both console |
3142 and window input. */ | 3215 and window input. */ |
3143 | 3216 |
3144 static int | 3217 static int |
3145 construct_modifiers (unsigned int wparam, unsigned int lparam) | 3218 construct_console_modifiers () |
3146 { | 3219 { |
3147 int mods; | 3220 int mods; |
3148 | |
3149 if (wparam != VK_CONTROL && wparam != VK_MENU) | |
3150 mods = GetLastError (); | |
3151 | 3221 |
3152 mods = 0; | 3222 mods = 0; |
3153 mods |= (modifier_set (VK_SHIFT)) ? SHIFT_PRESSED : 0; | 3223 mods |= (modifier_set (VK_SHIFT)) ? SHIFT_PRESSED : 0; |
3154 mods |= (modifier_set (VK_CAPITAL)) ? CAPSLOCK_ON : 0; | 3224 mods |= (modifier_set (VK_CAPITAL)) ? CAPSLOCK_ON : 0; |
3225 mods |= (modifier_set (VK_SCROLL)) ? SCROLLLOCK_ON : 0; | |
3226 mods |= (modifier_set (VK_NUMLOCK)) ? NUMLOCK_ON : 0; | |
3155 mods |= (modifier_set (VK_LCONTROL)) ? LEFT_CTRL_PRESSED : 0; | 3227 mods |= (modifier_set (VK_LCONTROL)) ? LEFT_CTRL_PRESSED : 0; |
3156 mods |= (modifier_set (VK_RCONTROL)) ? RIGHT_CTRL_PRESSED : 0; | 3228 mods |= (modifier_set (VK_RCONTROL)) ? RIGHT_CTRL_PRESSED : 0; |
3157 mods |= (modifier_set (VK_LMENU)) ? LEFT_ALT_PRESSED : 0; | 3229 mods |= (modifier_set (VK_LMENU)) ? LEFT_ALT_PRESSED : 0; |
3158 mods |= (modifier_set (VK_RMENU)) ? RIGHT_ALT_PRESSED : 0; | 3230 mods |= (modifier_set (VK_RMENU)) ? RIGHT_ALT_PRESSED : 0; |
3231 mods |= (modifier_set (VK_LWIN)) ? LEFT_WIN_PRESSED : 0; | |
3232 mods |= (modifier_set (VK_RWIN)) ? RIGHT_WIN_PRESSED : 0; | |
3233 mods |= (modifier_set (VK_APPS)) ? APPS_PRESSED : 0; | |
3159 | 3234 |
3160 return mods; | 3235 return mods; |
3161 } | 3236 } |
3162 | 3237 |
3163 static unsigned int | 3238 static int |
3164 map_keypad_keys (unsigned int wparam, unsigned int lparam) | 3239 w32_get_key_modifiers (unsigned int wparam, unsigned int lparam) |
3165 { | 3240 { |
3166 unsigned int extended = (lparam & 0x1000000L); | 3241 int mods; |
3167 | 3242 |
3168 if (wparam < VK_CLEAR || wparam > VK_DELETE) | 3243 /* Convert to emacs modifiers. */ |
3169 return wparam; | 3244 mods = w32_kbd_mods_to_emacs (construct_console_modifiers (), wparam); |
3170 | 3245 |
3171 if (wparam == VK_RETURN) | 3246 return mods; |
3247 } | |
3248 | |
3249 unsigned int | |
3250 map_keypad_keys (unsigned int virt_key, unsigned int extended) | |
3251 { | |
3252 if (virt_key < VK_CLEAR || virt_key > VK_DELETE) | |
3253 return virt_key; | |
3254 | |
3255 if (virt_key == VK_RETURN) | |
3172 return (extended ? VK_NUMPAD_ENTER : VK_RETURN); | 3256 return (extended ? VK_NUMPAD_ENTER : VK_RETURN); |
3173 | 3257 |
3174 if (wparam >= VK_PRIOR && wparam <= VK_DOWN) | 3258 if (virt_key >= VK_PRIOR && virt_key <= VK_DOWN) |
3175 return (!extended ? (VK_NUMPAD_PRIOR + (wparam - VK_PRIOR)) : wparam); | 3259 return (!extended ? (VK_NUMPAD_PRIOR + (virt_key - VK_PRIOR)) : virt_key); |
3176 | 3260 |
3177 if (wparam == VK_INSERT || wparam == VK_DELETE) | 3261 if (virt_key == VK_INSERT || virt_key == VK_DELETE) |
3178 return (!extended ? (VK_NUMPAD_INSERT + (wparam - VK_INSERT)) : wparam); | 3262 return (!extended ? (VK_NUMPAD_INSERT + (virt_key - VK_INSERT)) : virt_key); |
3179 | 3263 |
3180 if (wparam == VK_CLEAR) | 3264 if (virt_key == VK_CLEAR) |
3181 return (!extended ? VK_NUMPAD_CLEAR : wparam); | 3265 return (!extended ? VK_NUMPAD_CLEAR : virt_key); |
3182 | 3266 |
3183 return wparam; | 3267 return virt_key; |
3268 } | |
3269 | |
3270 /* List of special key combinations which w32 would normally capture, | |
3271 but emacs should grab instead. Not directly visible to lisp, to | |
3272 simplify synchronization. Each item is an integer encoding a virtual | |
3273 key code and modifier combination to capture. */ | |
3274 Lisp_Object w32_grabbed_keys; | |
3275 | |
3276 #define HOTKEY(vk,mods) make_number (((vk) & 255) | ((mods) << 8)) | |
3277 #define HOTKEY_ID(k) (XFASTINT (k) & 0xbfff) | |
3278 #define HOTKEY_VK_CODE(k) (XFASTINT (k) & 255) | |
3279 #define HOTKEY_MODIFIERS(k) (XFASTINT (k) >> 8) | |
3280 | |
3281 /* Register hot-keys for reserved key combinations when Emacs has | |
3282 keyboard focus, since this is the only way Emacs can receive key | |
3283 combinations like Alt-Tab which are used by the system. */ | |
3284 | |
3285 static void | |
3286 register_hot_keys (hwnd) | |
3287 HWND hwnd; | |
3288 { | |
3289 Lisp_Object keylist; | |
3290 | |
3291 /* Use GC_CONSP, since we are called asynchronously. */ | |
3292 for (keylist = w32_grabbed_keys; GC_CONSP (keylist); keylist = XCDR (keylist)) | |
3293 { | |
3294 Lisp_Object key = XCAR (keylist); | |
3295 | |
3296 /* Deleted entries get set to nil. */ | |
3297 if (!INTEGERP (key)) | |
3298 continue; | |
3299 | |
3300 RegisterHotKey (hwnd, HOTKEY_ID (key), | |
3301 HOTKEY_MODIFIERS (key), HOTKEY_VK_CODE (key)); | |
3302 } | |
3303 } | |
3304 | |
3305 static void | |
3306 unregister_hot_keys (hwnd) | |
3307 HWND hwnd; | |
3308 { | |
3309 Lisp_Object keylist; | |
3310 | |
3311 /* Use GC_CONSP, since we are called asynchronously. */ | |
3312 for (keylist = w32_grabbed_keys; GC_CONSP (keylist); keylist = XCDR (keylist)) | |
3313 { | |
3314 Lisp_Object key = XCAR (keylist); | |
3315 | |
3316 if (!INTEGERP (key)) | |
3317 continue; | |
3318 | |
3319 UnregisterHotKey (hwnd, HOTKEY_ID (key)); | |
3320 } | |
3321 } | |
3322 | |
3323 static void | |
3324 post_character_message (hwnd, msg, wParam, lParam, modifiers) | |
3325 HWND hwnd; | |
3326 UINT msg; | |
3327 WPARAM wParam; | |
3328 LPARAM lParam; | |
3329 DWORD modifiers; | |
3330 | |
3331 { | |
3332 W32Msg wmsg; | |
3333 | |
3334 wmsg.dwModifiers = modifiers; | |
3335 | |
3336 /* Detect quit_char and set quit-flag directly. Note that we | |
3337 still need to post a message to ensure the main thread will be | |
3338 woken up if blocked in sys_select(), but we do NOT want to post | |
3339 the quit_char message itself (because it will usually be as if | |
3340 the user had typed quit_char twice). Instead, we post a dummy | |
3341 message that has no particular effect. */ | |
3342 { | |
3343 int c = wParam; | |
3344 if (isalpha (c) && wmsg.dwModifiers == ctrl_modifier) | |
3345 c = make_ctrl_char (c) & 0377; | |
3346 if (c == quit_char) | |
3347 { | |
3348 Vquit_flag = Qt; | |
3349 | |
3350 /* The choice of message is somewhat arbitrary, as long as | |
3351 the main thread handler just ignores it. */ | |
3352 msg = WM_NULL; | |
3353 | |
3354 /* Interrupt any blocking system calls. */ | |
3355 signal_quit (); | |
3356 } | |
3357 } | |
3358 | |
3359 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | |
3184 } | 3360 } |
3185 | 3361 |
3186 /* Main message dispatch loop. */ | 3362 /* Main message dispatch loop. */ |
3187 | 3363 |
3188 static void | 3364 static void |
3189 w32_msg_pump (deferred_msg * msg_buf) | 3365 w32_msg_pump (deferred_msg * msg_buf) |
3190 { | 3366 { |
3191 MSG msg; | 3367 MSG msg; |
3368 int result; | |
3369 HWND focus_window; | |
3192 | 3370 |
3193 msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL); | 3371 msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL); |
3194 | 3372 |
3195 while (GetMessage (&msg, NULL, 0, 0)) | 3373 while (GetMessage (&msg, NULL, 0, 0)) |
3196 { | 3374 { |
3205 break; | 3383 break; |
3206 case WM_EMACS_SETLOCALE: | 3384 case WM_EMACS_SETLOCALE: |
3207 SetThreadLocale (msg.wParam); | 3385 SetThreadLocale (msg.wParam); |
3208 /* Reply is not expected. */ | 3386 /* Reply is not expected. */ |
3209 break; | 3387 break; |
3388 case WM_EMACS_SETKEYBOARDLAYOUT: | |
3389 result = (int) ActivateKeyboardLayout ((HKL) msg.wParam, 0); | |
3390 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, | |
3391 result, 0)) | |
3392 abort (); | |
3393 break; | |
3394 case WM_EMACS_REGISTER_HOT_KEY: | |
3395 focus_window = GetFocus (); | |
3396 if (focus_window != NULL) | |
3397 RegisterHotKey (focus_window, | |
3398 HOTKEY_ID (msg.wParam), | |
3399 HOTKEY_MODIFIERS (msg.wParam), | |
3400 HOTKEY_VK_CODE (msg.wParam)); | |
3401 /* Reply is not expected. */ | |
3402 break; | |
3403 case WM_EMACS_UNREGISTER_HOT_KEY: | |
3404 focus_window = GetFocus (); | |
3405 if (focus_window != NULL) | |
3406 UnregisterHotKey (focus_window, HOTKEY_ID (msg.wParam)); | |
3407 /* Mark item as erased. */ | |
3408 XCAR ((Lisp_Object) msg.lParam) = Qnil; | |
3409 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) | |
3410 abort (); | |
3411 break; | |
3210 default: | 3412 default: |
3211 /* No need to be so draconian! */ | |
3212 /* abort (); */ | |
3213 DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message)); | 3413 DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message)); |
3214 } | 3414 } |
3215 } | 3415 } |
3216 else | 3416 else |
3217 { | 3417 { |
3323 | 3523 |
3324 return 0; | 3524 return 0; |
3325 } | 3525 } |
3326 | 3526 |
3327 /* Main window procedure */ | 3527 /* Main window procedure */ |
3328 | |
3329 extern char *lispy_function_keys[]; | |
3330 | 3528 |
3331 LRESULT CALLBACK | 3529 LRESULT CALLBACK |
3332 w32_wnd_proc (hwnd, msg, wParam, lParam) | 3530 w32_wnd_proc (hwnd, msg, wParam, lParam) |
3333 HWND hwnd; | 3531 HWND hwnd; |
3334 UINT msg; | 3532 UINT msg; |
3390 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | 3588 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
3391 | 3589 |
3392 return (0); | 3590 return (0); |
3393 } | 3591 } |
3394 | 3592 |
3593 case WM_INPUTLANGCHANGE: | |
3594 /* Inform lisp thread of keyboard layout changes. */ | |
3595 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | |
3596 | |
3597 /* Clear dead keys in the keyboard state; for simplicity only | |
3598 preserve modifier key states. */ | |
3599 { | |
3600 int i; | |
3601 BYTE keystate[256]; | |
3602 | |
3603 GetKeyboardState (keystate); | |
3604 for (i = 0; i < 256; i++) | |
3605 if (1 | |
3606 && i != VK_SHIFT | |
3607 && i != VK_LSHIFT | |
3608 && i != VK_RSHIFT | |
3609 && i != VK_CAPITAL | |
3610 && i != VK_NUMLOCK | |
3611 && i != VK_SCROLL | |
3612 && i != VK_CONTROL | |
3613 && i != VK_LCONTROL | |
3614 && i != VK_RCONTROL | |
3615 && i != VK_MENU | |
3616 && i != VK_LMENU | |
3617 && i != VK_RMENU | |
3618 && i != VK_LWIN | |
3619 && i != VK_RWIN) | |
3620 keystate[i] = 0; | |
3621 SetKeyboardState (keystate); | |
3622 } | |
3623 goto dflt; | |
3624 | |
3625 case WM_HOTKEY: | |
3626 /* Synchronize hot keys with normal input. */ | |
3627 PostMessage (hwnd, WM_KEYDOWN, HIWORD (lParam), 0); | |
3628 return (0); | |
3629 | |
3395 case WM_KEYUP: | 3630 case WM_KEYUP: |
3396 case WM_SYSKEYUP: | 3631 case WM_SYSKEYUP: |
3397 record_keyup (wParam, lParam); | 3632 record_keyup (wParam, lParam); |
3398 goto dflt; | 3633 goto dflt; |
3399 | 3634 |
3400 case WM_KEYDOWN: | 3635 case WM_KEYDOWN: |
3401 case WM_SYSKEYDOWN: | 3636 case WM_SYSKEYDOWN: |
3637 /* Ignore keystrokes we fake ourself; see below. */ | |
3638 if (dpyinfo->faked_key == wParam) | |
3639 { | |
3640 dpyinfo->faked_key = 0; | |
3641 return 0; | |
3642 } | |
3643 | |
3402 /* Synchronize modifiers with current keystroke. */ | 3644 /* Synchronize modifiers with current keystroke. */ |
3403 sync_modifiers (); | 3645 sync_modifiers (); |
3404 | |
3405 record_keydown (wParam, lParam); | 3646 record_keydown (wParam, lParam); |
3406 | 3647 wParam = map_keypad_keys (wParam, (lParam & 0x1000000L) != 0); |
3407 wParam = map_keypad_keys (wParam, lParam); | |
3408 | 3648 |
3409 windows_translate = 0; | 3649 windows_translate = 0; |
3410 switch (wParam) { | 3650 |
3411 case VK_LWIN: | 3651 switch (wParam) |
3412 case VK_RWIN: | 3652 { |
3413 case VK_APPS: | 3653 case VK_LWIN: |
3414 /* More support for these keys will likely be necessary. */ | 3654 if (NILP (Vw32_pass_lwindow_to_system)) |
3415 if (!NILP (Vw32_pass_optional_keys_to_system)) | 3655 { |
3656 /* Prevent system from acting on keyup (which opens the | |
3657 Start menu if no other key was pressed) by simulating a | |
3658 press of Space which we will ignore. */ | |
3659 if (GetAsyncKeyState (wParam) & 1) | |
3660 { | |
3661 dpyinfo->faked_key = VK_SPACE; | |
3662 keybd_event (VK_SPACE, | |
3663 (BYTE) MapVirtualKey (VK_SPACE, 0), 0, 0); | |
3664 } | |
3665 } | |
3666 if (!NILP (Vw32_lwindow_modifier)) | |
3667 return 0; | |
3668 break; | |
3669 case VK_RWIN: | |
3670 if (NILP (Vw32_pass_rwindow_to_system)) | |
3671 { | |
3672 if (GetAsyncKeyState (wParam) & 1) | |
3673 { | |
3674 dpyinfo->faked_key = VK_SPACE; | |
3675 keybd_event (VK_SPACE, | |
3676 (BYTE) MapVirtualKey (VK_SPACE, 0), 0, 0); | |
3677 } | |
3678 } | |
3679 if (!NILP (Vw32_rwindow_modifier)) | |
3680 return 0; | |
3681 break; | |
3682 case VK_APPS: | |
3683 if (!NILP (Vw32_apps_modifier)) | |
3684 return 0; | |
3685 break; | |
3686 case VK_MENU: | |
3687 if (NILP (Vw32_pass_alt_to_system)) | |
3688 return 0; | |
3416 windows_translate = 1; | 3689 windows_translate = 1; |
3417 break; | 3690 break; |
3418 case VK_MENU: | 3691 case VK_CAPITAL: |
3419 if (NILP (Vw32_pass_alt_to_system)) | 3692 /* Decide whether to treat as modifier or function key. */ |
3693 if (NILP (Vw32_enable_caps_lock)) | |
3694 goto disable_lock_key; | |
3420 return 0; | 3695 return 0; |
3421 windows_translate = 1; | 3696 case VK_NUMLOCK: |
3422 break; | 3697 /* Decide whether to treat as modifier or function key. */ |
3423 case VK_CONTROL: | 3698 if (NILP (Vw32_enable_num_lock)) |
3424 case VK_CAPITAL: | 3699 goto disable_lock_key; |
3425 case VK_SHIFT: | 3700 return 0; |
3426 case VK_NUMLOCK: | 3701 case VK_SCROLL: |
3427 case VK_SCROLL: | 3702 /* Decide whether to treat as modifier or function key. */ |
3428 windows_translate = 1; | 3703 if (NILP (Vw32_scroll_lock_modifier)) |
3429 break; | 3704 goto disable_lock_key; |
3430 default: | 3705 return 0; |
3431 /* If not defined as a function key, change it to a WM_CHAR message. */ | 3706 disable_lock_key: |
3432 if (lispy_function_keys[wParam] == 0) | 3707 /* Ensure the appropriate lock key state is off (and the |
3433 msg = WM_CHAR; | 3708 indicator light as well). */ |
3434 break; | 3709 if (GetAsyncKeyState (wParam) & 0x8000) |
3435 } | 3710 { |
3711 /* Fake another press of the relevant key. Apparently, | |
3712 this really is the only way to turn off the indicator. */ | |
3713 dpyinfo->faked_key = wParam; | |
3714 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0), | |
3715 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); | |
3716 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0), | |
3717 KEYEVENTF_EXTENDEDKEY | 0, 0); | |
3718 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0), | |
3719 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); | |
3720 } | |
3721 break; | |
3722 case VK_CONTROL: | |
3723 case VK_SHIFT: | |
3724 case VK_PROCESSKEY: /* Generated by IME. */ | |
3725 windows_translate = 1; | |
3726 break; | |
3727 default: | |
3728 /* If not defined as a function key, change it to a WM_CHAR message. */ | |
3729 if (lispy_function_keys[wParam] == 0) | |
3730 { | |
3731 if (!NILP (Vw32_recognize_altgr) | |
3732 && modifier_set (VK_LCONTROL) && modifier_set (VK_RMENU)) | |
3733 { | |
3734 /* Always let TranslateMessage handle AltGr key chords; | |
3735 for some reason, ToAscii doesn't always process AltGr | |
3736 chords correctly. */ | |
3737 windows_translate = 1; | |
3738 } | |
3739 else if (modifier_set (VK_CONTROL) || modifier_set (VK_MENU)) | |
3740 { | |
3741 /* Handle key chords including any modifiers other than shift | |
3742 directly, in order to preserve as much modifier information as | |
3743 possible. */ | |
3744 if ('A' <= wParam && wParam <= 'Z') | |
3745 { | |
3746 /* Don't translate modified alphabetic keystrokes, | |
3747 so the user doesn't need to constantly switch | |
3748 layout to type control or meta keystrokes when | |
3749 the normal layout translates alphabetic | |
3750 characters to non-ascii characters. */ | |
3751 if (!modifier_set (VK_SHIFT)) | |
3752 wParam += ('a' - 'A'); | |
3753 msg = WM_CHAR; | |
3754 } | |
3755 else | |
3756 { | |
3757 /* Try to handle other keystrokes by determining the | |
3758 base character (ie. translating the base key plus | |
3759 shift modifier). */ | |
3760 int add; | |
3761 int isdead = 0; | |
3762 KEY_EVENT_RECORD key; | |
3763 | |
3764 key.bKeyDown = TRUE; | |
3765 key.wRepeatCount = 1; | |
3766 key.wVirtualKeyCode = wParam; | |
3767 key.wVirtualScanCode = (lParam & 0xFF0000) >> 16; | |
3768 key.uChar.AsciiChar = 0; | |
3769 key.dwControlKeyState = construct_console_modifiers (); | |
3770 | |
3771 add = w32_kbd_patch_key (&key); | |
3772 /* 0 means an unrecognised keycode, negative means | |
3773 dead key. Ignore both. */ | |
3774 while (--add >= 0) | |
3775 { | |
3776 /* Forward asciified character sequence. */ | |
3777 post_character_message | |
3778 (hwnd, WM_CHAR, key.uChar.AsciiChar, lParam, | |
3779 w32_get_key_modifiers (wParam, lParam)); | |
3780 w32_kbd_patch_key (&key); | |
3781 } | |
3782 return 0; | |
3783 } | |
3784 } | |
3785 else | |
3786 { | |
3787 /* Let TranslateMessage handle everything else. */ | |
3788 windows_translate = 1; | |
3789 } | |
3790 } | |
3791 } | |
3436 | 3792 |
3437 if (windows_translate) | 3793 if (windows_translate) |
3438 { | 3794 { |
3439 MSG windows_msg = { hwnd, msg, wParam, lParam, 0, {0,0} }; | 3795 MSG windows_msg = { hwnd, msg, wParam, lParam, 0, {0,0} }; |
3440 | 3796 |
3445 | 3801 |
3446 /* Fall through */ | 3802 /* Fall through */ |
3447 | 3803 |
3448 case WM_SYSCHAR: | 3804 case WM_SYSCHAR: |
3449 case WM_CHAR: | 3805 case WM_CHAR: |
3450 wmsg.dwModifiers = construct_modifiers (wParam, lParam); | 3806 post_character_message (hwnd, msg, wParam, lParam, |
3451 | 3807 w32_get_key_modifiers (wParam, lParam)); |
3452 #if 1 | |
3453 /* Detect quit_char and set quit-flag directly. Note that we | |
3454 still need to post a message to ensure the main thread will be | |
3455 woken up if blocked in sys_select(), but we do NOT want to post | |
3456 the quit_char message itself (because it will usually be as if | |
3457 the user had typed quit_char twice). Instead, we post a dummy | |
3458 message that has no particular effect. */ | |
3459 { | |
3460 int c = wParam; | |
3461 if (isalpha (c) && (wmsg.dwModifiers == LEFT_CTRL_PRESSED | |
3462 || wmsg.dwModifiers == RIGHT_CTRL_PRESSED)) | |
3463 c = make_ctrl_char (c) & 0377; | |
3464 if (c == quit_char) | |
3465 { | |
3466 Vquit_flag = Qt; | |
3467 | |
3468 /* The choice of message is somewhat arbitrary, as long as | |
3469 the main thread handler just ignores it. */ | |
3470 msg = WM_NULL; | |
3471 | |
3472 /* Interrupt any blocking system calls. */ | |
3473 signal_quit (); | |
3474 } | |
3475 } | |
3476 #endif | |
3477 | |
3478 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | |
3479 | |
3480 break; | 3808 break; |
3481 | 3809 |
3482 /* Simulate middle mouse button events when left and right buttons | 3810 /* Simulate middle mouse button events when left and right buttons |
3483 are used together, but only if user has two button mouse. */ | 3811 are used together, but only if user has two button mouse. */ |
3484 case WM_LBUTTONDOWN: | 3812 case WM_LBUTTONDOWN: |
3815 if (LOWORD (lParam) == HTCLIENT ) | 4143 if (LOWORD (lParam) == HTCLIENT ) |
3816 return MA_ACTIVATEANDEAT; | 4144 return MA_ACTIVATEANDEAT; |
3817 goto dflt; | 4145 goto dflt; |
3818 #endif | 4146 #endif |
3819 | 4147 |
4148 case WM_ACTIVATEAPP: | |
4149 dpyinfo->faked_key = 0; | |
4150 reset_modifiers (); | |
3820 case WM_ACTIVATE: | 4151 case WM_ACTIVATE: |
3821 case WM_ACTIVATEAPP: | |
3822 case WM_WINDOWPOSCHANGED: | 4152 case WM_WINDOWPOSCHANGED: |
3823 case WM_SHOWWINDOW: | 4153 case WM_SHOWWINDOW: |
3824 /* Inform lisp thread that a frame might have just been obscured | 4154 /* Inform lisp thread that a frame might have just been obscured |
3825 or exposed, so should recheck visibility of all frames. */ | 4155 or exposed, so should recheck visibility of all frames. */ |
3826 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | 4156 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
3827 goto dflt; | 4157 goto dflt; |
3828 | 4158 |
3829 case WM_SETFOCUS: | 4159 case WM_SETFOCUS: |
3830 reset_modifiers (); | 4160 register_hot_keys (hwnd); |
4161 goto command; | |
3831 case WM_KILLFOCUS: | 4162 case WM_KILLFOCUS: |
4163 unregister_hot_keys (hwnd); | |
3832 case WM_MOVE: | 4164 case WM_MOVE: |
3833 case WM_SIZE: | 4165 case WM_SIZE: |
3834 case WM_COMMAND: | 4166 case WM_COMMAND: |
4167 command: | |
3835 wmsg.dwModifiers = w32_get_modifiers (); | 4168 wmsg.dwModifiers = w32_get_modifiers (); |
3836 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); | 4169 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
3837 goto dflt; | 4170 goto dflt; |
3838 | 4171 |
3839 case WM_CLOSE: | 4172 case WM_CLOSE: |
6084 PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, XINT (command), 0); | 6417 PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, XINT (command), 0); |
6085 | 6418 |
6086 return Qnil; | 6419 return Qnil; |
6087 } | 6420 } |
6088 | 6421 |
6422 /* Lookup virtual keycode from string representing the name of a | |
6423 non-ascii keystroke into the corresponding virtual key, using | |
6424 lispy_function_keys. */ | |
6425 static int | |
6426 lookup_vk_code (char *key) | |
6427 { | |
6428 int i; | |
6429 | |
6430 for (i = 0; i < 256; i++) | |
6431 if (lispy_function_keys[i] != 0 | |
6432 && strcmp (lispy_function_keys[i], key) == 0) | |
6433 return i; | |
6434 | |
6435 return -1; | |
6436 } | |
6437 | |
6438 /* Convert a one-element vector style key sequence to a hot key | |
6439 definition. */ | |
6440 static int | |
6441 w32_parse_hot_key (key) | |
6442 Lisp_Object key; | |
6443 { | |
6444 /* Copied from Fdefine_key and store_in_keymap. */ | |
6445 register Lisp_Object c; | |
6446 int vk_code; | |
6447 int lisp_modifiers; | |
6448 int w32_modifiers; | |
6449 struct gcpro gcpro1; | |
6450 | |
6451 CHECK_VECTOR (key, 0); | |
6452 | |
6453 if (XFASTINT (Flength (key)) != 1) | |
6454 return Qnil; | |
6455 | |
6456 GCPRO1 (key); | |
6457 | |
6458 c = Faref (key, make_number (0)); | |
6459 | |
6460 if (CONSP (c) && lucid_event_type_list_p (c)) | |
6461 c = Fevent_convert_list (c); | |
6462 | |
6463 UNGCPRO; | |
6464 | |
6465 if (! INTEGERP (c) && ! SYMBOLP (c)) | |
6466 error ("Key definition is invalid"); | |
6467 | |
6468 /* Work out the base key and the modifiers. */ | |
6469 if (SYMBOLP (c)) | |
6470 { | |
6471 c = parse_modifiers (c); | |
6472 lisp_modifiers = Fcar (Fcdr (c)); | |
6473 c = Fcar (c); | |
6474 if (!SYMBOLP (c)) | |
6475 abort (); | |
6476 vk_code = lookup_vk_code (XSYMBOL (c)->name->data); | |
6477 } | |
6478 else if (INTEGERP (c)) | |
6479 { | |
6480 lisp_modifiers = XINT (c) & ~CHARACTERBITS; | |
6481 /* Many ascii characters are their own virtual key code. */ | |
6482 vk_code = XINT (c) & CHARACTERBITS; | |
6483 } | |
6484 | |
6485 if (vk_code < 0 || vk_code > 255) | |
6486 return Qnil; | |
6487 | |
6488 if ((lisp_modifiers & meta_modifier) != 0 | |
6489 && !NILP (Vw32_alt_is_meta)) | |
6490 lisp_modifiers |= alt_modifier; | |
6491 | |
6492 /* Convert lisp modifiers to Windows hot-key form. */ | |
6493 w32_modifiers = (lisp_modifiers & hyper_modifier) ? MOD_WIN : 0; | |
6494 w32_modifiers |= (lisp_modifiers & alt_modifier) ? MOD_ALT : 0; | |
6495 w32_modifiers |= (lisp_modifiers & ctrl_modifier) ? MOD_CONTROL : 0; | |
6496 w32_modifiers |= (lisp_modifiers & shift_modifier) ? MOD_SHIFT : 0; | |
6497 | |
6498 return HOTKEY (vk_code, w32_modifiers); | |
6499 } | |
6500 | |
6501 DEFUN ("w32-register-hot-key", Fw32_register_hot_key, Sw32_register_hot_key, 1, 1, 0, | |
6502 "Register KEY as a hot-key combination.\n\ | |
6503 Certain key combinations like Alt-Tab are reserved for system use on\n\ | |
6504 Windows, and therefore are normally intercepted by the system. However,\n\ | |
6505 most of these key combinations can be received by registering them as\n\ | |
6506 hot-keys, overriding their special meaning.\n\ | |
6507 \n\ | |
6508 KEY must be a one element key definition in vector form that would be\n\ | |
6509 acceptable to `define-key' (e.g. [A-tab] for Alt-Tab). The meta\n\ | |
6510 modifier is interpreted as Alt if `w32-alt-is-meta' is t, and hyper\n\ | |
6511 is always interpreted as the Windows modifier keys.\n\ | |
6512 \n\ | |
6513 The return value is the hotkey-id if registered, otherwise nil.") | |
6514 (key) | |
6515 Lisp_Object key; | |
6516 { | |
6517 key = w32_parse_hot_key (key); | |
6518 | |
6519 if (NILP (Fmemq (key, w32_grabbed_keys))) | |
6520 { | |
6521 /* Reuse an empty slot if possible. */ | |
6522 Lisp_Object item = Fmemq (Qnil, w32_grabbed_keys); | |
6523 | |
6524 /* Safe to add new key to list, even if we have focus. */ | |
6525 if (NILP (item)) | |
6526 w32_grabbed_keys = Fcons (key, w32_grabbed_keys); | |
6527 else | |
6528 XCAR (item) = key; | |
6529 | |
6530 /* Notify input thread about new hot-key definition, so that it | |
6531 takes effect without needing to switch focus. */ | |
6532 PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY, | |
6533 (WPARAM) key, 0); | |
6534 } | |
6535 | |
6536 return key; | |
6537 } | |
6538 | |
6539 DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key, Sw32_unregister_hot_key, 1, 1, 0, | |
6540 "Unregister HOTKEY as a hot-key combination.") | |
6541 (key) | |
6542 Lisp_Object key; | |
6543 { | |
6544 Lisp_Object item; | |
6545 | |
6546 if (!INTEGERP (key)) | |
6547 key = w32_parse_hot_key (key); | |
6548 | |
6549 item = Fmemq (key, w32_grabbed_keys); | |
6550 | |
6551 if (!NILP (item)) | |
6552 { | |
6553 /* Notify input thread about hot-key definition being removed, so | |
6554 that it takes effect without needing focus switch. */ | |
6555 if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY, | |
6556 (WPARAM) XINT (XCAR (item)), (LPARAM) item)) | |
6557 { | |
6558 MSG msg; | |
6559 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); | |
6560 } | |
6561 return Qt; | |
6562 } | |
6563 return Qnil; | |
6564 } | |
6565 | |
6566 DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys, Sw32_registered_hot_keys, 0, 0, 0, | |
6567 "Return list of registered hot-key IDs.") | |
6568 () | |
6569 { | |
6570 return Fcopy_sequence (w32_grabbed_keys); | |
6571 } | |
6572 | |
6573 DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key, Sw32_reconstruct_hot_key, 1, 1, 0, | |
6574 "Convert hot-key ID to a lisp key combination.") | |
6575 (hotkeyid) | |
6576 Lisp_Object hotkeyid; | |
6577 { | |
6578 int vk_code, w32_modifiers; | |
6579 Lisp_Object key; | |
6580 | |
6581 CHECK_NUMBER (hotkeyid, 0); | |
6582 | |
6583 vk_code = HOTKEY_VK_CODE (hotkeyid); | |
6584 w32_modifiers = HOTKEY_MODIFIERS (hotkeyid); | |
6585 | |
6586 if (lispy_function_keys[vk_code]) | |
6587 key = intern (lispy_function_keys[vk_code]); | |
6588 else | |
6589 key = make_number (vk_code); | |
6590 | |
6591 key = Fcons (key, Qnil); | |
6592 if (w32_modifiers & MOD_SHIFT) | |
6593 key = Fcons (intern ("shift"), key); | |
6594 if (w32_modifiers & MOD_CONTROL) | |
6595 key = Fcons (intern ("control"), key); | |
6596 if (w32_modifiers & MOD_ALT) | |
6597 key = Fcons (intern (NILP (Vw32_alt_is_meta) ? "alt" : "meta"), key); | |
6598 if (w32_modifiers & MOD_WIN) | |
6599 key = Fcons (intern ("hyper"), key); | |
6600 | |
6601 return key; | |
6602 } | |
6089 | 6603 |
6090 syms_of_w32fns () | 6604 syms_of_w32fns () |
6091 { | 6605 { |
6092 /* This is zero if not using MS-Windows. */ | 6606 /* This is zero if not using MS-Windows. */ |
6093 w32_in_use = 0; | 6607 w32_in_use = 0; |
6169 Fput (Qundefined_color, Qerror_conditions, | 6683 Fput (Qundefined_color, Qerror_conditions, |
6170 Fcons (Qundefined_color, Fcons (Qerror, Qnil))); | 6684 Fcons (Qundefined_color, Fcons (Qerror, Qnil))); |
6171 Fput (Qundefined_color, Qerror_message, | 6685 Fput (Qundefined_color, Qerror_message, |
6172 build_string ("Undefined color")); | 6686 build_string ("Undefined color")); |
6173 | 6687 |
6688 staticpro (&w32_grabbed_keys); | |
6689 w32_grabbed_keys = Qnil; | |
6690 | |
6174 DEFVAR_LISP ("w32-color-map", &Vw32_color_map, | 6691 DEFVAR_LISP ("w32-color-map", &Vw32_color_map, |
6175 "A array of color name mappings for windows."); | 6692 "An array of color name mappings for windows."); |
6176 Vw32_color_map = Qnil; | 6693 Vw32_color_map = Qnil; |
6177 | 6694 |
6178 DEFVAR_LISP ("w32-pass-alt-to-system", &Vw32_pass_alt_to_system, | 6695 DEFVAR_LISP ("w32-pass-alt-to-system", &Vw32_pass_alt_to_system, |
6179 "Non-nil if alt key presses are passed on to Windows.\n\ | 6696 "Non-nil if alt key presses are passed on to Windows.\n\ |
6180 When non-nil, for example, alt pressed and released and then space will\n\ | 6697 When non-nil, for example, alt pressed and released and then space will\n\ |
6184 DEFVAR_LISP ("w32-alt-is-meta", &Vw32_alt_is_meta, | 6701 DEFVAR_LISP ("w32-alt-is-meta", &Vw32_alt_is_meta, |
6185 "Non-nil if the alt key is to be considered the same as the meta key.\n\ | 6702 "Non-nil if the alt key is to be considered the same as the meta key.\n\ |
6186 When nil, Emacs will translate the alt key to the Alt modifier, and not Meta."); | 6703 When nil, Emacs will translate the alt key to the Alt modifier, and not Meta."); |
6187 Vw32_alt_is_meta = Qt; | 6704 Vw32_alt_is_meta = Qt; |
6188 | 6705 |
6189 DEFVAR_LISP ("w32-pass-optional-keys-to-system", | 6706 DEFVAR_LISP ("w32-pass-lwindow-to-system", |
6190 &Vw32_pass_optional_keys_to_system, | 6707 &Vw32_pass_lwindow_to_system, |
6191 "Non-nil if the 'optional' keys (left window, right window,\n\ | 6708 "Non-nil if the left \"Windows\" key is passed on to Windows.\n\ |
6192 and application keys) are passed on to Windows."); | 6709 When non-nil, the Start menu is opened by tapping the key."); |
6193 Vw32_pass_optional_keys_to_system = Qnil; | 6710 Vw32_pass_lwindow_to_system = Qt; |
6711 | |
6712 DEFVAR_LISP ("w32-pass-rwindow-to-system", | |
6713 &Vw32_pass_rwindow_to_system, | |
6714 "Non-nil if the right \"Windows\" key is passed on to Windows.\n\ | |
6715 When non-nil, the Start menu is opened by tapping the key."); | |
6716 Vw32_pass_rwindow_to_system = Qt; | |
6717 | |
6718 DEFVAR_LISP ("w32-enable-num-lock", | |
6719 &Vw32_enable_num_lock, | |
6720 "Non-nil if Num Lock should act normally.\n\ | |
6721 Set to nil to see Num Lock as the key `kp-numlock'."); | |
6722 Vw32_enable_num_lock = Qt; | |
6723 | |
6724 DEFVAR_LISP ("w32-enable-caps-lock", | |
6725 &Vw32_enable_caps_lock, | |
6726 "Non-nil if Caps Lock should act normally.\n\ | |
6727 Set to nil to see Caps Lock as the key `capslock'."); | |
6728 Vw32_enable_caps_lock = Qt; | |
6729 | |
6730 DEFVAR_LISP ("w32-scroll-lock-modifier", | |
6731 &Vw32_scroll_lock_modifier, | |
6732 "Modifier to use for the Scroll Lock on state.\n\ | |
6733 The value can be hyper, super, meta, alt, control or shift for the\n\ | |
6734 respective modifier, or nil to see Scroll Lock as the key `scroll'.\n\ | |
6735 Any other value will cause the key to be ignored."); | |
6736 Vw32_scroll_lock_modifier = Qt; | |
6737 | |
6738 DEFVAR_LISP ("w32-lwindow-modifier", | |
6739 &Vw32_lwindow_modifier, | |
6740 "Modifier to use for the left \"Windows\" key.\n\ | |
6741 The value can be hyper, super, meta, alt, control or shift for the\n\ | |
6742 respective modifier, or nil to appear as the key `lwindow'.\n\ | |
6743 Any other value will cause the key to be ignored."); | |
6744 Vw32_lwindow_modifier = Qnil; | |
6745 | |
6746 DEFVAR_LISP ("w32-rwindow-modifier", | |
6747 &Vw32_rwindow_modifier, | |
6748 "Modifier to use for the right \"Windows\" key.\n\ | |
6749 The value can be hyper, super, meta, alt, control or shift for the\n\ | |
6750 respective modifier, or nil to appear as the key `rwindow'.\n\ | |
6751 Any other value will cause the key to be ignored."); | |
6752 Vw32_rwindow_modifier = Qnil; | |
6753 | |
6754 DEFVAR_LISP ("w32-apps-modifier", | |
6755 &Vw32_apps_modifier, | |
6756 "Modifier to use for the \"Apps\" key.\n\ | |
6757 The value can be hyper, super, meta, alt, control or shift for the\n\ | |
6758 respective modifier, or nil to appear as the key `apps'.\n\ | |
6759 Any other value will cause the key to be ignored."); | |
6760 Vw32_apps_modifier = Qnil; | |
6194 | 6761 |
6195 DEFVAR_LISP ("w32-enable-italics", &Vw32_enable_italics, | 6762 DEFVAR_LISP ("w32-enable-italics", &Vw32_enable_italics, |
6196 "Non-nil enables selection of artificially italicized fonts."); | 6763 "Non-nil enables selection of artificially italicized fonts."); |
6197 Vw32_enable_italics = Qnil; | 6764 Vw32_enable_italics = Qnil; |
6198 | 6765 |
6312 defsubr (&Sw32_select_font); | 6879 defsubr (&Sw32_select_font); |
6313 defsubr (&Sw32_define_rgb_color); | 6880 defsubr (&Sw32_define_rgb_color); |
6314 defsubr (&Sw32_default_color_map); | 6881 defsubr (&Sw32_default_color_map); |
6315 defsubr (&Sw32_load_color_file); | 6882 defsubr (&Sw32_load_color_file); |
6316 defsubr (&Sw32_send_sys_command); | 6883 defsubr (&Sw32_send_sys_command); |
6884 defsubr (&Sw32_register_hot_key); | |
6885 defsubr (&Sw32_unregister_hot_key); | |
6886 defsubr (&Sw32_registered_hot_keys); | |
6887 defsubr (&Sw32_reconstruct_hot_key); | |
6317 | 6888 |
6318 /* Setting callback functions for fontset handler. */ | 6889 /* Setting callback functions for fontset handler. */ |
6319 get_font_info_func = w32_get_font_info; | 6890 get_font_info_func = w32_get_font_info; |
6320 list_fonts_func = w32_list_fonts; | 6891 list_fonts_func = w32_list_fonts; |
6321 load_font_func = w32_load_font; | 6892 load_font_func = w32_load_font; |
6326 } | 6897 } |
6327 | 6898 |
6328 #undef abort | 6899 #undef abort |
6329 | 6900 |
6330 void | 6901 void |
6902 /* For convenience when debugging. */ | |
6903 int | |
6904 w32_last_error() | |
6905 { | |
6906 return GetLastError (); | |
6907 } | |
6331 w32_abort() | 6908 w32_abort() |
6332 { | 6909 { |
6333 int button; | 6910 int button; |
6334 button = MessageBox (NULL, | 6911 button = MessageBox (NULL, |
6335 "A fatal error has occurred!\n\n" | 6912 "A fatal error has occurred!\n\n" |