]> Pileus Git - ~andy/gtk/commitdiff
Fix bugs that crashed gdk_display_close() on x11
authorHavoc Pennington <hp@pobox.com>
Sun, 19 Sep 2010 02:57:36 +0000 (22:57 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Sun, 19 Sep 2010 02:57:36 +0000 (22:57 -0400)
* _gdk_device_set_associated_device() did not allow NULL device
* GdkDisplay should dispose device manager to avoid devices
  trying to touch the display in finalize
* GdkDeviceManagerXI did not ref devices in id hash
* GdkDisplayX11 did not ref devices in ->input_devices

gdk/gdkdevice.c
gdk/gdkdisplay.c
gdk/x11/gdkdevicemanager-x11.c
gdk/x11/gdkdevicemanager-xi.c
gdk/x11/gdkdevicemanager-xi2.c
gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkeventsource.c

index 5c62e091ae22cecc553ab9e8239a65be8416bc93..3c8114b5473d933a736b14b5ac261e3fe2efd7a9 100644 (file)
@@ -766,7 +766,7 @@ _gdk_device_set_associated_device (GdkDevice *device,
   GdkDevicePrivate *priv;
 
   g_return_if_fail (GDK_IS_DEVICE (device));
-  g_return_if_fail (GDK_IS_DEVICE (associated));
+  g_return_if_fail (associated == NULL || GDK_IS_DEVICE (associated));
 
   priv = device->priv;
 
index dc1c5c8f041b8cb82f3af66ce0ef204e74a34992..e74f74e455606481c674265e32f3c5687f242cb7 100644 (file)
@@ -278,7 +278,7 @@ gdk_display_dispose (GObject *object)
 
   _gdk_displays = g_slist_remove (_gdk_displays, object);
 
-  if (gdk_display_get_default() == display)
+  if (gdk_display_get_default () == display)
     {
       if (_gdk_displays)
         gdk_display_manager_set_default_display (gdk_display_manager_get(),
@@ -289,7 +289,13 @@ gdk_display_dispose (GObject *object)
     }
 
   if (device_manager)
-    g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, object);
+    {
+      /* this is to make it drop devices which may require using the X
+       * display and therefore can't be cleaned up in finalize.
+       * It will also disconnect device_removed_cb
+       */
+      g_object_run_dispose (G_OBJECT (display->device_manager));
+    }
 
   G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
 }
index 335764b7f01bb41127dffdad1ccb51274cb08c60..e1cefaa04552e5e936914ed2329a91b46658d49a 100644 (file)
@@ -53,6 +53,8 @@ _gdk_device_manager_new (GdkDisplay *display)
             {
               GdkDeviceManagerXI2 *device_manager_xi2;
 
+              GDK_NOTE (INPUT, g_print ("Creating XI2 device manager\n"));
+
               device_manager_xi2 = g_object_new (GDK_TYPE_DEVICE_MANAGER_XI2,
                                                  "display", display,
                                                  NULL);
@@ -62,14 +64,20 @@ _gdk_device_manager_new (GdkDisplay *display)
             }
           else
 #endif /* XINPUT_2 */
-            return g_object_new (GDK_TYPE_DEVICE_MANAGER_XI,
-                                 "display", display,
-                                 "event-base", firstevent,
-                                 NULL);
+            {
+              GDK_NOTE (INPUT, g_print ("Creating XI device manager\n"));
+
+              return g_object_new (GDK_TYPE_DEVICE_MANAGER_XI,
+                                   "display", display,
+                                   "event-base", firstevent,
+                                   NULL);
+            }
         }
 #endif /* XINPUT_2 || XINPUT_XFREE */
     }
 
+  GDK_NOTE (INPUT, g_print ("Creating core device manager\n"));
+
   return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
                        "display", display,
                        NULL);
index e11cb58a6b31c84bb434f6dabc888ac334a03625..7229b58b2d10a2bdf3c617a8bcc38ca42b7c02d6 100644 (file)
@@ -37,7 +37,7 @@ struct _GdkDeviceManagerXIPrivate
 };
 
 static void gdk_device_manager_xi_constructed  (GObject      *object);
-static void gdk_device_manager_xi_finalize     (GObject      *object);
+static void gdk_device_manager_xi_dispose      (GObject      *object);
 static void gdk_device_manager_xi_set_property (GObject      *object,
                                                 guint         prop_id,
                                                 const GValue *value,
@@ -72,7 +72,7 @@ gdk_device_manager_xi_class_init (GdkDeviceManagerXIClass *klass)
   GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
 
   object_class->constructed = gdk_device_manager_xi_constructed;
-  object_class->finalize = gdk_device_manager_xi_finalize;
+  object_class->dispose = gdk_device_manager_xi_dispose;
   object_class->set_property = gdk_device_manager_xi_set_property;
   object_class->get_property = gdk_device_manager_xi_get_property;
 
@@ -279,7 +279,7 @@ gdk_device_manager_xi_constructed (GObject *object)
           priv->devices = g_list_prepend (priv->devices, device);
           g_hash_table_insert (priv->id_table,
                                GINT_TO_POINTER (devices[i].id),
-                               device);
+                               g_object_ref (device));
         }
     }
 
@@ -294,7 +294,7 @@ gdk_device_manager_xi_constructed (GObject *object)
 }
 
 static void
