opengl32: Use proper handles for GL contexts and pass a context pointer to the WGL driver functions.

This commit is contained in:
Alexandre Julliard 2012-06-29 12:29:55 +02:00
parent f88231b96b
commit 0045ec9dfb
5 changed files with 206 additions and 110 deletions

View File

@ -666,22 +666,23 @@ static BOOL nulldrv_UnrealizePalette( HPALETTE palette )
return FALSE;
}
static BOOL nulldrv_wglCopyContext( HGLRC src, HGLRC dst, UINT mask )
static BOOL nulldrv_wglCopyContext( struct wgl_context *src, struct wgl_context *dst, UINT mask )
{
return FALSE;
}
static HGLRC nulldrv_wglCreateContext( HDC hdc )
static struct wgl_context *nulldrv_wglCreateContext( HDC hdc )
{
return 0;
}
static HGLRC nulldrv_wglCreateContextAttribsARB( HDC hdc, HGLRC share_ctx, const int *attribs )
static struct wgl_context *nulldrv_wglCreateContextAttribsARB( HDC hdc, struct wgl_context *share_ctx,
const int *attribs )
{
return 0;
}
static BOOL nulldrv_wglDeleteContext( HGLRC hglrc )
static BOOL nulldrv_wglDeleteContext( struct wgl_context *context )
{
return FALSE;
}
@ -696,17 +697,17 @@ static PROC nulldrv_wglGetProcAddress( LPCSTR name )
return NULL;
}
static BOOL nulldrv_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc )
static BOOL nulldrv_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *context )
{
return FALSE;
}
static BOOL nulldrv_wglMakeCurrent( HDC hdc, HGLRC hglrc )
static BOOL nulldrv_wglMakeCurrent( HDC hdc, struct wgl_context *context )
{
return FALSE;
}
static BOOL nulldrv_wglShareLists( HGLRC org, HGLRC dst )
static BOOL nulldrv_wglShareLists( struct wgl_context *org, struct wgl_context *dst )
{
return FALSE;
}

View File

