[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1002023: Partial bugfix



I created the attached patch, based on an upstream patch. I re-compiled
the Wine packages with this patch, and tested it. It prevents Flight
Simulator 2004 and Age of Empires II from crashing.

In AoE, the game is playable, though in my case the window contents
wasn't correctly sized to the (Wine desktop) window size; this might be
specific to my current set-up though, and I could do more testing.

In FS, the menu is usable, but when flying, the screen contents is
garbage, and the 3D elements (environment and also cockpit elements)
are not drawn. The window menu *is* visible. The game is not crashed
though, and based on the sounds, it does respond as expected to
keyboard input.

Note: I used a VM with i386 Debian 11 installed to compile the i386
Wine packages. Getting the wine packages compiled took a lot more
effort than creating the patch for this Wine version.
From: Corné Plooy <cornwarecjp@ultimatestunts.nl>
Subject: [PATCH] x11drv: Remove active client window from window data before
deleting it.

Fixes a crash with BadDrawable X error which happens when client window is used
in windows.c:sync_client_position() after the GL drawable has been deleted.
This does not happen under normal circumstances as the next GL drawable created
overrides client window in window structure. But in case new drawable gets
DC_GL_PIXMAP_WIN type it doesn't.

Origin: https://bugs.winehq.org/attachment.cgi?id=67883
Bug: https://bugs.winehq.org/show_bug.cgi?id=49649
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002023

--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -241,6 +241,7 @@
 struct gl_drawable
 {
     LONG                           ref;          /* reference count */
+    HWND                           hwnd;
     enum dc_gl_type                type;         /* type of GL surface */
     GLXDrawable                    drawable;     /* drawable for rendering with GL */
     Window                         window;       /* window if drawable is a GLXWindow */
@@ -1162,10 +1163,23 @@
     {
     case DC_GL_WINDOW:
     case DC_GL_CHILD_WIN:
+    {
+        struct x11drv_win_data *data = get_win_data( gl->hwnd );
+
         TRACE( "destroying %lx drawable %lx\n", gl->window, gl->drawable );
+        if (data)
+        {
+            if (data->client_window == gl->window)
+            {
+                XDeleteContext( data->display, data->client_window, winContext );
+                data->client_window = 0;
+            }
+            release_win_data( data );
+        }
         pglXDestroyWindow( gdi_display, gl->drawable );
         XDestroyWindow( gdi_display, gl->window );
         break;
+    }
     case DC_GL_PIXMAP_WIN:
         TRACE( "destroying pixmap %lx drawable %lx\n", gl->pixmap, gl->drawable );
         pglXDestroyPixmap( gdi_display, gl->drawable );
@@ -1321,6 +1335,7 @@
     /* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI
      * there is no way to query it, so we have to store it here.
      */
+    gl->hwnd = hwnd;
     gl->swap_interval = 1;
     gl->refresh_swap_interval = TRUE;
     gl->format = format;

Reply to: