summaryrefslogtreecommitdiff
path: root/gdk/win32
diff options
context:
space:
mode:
authorAndrew Chadwick <a.t.chadwick@gmail.com>2016-11-20 01:57:07 +0000
committerIgnacio Casal Quinteiro <icq@gnome.org>2016-11-22 12:52:00 +0100
commit66a08bf3a65c41cf549642c7b4293c917f881e34 (patch)
treec2dfd3221b06bf7a4d21296c578cfc8aef49b03e /gdk/win32
parentdd6a00bb31051c5ee86f7e4a1d62f878a1cd99f7 (diff)
downloadgtk+-66a08bf3a65c41cf549642c7b4293c917f881e34.tar.gz
wintab: init only after the display is assigned
Only attempt to initialize Wintab after the display manager announces that the first default display has been set. Fixes a segfault during initialization of specific tablet drivers' wintab32.dlls. Add assertions and verbose comments explaining this nonsense because this stuff is a pain to have to keep fixing. https://bugzilla.gnome.org/show_bug.cgi?id=774379
Diffstat (limited to 'gdk/win32')
-rw-r--r--gdk/win32/gdkdevicemanager-win32.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/gdk/win32/gdkdevicemanager-win32.c b/gdk/win32/gdkdevicemanager-win32.c
index 86d23ca381..73ba2ad57c 100644
--- a/gdk/win32/gdkdevicemanager-win32.c
+++ b/gdk/win32/gdkdevicemanager-win32.c
@@ -66,6 +66,8 @@ static t_WTOverlap p_WTOverlap;
static t_WTPacket p_WTPacket;
static t_WTQueueSizeSet p_WTQueueSizeSet;
+static gboolean default_display_opened = FALSE;
+
G_DEFINE_TYPE (GdkDeviceManagerWin32, gdk_device_manager_win32, GDK_TYPE_DEVICE_MANAGER)
static GdkDevice *
@@ -675,11 +677,42 @@ wintab_init_check (GdkDeviceManagerWin32 *device_manager)
}
}
+/* Only initialize Wintab after the default display is set for
+ * the first time. WTOpenA() executes code beyond our control,
+ * and it can cause messages to be sent to the application even
+ * before a window is opened. GDK has to be in a fit state to
+ * handle them when they come.
+ *
+ * https://bugzilla.gnome.org/show_bug.cgi?id=774379
+ */
+static void
+wintab_default_display_notify_cb (GdkDisplayManager *display_manager)
+{
+ GdkDeviceManagerWin32 *device_manager = NULL;
+ GdkDisplay *display = gdk_display_get_default();
+
+ if (default_display_opened)
+ return;
+
+ g_assert (display != NULL);
+
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+ device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (display));
+G_GNUC_END_IGNORE_DEPRECATIONS;
+ g_assert (display_manager != NULL);
+
+ default_display_opened = TRUE;
+ GDK_NOTE (INPUT, g_print ("wintab init: doing delayed initialization\n"));
+ wintab_init_check (device_manager);
+}
+
static void
gdk_device_manager_win32_constructed (GObject *object)
{
GdkDeviceManagerWin32 *device_manager;
GdkSeat *seat;
+ GdkDisplayManager *display_manager = NULL;
+ GdkDisplay *default_display = NULL;
device_manager = GDK_DEVICE_MANAGER_WIN32 (object);
device_manager->core_pointer =
@@ -722,7 +755,18 @@ gdk_device_manager_win32_constructed (GObject *object)
gdk_seat_default_add_slave (GDK_SEAT_DEFAULT (seat), device_manager->system_keyboard);
g_object_unref (seat);
- wintab_init_check (device_manager);
+ /* Only call Wintab init stuff after the default display
+ * is globally known and accessible through the display manager
+ * singleton. Approach lifted from gtkmodules.c.
+ */
+ display_manager = gdk_display_manager_get();
+ g_assert (display_manager != NULL);
+ default_display = gdk_display_manager_get_default_display (display_manager);
+ g_assert (default_display == NULL);
+
+ g_signal_connect (display_manager, "notify::default-display",
+ G_CALLBACK (wintab_default_display_notify_cb),
+ NULL);
}
static GList *