[gtk+] wayland: Handle seat removal



commit 4987728d7aa0584c013c0a7d33a1eab9d4c26d7a
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Mar 26 22:57:46 2013 -0400

    wayland: Handle seat removal
    
    Also, emit ::device-added and ::device-removed signals
    as devices appear and disappear.

 gdk/wayland/gdkdevice-wayland.c  |   48 +++++++++++++++++++++++++++++++++----
 gdk/wayland/gdkdisplay-wayland.c |    8 +++---
 gdk/wayland/gdkprivate-wayland.h |   11 +++++---
 gdk/wayland/gdkscreen-wayland.c  |    4 +-
 4 files changed, 55 insertions(+), 16 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index aa69636..31e47d0 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -30,7 +30,6 @@
 #include "gdkkeysyms.h"
 #include "gdkdeviceprivate.h"
 #include "gdkdevicemanagerprivate.h"
-#include "gdkprivate-wayland.h"
 
 #include <xkbcommon/xkbcommon.h>
 #include <X11/keysym.h>
@@ -46,6 +45,7 @@ typedef struct _GdkWaylandSelectionOffer GdkWaylandSelectionOffer;
 
 struct _GdkWaylandDeviceData
 {
+  guint32 id;
   struct wl_seat *wl_seat;
   struct wl_pointer *wl_pointer;
   struct wl_keyboard *wl_keyboard;
@@ -1128,6 +1128,8 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
 
       device_manager->devices =
         g_list_prepend (device_manager->devices, device->pointer);
+
+      g_signal_emit_by_name (device_manager, "device-added", device->pointer);
     }
   else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && device->wl_pointer)
     {
@@ -1137,11 +1139,12 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
       device_manager->devices =
         g_list_remove (device_manager->devices, device->pointer);
 
+      g_signal_emit_by_name (device_manager, "device-removed", device->pointer);
       g_object_unref (device->pointer);
       device->pointer = NULL;
     }
 
-  if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !device->wl_keyboard) 
+  if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !device->wl_keyboard)
     {
       device->wl_keyboard = wl_seat_get_keyboard(seat);
       wl_keyboard_set_user_data(device->wl_keyboard, device);
@@ -1161,6 +1164,8 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
 
       device_manager->devices =
         g_list_prepend (device_manager->devices, device->keyboard);
+
+      g_signal_emit_by_name (device_manager, "device-added", device->keyboard);
     }
   else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && device->wl_keyboard) 
     {
@@ -1170,6 +1175,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
       device_manager->devices =
         g_list_remove (device_manager->devices, device->keyboard);
 
+      g_signal_emit_by_name (device_manager, "device-removed", device->keyboard);
       g_object_unref (device->keyboard);
       device->keyboard = NULL;
     }
@@ -1181,8 +1187,10 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
     }
 
   /* Once we have the capabilities event we know we have all events
-   * from the wl_seat and need no further init roundtrips. */
-  display->init_ref_count--;
+   * from the wl_seat and need no further init roundtrips.
+   */
+  if (display->init_ref_count > 0)
+    display->init_ref_count--;
 }
 
 static const struct wl_seat_listener seat_listener = {
@@ -1205,8 +1213,9 @@ init_settings (GdkWaylandDeviceData *device)
 }
 
 void
-_gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
-                                       struct wl_seat *wl_seat)
+_gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager,
+                                      guint32           id,
+                                     struct wl_seat   *wl_seat)
 {
   GdkDisplay *display;
   GdkWaylandDisplay *display_wayland;
@@ -1216,6 +1225,7 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
   display_wayland = GDK_WAYLAND_DISPLAY (display);
 
   device = g_new0 (GdkWaylandDeviceData, 1);
+  device->id = id;
   device->keymap = _gdk_wayland_keymap_new ();
   device->display = display;
   device->device_manager = device_manager;
@@ -1237,6 +1247,32 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
   init_settings (device);
 }
 
