From 4d73ba6e21d213458b1f889cfe5060d3f4451b26 Mon Sep 17 00:00:00 2001 From: Gavriel State Date: Wed, 28 Mar 2001 01:45:08 +0000 Subject: [PATCH] - Always use a double-buffered visual if one is available. - Ensure that all colormaps created use the double-buffered visual if it exists. This prevents problems where DRI GL implementations fail to work unless the colormap visual matches the window visual matches the glX visual. - Get around similar visual issue with the default GL context created for apps that don't create their own contexts before trying to use GL functions. --- dlls/opengl32/wgl.c | 30 +++++++++++++--- dlls/x11drv/x11drv_main.c | 72 +++++++++++++++++++++++---------------- graphics/x11drv/palette.c | 10 +++--- windows/x11drv/wnd.c | 7 ++-- 4 files changed, 77 insertions(+), 42 deletions(-) diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index 0be5020ea4c..71bafbad84e 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -78,6 +78,8 @@ HGLRC WINAPI wglCreateContext(HDC hdc) { X11DRV_PDEVICE *physDev; XVisualInfo *vis; Wine_GLContext *ret; + int num; + XVisualInfo template; TRACE("(%08x)\n", hdc); @@ -88,8 +90,9 @@ HGLRC WINAPI wglCreateContext(HDC hdc) { physDev = (X11DRV_PDEVICE *)dc->physDev; - /* First, get the visual for the choosen pixel format */ - vis = physDev->visuals[physDev->current_pf - 1]; + /* First, get the visual in use by the X11DRV */ + template.visualid = XVisualIDFromVisual(X11DRV_GetVisual()); + vis = XGetVisualInfo(display, VisualIDMask, &template, &num); if (vis == NULL) { ERR("NULL visual !!!\n"); @@ -299,7 +302,7 @@ void* WINAPI wglGetProcAddress(LPCSTR lpszProc) { return ret->func; } else { - ERR("Extension defined in the OpenGL library but NOT in opengl_ext.c... Please report (lionel.ulmer@free.fr) !\n"); + ERR("Extension %s defined in the OpenGL library but NOT in opengl_ext.c... Please report (lionel.ulmer@free.fr) !\n", lpszProc); return NULL; } } @@ -458,6 +461,8 @@ BOOL WINAPI wglUseFontOutlinesA(HDC hdc, /* This is for brain-dead applications that use OpenGL functions before even creating a rendering context.... */ static void process_attach(void) { + XWindowAttributes win_attr; + Visual *rootVisual; int num; XVisualInfo template; XVisualInfo *vis = NULL; @@ -468,7 +473,24 @@ static void process_attach(void) { } ENTER_GL(); - template.visualid = XVisualIDFromVisual(visual); + + /* Try to get the visual from the Root Window. We can't use the standard (presumably + double buffered) X11DRV visual with the Root Window, since we don't know if the Root + Window was created using the standard X11DRV visual, and glXMakeCurrent can't deal + with mismatched visuals. Note that the Root Window visual may not be double + buffered, so apps actually attempting to render this way may flicker */ + if (TSXGetWindowAttributes( display, X11DRV_GetXRootWindow(), &win_attr )) + { + rootVisual = win_attr.visual; + } + else + { + /* Get the default visual, since we can't seem to get the attributes from the + Root Window. Let's hope that the Root Window Visual matches the DefaultVisual */ + rootVisual = DefaultVisual( display, DefaultScreen(display) ); + } + + template.visualid = XVisualIDFromVisual(rootVisual); vis = XGetVisualInfo(display, VisualIDMask, &template, &num); if (vis != NULL) default_cx = glXCreateContext(display, vis, 0, GL_TRUE); if (default_cx != NULL) glXMakeCurrent(display, X11DRV_GetXRootWindow(), default_cx); diff --git a/dlls/x11drv/x11drv_main.c b/dlls/x11drv/x11drv_main.c index d8448547674..af2f4ddf80b 100644 --- a/dlls/x11drv/x11drv_main.c +++ b/dlls/x11drv/x11drv_main.c @@ -192,6 +192,37 @@ static void setup_options(void) } +/*********************************************************************** + * setup_opengl_visual + * + * Setup the default visual used for OpenGL and Direct3D, and the desktop + * window (if it exists). If OpenGL isn't available, the visual is simply + * set to the default visual for the display + */ +XVisualInfo *desktop_vi = NULL; +#ifdef HAVE_OPENGL +static void setup_opengl_visual( void ) +{ + int err_base, evt_base; + + /* In order to support OpenGL or D3D, we require a double-buffered + * visual */ + if (glXQueryExtension(display, &err_base, &evt_base) == True) { + int dblBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None}; + + ENTER_GL(); + desktop_vi = glXChooseVisual(display, DefaultScreen(display), dblBuf); + LEAVE_GL(); + } + + if (desktop_vi != NULL) { + visual = desktop_vi->visual; + screen = ScreenOfDisplay(display, desktop_vi->screen); + screen_depth = desktop_vi->depth; + } +} +#endif /* HAVE_OPENGL */ + /*********************************************************************** * create_desktop * @@ -208,27 +239,6 @@ static void create_desktop( const char *geometry ) XSetWindowAttributes win_attr; XTextProperty window_name; Atom XA_WM_DELETE_WINDOW; - /* Used to create the desktop window with a good visual */ - XVisualInfo *vi = NULL; -#ifdef HAVE_OPENGL - BOOL dblbuf_visual; - int err_base, evt_base; - - /* Get in wine.ini if the desktop window should have a double-buffered visual or not. - But first, test if OpenGL is even supported on the display ! */ - if (glXQueryExtension(display, &err_base, &evt_base) == True) { - dblbuf_visual = PROFILE_GetWineIniBool( "x11drv", "DesktopDoubleBuffered", 0 ); - if (dblbuf_visual) { - int dblBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None}; - - ENTER_GL(); - vi = glXChooseVisual(display, DefaultScreen(display), dblBuf); - win_attr.colormap = XCreateColormap(display, RootWindow(display,vi->screen), - vi->visual, AllocNone); - LEAVE_GL(); - } - } -#endif /* HAVE_OPENGL */ flags = TSXParseGeometry( geometry, &x, &y, &width, &height ); screen_width = width; @@ -241,18 +251,17 @@ static void create_desktop( const char *geometry ) ButtonReleaseMask | EnterWindowMask; win_attr.cursor = TSXCreateFontCursor( display, XC_top_left_arrow ); - if (vi != NULL) { - visual = vi->visual; - screen = ScreenOfDisplay(display, vi->screen); - screen_depth = vi->depth; + if (desktop_vi != NULL) { + win_attr.colormap = XCreateColormap(display, RootWindow(display,desktop_vi->screen), + desktop_vi->visual, AllocNone); } root_window = TSXCreateWindow( display, - (vi == NULL ? DefaultRootWindow(display) : RootWindow(display, vi->screen)), + (desktop_vi == NULL ? DefaultRootWindow(display) : RootWindow(display, desktop_vi->screen)), x, y, width, height, 0, - (vi == NULL ? CopyFromParent : vi->depth), + (desktop_vi == NULL ? CopyFromParent : desktop_vi->depth), InputOutput, - (vi == NULL ? CopyFromParent : vi->visual), - CWBackPixel | CWEventMask | CWCursor | (vi == NULL ? 0 : CWColormap), + (desktop_vi == NULL ? CopyFromParent : desktop_vi->visual), + CWBackPixel | CWEventMask | CWCursor | (desktop_vi == NULL ? 0 : CWColormap), &win_attr ); /* Set window manager properties */ @@ -342,6 +351,11 @@ static void process_attach(void) } else screen_depth = DefaultDepthOfScreen( screen ); + /* If OpenGL is available, change the default visual, etc as necessary */ +#ifdef HAVE_OPENGL + setup_opengl_visual(); +#endif /* HAVE_OPENGL */ + /* tell the libX11 that we will do input method handling ourselves * that keep libX11 from doing anything whith dead keys, allowing Wine * to have total control over dead keys, that is this line allows diff --git a/graphics/x11drv/palette.c b/graphics/x11drv/palette.c index a60cbe010f3..6e330202435 100644 --- a/graphics/x11drv/palette.c +++ b/graphics/x11drv/palette.c @@ -139,11 +139,11 @@ BOOL X11DRV_PALETTE_Init(void) break; } } - X11DRV_PALETTE_PaletteXColormap = DefaultColormapOfScreen( X11DRV_GetXScreen() ); + X11DRV_PALETTE_PaletteXColormap = TSXCreateColormap(display, X11DRV_GetXRootWindow(), visual, AllocNone); break; case StaticGray: - X11DRV_PALETTE_PaletteXColormap = DefaultColormapOfScreen( X11DRV_GetXScreen() ); + X11DRV_PALETTE_PaletteXColormap = TSXCreateColormap(display, X11DRV_GetXRootWindow(), visual, AllocNone); X11DRV_PALETTE_PaletteFlags |= X11DRV_PALETTE_FIXED; X11DRV_PALETTE_Graymax = (1 << X11DRV_GetDepth())-1; break; @@ -161,18 +161,18 @@ BOOL X11DRV_PALETTE_Init(void) for( white = X11DRV_DevCaps.sizePalette - 1; !(white & 1); white >>= 1 ) monoPlane++; X11DRV_PALETTE_PaletteFlags = (white & mask) ? X11DRV_PALETTE_WHITESET : 0; - X11DRV_PALETTE_PaletteXColormap = DefaultColormapOfScreen( X11DRV_GetXScreen() ); + X11DRV_PALETTE_PaletteXColormap = TSXCreateColormap(display, X11DRV_GetXRootWindow(), visual, AllocNone); TSXFree(depths); break; } TSXFree(depths); - X11DRV_PALETTE_PaletteXColormap = DefaultColormapOfScreen( X11DRV_GetXScreen() ); + X11DRV_PALETTE_PaletteXColormap = TSXCreateColormap(display, X11DRV_GetXRootWindow(), visual, AllocNone); X11DRV_PALETTE_PaletteFlags |= X11DRV_PALETTE_FIXED; X11DRV_PALETTE_ComputeShifts(visual->red_mask, &X11DRV_PALETTE_Redshift, &X11DRV_PALETTE_Redmax); X11DRV_PALETTE_ComputeShifts(visual->green_mask, &X11DRV_PALETTE_Greenshift, &X11DRV_PALETTE_Greenmax); X11DRV_PALETTE_ComputeShifts(visual->blue_mask, &X11DRV_PALETTE_Blueshift, &X11DRV_PALETTE_Bluemax); break; - } + } } TRACE(" visual class %i (%i)\n", visual->class, monoPlane); diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c index cc2c69c3a48..20e9cdad3d8 100644 --- a/windows/x11drv/wnd.c +++ b/windows/x11drv/wnd.c @@ -349,17 +349,16 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CREATESTRUCTA *cs, BOOL bUnicode) if (cs->cx <= 0) cs->cx = 1; if (cs->cy <= 0) cs->cy = 1; - ((X11DRV_WND_DATA *) wndPtr->pDriverData)->window = TSXCreateWindow( display, X11DRV_GetXRootWindow(), cs->x, cs->y, cs->cx, cs->cy, - 0, CopyFromParent, - InputOutput, CopyFromParent, + 0, screen_depth, + InputOutput, visual, CWEventMask | CWOverrideRedirect | CWColormap | CWCursor | CWSaveUnder | CWBackingStore | CWBitGravity, &win_attr ); - + if(!(wGroupLeader = X11DRV_WND_GetXWindow(wndPtr))) return FALSE;