keymap: consider modifier state when picking a mapping
Pass the modifier state to the keymap lookup function. In case multiple keysym -> keycode mappings exist look at the modifier state and prefer the mapping where the modifier state matches. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Message-id: 20180222070513.8740-6-kraxel@redhat.com
This commit is contained in:
		
							parent
							
								
									23ad24e48c
								
							
						
					
					
						commit
						abb4f2c965
					
				| @ -271,7 +271,8 @@ static void curses_refresh(DisplayChangeListener *dcl) | |||||||
|                     keysym = chr; |                     keysym = chr; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK); |             keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK, | ||||||
|  |                                       false, false, false); | ||||||
|             if (keycode == 0) |             if (keycode == 0) | ||||||
|                 continue; |                 continue; | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										33
									
								
								ui/keymaps.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								ui/keymaps.c
									
									
									
									
									
								
							| @ -176,8 +176,12 @@ kbd_layout_t *init_keyboard_layout(const name2keysym_t *table, | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| int keysym2scancode(kbd_layout_t *k, int keysym) | int keysym2scancode(kbd_layout_t *k, int keysym, | ||||||
|  |                     bool shift, bool altgr, bool ctrl) | ||||||
| { | { | ||||||
|  |     static const uint32_t mask = | ||||||
|  |         SCANCODE_SHIFT | SCANCODE_ALTGR | SCANCODE_CTRL; | ||||||
|  |     uint32_t mods, i; | ||||||
|     struct keysym2code *keysym2code; |     struct keysym2code *keysym2code; | ||||||
| 
 | 
 | ||||||
| #ifdef XK_ISO_Left_Tab | #ifdef XK_ISO_Left_Tab | ||||||
| @ -193,6 +197,33 @@ int keysym2scancode(kbd_layout_t *k, int keysym) | |||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (keysym2code->count == 1) { | ||||||
|  |         return keysym2code->keycodes[0]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|  |      * We have multiple keysym -> keycode mappings. | ||||||
|  |      * | ||||||
|  |      * Check whenever we find one mapping where the modifier state of | ||||||
|  |      * the mapping matches the current user interface modifier state. | ||||||
|  |      * If so, prefer that one. | ||||||
|  |      */ | ||||||
|  |     mods = 0; | ||||||
|  |     if (shift) { | ||||||
|  |         mods |= SCANCODE_SHIFT; | ||||||
|  |     } | ||||||
|  |     if (altgr) { | ||||||
|  |         mods |= SCANCODE_ALTGR; | ||||||
|  |     } | ||||||
|  |     if (ctrl) { | ||||||
|  |         mods |= SCANCODE_CTRL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < keysym2code->count; i++) { | ||||||
|  |         if ((keysym2code->keycodes[i] & mask) == mods) { | ||||||
|  |             return keysym2code->keycodes[i]; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|     return keysym2code->keycodes[0]; |     return keysym2code->keycodes[0]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -54,7 +54,8 @@ typedef struct kbd_layout_t kbd_layout_t; | |||||||
| 
 | 
 | ||||||
| kbd_layout_t *init_keyboard_layout(const name2keysym_t *table, | kbd_layout_t *init_keyboard_layout(const name2keysym_t *table, | ||||||
|                                    const char *language); |                                    const char *language); | ||||||
| int keysym2scancode(kbd_layout_t *k, int keysym); | int keysym2scancode(kbd_layout_t *k, int keysym, | ||||||
|  |                     bool shift, bool altgr, bool ctrl); | ||||||
| int keycode_is_keypad(kbd_layout_t *k, int keycode); | int keycode_is_keypad(kbd_layout_t *k, int keycode); | ||||||
| int keysym_is_numlock(kbd_layout_t *k, int keysym); | int keysym_is_numlock(kbd_layout_t *k, int keysym); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								ui/sdl.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								ui/sdl.c
									
									
									
									
									
								
							| @ -201,6 +201,9 @@ static kbd_layout_t *kbd_layout = NULL; | |||||||
| 
 | 
 | ||||||
| static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev) | static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev) | ||||||
| { | { | ||||||
|  |     bool shift = modifiers_state[0x2a] || modifiers_state[0x36]; | ||||||
|  |     bool altgr = modifiers_state[0xb8]; | ||||||
|  |     bool ctrl  = modifiers_state[0x1d] || modifiers_state[0x9d]; | ||||||
|     int keysym; |     int keysym; | ||||||
|     /* workaround for X11+SDL bug with AltGR */ |     /* workaround for X11+SDL bug with AltGR */ | ||||||
|     keysym = ev->keysym.sym; |     keysym = ev->keysym.sym; | ||||||
| @ -210,7 +213,8 @@ static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev) | |||||||
|     if (keysym == 92 && ev->keysym.scancode == 133) { |     if (keysym == 92 && ev->keysym.scancode == 133) { | ||||||
|         keysym = 0xa5; |         keysym = 0xa5; | ||||||
|     } |     } | ||||||
|     return keysym2scancode(kbd_layout, keysym) & SCANCODE_KEYMASK; |     return keysym2scancode(kbd_layout, keysym, | ||||||
|  |                            shift, altgr, ctrl) & SCANCODE_KEYMASK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										9
									
								
								ui/vnc.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								ui/vnc.c
									
									
									
									
									
								
							| @ -1734,7 +1734,8 @@ static void reset_keys(VncState *vs) | |||||||
| 
 | 
 | ||||||
| static void press_key(VncState *vs, int keysym) | static void press_key(VncState *vs, int keysym) | ||||||
| { | { | ||||||
|     int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK; |     int keycode = keysym2scancode(vs->vd->kbd_layout, keysym, | ||||||
|  |                                   false, false, false) & SCANCODE_KEYMASK; | ||||||
|     qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true); |     qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true); | ||||||
|     qemu_input_event_send_key_delay(vs->vd->key_delay_ms); |     qemu_input_event_send_key_delay(vs->vd->key_delay_ms); | ||||||
|     qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false); |     qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false); | ||||||
| @ -1993,6 +1994,9 @@ static const char *code2name(int keycode) | |||||||
| 
 | 
 | ||||||
| static void key_event(VncState *vs, int down, uint32_t sym) | static void key_event(VncState *vs, int down, uint32_t sym) | ||||||
| { | { | ||||||
|  |     bool shift = vs->modifiers_state[0x2a] || vs->modifiers_state[0x36]; | ||||||
|  |     bool altgr = vs->modifiers_state[0xb8]; | ||||||
|  |     bool ctrl  = vs->modifiers_state[0x1d] || vs->modifiers_state[0x9d]; | ||||||
|     int keycode; |     int keycode; | ||||||
|     int lsym = sym; |     int lsym = sym; | ||||||
| 
 | 
 | ||||||
| @ -2000,7 +2004,8 @@ static void key_event(VncState *vs, int down, uint32_t sym) | |||||||
|         lsym = lsym - 'A' + 'a'; |         lsym = lsym - 'A' + 'a'; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK; |     keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF, | ||||||
|  |                               shift, altgr, ctrl) & SCANCODE_KEYMASK; | ||||||
|     trace_vnc_key_event_map(down, sym, keycode, code2name(keycode)); |     trace_vnc_key_event_map(down, sym, keycode, code2name(keycode)); | ||||||
|     do_key_event(vs, down, keycode, sym); |     do_key_event(vs, down, keycode, sym); | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Gerd Hoffmann
						Gerd Hoffmann