+void
+_gdk_wayland_device_manager_remove_seat (GdkDeviceManager *manager,
+                                         guint32           id)
+{
+  GdkWaylandDeviceManager *device_manager = GDK_WAYLAND_DEVICE_MANAGER (manager);
+  GList *l;
+
+  for (l = device_manager->devices; l != NULL; l = l->next)
+    {
+      GdkWaylandDevice *wayland_device = l->data;
+      GdkWaylandDeviceData *device = wayland_device->device;
+
+      if (device->id == id)
+        {
+          seat_handle_capabilities (device, device->wl_seat, 0);
+          g_object_unref (device->keymap);
+          wl_surface_destroy (device->pointer_surface);
+          /* FIXME: destroy data_device */
+          g_clear_object (&device->keyboard_settings);
+          g_free (device);
+
+          break;
+        }
+    }
+}
+
 static void
 free_device (gpointer data)
 {
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index bf22014..0e4701e 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -120,8 +120,7 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id
     display_wayland->init_ref_count++;
   } else if (strcmp(interface, "wl_seat") == 0) {
     seat = wl_registry_bind(display_wayland->wl_registry, id, &wl_seat_interface, 1);
-    _gdk_wayland_device_manager_add_device (gdk_display->device_manager,
-                                           seat);
+    _gdk_wayland_device_manager_add_seat (gdk_display->device_manager, id, seat);
     /* We need to roundtrip until we've received the wl_seat
      * capabilities event which informs us of available input devices
      * on this seat. */
@@ -139,9 +138,10 @@ gdk_registry_handle_global_remove(void               *data,
                                   uint32_t            id)
 {
   GdkWaylandDisplay *display_wayland = data;
+  GdkDisplay *display = GDK_DISPLAY (display_wayland);
 
-  /* We don't know what this item is - try as an output */
-  _gdk_wayland_screen_remove_output_by_id (display_wayland->screen, id);
+  _gdk_wayland_device_manager_remove_seat (display->device_manager, id);
+  _gdk_wayland_screen_remove_output (display_wayland->screen, id);
 
   /* FIXME: the object needs to be destroyed here, we're leaking */
 }
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index 0bdba52..5ed4ce4 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -132,8 +132,11 @@ gchar *     _gdk_wayland_display_utf8_to_string_target (GdkDisplay  *display,
                                                        const gchar *str);
 
 GdkDeviceManager *_gdk_wayland_device_manager_new (GdkDisplay *display);
-void              _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
-                                                         struct wl_seat *seat);
+void              _gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager,
+                                                        guint32           id,
+                                                       struct wl_seat   *seat);
+void              _gdk_wayland_device_manager_remove_seat (GdkDeviceManager *device_manager,
+                                                           guint32           id);
 
 GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device);
 
@@ -154,8 +157,8 @@ GdkScreen *_gdk_wayland_screen_new (GdkDisplay *display);
 void _gdk_wayland_screen_add_output (GdkScreen        *screen,
                                      guint32           id,
                                      struct wl_output *output);
-void _gdk_wayland_screen_remove_output_by_id (GdkScreen *screen,
-                                              guint32 id);
+void _gdk_wayland_screen_remove_output (GdkScreen *screen,
+                                        guint32 id);
 
 void _gdk_wayland_display_manager_add_display (GdkDisplayManager *manager,
                                               GdkDisplay        *display);
diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c
index c357121..ee4200b 100644
--- a/gdk/wayland/gdkscreen-wayland.c
+++ b/gdk/wayland/gdkscreen-wayland.c
@@ -952,8 +952,8 @@ _gdk_wayland_screen_add_output (GdkScreen        *screen,
 }
 
 void
-_gdk_wayland_screen_remove_output_by_id (GdkScreen *screen,
-                                         guint32    id)
+_gdk_wayland_screen_remove_output (GdkScreen *screen,
+                                   guint32    id)
 {
   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
   int i;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]