winex11: Add helper functions to retrieve drawable information for a window or DC.
This commit is contained in:
parent
025f4aed1e
commit
115d488183
|
@ -1119,6 +1119,21 @@ static inline void sync_context(struct wgl_context *context)
|
|||
LeaveCriticalSection( &context_section );
|
||||
}
|
||||
|
||||
static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc )
|
||||
{
|
||||
struct gl_drawable *gl;
|
||||
|
||||
EnterCriticalSection( &context_section );
|
||||
if (hwnd && !XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) return gl;
|
||||
if (hdc && !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) return gl;
|
||||
LeaveCriticalSection( &context_section );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void release_gl_drawable( struct gl_drawable *gl )
|
||||
{
|
||||
if (gl) LeaveCriticalSection( &context_section );
|
||||
}
|
||||
|
||||
static GLXContext create_glxcontext(Display *display, struct wgl_context *context, GLXContext shareList)
|
||||
{
|
||||
|
@ -1305,9 +1320,7 @@ void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_r
|
|||
changes.width = min( max( 1, client_rect->right - client_rect->left ), 65535 );
|
||||
changes.height = min( max( 1, client_rect->bottom - client_rect->top ), 65535 );
|
||||
|
||||
EnterCriticalSection( &context_section );
|
||||
|
||||
if (XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) goto done;
|
||||
if (!(gl = get_gl_drawable( hwnd, 0 ))) return;
|
||||
|
||||
if (changes.width != gl->rect.right - gl->rect.left) mask |= CWWidth;
|
||||
if (changes.height != gl->rect.bottom - gl->rect.top) mask |= CWHeight;
|
||||
|
@ -1349,7 +1362,7 @@ void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_r
|
|||
}
|
||||
SetRect( &gl->rect, changes.x, changes.y, changes.x + changes.width, changes.y + changes.height );
|
||||
done:
|
||||
LeaveCriticalSection( &context_section );
|
||||
release_gl_drawable( gl );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1508,20 +1521,17 @@ static int glxdrv_wglDescribePixelFormat( HDC hdc, int iPixelFormat,
|
|||
*/
|
||||
static int glxdrv_wglGetPixelFormat( HDC hdc )
|
||||
{
|
||||
HWND hwnd = WindowFromDC( hdc );
|
||||
struct gl_drawable *gl;
|
||||
int ret = 0;
|
||||
|
||||
EnterCriticalSection( &context_section );
|
||||
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) ||
|
||||
!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
|
||||
if ((gl = get_gl_drawable( WindowFromDC( hdc ), hdc )))
|
||||
{
|
||||
ret = gl->format - pixel_formats + 1;
|
||||
LeaveCriticalSection( &context_section );
|
||||
|
||||
/* Offscreen formats can't be used with traditional WGL calls.
|
||||
* As has been verified on Windows GetPixelFormat doesn't fail but returns iPixelFormat=1. */
|
||||
if (ret && !is_onscreen_pixel_format( ret )) ret = 1;
|
||||
|
||||
/* Offscreen formats can't be used with traditional WGL calls.
|
||||
* As has been verified on Windows GetPixelFormat doesn't fail but returns iPixelFormat=1. */
|
||||
if (!is_onscreen_pixel_format( ret )) ret = 1;
|
||||
release_gl_drawable( gl );
|
||||
}
|
||||
TRACE( "%p -> %d\n", hdc, ret );
|
||||
return ret;
|
||||
}
|
||||
|
@ -1532,7 +1542,7 @@ static int glxdrv_wglGetPixelFormat( HDC hdc )
|
|||
static BOOL glxdrv_wglSetPixelFormat( HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd )
|
||||
{
|
||||
const struct wgl_pixel_format *fmt;
|
||||
int value, prev = 0;
|
||||
int value;
|
||||
struct gl_drawable *gl;
|
||||
HWND hwnd = WindowFromDC( hdc );
|
||||
|
||||
|
@ -1558,12 +1568,12 @@ static BOOL glxdrv_wglSetPixelFormat( HDC hdc, int iPixelFormat, const PIXELFORM
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
EnterCriticalSection( &context_section );
|
||||
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ))
|
||||
prev = gl->format - pixel_formats + 1;
|
||||
LeaveCriticalSection( &context_section );
|
||||
|
||||
if (prev) return prev == iPixelFormat; /* cannot change it if already set */
|
||||
if ((gl = get_gl_drawable( hwnd, hdc )))
|
||||
{
|
||||
int prev = gl->format - pixel_formats + 1;
|
||||
release_gl_drawable( gl );
|
||||
return prev == iPixelFormat; /* cannot change it if already set */
|
||||
}
|
||||
|
||||
if(!SendMessageW(hwnd, WM_X11DRV_SET_WIN_FORMAT, fmt->fmt_id, 0)) {
|
||||
ERR("Couldn't set format of the window, returning failure\n");
|
||||
|
@ -1609,24 +1619,22 @@ static struct wgl_context *glxdrv_wglCreateContext( HDC hdc )
|
|||
{
|
||||
struct wgl_context *ret = NULL;
|
||||
struct gl_drawable *gl;
|
||||
HWND hwnd = WindowFromDC( hdc );
|
||||
|
||||
EnterCriticalSection( &context_section );
|
||||
|
||||
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) ||
|
||||
!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
|
||||
if (!(gl = get_gl_drawable( WindowFromDC( hdc ), hdc )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PIXEL_FORMAT );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret))))
|
||||
{
|
||||
if (!(ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)))) goto done;
|
||||
ret->hdc = hdc;
|
||||
ret->fmt = gl->format;
|
||||
ret->vis = pglXGetVisualFromFBConfig(gdi_display, gl->format->fbconfig);
|
||||
ret->ctx = create_glxcontext(gdi_display, ret, NULL);
|
||||
list_add_head( &context_list, &ret->entry );
|
||||
}
|
||||
else SetLastError( ERROR_INVALID_PIXEL_FORMAT );
|
||||
|
||||
done:
|
||||
LeaveCriticalSection( &context_section );
|
||||
release_gl_drawable( gl );
|
||||
TRACE( "%p -> %p\n", hdc, ret );
|
||||
return ret;
|
||||
}
|
||||
|
@ -1662,7 +1670,6 @@ static PROC glxdrv_wglGetProcAddress(LPCSTR lpszProc)
|
|||
static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
HWND hwnd;
|
||||
struct gl_drawable *gl;
|
||||
|
||||
TRACE("(%p,%p)\n", hdc, ctx);
|
||||
|
@ -1674,11 +1681,7 @@ static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
hwnd = WindowFromDC( hdc );
|
||||
EnterCriticalSection( &context_section );
|
||||
|
||||
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) ||
|
||||
!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
|
||||
if ((gl = get_gl_drawable( WindowFromDC( hdc ), hdc )))
|
||||
{
|
||||
if (ctx->fmt != gl->format)
|
||||
{
|
||||
|
@ -1707,7 +1710,7 @@ static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx)
|
|||
SetLastError( ERROR_INVALID_HANDLE );
|
||||
|
||||
done:
|
||||
LeaveCriticalSection( &context_section );
|
||||
release_gl_drawable( gl );
|
||||
TRACE( "%p,%p returning %d\n", hdc, ctx, ret );
|
||||
return ret;
|
||||
}
|
||||
|
@ -1718,8 +1721,7 @@ done:
|
|||
static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *ctx )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
HWND draw_hwnd, read_hwnd;
|
||||
struct gl_drawable *draw_gl, *read_gl;
|
||||
struct gl_drawable *draw_gl, *read_gl = NULL;
|
||||
|
||||
TRACE("(%p,%p,%p)\n", draw_hdc, read_hdc, ctx);
|
||||
|
||||
|
@ -1732,17 +1734,9 @@ static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct
|
|||
|
||||
if (!pglXMakeContextCurrent) return FALSE;
|
||||
|
||||
draw_hwnd = WindowFromDC( draw_hdc );
|
||||
read_hwnd = WindowFromDC( read_hdc );
|
||||
EnterCriticalSection( &context_section );
|
||||
|
||||
if (!XFindContext( gdi_display, (XID)draw_hwnd, gl_hwnd_context, (char **)&draw_gl ) ||
|
||||
!XFindContext( gdi_display, (XID)draw_hdc, gl_pbuffer_context, (char **)&draw_gl ))
|
||||
if ((draw_gl = get_gl_drawable( WindowFromDC( draw_hdc ), draw_hdc )))
|
||||
{
|
||||
if (XFindContext( gdi_display, (XID)read_hwnd, gl_hwnd_context, (char **)&read_gl ) &&
|
||||
XFindContext( gdi_display, (XID)read_hdc, gl_pbuffer_context, (char **)&read_gl ))
|
||||
read_gl = NULL;
|
||||
|
||||
read_gl = get_gl_drawable( WindowFromDC( read_hdc ), read_hdc );
|
||||
ret = pglXMakeContextCurrent(gdi_display, draw_gl->drawable,
|
||||
read_gl ? read_gl->drawable : 0, ctx->ctx);
|
||||
if (ret)
|
||||
|
@ -1758,7 +1752,8 @@ static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct
|
|||
}
|
||||
SetLastError( ERROR_INVALID_HANDLE );
|
||||
done:
|
||||
LeaveCriticalSection( &context_section );
|
||||
release_gl_drawable( read_gl );
|
||||
release_gl_drawable( draw_gl );
|
||||
TRACE( "%p,%p,%p returning %d\n", draw_hdc, read_hdc, ctx, ret );
|
||||
return ret;
|
||||
}
|
||||
|
@ -1866,16 +1861,17 @@ static struct wgl_context *X11DRV_wglCreateContextAttribsARB( HDC hdc, struct wg
|
|||
{
|
||||
struct wgl_context *ret = NULL;
|
||||
struct gl_drawable *gl;
|
||||
HWND hwnd = WindowFromDC( hdc );
|
||||
|
||||
TRACE("(%p %p %p)\n", hdc, hShareContext, attribList);
|
||||
|
||||
EnterCriticalSection( &context_section );
|
||||
|
||||
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) ||
|
||||
!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
|
||||
if (!(gl = get_gl_drawable( WindowFromDC( hdc ), hdc )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PIXEL_FORMAT );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret))))
|
||||
{
|
||||
if (!(ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)))) goto done;
|
||||
ret->hdc = hdc;
|
||||
ret->fmt = gl->format;
|
||||
ret->vis = NULL; /* glXCreateContextAttribsARB requires a fbconfig instead of a visual */
|
||||
|
@ -1920,20 +1916,17 @@ static struct wgl_context *X11DRV_wglCreateContextAttribsARB( HDC hdc, struct wg
|
|||
X11DRV_expect_error(gdi_display, GLXErrorHandler, NULL);
|
||||
ret->ctx = create_glxcontext(gdi_display, ret, NULL);
|
||||
XSync(gdi_display, False);
|
||||
if (!X11DRV_check_error() && ret->ctx)
|
||||
if (X11DRV_check_error() || !ret->ctx)
|
||||
{
|
||||
list_add_head( &context_list, &ret->entry );
|
||||
goto done;
|
||||
/* In the future we should convert the GLX error to a win32 one here if needed */
|
||||
ERR("Context creation failed\n");
|
||||
HeapFree( GetProcessHeap(), 0, ret );
|
||||
ret = NULL;
|
||||
}
|
||||
/* In the future we should convert the GLX error to a win32 one here if needed */
|
||||
ERR("Context creation failed\n");
|
||||
HeapFree( GetProcessHeap(), 0, ret );
|
||||
ret = NULL;
|
||||
else list_add_head( &context_list, &ret->entry );
|
||||
}
|
||||
else SetLastError( ERROR_INVALID_PIXEL_FORMAT );
|
||||
|
||||
done:
|
||||
LeaveCriticalSection( &context_section );
|
||||
release_gl_drawable( gl );
|
||||
TRACE( "%p -> %p\n", hdc, ret );
|
||||
return ret;
|
||||
}
|
||||
|
@ -3030,43 +3023,39 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
|
|||
enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE;
|
||||
struct gl_drawable *gl;
|
||||
struct wgl_context *ctx = NtCurrentTeb()->glContext;
|
||||
HWND hwnd = WindowFromDC( hdc );
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("(%p)\n", hdc);
|
||||
|
||||
EnterCriticalSection( &context_section );
|
||||
|
||||
if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) ||
|
||||
!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
|
||||
if (!(gl = get_gl_drawable( WindowFromDC( hdc ), hdc )))
|
||||
{
|
||||
switch (gl->type)
|
||||
{
|
||||
case DC_GL_PIXMAP_WIN:
|
||||
if (ctx) sync_context( ctx );
|
||||
if (pglXCopySubBufferMESA) {
|
||||
/* (glX)SwapBuffers has an implicit glFlush effect, however
|
||||
* GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before
|
||||
* copying */
|
||||
pglFlush();
|
||||
pglXCopySubBufferMESA( gdi_display, gl->drawable, 0, 0,
|
||||
gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top );
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
pglXSwapBuffers(gdi_display, gl->drawable);
|
||||
SetLastError( ERROR_INVALID_HANDLE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (gl->type)
|
||||
{
|
||||
case DC_GL_PIXMAP_WIN:
|
||||
if (ctx) sync_context( ctx );
|
||||
if (pglXCopySubBufferMESA) {
|
||||
/* (glX)SwapBuffers has an implicit glFlush effect, however
|
||||
* GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before
|
||||
* copying */
|
||||
pglFlush();
|
||||
pglXCopySubBufferMESA( gdi_display, gl->drawable, 0, 0,
|
||||
gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top );
|
||||
break;
|
||||
}
|
||||
ret = TRUE;
|
||||
/* fall through */
|
||||
default:
|
||||
pglXSwapBuffers(gdi_display, gl->drawable);
|
||||
break;
|
||||
}
|
||||
else SetLastError( ERROR_INVALID_HANDLE );
|
||||
|
||||
LeaveCriticalSection( &context_section );
|
||||
release_gl_drawable( gl );
|
||||
|
||||
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL );
|
||||
|
||||
return ret;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL create_glx_dc( PHYSDEV *pdev )
|
||||
|
@ -3134,14 +3123,13 @@ static INT glxdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_d
|
|||
struct gl_drawable *gl;
|
||||
const struct x11drv_escape_set_drawable *data = in_data;
|
||||
|
||||
EnterCriticalSection( &context_section );
|
||||
if (!XFindContext( gdi_display, (XID)data->hwnd, gl_hwnd_context, (char **)&gl ) ||
|
||||
!XFindContext( gdi_display, (XID)dev->hdc, gl_pbuffer_context, (char **)&gl ))
|
||||
if ((gl = get_gl_drawable( data->hwnd, dev->hdc )))
|
||||
{
|
||||
physdev->format = gl->format;
|
||||
physdev->type = gl->type;
|
||||
physdev->drawable = gl->drawable;
|
||||
physdev->pixmap = gl->pixmap;
|
||||
release_gl_drawable( gl );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3150,7 +3138,6 @@ static INT glxdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_d
|
|||
physdev->drawable = 0;
|
||||
physdev->pixmap = 0;
|
||||
}
|
||||
LeaveCriticalSection( &context_section );
|
||||
TRACE( "SET_DRAWABLE hdc %p drawable %lx pf %p type %u\n",
|
||||
dev->hdc, physdev->drawable, physdev->format, physdev->type );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue