wayland: Refactor the keymap handling so it is associated with device
Although GDK expects the keymap to be associated with the display under Wayland this is really associated with the input device so expose this by finding the first keyboard device. Signed-off-by: Rob Bradford <rob@linux.intel.com>
This commit is contained in:
		 José Dapena Paz
					José Dapena Paz
				
			
				
					committed by
					
						 Rob Bradford
						Rob Bradford
					
				
			
			
				
	
			
			
			 Rob Bradford
						Rob Bradford
					
				
			
						parent
						
							fb76a0a000
						
					
				
				
					commit
					d2267824b3
				
			| @ -65,6 +65,8 @@ struct _GdkWaylandDevice | ||||
|   GdkDevice *pointer; | ||||
|   GdkDevice *keyboard; | ||||
|  | ||||
|   GdkKeymap *keymap; | ||||
|  | ||||
|   GdkModifierType modifiers; | ||||
|   GdkWindow *pointer_focus; | ||||
|   GdkWindow *keyboard_focus; | ||||
| @ -376,6 +378,12 @@ _gdk_wayland_device_get_wl_keyboard (GdkDevice *device) | ||||
|   return GDK_DEVICE_CORE (device)->device->wl_keyboard; | ||||
| } | ||||
|  | ||||
| GdkKeymap * | ||||
| _gdk_wayland_device_get_keymap (GdkDevice *device) | ||||
| { | ||||
|   return GDK_DEVICE_CORE (device)->device->keymap; | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| static void | ||||
| input_handle_motion(void *data, struct wl_input_device *input_device, | ||||
| @ -1157,36 +1165,10 @@ keyboard_handle_keymap (void               *data, | ||||
|                        uint32_t            size) | ||||
| { | ||||
|   GdkWaylandDevice *device = data; | ||||
|   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display); | ||||
|   GdkKeymap *gdk_keymap; | ||||
|   gchar *keymap_data; | ||||
|   struct xkb_keymap *keymap; | ||||
|   if (device->keymap) | ||||
|     g_object_unref (device->keymap); | ||||
|  | ||||
|   if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) | ||||
|     { | ||||
|       g_critical (G_STRLOC ": Unknown keymap format"); | ||||
|       close (fd); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   keymap_data = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0); | ||||
|   if (keymap_data == MAP_FAILED) | ||||
|     { | ||||
|       g_critical (G_STRLOC ": Unable to map fd for keymap %s", g_strerror (errno)); | ||||
|       close (fd); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   keymap = xkb_map_new_from_string (display->xkb_context, | ||||
|                                     keymap_data, | ||||
|                                     format, | ||||
|                                     0); | ||||
|  | ||||
|   munmap (keymap_data, size); | ||||
|   close (fd); | ||||
|  | ||||
|   gdk_keymap = _gdk_wayland_display_get_keymap (device->display); | ||||
|   _gdk_wayland_keymap_update_keymap (gdk_keymap, keymap); | ||||
|   device->keymap = _gdk_wayland_keymap_new_from_fd (format, fd, size); | ||||
| } | ||||
|  | ||||
| static void | ||||
| @ -1386,6 +1368,7 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, | ||||
|   display_wayland = GDK_WAYLAND_DISPLAY (display); | ||||
|  | ||||
|   device = g_new0 (GdkWaylandDevice, 1); | ||||
|   device->keymap = _gdk_wayland_keymap_new (); | ||||
|   device->display = display; | ||||
|   device->device_manager = device_manager; | ||||
|  | ||||
|  | ||||
| @ -536,15 +536,26 @@ gdk_wayland_display_event_data_free (GdkDisplay *display, | ||||
| GdkKeymap * | ||||
| _gdk_wayland_display_get_keymap (GdkDisplay *display) | ||||
| { | ||||
|   GdkWaylandDisplay *display_wayland; | ||||
|   GdkDeviceManager *device_manager; | ||||
|   GList *list, *l; | ||||
|   GdkDevice *core_keyboard = NULL; | ||||
|  | ||||
|   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); | ||||
|   display_wayland = GDK_WAYLAND_DISPLAY (display); | ||||
|   device_manager = gdk_display_get_device_manager (display); | ||||
|   list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER); | ||||
|  | ||||
|   if (!display_wayland->keymap) | ||||
|     display_wayland->keymap = _gdk_wayland_keymap_new (display); | ||||
|   for (l = list; l; l = l->next) | ||||
|     { | ||||
|       GdkDevice *device; | ||||
|       device = list->data; | ||||
|  | ||||
|   return display_wayland->keymap; | ||||
|       if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD) | ||||
| 	continue; | ||||
|  | ||||
|       core_keyboard = device; | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   return core_keyboard?_gdk_wayland_device_get_keymap (core_keyboard):NULL; | ||||
| } | ||||
|  | ||||
| static void | ||||
|  | ||||
| @ -30,13 +30,13 @@ | ||||
| #include <unistd.h> | ||||
| #include <limits.h> | ||||
| #include <errno.h> | ||||
| #include <sys/mman.h> | ||||
|  | ||||
| #include "gdk.h" | ||||
| #include "gdkwayland.h" | ||||
|  | ||||
| #include "gdkprivate-wayland.h" | ||||
| #include "gdkinternals.h" | ||||
| #include "gdkdisplay-wayland.h" | ||||
| #include "gdkkeysprivate.h" | ||||
|  | ||||
| #include <xkbcommon/xkbcommon.h> | ||||
| @ -47,13 +47,8 @@ typedef struct _GdkWaylandKeymapClass     GdkWaylandKeymapClass; | ||||
| struct _GdkWaylandKeymap | ||||
| { | ||||
|   GdkKeymap parent_instance; | ||||
|   GdkModifierType modmap[8]; | ||||
|   struct xkb_desc *xkb; | ||||
|   struct xkb_keymap *keymap; | ||||
|   struct xkb_state *state; | ||||
|   xkb_mod_mask_t control_mask; | ||||
|   xkb_mod_mask_t alt_mask; | ||||
|   xkb_mod_mask_t shift_mask; | ||||
|  | ||||
|   struct xkb_keymap *xkb_keymap; | ||||
| }; | ||||
|  | ||||
| struct _GdkWaylandKeymapClass | ||||
| @ -645,51 +640,56 @@ update_keymaps (GdkWaylandKeymap *keymap) | ||||
| #endif | ||||
|  | ||||
| GdkKeymap * | ||||
| _gdk_wayland_keymap_new (GdkDisplay *display) | ||||
| _gdk_wayland_keymap_new () | ||||
| { | ||||
|   GdkWaylandKeymap *keymap; | ||||
|   struct xkb_context *context; | ||||
|   struct xkb_rule_names names; | ||||
|  | ||||
|   keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL); | ||||
|   GDK_KEYMAP (keymap)->display = display; | ||||
| #if 0 | ||||
|  | ||||
|   context = xkb_context_new (0); | ||||
|  | ||||
|   names.rules = "evdev"; | ||||
|   names.model = "pc105"; | ||||
|   names.layout = "us"; | ||||
|   names.variant = ""; | ||||
|   names.options = ""; | ||||
|   keymap->xkb = xkb_compile_keymap_from_rules(&names); | ||||
|   update_modmap (keymap); | ||||
|   update_keymaps (keymap); | ||||
| #endif | ||||
|   keymap->xkb_keymap = xkb_map_new_from_names(context, &names, XKB_MAP_COMPILE_PLACEHOLDER); | ||||
|   xkb_context_unref (context); | ||||
|  | ||||
|   return GDK_KEYMAP (keymap); | ||||
| } | ||||
|  | ||||
| void | ||||
| _gdk_wayland_keymap_update_keymap (GdkKeymap  *gdk_keymap, | ||||
|                                    struct xkb_keymap *xkb_keymap) | ||||
| GdkKeymap * | ||||
| _gdk_wayland_keymap_new_from_fd (uint32_t format, | ||||
|                                  uint32_t fd, uint32_t size) | ||||
| { | ||||
|   GdkWaylandKeymap *keymap; | ||||
|   struct xkb_context *context; | ||||
|   char *map_str; | ||||
|  | ||||
|   keymap = GDK_WAYLAND_KEYMAP (gdk_keymap); | ||||
|   keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL); | ||||
|  | ||||
|   if (keymap->keymap) | ||||
|     xkb_map_unref (keymap->keymap); | ||||
|   context = xkb_context_new (0); | ||||
|  | ||||
|   keymap->keymap = xkb_keymap; | ||||
|   map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); | ||||
|   if (map_str == MAP_FAILED) { | ||||
|     close(fd); | ||||
|     return NULL; | ||||
|   } | ||||
|  | ||||
|   if (keymap->state) | ||||
|     xkb_state_unref (keymap->state); | ||||
|   keymap->xkb_keymap = xkb_map_new_from_string (context, map_str, format, XKB_MAP_COMPILE_PLACEHOLDER); | ||||
|   munmap (map_str, size); | ||||
|   close (fd); | ||||
|   xkb_context_unref (context); | ||||
|  | ||||
|   keymap->state = xkb_state_new (keymap->keymap); | ||||
|   return GDK_KEYMAP (keymap); | ||||
| } | ||||
|  | ||||
|   keymap->control_mask = | ||||
|     1 << xkb_map_mod_get_index(keymap->keymap, "Control"); | ||||
|   keymap->alt_mask = | ||||
|     1 << xkb_map_mod_get_index(keymap->keymap, "Mod1"); | ||||
|   keymap->shift_mask = | ||||
|     1 << xkb_map_mod_get_index(keymap->keymap, "Shift"); | ||||
| struct xkb_keymap *_gdk_wayland_keymap_get_xkb_keymap (GdkKeymap *keymap) | ||||
| { | ||||
|   return GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap; | ||||
| } | ||||
|  | ||||
| struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap) | ||||
|  | ||||
| @ -48,7 +48,9 @@ GType _gdk_wayland_window_get_type    (void); | ||||
| void _gdk_wayland_window_add_focus    (GdkWindow *window); | ||||
| void _gdk_wayland_window_remove_focus (GdkWindow *window); | ||||
|  | ||||
| GdkKeymap *_gdk_wayland_keymap_new (GdkDisplay *display); | ||||
| GdkKeymap *_gdk_wayland_keymap_new (void); | ||||
| GdkKeymap *_gdk_wayland_keymap_new_from_fd (uint32_t format, | ||||
|                                             uint32_t fd, uint32_t size); | ||||
| struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap); | ||||
|  | ||||
| GdkCursor *_gdk_wayland_display_get_cursor_for_type (GdkDisplay    *display, | ||||
| @ -90,10 +92,6 @@ void _gdk_wayland_display_create_window_impl (GdkDisplay    *display, | ||||
| 					      GdkWindowAttr *attributes, | ||||
| 					      gint           attributes_mask); | ||||
|  | ||||
| GdkKeymap *_gdk_wayland_display_get_keymap (GdkDisplay *display); | ||||
| void       _gdk_wayland_keymap_update_keymap (GdkKeymap  *gdk_keymap, | ||||
|                                               struct xkb_keymap *xkb_keymap); | ||||
|  | ||||
| GdkWindow *_gdk_wayland_display_get_selection_owner (GdkDisplay *display, | ||||
| 						 GdkAtom     selection); | ||||
| gboolean   _gdk_wayland_display_set_selection_owner (GdkDisplay *display, | ||||
| @ -134,6 +132,8 @@ struct wl_seat *_gdk_wayland_device_get_wl_seat (GdkDevice *device); | ||||
| struct wl_pointer *_gdk_wayland_device_get_wl_pointer (GdkDevice *device); | ||||
| struct wl_keyboard *_gdk_wayland_device_get_wl_keyboard (GdkDevice *device); | ||||
|  | ||||
| GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device); | ||||
|  | ||||
| void     _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event); | ||||
| GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display); | ||||
| void     _gdk_wayland_display_queue_events (GdkDisplay *display); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user