Use GdkWindow to avoid Gtk's poor handling of foreign windows.

This commit is contained in:
Brandon Wright 2018-05-05 13:49:42 -05:00
parent 4733942460
commit 0c8ea1671d
3 changed files with 42 additions and 78 deletions

View File

@ -250,9 +250,6 @@ S9xGTKDisplayDriver::clear (void)
void void
S9xGTKDisplayDriver::refresh (int width, int height) S9xGTKDisplayDriver::refresh (int width, int height)
{ {
if (!config->rom_loaded)
return;
clear (); clear ();
return; return;

View File

@ -726,8 +726,7 @@ S9xOpenGLDisplayDriver::refresh (int width, int height)
void void
S9xOpenGLDisplayDriver::resize_window (int width, int height) S9xOpenGLDisplayDriver::resize_window (int width, int height)
{ {
g_object_unref (gdk_window); gdk_window_destroy (gdk_window);
XDestroyWindow (display, xwindow);
create_window (width, height); create_window (width, height);
glXMakeCurrent (display, xwindow, glx_context); glXMakeCurrent (display, xwindow, glx_context);
@ -737,43 +736,27 @@ S9xOpenGLDisplayDriver::resize_window (int width, int height)
void void
S9xOpenGLDisplayDriver::create_window (int width, int height) 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; gdk_window = gdk_window_new (gtk_widget_get_window (drawing_area),
window_attr.border_pixel = 0; &window_attr,
window_attr.event_mask = StructureNotifyMask | ExposureMask; GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
window_attr.do_not_propagate_mask = 0; gdk_window_set_user_data (gdk_window, (gpointer) drawing_area);
window_attr.save_under = False;
window_attr.background_pixmap = None;
xwindow = XCreateWindow (display, gdk_window_show (gdk_window);
GDK_COMPAT_WINDOW_XID (gtk_widget_get_window (drawing_area)), xwindow = gdk_x11_window_get_xid (gdk_window);
0,
0,
width,
height,
0,
vi->depth,
InputOutput,
vi->visual,
CWColormap | CWBorderPixel | CWBackPixmap | CWEventMask | CWSaveUnder | CWDontPropagate,
&window_attr);
XSync (display, False);
output_window_width = width; output_window_width = width;
output_window_height = height; 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 int
@ -791,6 +774,7 @@ S9xOpenGLDisplayDriver::init_glx (void)
return 0; return 0;
} }
xcolormap = XCreateColormap (display, xcolormap = XCreateColormap (display,
GDK_COMPAT_WINDOW_XID (gtk_widget_get_window (drawing_area)), GDK_COMPAT_WINDOW_XID (gtk_widget_get_window (drawing_area)),
vi->visual, vi->visual,
@ -981,12 +965,11 @@ S9xOpenGLDisplayDriver::deinit (void)
glDeleteTextures (1, &texmap); glDeleteTextures (1, &texmap);
glXDestroyContext (display, glx_context); glXDestroyContext (display, glx_context);
gdk_window_destroy (gdk_window);
XFree (vi); XFree (vi);
XFreeColormap (display, xcolormap); XFreeColormap (display, xcolormap);
g_object_unref (gdk_window);
XDestroyWindow (display, xwindow);
return; return;
} }

View File

@ -39,8 +39,7 @@ S9xXVDisplayDriver::S9xXVDisplayDriver (Snes9xWindow *window,
void void
S9xXVDisplayDriver::resize_window (int width, int height) S9xXVDisplayDriver::resize_window (int width, int height)
{ {
g_object_unref (gdk_window); gdk_window_destroy (gdk_window);
XDestroyWindow (display, xwindow);
create_window (width, height); create_window (width, height);
return; return;
@ -49,41 +48,27 @@ S9xXVDisplayDriver::resize_window (int width, int height)
void void
S9xXVDisplayDriver::create_window (int width, int height) 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; gdk_window = gdk_window_new (gtk_widget_get_window (drawing_area),
window_attr.border_pixel = 0; &window_attr,
window_attr.event_mask = StructureNotifyMask | ExposureMask; GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
window_attr.background_pixmap = None; gdk_window_set_user_data (gdk_window, (gpointer) drawing_area);
xwindow = XCreateWindow (display, gdk_window_show (gdk_window);
GDK_COMPAT_WINDOW_XID (gtk_widget_get_window (drawing_area)), xwindow = gdk_x11_window_get_xid (gdk_window);
0,
0,
width,
height,
0,
vi->depth,
InputOutput,
vi->visual,
CWColormap | CWBorderPixel | CWBackPixmap | CWEventMask,
&window_attr);
XSync (display, False);
output_window_width = width; output_window_width = width;
output_window_height = height; 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 void
@ -402,9 +387,9 @@ S9xXVDisplayDriver::init (void)
int r, g, b; int r, g, b;
int y, u, v; int y, u, v;
r = (color & 0xf800) >> 8; r = ((color & 0xf800) >> 8) | ((color >> 13) & 0x7);
g = (color & 0x07e0) >> 3; g = ((color & 0x07e0) >> 3) | ((color >> 9 ) & 0x3);
b = (color & 0x001F) << 3; b = ((color & 0x001F) << 3) | ((color >> 3 ) & 0x7);
y = (int) ((0.257 * ((double) r)) + (0.504 * ((double) g)) + (0.098 * ((double) b)) + 16.0); 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); u = (int) ((-0.148 * ((double) r)) + (-0.291 * ((double) g)) + (0.439 * ((double) b)) + 128.0);
@ -485,15 +470,14 @@ S9xXVDisplayDriver::init (void)
void void
S9xXVDisplayDriver::deinit (void) S9xXVDisplayDriver::deinit (void)
{ {
gdk_window_destroy (gdk_window);
XShmDetach (display, &shm); XShmDetach (display, &shm);
XSync (display, 0); XSync (display, 0);
XFreeColormap (display, xcolormap); XFreeColormap (display, xcolormap);
XFree (vi); XFree (vi);
g_object_unref (gdk_window);
XDestroyWindow (display, xwindow);
free (buffer[0]); free (buffer[0]);
free (buffer[1]); free (buffer[1]);