From 0c8ea1671deab37dd79dbb7dc4cfa953440c0d31 Mon Sep 17 00:00:00 2001 From: Brandon Wright Date: Sat, 5 May 2018 13:49:42 -0500 Subject: [PATCH] Use GdkWindow to avoid Gtk's poor handling of foreign windows. --- gtk/src/gtk_display_driver_gtk.cpp | 3 -- gtk/src/gtk_display_driver_opengl.cpp | 57 +++++++++---------------- gtk/src/gtk_display_driver_xv.cpp | 60 ++++++++++----------------- 3 files changed, 42 insertions(+), 78 deletions(-) diff --git a/gtk/src/gtk_display_driver_gtk.cpp b/gtk/src/gtk_display_driver_gtk.cpp index dc33b946..76163959 100644 --- a/gtk/src/gtk_display_driver_gtk.cpp +++ b/gtk/src/gtk_display_driver_gtk.cpp @@ -250,9 +250,6 @@ S9xGTKDisplayDriver::clear (void) void S9xGTKDisplayDriver::refresh (int width, int height) { - if (!config->rom_loaded) - return; - clear (); return; diff --git a/gtk/src/gtk_display_driver_opengl.cpp b/gtk/src/gtk_display_driver_opengl.cpp index ea6ac962..f8c3da0c 100644 --- a/gtk/src/gtk_display_driver_opengl.cpp +++ b/gtk/src/gtk_display_driver_opengl.cpp @@ -726,8 +726,7 @@ S9xOpenGLDisplayDriver::refresh (int width, int height) void S9xOpenGLDisplayDriver::resize_window (int width, int height) { - g_object_unref (gdk_window); - XDestroyWindow (display, xwindow); + gdk_window_destroy (gdk_window); create_window (width, height); glXMakeCurrent (display, xwindow, glx_context); @@ -737,43 +736,27 @@ S9xOpenGLDisplayDriver::resize_window (int width, int height) void S9xOpenGLDisplayDriver::create_window (int width, int height) { - XSetWindowAttributes window_attr; + GdkWindowAttr window_attr; + memset (&window_attr, 0, sizeof (GdkWindowAttr)); + window_attr.event_mask = GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK; + window_attr.width = width; + window_attr.height = height; + window_attr.x = 0; + window_attr.y = 0; + window_attr.wclass = GDK_INPUT_OUTPUT; + window_attr.window_type = GDK_WINDOW_CHILD; + window_attr.visual = gdk_x11_screen_lookup_visual (gtk_widget_get_screen (drawing_area), vi->visualid); - window_attr.colormap = xcolormap; - window_attr.border_pixel = 0; - window_attr.event_mask = StructureNotifyMask | ExposureMask; - window_attr.do_not_propagate_mask = 0; - window_attr.save_under = False; - window_attr.background_pixmap = None; + gdk_window = gdk_window_new (gtk_widget_get_window (drawing_area), + &window_attr, + GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL); + gdk_window_set_user_data (gdk_window, (gpointer) drawing_area); - xwindow = XCreateWindow (display, - GDK_COMPAT_WINDOW_XID (gtk_widget_get_window (drawing_area)), - 0, - 0, - width, - height, - 0, - vi->depth, - InputOutput, - vi->visual, - CWColormap | CWBorderPixel | CWBackPixmap | CWEventMask | CWSaveUnder | CWDontPropagate, - &window_attr); - XSync (display, False); + gdk_window_show (gdk_window); + xwindow = gdk_x11_window_get_xid (gdk_window); output_window_width = width; output_window_height = height; - - XMapWindow (display, xwindow); - XSync (display, False); - -#if GTK_MAJOR_VERSION >= 3 - gdk_window = gdk_x11_window_foreign_new_for_display (gtk_widget_get_display (drawing_area), xwindow); -#else - gdk_window = gdk_window_foreign_new (xwindow); -#endif - XSync (display, False); - - gdk_window_set_user_data (gdk_window, drawing_area); } int @@ -791,6 +774,7 @@ S9xOpenGLDisplayDriver::init_glx (void) return 0; } + xcolormap = XCreateColormap (display, GDK_COMPAT_WINDOW_XID (gtk_widget_get_window (drawing_area)), vi->visual, @@ -981,12 +965,11 @@ S9xOpenGLDisplayDriver::deinit (void) glDeleteTextures (1, &texmap); glXDestroyContext (display, glx_context); + gdk_window_destroy (gdk_window); + XFree (vi); XFreeColormap (display, xcolormap); - g_object_unref (gdk_window); - XDestroyWindow (display, xwindow); - return; } diff --git a/gtk/src/gtk_display_driver_xv.cpp b/gtk/src/gtk_display_driver_xv.cpp index 8d4b6f93..849a84f1 100644 --- a/gtk/src/gtk_display_driver_xv.cpp +++ b/gtk/src/gtk_display_driver_xv.cpp @@ -39,8 +39,7 @@ S9xXVDisplayDriver::S9xXVDisplayDriver (Snes9xWindow *window, void S9xXVDisplayDriver::resize_window (int width, int height) { - g_object_unref (gdk_window); - XDestroyWindow (display, xwindow); + gdk_window_destroy (gdk_window); create_window (width, height); return; @@ -49,41 +48,27 @@ S9xXVDisplayDriver::resize_window (int width, int height) void S9xXVDisplayDriver::create_window (int width, int height) { - XSetWindowAttributes window_attr; + GdkWindowAttr window_attr; + memset (&window_attr, 0, sizeof (GdkWindowAttr)); + window_attr.event_mask = GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK; + window_attr.width = width; + window_attr.height = height; + window_attr.x = 0; + window_attr.y = 0; + window_attr.wclass = GDK_INPUT_OUTPUT; + window_attr.window_type = GDK_WINDOW_CHILD; + window_attr.visual = gdk_x11_screen_lookup_visual (gtk_widget_get_screen (drawing_area), vi->visualid); - window_attr.colormap = xcolormap; - window_attr.border_pixel = 0; - window_attr.event_mask = StructureNotifyMask | ExposureMask; - window_attr.background_pixmap = None; + gdk_window = gdk_window_new (gtk_widget_get_window (drawing_area), + &window_attr, + GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL); + gdk_window_set_user_data (gdk_window, (gpointer) drawing_area); - xwindow = XCreateWindow (display, - GDK_COMPAT_WINDOW_XID (gtk_widget_get_window (drawing_area)), - 0, - 0, - width, - height, - 0, - vi->depth, - InputOutput, - vi->visual, - CWColormap | CWBorderPixel | CWBackPixmap | CWEventMask, - &window_attr); - XSync (display, False); + gdk_window_show (gdk_window); + xwindow = gdk_x11_window_get_xid (gdk_window); output_window_width = width; output_window_height = height; - - XMapWindow (display, xwindow); - XSync (display, False); - -#if GTK_MAJOR_VERSION >= 3 - gdk_window = gdk_x11_window_foreign_new_for_display (gtk_widget_get_display (drawing_area), xwindow); -#else - gdk_window = gdk_window_foreign_new (xwindow); -#endif - XSync (display, False); - - gdk_window_set_user_data (gdk_window, drawing_area); } void @@ -402,9 +387,9 @@ S9xXVDisplayDriver::init (void) int r, g, b; int y, u, v; - r = (color & 0xf800) >> 8; - g = (color & 0x07e0) >> 3; - b = (color & 0x001F) << 3; + r = ((color & 0xf800) >> 8) | ((color >> 13) & 0x7); + g = ((color & 0x07e0) >> 3) | ((color >> 9 ) & 0x3); + b = ((color & 0x001F) << 3) | ((color >> 3 ) & 0x7); y = (int) ((0.257 * ((double) r)) + (0.504 * ((double) g)) + (0.098 * ((double) b)) + 16.0); u = (int) ((-0.148 * ((double) r)) + (-0.291 * ((double) g)) + (0.439 * ((double) b)) + 128.0); @@ -485,15 +470,14 @@ S9xXVDisplayDriver::init (void) void S9xXVDisplayDriver::deinit (void) { + gdk_window_destroy (gdk_window); + XShmDetach (display, &shm); XSync (display, 0); XFreeColormap (display, xcolormap); XFree (vi); - g_object_unref (gdk_window); - XDestroyWindow (display, xwindow); - free (buffer[0]); free (buffer[1]);