@ -895,7 +895,7 @@ static void test_opengl3(HDC hdc)
HGLRC gl3Ctx;
DWORD error;
gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0);
todo_wine ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n");
ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n");
error = GetLastError();
/* The Nvidia implementation seems to return hresults instead of win32 error codes */
todo_wine ok(error == ERROR_INVALID_OPERATION ||

View File

@ -79,6 +79,84 @@ extern INT WINAPI GdiDescribePixelFormat( HDC hdc, INT fmt, UINT size, PIXELFORM
extern BOOL WINAPI GdiSetPixelFormat( HDC hdc, INT fmt, const PIXELFORMATDESCRIPTOR *pfd );
extern BOOL WINAPI GdiSwapBuffers( HDC hdc );
/* handle management */
#define MAX_WGL_HANDLES 1024
struct wgl_handle
{
UINT handle;
struct wgl_context *context;
};
static struct wgl_handle wgl_handles[MAX_WGL_HANDLES];
static struct wgl_handle *next_free;
static unsigned int handle_count;
static CRITICAL_SECTION wgl_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &wgl_section,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": wgl_section") }
};
static CRITICAL_SECTION wgl_section = { &critsect_debug, -1, 0, 0, 0, 0 };
static inline HGLRC next_handle( struct wgl_handle *ptr )
{
WORD generation = HIWORD( ptr->handle ) + 1;
if (!generation) generation++;
ptr->handle = MAKELONG( ptr - wgl_handles, generation );
return ULongToHandle( ptr->handle );
}
static struct wgl_handle *get_handle_ptr( HGLRC handle )
{
unsigned int index = LOWORD( handle );
EnterCriticalSection( &wgl_section );
if (index < handle_count && ULongToHandle(wgl_handles[index].handle) == handle)
return &wgl_handles[index];
LeaveCriticalSection( &wgl_section );
SetLastError( ERROR_INVALID_HANDLE );
return NULL;
}
static void release_handle_ptr( struct wgl_handle *ptr )
{
if (ptr) LeaveCriticalSection( &wgl_section );
}
static HGLRC alloc_handle( struct wgl_context *context )
{
HGLRC handle = 0;
struct wgl_handle *ptr = NULL;
EnterCriticalSection( &wgl_section );
if ((ptr = next_free))
next_free = (struct wgl_handle *)next_free->context;
else if (handle_count < MAX_WGL_HANDLES)
ptr = &wgl_handles[handle_count++];
if (ptr)
{
ptr->context = context;
handle = next_handle( ptr );
}
else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
LeaveCriticalSection( &wgl_section );
return handle;
}
static void free_handle_ptr( struct wgl_handle *ptr )
{
ptr->handle &= ~0xffff;
ptr->context = (struct wgl_context *)next_free;
next_free = ptr;
LeaveCriticalSection( &wgl_section );
}
/***********************************************************************
* wglSetPixelFormat(OPENGL32.@)
*/
@ -93,12 +171,16 @@ BOOL WINAPI wglSetPixelFormat( HDC hdc, INT iPixelFormat,
*/
BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
{
if (!hglrcSrc || !hglrcDst)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return wgl_driver->p_wglCopyContext(hglrcSrc, hglrcDst, mask);
struct wgl_handle *src, *dst;
BOOL ret = FALSE;
if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
if ((dst = get_handle_ptr( hglrcDst )))
ret = wgl_driver->p_wglCopyContext( src->context, dst->context, mask );
release_handle_ptr( dst );
release_handle_ptr( src );
return ret;
}
/***********************************************************************
@ -106,12 +188,17 @@ BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
*/
BOOL WINAPI wglDeleteContext(HGLRC hglrc)
{
if (!hglrc)
struct wgl_handle *ptr = get_handle_ptr( hglrc );
if (!ptr) return FALSE;
if (hglrc == NtCurrentTeb()->glCurrentRC) wglMakeCurrent( 0, 0 );
if (!wgl_driver->p_wglDeleteContext( ptr->context ))
{
SetLastError(ERROR_INVALID_HANDLE);
release_handle_ptr( ptr );
return FALSE;
}
return wgl_driver->p_wglDeleteContext(hglrc);
free_handle_ptr( ptr );
return TRUE;
}
/***********************************************************************
@ -119,12 +206,19 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc)
*/
BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
{
if (!hglrc && !hdc && !NtCurrentTeb()->glContext)
struct wgl_handle *ptr = NULL;
BOOL ret;
if (!hglrc && !hdc && !NtCurrentTeb()->glCurrentRC)
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
return wgl_driver->p_wglMakeCurrent(hdc, hglrc);
if (hglrc && !(ptr = get_handle_ptr( hglrc ))) return FALSE;
ret = wgl_driver->p_wglMakeCurrent( hdc, ptr ? ptr->context : NULL );
if (ret) NtCurrentTeb()->glCurrentRC = hglrc;
release_handle_ptr( ptr );
return ret;
}
/***********************************************************************
@ -132,7 +226,20 @@ BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
*/
static HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attribs )
{
return wgl_driver->p_wglCreateContextAttribsARB( hdc, share, attribs );
HGLRC ret = 0;
struct wgl_context *context;
struct wgl_handle *share_ptr = NULL;
if (share && !(share_ptr = get_handle_ptr( share ))) return 0;
if ((context = wgl_driver->p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->context : NULL,
attribs )))
{
ret = alloc_handle( context );
if (!ret) wgl_driver->p_wglDeleteContext( context );
}
release_handle_ptr( share_ptr );
return ret;
}
/***********************************************************************
@ -140,20 +247,31 @@ static HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int
*/
static BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc )
{
return wgl_driver->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, hglrc );
struct wgl_handle *ptr = NULL;
BOOL ret;
if (hglrc && !(ptr = get_handle_ptr( hglrc ))) return FALSE;
ret = wgl_driver->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ptr ? ptr->context : NULL );
if (ret) NtCurrentTeb()->glCurrentRC = hglrc;
release_handle_ptr( ptr );
return ret;
}
/***********************************************************************
* wglShareLists (OPENGL32.@)
*/
BOOL WINAPI wglShareLists(HGLRC hglrc1, HGLRC hglrc2)
BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst)
{
if (!hglrc1 || !hglrc2)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return wgl_driver->p_wglShareLists(hglrc1, hglrc2);
BOOL ret = FALSE;
struct wgl_handle *src, *dst;
if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
if ((dst = get_handle_ptr( hglrcDst )))
ret = wgl_driver->p_wglShareLists( src->context, dst->context );
release_handle_ptr( dst );
release_handle_ptr( src );
return ret;
}
/***********************************************************************
@ -169,7 +287,13 @@ HDC WINAPI wglGetCurrentDC(void)
*/
HGLRC WINAPI wglCreateContext(HDC hdc)
{
return wgl_driver->p_wglCreateContext(hdc);
HGLRC ret = 0;
struct wgl_context *context = wgl_driver->p_wglCreateContext( hdc );
if (!context) return 0;
ret = alloc_handle( context );
if (!ret) wgl_driver->p_wglDeleteContext( context );
return ret;
}
/***********************************************************************
@ -177,7 +301,7 @@ HGLRC WINAPI wglCreateContext(HDC hdc)
*/
HGLRC WINAPI wglGetCurrentContext(void)
{
return NtCurrentTeb()->glContext;
return NtCurrentTeb()->glCurrentRC;
}
/***********************************************************************

View File

@ -110,7 +110,8 @@ typedef struct wine_glpixelformat {
DWORD dwFlags; /* We store some PFD_* flags in here for emulated bitmap formats */
} WineGLPixelFormat;
typedef struct wine_glcontext {
struct wgl_context
{
HDC hdc;
BOOL has_been_current;
BOOL sharing;
@ -128,7 +129,7 @@ typedef struct wine_glcontext {
GLXPixmap glxpixmap; /* GLX pixmap for memory DCs */
SIZE pixmap_size; /* pixmap size for memory DCs */
struct list entry;
} Wine_GLContext;
};
typedef struct wine_glpbuffer {
Drawable drawable;
@ -613,15 +614,7 @@ failed:
return FALSE;
}
static inline BOOL is_valid_context( Wine_GLContext *ctx )
{
Wine_GLContext *ptr;
LIST_FOR_EACH_ENTRY( ptr, &context_list, struct wine_glcontext, entry )
if (ptr == ctx) return TRUE;
return FALSE;
}
static int describeContext(Wine_GLContext* ctx) {
static int describeContext( struct wgl_context *ctx ) {
int tmp;
int ctx_vis_id;
TRACE(" Context %p have (vis:%p):\n", ctx, ctx->vis);
@ -1081,8 +1074,8 @@ static int pixelformat_from_fbconfig_id(XID fbconfig_id)
/* Mark any allocated context using the glx drawable 'old' to use 'new' */
void mark_drawable_dirty(Drawable old, Drawable new)
{
Wine_GLContext *ctx;
LIST_FOR_EACH_ENTRY( ctx, &context_list, struct wine_glcontext, entry )
struct wgl_context *ctx;
LIST_FOR_EACH_ENTRY( ctx, &context_list, struct wgl_context, entry )
{
if (old == ctx->drawables[0]) {
ctx->drawables[0] = new;
@ -1096,7 +1089,7 @@ void mark_drawable_dirty(Drawable old, Drawable new)
}
/* Given the current context, make sure its drawable is sync'd */
static inline void sync_context(Wine_GLContext *context)
static inline void sync_context(struct wgl_context *context)
{
if(context && context->refresh_drawables) {
if (glxRequireVersion(3))
@ -1109,7 +1102,7 @@ static inline void sync_context(Wine_GLContext *context)
}
static GLXContext create_glxcontext(Display *display, Wine_GLContext *context, GLXContext shareList)
static GLXContext create_glxcontext(Display *display, struct wgl_context *context, GLXContext shareList)
{
GLXContext ctx;
@ -1400,12 +1393,9 @@ static BOOL glxdrv_SetPixelFormat(PHYSDEV dev, int iPixelFormat, const PIXELFORM
/***********************************************************************
* glxdrv_wglCopyContext
*/
static BOOL glxdrv_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
static BOOL glxdrv_wglCopyContext(struct wgl_context *src, struct wgl_context *dst, UINT mask)
{
Wine_GLContext *src = (Wine_GLContext*)hglrcSrc;
Wine_GLContext *dst = (Wine_GLContext*)hglrcDst;
TRACE("hglrcSrc: (%p), hglrcDst: (%p), mask: %#x\n", hglrcSrc, hglrcDst, mask);
TRACE("%p -> %p mask %#x\n", src, dst, mask);
wine_tsx11_lock();
pglXCopyContext(gdi_display, src->ctx, dst->ctx, mask);
@ -1418,10 +1408,10 @@ static BOOL glxdrv_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
/***********************************************************************
* glxdrv_wglCreateContext
*/
static HGLRC glxdrv_wglCreateContext( HDC hdc )
static struct wgl_context *glxdrv_wglCreateContext( HDC hdc )
{
struct x11drv_escape_get_drawable escape;
Wine_GLContext *ret;
struct wgl_context *ret;
WineGLPixelFormat *fmt;
int fmt_count = 0;
@ -1457,24 +1447,15 @@ static HGLRC glxdrv_wglCreateContext( HDC hdc )
wine_tsx11_unlock();
TRACE(" creating context %p (GL context creation delayed)\n", ret);
return (HGLRC) ret;
return ret;
}
/***********************************************************************
* glxdrv_wglDeleteContext
*/
static BOOL glxdrv_wglDeleteContext(HGLRC hglrc)
static BOOL glxdrv_wglDeleteContext(struct wgl_context *ctx)
{
Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
TRACE("(%p)\n", hglrc);
if (!is_valid_context(ctx))
{
WARN("Error deleting context !\n");
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
TRACE("(%p)\n", ctx);
/* WGL doesn't allow deletion of a context which is current in another thread */
if (ctx->tid != 0 && ctx->tid != GetCurrentThreadId())
@ -1484,15 +1465,6 @@ static BOOL glxdrv_wglDeleteContext(HGLRC hglrc)
return FALSE;
}
/* WGL makes a context not current if it is active before deletion. GLX waits until the context is not current. */
if (ctx == NtCurrentTeb()->glContext)
{
wine_tsx11_lock();
pglXMakeCurrent(gdi_display, None, NULL);
wine_tsx11_unlock();
NtCurrentTeb()->glContext = NULL;
}
wine_tsx11_lock();
list_remove( &ctx->entry );
if (ctx->ctx) pglXDestroyContext( gdi_display, ctx->ctx );
@ -1513,7 +1485,7 @@ static BOOL glxdrv_wglDeleteContext(HGLRC hglrc)
static HDC WINAPI X11DRV_wglGetCurrentReadDCARB(void)
{
HDC ret = 0;
Wine_GLContext *ctx = NtCurrentTeb()->glContext;
struct wgl_context *ctx = NtCurrentTeb()->glContext;
if (ctx) ret = ctx->read_hdc;
@ -1554,7 +1526,7 @@ static PROC glxdrv_wglGetProcAddress(LPCSTR lpszProc)
return NULL;
}
static GLXPixmap get_context_pixmap( HDC hdc, struct wine_glcontext *ctx )
static GLXPixmap get_context_pixmap( HDC hdc, struct wgl_context *ctx )
{
if (!ctx->pixmap)
{
@ -1576,16 +1548,15 @@ static GLXPixmap get_context_pixmap( HDC hdc, struct wine_glcontext *ctx )
/***********************************************************************
* glxdrv_wglMakeCurrent
*/
static BOOL glxdrv_wglMakeCurrent(HDC hdc, HGLRC hglrc)
static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx)
{
BOOL ret;
Wine_GLContext *prev_ctx = NtCurrentTeb()->glContext;
Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
struct wgl_context *prev_ctx = NtCurrentTeb()->glContext;
struct x11drv_escape_get_drawable escape;
TRACE("(%p,%p)\n", hdc, hglrc);
TRACE("(%p,%p)\n", hdc, ctx);
if (hglrc == NULL)
if (!ctx)
{
if (prev_ctx) prev_ctx->tid = 0;
@ -1656,16 +1627,15 @@ static BOOL glxdrv_wglMakeCurrent(HDC hdc, HGLRC hglrc)
/***********************************************************************
* glxdrv_wglMakeContextCurrentARB
*/
static BOOL glxdrv_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc )
static BOOL glxdrv_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *ctx )
{
Wine_GLContext *ctx = (Wine_GLContext *)hglrc;
Wine_GLContext *prev_ctx = NtCurrentTeb()->glContext;
struct wgl_context *prev_ctx = NtCurrentTeb()->glContext;
struct x11drv_escape_get_drawable escape_draw, escape_read;
BOOL ret;
TRACE("(%p,%p,%p)\n", draw_hdc, read_hdc, hglrc);
TRACE("(%p,%p,%p)\n", draw_hdc, read_hdc, ctx);
if (hglrc == NULL)
if (!ctx)
{
if (prev_ctx) prev_ctx->tid = 0;
@ -1673,6 +1643,7 @@ static BOOL glxdrv_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC h
ret = pglXMakeCurrent(gdi_display, None, NULL);
wine_tsx11_unlock();
NtCurrentTeb()->glContext = NULL;
return TRUE;
}
escape_draw.code = X11DRV_GET_DRAWABLE;
@ -1725,11 +1696,8 @@ static BOOL glxdrv_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC h
/***********************************************************************
* glxdrv_wglShareLists
*/
static BOOL glxdrv_wglShareLists(HGLRC hglrc1, HGLRC hglrc2)
static BOOL glxdrv_wglShareLists(struct wgl_context *org, struct wgl_context *dest)
{
Wine_GLContext *org = (Wine_GLContext *) hglrc1;
Wine_GLContext *dest = (Wine_GLContext *) hglrc2;
TRACE("(%p, %p)\n", org, dest);
/* Sharing of display lists works differently in GLX and WGL. In case of GLX it is done
@ -1783,7 +1751,7 @@ static BOOL glxdrv_wglShareLists(HGLRC hglrc1, HGLRC hglrc2)
*/
static HDC glxdrv_wglGetCurrentDC(void)
{
Wine_GLContext *ctx = NtCurrentTeb()->glContext;
struct wgl_context *ctx = NtCurrentTeb()->glContext;
if (!ctx) return NULL;
TRACE("hdc %p\n", ctx->hdc);
@ -1798,7 +1766,7 @@ static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params)
{
case GL_DEPTH_BITS:
{
Wine_GLContext *ctx = NtCurrentTeb()->glContext;
struct wgl_context *ctx = NtCurrentTeb()->glContext;
pglGetIntegerv(pname, params);
/**
@ -1814,7 +1782,7 @@ static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params)
}
case GL_ALPHA_BITS:
{
Wine_GLContext *ctx = NtCurrentTeb()->glContext;
struct wgl_context *ctx = NtCurrentTeb()->glContext;
pglXGetFBConfigAttrib(gdi_display, ctx->fmt->fbconfig, GLX_ALPHA_SIZE, params);
TRACE("returns GL_ALPHA_BITS as '%d'\n", *params);
@ -1827,7 +1795,7 @@ static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params)
wine_tsx11_unlock();
}
static void flush_pixmap( struct wine_glcontext *ctx )
static void flush_pixmap( struct wgl_context *ctx )
{
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *info = (BITMAPINFO *)buffer;
@ -1874,7 +1842,7 @@ static void flush_gl_drawable( struct glx_physdev *physdev )
static void WINAPI X11DRV_wglFinish(void)
{
Wine_GLContext *ctx = NtCurrentTeb()->glContext;
struct wgl_context *ctx = NtCurrentTeb()->glContext;
enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE;
wine_tsx11_lock();
@ -1890,7 +1858,7 @@ static void WINAPI X11DRV_wglFinish(void)
static void WINAPI X11DRV_wglFlush(void)
{
Wine_GLContext *ctx = NtCurrentTeb()->glContext;
struct wgl_context *ctx = NtCurrentTeb()->glContext;
enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE;
wine_tsx11_lock();
@ -1907,10 +1875,11 @@ static void WINAPI X11DRV_wglFlush(void)
/***********************************************************************
* glxdrv_wglCreateContextAttribsARB
*/
static HGLRC glxdrv_wglCreateContextAttribsARB( HDC hdc, HGLRC hShareContext, const int* attribList )
static struct wgl_context *glxdrv_wglCreateContextAttribsARB( HDC hdc, struct wgl_context *hShareContext,
const int* attribList )
{
struct x11drv_escape_get_drawable escape;
Wine_GLContext *ret;
struct wgl_context *ret;
WineGLPixelFormat *fmt;
int fmt_count = 0;
@ -1994,7 +1963,7 @@ static HGLRC glxdrv_wglCreateContextAttribsARB( HDC hdc, HGLRC hShareContext, co
list_add_head( &context_list, &ret->entry );
wine_tsx11_unlock();
TRACE(" creating context %p\n", ret);
return (HGLRC) ret;
return ret;
}
/**
@ -3262,7 +3231,7 @@ BOOL destroy_glxpixmap(Display *display, XID glxpixmap)
static BOOL glxdrv_SwapBuffers(PHYSDEV dev)
{
struct glx_physdev *physdev = get_glxdrv_dev( dev );
Wine_GLContext *ctx = NtCurrentTeb()->glContext;
struct wgl_context *ctx = NtCurrentTeb()->glContext;
TRACE("(%p)\n", dev->hdc);

View File

@ -198,7 +198,7 @@ struct gdi_dc_funcs
};
/* increment this when you change the DC function table */
#define WINE_GDI_DRIVER_VERSION 39
#define WINE_GDI_DRIVER_VERSION 40
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */
#define GDI_PRIORITY_FONT_DRV 100 /* any font driver */
@ -226,18 +226,20 @@ static inline void push_dc_driver( PHYSDEV *dev, PHYSDEV physdev, const struct g
/* OpenGL support */
struct wgl_context;
struct wgl_funcs
{
INT (*p_GetPixelFormat)(HDC);
BOOL (*p_wglCopyContext)(HGLRC,HGLRC,UINT);
HGLRC (*p_wglCreateContext)(HDC);
HGLRC (*p_wglCreateContextAttribsARB)(HDC,HGLRC,const int*);
BOOL (*p_wglDeleteContext)(HGLRC);
HDC (*p_wglGetCurrentDC)(void);
PROC (*p_wglGetProcAddress)(LPCSTR);
BOOL (*p_wglMakeContextCurrentARB)(HDC,HDC,HGLRC);
BOOL (*p_wglMakeCurrent)(HDC,HGLRC);
BOOL (*p_wglShareLists)(HGLRC,HGLRC);
INT (*p_GetPixelFormat)(HDC);
BOOL (*p_wglCopyContext)(struct wgl_context*,struct wgl_context*,UINT);
struct wgl_context* (*p_wglCreateContext)(HDC);
struct wgl_context* (*p_wglCreateContextAttribsARB)(HDC,struct wgl_context*,const int*);
BOOL (*p_wglDeleteContext)(struct wgl_context*);
HDC (*p_wglGetCurrentDC)(void);
PROC (*p_wglGetProcAddress)(LPCSTR);
BOOL (*p_wglMakeContextCurrentARB)(HDC,HDC,struct wgl_context*);
BOOL (*p_wglMakeCurrent)(HDC,struct wgl_context*);
BOOL (*p_wglShareLists)(struct wgl_context*,struct wgl_context*);
};
/* the DC hook support is only exported on Win16, the 32-bit version is a Wine extension */