From 9e034b7fb816b4f9f043ce8f20091ccecdfca631 Mon Sep 17 00:00:00 2001 From: Raphael Junqueira Date: Thu, 28 Apr 2005 18:29:12 +0000 Subject: [PATCH] - valid implementation of X11DRV_ChoosePixelFormat using GLX1.3 API (ie. using real card caps and not ugly way using visuals array) to be compatible with opengl32 pixel formats (wgl*PixelFormat* APIs) as they need to be the same - add more traces to xrandr --- dlls/x11drv/opengl.c | 230 +++++++++++++++++++++++++------------------ dlls/x11drv/xrandr.c | 22 ++++- 2 files changed, 154 insertions(+), 98 deletions(-) diff --git a/dlls/x11drv/opengl.c b/dlls/x11drv/opengl.c index 15cd3b50ca3..481665c12fc 100644 --- a/dlls/x11drv/opengl.c +++ b/dlls/x11drv/opengl.c @@ -87,6 +87,9 @@ static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) { DPRINTF("\n"); DPRINTF(" - Color : %d\n", ppfd->cColorBits); + DPRINTF(" - Red : %d\n", ppfd->cRedBits); + DPRINTF(" - Green : %d\n", ppfd->cGreenBits); + DPRINTF(" - Blue : %d\n", ppfd->cBlueBits); DPRINTF(" - Alpha : %d\n", ppfd->cAlphaBits); DPRINTF(" - Accum : %d\n", ppfd->cAccumBits); DPRINTF(" - Depth : %d\n", ppfd->cDepthBits); @@ -112,10 +115,15 @@ static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) { static void *opengl_handle; #define MAKE_FUNCPTR(f) static typeof(f) * p##f; +MAKE_FUNCPTR(glGetError) MAKE_FUNCPTR(glXChooseVisual) MAKE_FUNCPTR(glXGetConfig) MAKE_FUNCPTR(glXSwapBuffers) MAKE_FUNCPTR(glXQueryExtension) + +MAKE_FUNCPTR(glXGetFBConfigs) +MAKE_FUNCPTR(glXChooseFBConfig) +MAKE_FUNCPTR(glXGetFBConfigAttrib) #undef MAKE_FUNCPTR void X11DRV_OpenGL_Init(Display *display) { @@ -125,10 +133,15 @@ void X11DRV_OpenGL_Init(Display *display) { if (opengl_handle == NULL) return; #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(opengl_handle, #f, NULL, 0)) == NULL) goto sym_not_found; +LOAD_FUNCPTR(glGetError) LOAD_FUNCPTR(glXChooseVisual) LOAD_FUNCPTR(glXGetConfig) LOAD_FUNCPTR(glXSwapBuffers) LOAD_FUNCPTR(glXQueryExtension) + +LOAD_FUNCPTR(glXGetFBConfigs) +LOAD_FUNCPTR(glXChooseFBConfig) +LOAD_FUNCPTR(glXGetFBConfigAttrib) #undef LOAD_FUNCPTR wine_tsx11_lock(); @@ -146,21 +159,22 @@ sym_not_found: opengl_handle = NULL; } -/* X11DRV_ChoosePixelFormat +#define TEST_AND_ADD1(t,a) if (t) att_list[att_pos++] = (a) +#define TEST_AND_ADD2(t,a,b) if (t) { att_list[att_pos++] = (a); att_list[att_pos++] = (b); } +#define NULL_TEST_AND_ADD2(tv,a,b) att_list[att_pos++] = (a); att_list[att_pos++] = ((tv) == 0 ? 0 : (b)) +#define ADD2(a,b) att_list[att_pos++] = (a); att_list[att_pos++] = (b) - Equivalent of glXChooseVisual -*/ -int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev, +/** + * X11DRV_ChoosePixelFormat + * + * Equivalent of glXChooseVisual + */ +int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev, const PIXELFORMATDESCRIPTOR *ppfd) { -#define TEST_AND_ADD1(t,a) if (t) att_list[att_pos++] = a -#define TEST_AND_ADD2(t,a,b) if (t) { att_list[att_pos++] = a; att_list[att_pos++] = b; } -#define NULL_TEST_AND_ADD2(tv,a,b) att_list[att_pos++] = a; att_list[att_pos++] = ((tv) == 0 ? 0 : b) -#define ADD2(a,b) att_list[att_pos++] = a; att_list[att_pos++] = b - int att_list[64]; int att_pos = 0; - XVisualInfo *vis; - int i; + GLXFBConfig* cfgs = NULL; + int ret = 0; if (opengl_handle == NULL) { ERR("No libGL on this box - disabling OpenGL support !\n"); @@ -180,58 +194,82 @@ int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev, } /* Now, build the request to GLX */ - TEST_AND_ADD1(ppfd->dwFlags & PFD_DOUBLEBUFFER, GLX_DOUBLEBUFFER); + TEST_AND_ADD2(ppfd->dwFlags & PFD_DOUBLEBUFFER, GLX_DOUBLEBUFFER, TRUE); TEST_AND_ADD1(ppfd->dwFlags & PFD_STEREO, GLX_STEREO); - TEST_AND_ADD1(ppfd->iPixelType == PFD_TYPE_RGBA, GLX_RGBA); - TEST_AND_ADD2(ppfd->iPixelType == PFD_TYPE_COLORINDEX, GLX_BUFFER_SIZE, ppfd->cColorBits); - - NULL_TEST_AND_ADD2(ppfd->cDepthBits, GLX_DEPTH_SIZE, 8); + + if (ppfd->iPixelType == PFD_TYPE_COLORINDEX) { + ADD2(GLX_BUFFER_SIZE, ppfd->cColorBits); + } + if (ppfd->iPixelType == PFD_TYPE_RGBA) { + ADD2(GLX_RENDER_TYPE, GLX_RGBA_BIT); + ADD2(GLX_BUFFER_SIZE, ppfd->cColorBits); + TEST_AND_ADD2(ppfd->cDepthBits, GLX_DEPTH_SIZE, ppfd->cDepthBits); + TEST_AND_ADD2(ppfd->cAlphaBits, GLX_ALPHA_SIZE, ppfd->cAlphaBits); + } + TEST_AND_ADD2(ppfd->cStencilBits, GLX_STENCIL_SIZE, ppfd->cStencilBits); + TEST_AND_ADD2(ppfd->cAuxBuffers, GLX_AUX_BUFFERS, ppfd->cAuxBuffers); + /* These flags are not supported yet... - - NULL_TEST_AND_ADD2(ppfd->cAlphaBits, GLX_ALPHA_SIZE, 8); - ADD2(GLX_ACCUM_SIZE, ppfd->cAccumBits); */ - ADD2(GLX_STENCIL_SIZE, ppfd->cStencilBits); /* now supported */ - /* ADD2(GLX_AUX_BUFFERS, ppfd->cAuxBuffers); */ + ADD2(GLX_ACCUM_SIZE, ppfd->cAccumBits); + */ att_list[att_pos] = None; - wine_tsx11_lock(); { - /* - This command cannot be used as we need to use the default visual... - Let's hope it at least contains some OpenGL functionnalities + wine_tsx11_lock(); + { + int nCfgs = 0; + int gl_test = 0; + int fmt_id; - vis = glXChooseVisual(gdi_display, DefaultScreen(gdi_display), att_list); - */ - int num; - XVisualInfo template; + GLXFBConfig* cfgs_fmt = NULL; + int nCfgs_fmt = 0; + int tmp_fmt_id; + UINT it_fmt; - template.visualid = XVisualIDFromVisual(visual); - vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num); - - TRACE("Found visual : %p - returns %d\n", vis, physDev->used_visuals + 1); - } - wine_tsx11_unlock(); - - if (vis == NULL) { - ERR("No visual found !\n"); - /* Should SetError here... */ - return 0; - } - /* try to find the visualid in the already created visuals */ - for( i=0; iused_visuals; i++ ) { - if ( vis->visualid == physDev->visuals[i]->visualid ) { - XFree(vis); - return i+1; + cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), att_list, &nCfgs); + if (NULL == cfgs || 0 == nCfgs) { + ERR("glXChooseFBConfig returns NULL (glError: %d)\n", pglGetError()); + ret = 0; + goto choose_exit; + } + + gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs[0], GLX_FBCONFIG_ID, &fmt_id); + if (gl_test) { + ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n"); + ret = 0; + goto choose_exit; + } + + cfgs_fmt = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs_fmt); + if (NULL == cfgs_fmt) { + ERR("Failed to get All FB Configs\n"); + ret = 0; + goto choose_exit; } - } - /* now give up, if the maximum is reached */ - if (physDev->used_visuals == MAX_PIXELFORMATS) { - ERR("Maximum number of visuals reached !\n"); - /* Should SetError here... */ - return 0; - } - physDev->visuals[physDev->used_visuals++] = vis; - return physDev->used_visuals; + for (it_fmt = 0; it_fmt < nCfgs_fmt; ++it_fmt) { + gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs_fmt[it_fmt], GLX_FBCONFIG_ID, &tmp_fmt_id); + if (gl_test) { + ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n"); + XFree(cfgs_fmt); + ret = 0; + goto choose_exit; + } + if (fmt_id == tmp_fmt_id) { + ret = it_fmt + 1; + break ; + } + } + if (it_fmt == nCfgs_fmt) { + ERR("Failed to get valid fmt for FBCONFIG_ID(%d)\n", fmt_id); + ret = 0; + } + XFree(cfgs_fmt); + } + +choose_exit: + if (NULL != cfgs) XFree(cfgs); + wine_tsx11_unlock(); + return ret; } /* X11DRV_DescribePixelFormat @@ -242,10 +280,15 @@ int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev, int iPixelFormat, UINT nBytes, PIXELFORMATDESCRIPTOR *ppfd) { - XVisualInfo *vis; + /*XVisualInfo *vis;*/ int value; int rb,gb,bb,ab; + GLXFBConfig* cfgs = NULL; + GLXFBConfig cur; + int nCfgs = 0; + int ret = 0; + if (opengl_handle == NULL) { ERR("No libGL on this box - disabling OpenGL support !\n"); return 0; @@ -253,9 +296,21 @@ int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev, TRACE("(%p,%d,%d,%p)\n", physDev, iPixelFormat, nBytes, ppfd); + wine_tsx11_lock(); + cfgs = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs); + wine_tsx11_unlock(); + + if (NULL == cfgs || 0 == nCfgs) { + ERR("unexpected iPixelFormat(%d), returns NULL\n", iPixelFormat); + return 0; /* unespected error */ + } + if (ppfd == NULL) { /* The application is only querying the number of visuals */ - return MAX_PIXELFORMATS; + wine_tsx11_lock(); + if (NULL != cfgs) XFree(cfgs); + wine_tsx11_unlock(); + return nCfgs; } if (nBytes < sizeof(PIXELFORMATDESCRIPTOR)) { @@ -263,33 +318,14 @@ int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev, /* Should set error */ return 0; } - if ((iPixelFormat > MAX_PIXELFORMATS) || - (iPixelFormat > physDev->used_visuals + 1) || - (iPixelFormat <= 0)) { - ERR("Wrong pixel format !\n"); - /* Should set error */ - return 0; + + if (nCfgs < iPixelFormat) { + ERR("unexpected iPixelFormat(%d) > nFormats(%d), returns NULL\n", iPixelFormat, nCfgs); + return 0; /* unespected error */ } - if (iPixelFormat == physDev->used_visuals + 1) { - int dblBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None}; - - /* Create a 'standard' X Visual */ - wine_tsx11_lock(); - vis = pglXChooseVisual(gdi_display, DefaultScreen(gdi_display), dblBuf); - wine_tsx11_unlock(); - - WARN("Uninitialized Visual. Creating standard (%p) !\n", vis); - - if (vis == NULL) { - ERR("Could not create standard visual !\n"); - /* Should set error */ - return 0; - } - - physDev->visuals[physDev->used_visuals++] = vis; - } - vis = physDev->visuals[iPixelFormat - 1]; + ret = nCfgs; + cur = cfgs[iPixelFormat - 1]; memset(ppfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); @@ -298,27 +334,29 @@ int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev, /* These flags are always the same... */ ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED; /* Now the flags extraced from the Visual */ + wine_tsx11_lock(); - pglXGetConfig(gdi_display, vis, GLX_DOUBLEBUFFER, &value); if (value) ppfd->dwFlags |= PFD_DOUBLEBUFFER; - pglXGetConfig(gdi_display, vis, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO; + + pglXGetFBConfigAttrib(gdi_display, cur, GLX_DOUBLEBUFFER, &value); if (value) ppfd->dwFlags |= PFD_DOUBLEBUFFER; + pglXGetFBConfigAttrib(gdi_display, cur, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO; /* Pixel type */ - pglXGetConfig(gdi_display, vis, GLX_RGBA, &value); - if (value) + pglXGetFBConfigAttrib(gdi_display, cur, GLX_RENDER_TYPE, &value); + if (value & GLX_RGBA_BIT) ppfd->iPixelType = PFD_TYPE_RGBA; else ppfd->iPixelType = PFD_TYPE_COLORINDEX; /* Color bits */ - pglXGetConfig(gdi_display, vis, GLX_BUFFER_SIZE, &value); + pglXGetFBConfigAttrib(gdi_display, cur, GLX_BUFFER_SIZE, &value); ppfd->cColorBits = value; /* Red, green, blue and alpha bits / shifts */ if (ppfd->iPixelType == PFD_TYPE_RGBA) { - pglXGetConfig(gdi_display, vis, GLX_RED_SIZE, &rb); - pglXGetConfig(gdi_display, vis, GLX_GREEN_SIZE, &gb); - pglXGetConfig(gdi_display, vis, GLX_BLUE_SIZE, &bb); - pglXGetConfig(gdi_display, vis, GLX_ALPHA_SIZE, &ab); + pglXGetFBConfigAttrib(gdi_display, cur, GLX_RED_SIZE, &rb); + pglXGetFBConfigAttrib(gdi_display, cur, GLX_GREEN_SIZE, &gb); + pglXGetFBConfigAttrib(gdi_display, cur, GLX_BLUE_SIZE, &bb); + pglXGetFBConfigAttrib(gdi_display, cur, GLX_ALPHA_SIZE, &ab); ppfd->cRedBits = rb; ppfd->cRedShift = gb + bb + ab; @@ -341,11 +379,11 @@ int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev, /* Accums : to do ... */ /* Depth bits */ - pglXGetConfig(gdi_display, vis, GLX_DEPTH_SIZE, &value); + pglXGetFBConfigAttrib(gdi_display, cur, GLX_DEPTH_SIZE, &value); ppfd->cDepthBits = value; /* stencil bits */ - pglXGetConfig( gdi_display, vis, GLX_STENCIL_SIZE, &value ); + pglXGetFBConfigAttrib(gdi_display, cur, GLX_STENCIL_SIZE, &value); ppfd->cStencilBits = value; wine_tsx11_unlock(); @@ -358,7 +396,11 @@ int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev, dump_PIXELFORMATDESCRIPTOR(ppfd); } - return MAX_PIXELFORMATS; + wine_tsx11_lock(); + if (NULL != cfgs) XFree(cfgs); + wine_tsx11_unlock(); + + return ret; } /* X11DRV_GetPixelFormat diff --git a/dlls/x11drv/xrandr.c b/dlls/x11drv/xrandr.c index 64775c7f80b..cc7eee8f3b1 100644 --- a/dlls/x11drv/xrandr.c +++ b/dlls/x11drv/xrandr.c @@ -204,6 +204,12 @@ static void X11DRV_XRandR_SetCurrentMode(int mode) FIXME("Cannot change screen BPP from %ld to %ld\n", dwBpp, dd_modes[mode].dwBPP); } mode = mode%real_xrandr_modes_count; + + TRACE("Changing Resolution to %ldx%ld @%d Hz\n", + dd_modes[mode].dwWidth, + dd_modes[mode].dwHeight, + dd_modes[mode].wRefreshRate); + for (i = 0; i < real_xrandr_sizes_count; i++) { if ( (dd_modes[mode].dwWidth == real_xrandr_sizes[i].width ) && @@ -226,10 +232,9 @@ static void X11DRV_XRandR_SetCurrentMode(int mode) } else { - TRACE("Resizing X display to %ldx%ld\n", - dd_modes[mode].dwWidth, dd_modes[mode].dwHeight); - stat = pXRRSetScreenConfig (gdi_display, sc, root, - size, rot, CurrentTime); + TRACE("Resizing X display to %ldx%ld \n", + dd_modes[mode].dwWidth, dd_modes[mode].dwHeight); + stat = pXRRSetScreenConfig (gdi_display, sc, root, size, rot, CurrentTime); } } } @@ -270,19 +275,28 @@ void X11DRV_XRandR_Init(void) } if (ok) { + TRACE("XRandR: found %u resolutions sizes\n", real_xrandr_sizes_count); real_xrandr_rates = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(short *) * real_xrandr_sizes_count); real_xrandr_rates_count = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(int) * real_xrandr_sizes_count); for (i=0; i < real_xrandr_sizes_count; i++) { real_xrandr_rates[i] = pXRRRates (gdi_display, DefaultScreen(gdi_display), i, &(real_xrandr_rates_count[i])); + TRACE("- at %u: %dx%d (%d rates):", i, real_xrandr_sizes[i].width, real_xrandr_sizes[i].height, real_xrandr_rates_count[i]); if (real_xrandr_rates_count[i]) { + int j; nmodes += real_xrandr_rates_count[i]; + for (j = 0; j < real_xrandr_rates_count[i]; ++j) { + if (j > 0) TRACE(","); + TRACE(" %d", real_xrandr_rates[i][j]); + } } else { nmodes++; + TRACE(" "); } + TRACE(" Hz \n"); } } wine_tsx11_unlock();