diff options
author | Havoc Pennington <hp@pobox.com> | 2010-09-18 22:57:36 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2010-09-18 22:57:36 -0400 |
commit | c7d73ee5875786f88ab72ed94072d25c207bcf94 (patch) | |
tree | e658fc232cfa3a7ba071794ebe6d04eefdad45da /gdk | |
parent | b837ef5a6d2ce003eae3dd558ac1ac9934e9d72c (diff) | |
download | gtk+-c7d73ee5875786f88ab72ed94072d25c207bcf94.tar.gz |
Fix bugs that crashed gdk_display_close() on x11
* _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
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdkdevice.c | 2 | ||||
-rw-r--r-- | gdk/gdkdisplay.c | 10 | ||||
-rw-r--r-- | gdk/x11/gdkdevicemanager-x11.c | 16 | ||||
-rw-r--r-- | gdk/x11/gdkdevicemanager-xi.c | 17 | ||||
-rw-r--r-- | gdk/x11/gdkdevicemanager-xi2.c | 19 | ||||
-rw-r--r-- | gdk/x11/gdkdisplay-x11.c | 9 | ||||
-rw-r--r-- | gdk/x11/gdkeventsource.c | 5 |
7 files changed, 55 insertions, 23 deletions
diff --git a/gdk/gdkdevice.c b/gdk/gdkdevice.c index 5c62e091ae..3c8114b547 100644 --- a/gdk/gdkdevice.c +++ b/gdk/gdkdevice.c @@ -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; diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index dc1c5c8f04..e74f74e455 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -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); } diff --git a/gdk/x11/gdkdevicemanager-x11.c b/gdk/x11/gdkdevicemanager-x11.c index 335764b7f0..e1cefaa045 100644 --- a/gdk/x11/gdkdevicemanager-x11.c +++ b/gdk/x11/gdkdevicemanager-x11.c @@ -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); diff --git a/gdk/x11/gdkdevicemanager-xi.c b/gdk/x11/gdkdevicemanager-xi.c index e11cb58a6b..7229b58b2d 100644 --- a/gdk/x11/gdkdevicemanager-xi.c +++ b/gdk/x11/gdkdevicemanager-xi.c @@ -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 diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c index 36ae37ecab..51002c75f1 100644 --- a/gdk/x11/gdkdevicemanager-xi2.c +++ b/gdk/x11/gdkdevicemanager-xi2.c @@ -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 * diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index 9ad4178007..ea4e9914dc 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -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; } diff --git a/gdk/x11/gdkeventsource.c b/gdk/x11/gdkeventsource.c index d2304888a4..9521b9d20b 100644 --- a/gdk/x11/gdkeventsource.c +++ b/gdk/x11/gdkeventsource.c @@ -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); } |