-gdk_device_manager_xi_finalize (GObject *object)
+gdk_device_manager_xi_dispose (GObject *object)
 {
   GdkDeviceManagerXIPrivate *priv;
 
@@ -302,12 +302,17 @@ gdk_device_manager_xi_finalize (GObject *object)
 
   g_list_foreach (priv->devices, (GFunc) g_object_unref, NULL);
   g_list_free (priv->devices);
+  priv->devices = NULL;
 
-  g_hash_table_destroy (priv->id_table);
+  if (priv->id_table != NULL)
+    {
+      g_hash_table_destroy (priv->id_table);
+      priv->id_table = NULL;
+    }
 
   gdk_window_remove_filter (NULL, window_input_info_filter, object);
 
-  G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->dispose (object);
 }
 
 static void
index 36ae37ecab014efd230ff3d802681bcd267f3b20..51002c75f17f452bf0b994d46461d1354baa2659 100644 (file)
@@ -33,7 +33,7 @@
 
 
 static void    gdk_device_manager_xi2_constructed (GObject *object);
-static void    gdk_device_manager_xi2_finalize    (GObject *object);
+static void    gdk_device_manager_xi2_dispose     (GObject *object);
 
 static GList * gdk_device_manager_xi2_list_devices (GdkDeviceManager *device_manager,
                                                     GdkDeviceType     type);
@@ -63,7 +63,7 @@ gdk_device_manager_xi2_class_init (GdkDeviceManagerXI2Class *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->constructed = gdk_device_manager_xi2_constructed;
-  object_class->finalize = gdk_device_manager_xi2_finalize;
+  object_class->dispose = gdk_device_manager_xi2_dispose;
 
   device_manager_class->list_devices = gdk_device_manager_xi2_list_devices;
   device_manager_class->get_client_pointer = gdk_device_manager_xi2_get_client_pointer;
@@ -258,7 +258,7 @@ add_device (GdkDeviceManagerXI2 *device_manager,
 
   g_hash_table_replace (device_manager->id_table,
                         GINT_TO_POINTER (dev->deviceid),
-                        device);
+                        g_object_ref (device));
 
   if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard)
     device_manager->master_devices = g_list_append (device_manager->master_devices, device);
@@ -373,7 +373,7 @@ gdk_device_manager_xi2_constructed (GObject *object)
 }
 
 static void
-gdk_device_manager_xi2_finalize (GObject *object)
+gdk_device_manager_xi2_dispose (GObject *object)
 {
   GdkDeviceManagerXI2 *device_manager_xi2;
 
@@ -381,16 +381,23 @@ gdk_device_manager_xi2_finalize (GObject *object)
 
   g_list_foreach (device_manager_xi2->master_devices, (GFunc) g_object_unref, NULL);
   g_list_free (device_manager_xi2->master_devices);
+  device_manager_xi2->master_devices = NULL;
 
   g_list_foreach (device_manager_xi2->slave_devices, (GFunc) g_object_unref, NULL);
   g_list_free (device_manager_xi2->slave_devices);
+  device_manager_xi2->slave_devices = NULL;
 
   g_list_foreach (device_manager_xi2->floating_devices, (GFunc) g_object_unref, NULL);
   g_list_free (device_manager_xi2->floating_devices);
+  device_manager_xi2->floating_devices = NULL;
 
-  g_hash_table_destroy (device_manager_xi2->id_table);
+  if (device_manager_xi2->id_table)
+    {
+      g_hash_table_destroy (device_manager_xi2->id_table);
+      device_manager_xi2->id_table = NULL;
+    }
 
-  G_OBJECT_CLASS (gdk_device_manager_xi2_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gdk_device_manager_xi2_parent_class)->dispose (object);
 }
 
 static GList *
index 9ad4178007e82909b9abb9155fbcd2ec15c42944..ea4e9914dc5e97693de15d78414e90e70c53b196 100644 (file)
@@ -1154,7 +1154,8 @@ _gdk_input_init (GdkDisplay *display)
       if (device->source == GDK_SOURCE_KEYBOARD)
         continue;
 
-      display_x11->input_devices = g_list_prepend (display_x11->input_devices, l->data);
+      display_x11->input_devices = g_list_prepend (display_x11->input_devices,
+                                                   g_object_ref (l->data));
     }
 
   g_list_free (list);
@@ -1176,7 +1177,8 @@ _gdk_input_init (GdkDisplay *display)
     }
 
   /* Add the core pointer to the devices list */
-  display_x11->input_devices = g_list_prepend (display_x11->input_devices, display->core_pointer);
+  display_x11->input_devices = g_list_prepend (display_x11->input_devices,
+                                               g_object_ref (display->core_pointer));
 
   g_list_free (list);
 }
@@ -1449,8 +1451,7 @@ gdk_display_open (const gchar *display_name)
     _gdk_x11_screen_setup (display_x11->screens[i]);
 
   g_signal_emit_by_name (display, "opened");
-  g_signal_emit_by_name (gdk_display_manager_get(),
-                        "display_opened", display);
+  g_signal_emit_by_name (gdk_display_manager_get (), "display-opened", display);
 
   return display;
 }
index d2304888a4d60ff00827fa1b9cf79c09be4a5a12..9521b9d20b7f96d55efa6f11ea4f99ca56d8d34a 100644 (file)
@@ -312,6 +312,11 @@ gdk_event_source_dispatch (GSource     *source,
 static void
 gdk_event_source_finalize (GSource *source)
 {
+  GdkEventSource *event_source = (GdkEventSource *)source;
+
+  g_list_free (event_source->translators);
+  event_source->translators = NULL;
+
   event_sources = g_list_remove (event_sources, source);
 }