From 9377c23efffc0fede71128b1419a8a1debfa5c00 Mon Sep 17 00:00:00 2001
From: Roderick Colenbrander <thunderbird2k@gmx.net>
Date: Tue, 29 Aug 2006 16:56:57 +0200
Subject: [PATCH] winex11.drv: Import glx context code.

---
 dlls/opengl32/wgl.c               | 228 ++++--------------------
 dlls/winex11.drv/opengl.c         | 284 +++++++++++++++++++++++++++++-
 dlls/winex11.drv/winex11.drv.spec |   8 +
 3 files changed, 323 insertions(+), 197 deletions(-)

diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c
index c2e8e3ace1c..d6f1e6b90ee 100644
--- a/dlls/opengl32/wgl.c
+++ b/dlls/opengl32/wgl.c
@@ -59,8 +59,19 @@ typedef struct wine_glx_s {
   Bool         (*p_glXMakeContextCurrent) (Display *, GLXDrawable, GLXDrawable, GLXContext);
 } wine_glx_t;
 
+typedef struct wine_wgl_s {
+    HGLRC WINAPI (*p_wglCreateContext)(HDC hdc);
+    BOOL WINAPI  (*p_wglDeleteContext)(HGLRC hglrc);
+    HGLRC WINAPI (*p_wglGetCurrentContext)(void);
+    HDC WINAPI   (*p_wglGetCurrentDC)(void);
+    HDC WINAPI   (*p_wglGetCurrentReadDCARB)(void);
+    void WINAPI  (*p_wglGetIntegerv)(GLenum pname, GLint* params);
+} wine_wgl_t;
+
 /** global glx object */
 static wine_glx_t wine_glx;
+/** global wgl object */
+static wine_wgl_t wine_wgl;
 
 /* x11drv GDI escapes */
 #define X11DRV_ESCAPE 6789
@@ -101,15 +112,6 @@ typedef struct wine_glcontext {
   struct wine_glcontext *next;
   struct wine_glcontext *prev;
 } Wine_GLContext;
-static Wine_GLContext *context_list;
-
-static inline Wine_GLContext *get_context_from_GLXContext(GLXContext ctx)
-{
-    Wine_GLContext *ret;
-    if (!ctx) return NULL;
-    for (ret = context_list; ret; ret = ret->next) if (ctx == ret->ctx) break;
-    return ret;
-}
 
 void enter_gl(void)
 {
@@ -125,35 +127,6 @@ void enter_gl(void)
     return;
 }
 
-static inline void free_context(Wine_GLContext *context)
-{
-  if (context->next != NULL) context->next->prev = context->prev;
-  if (context->prev != NULL) context->prev->next = context->next;
-  else context_list = context->next;
-
-  HeapFree(GetProcessHeap(), 0, context);
-}
-
-static inline Wine_GLContext *alloc_context(void)
-{
-  Wine_GLContext *ret;
-
-  if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLContext))))
-  {
-      ret->next = context_list;
-      if (context_list) context_list->prev = ret;
-      context_list = ret;
-  }
-  return ret;
-}
-
-inline static BOOL is_valid_context( Wine_GLContext *ctx )
-{
-    Wine_GLContext *ptr;
-    for (ptr = context_list; ptr; ptr = ptr->next) if (ptr == ctx) break;
-    return (ptr != NULL);
-}
-
 /* retrieve the X display to use on a given DC */
 inline static Display *get_display( HDC hdc )
 {
@@ -177,18 +150,6 @@ inline static Drawable get_drawable( HDC hdc )
     return drawable;
 }
 
-/** for use of wglGetCurrentReadDCARB */
-inline static HDC get_hdc_from_Drawable(GLXDrawable d)
-{
-  Wine_GLContext *ret;
-  for (ret = context_list; ret; ret = ret->next) {  
-    if (d == get_drawable( ret->hdc )) {
-      return ret->hdc;
-    }
-  }
-  return NULL;
-}
-
 /* retrieve the X font to use on a given DC */
 inline static Font get_font( HDC hdc )
 {
@@ -267,64 +228,8 @@ BOOL ConvertPixelFormatWGLtoGLX(Display *display, int iPixelFormat, int *fmt_ind
  */
 HGLRC WINAPI wglCreateContext(HDC hdc)
 {
-  Wine_GLContext *ret;
-  Display *display = get_display( hdc );
-  int hdcPF = 1; /* We can only use the Wine's main visual which has an index of 1 */
-  int tmp = 0;
-  int fmt_index = 0;
-  GLXFBConfig cur_cfg;
-
-  TRACE("(%p)->(PF:%d)\n", hdc, hdcPF);
-
-  /* First, get the visual in use by the X11DRV */
-  if (!display) return 0;
-
-  /* We can only render using the iPixelFormat (1) of Wine's Main visual, we need to get the correspondig GLX format.
-   * If this fails something is very wrong on the system. */
-  if(!ConvertPixelFormatWGLtoGLX(display, hdcPF, &tmp, &fmt_index)) {
-    ERR("Cannot get FB Config for main iPixelFormat 1, expect problems!\n");
-    SetLastError(ERROR_INVALID_PIXEL_FORMAT);
-    return NULL;
-  }
-
-  {
-    int nCfgs_fmt = 0;
-    GLXFBConfig* cfgs_fmt = NULL;
-    int value;
-    int gl_test = 0;
-    cfgs_fmt = wine_glx.p_glXGetFBConfigs(display, DefaultScreen(display), &nCfgs_fmt);
-    if (NULL == cfgs_fmt || 0 == nCfgs_fmt) {
-      ERR("Cannot get FB Configs, expect problems.\n");
-      SetLastError(ERROR_INVALID_PIXEL_FORMAT);
-      return NULL;
-    }
-    if (nCfgs_fmt < fmt_index) {
-      ERR("(%p): unexpected pixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, fmt_index, nCfgs_fmt);
-      SetLastError(ERROR_INVALID_PIXEL_FORMAT);
-      return NULL;
-    }
-    cur_cfg = cfgs_fmt[fmt_index];
-    gl_test = wine_glx.p_glXGetFBConfigAttrib(display, cur_cfg, GLX_FBCONFIG_ID, &value);
-    if (gl_test) {
-      ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
-      SetLastError(ERROR_INVALID_PIXEL_FORMAT);
-      return NULL;
-    }
-    XFree(cfgs_fmt);
-  }
-
-  /* The context will be allocated in the wglMakeCurrent call */
-  ENTER_GL();
-  ret = alloc_context();
-  LEAVE_GL();
-  ret->hdc = hdc;
-  ret->display = display;
-  ret->fb_conf = cur_cfg;
-  /*ret->vis = vis;*/
-  ret->vis = wine_glx.p_glXGetVisualFromFBConfig(display, cur_cfg);
-
-  TRACE(" creating context %p (GL context creation delayed)\n", ret);
-  return (HGLRC) ret;
+    TRACE("(%p)\n", hdc);
+    return wine_wgl.p_wglCreateContext(hdc);
 }
 
 /***********************************************************************
@@ -358,28 +263,8 @@ BOOL WINAPI wglCopyContext(HGLRC hglrcSrc,
  */
 BOOL WINAPI wglDeleteContext(HGLRC hglrc)
 {
-  Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
-  BOOL ret = TRUE;
-
-  TRACE("(%p)\n", hglrc);
-
-  ENTER_GL();
-  /* A game (Half Life not to name it) deletes twice the same context,
-   * so make sure it is valid first */
-  if (is_valid_context( ctx ))
-  {
-      if (ctx->ctx) glXDestroyContext(ctx->display, ctx->ctx);
-      free_context(ctx);
-  }
-  else
-  {
-    WARN("Error deleting context !\n");
-    SetLastError(ERROR_INVALID_HANDLE);
-    ret = FALSE;
-  }
-  LEAVE_GL();
-
-  return ret;
+    TRACE("(%p)\n", hglrc);
+    return wine_wgl.p_wglDeleteContext(hglrc);
 }
 
 /***********************************************************************
@@ -399,42 +284,16 @@ BOOL WINAPI wglDescribeLayerPlane(HDC hdc,
  *		wglGetCurrentContext (OPENGL32.@)
  */
 HGLRC WINAPI wglGetCurrentContext(void) {
-  GLXContext gl_ctx;
-  Wine_GLContext *ret;
-
-  TRACE("()\n");
-
-  ENTER_GL();
-  gl_ctx = glXGetCurrentContext();
-  ret = get_context_from_GLXContext(gl_ctx);
-  LEAVE_GL();
-
-  TRACE(" returning %p (GL context %p)\n", ret, gl_ctx);
-
-  return (HGLRC)ret;
+    TRACE("\n");
+    return wine_wgl.p_wglGetCurrentContext();
 }
 
 /***********************************************************************
  *		wglGetCurrentDC (OPENGL32.@)
  */
 HDC WINAPI wglGetCurrentDC(void) {
-  GLXContext gl_ctx;
-  Wine_GLContext *ret;
-
-  TRACE("()\n");
-
-  ENTER_GL();
-  gl_ctx = glXGetCurrentContext();
-  ret = get_context_from_GLXContext(gl_ctx);
-  LEAVE_GL();
-
-  if (ret) {
-    TRACE(" returning %p (GL context %p - Wine context %p)\n", ret->hdc, gl_ctx, ret);
-    return ret->hdc;
-  } else {
-    TRACE(" no Wine context found for GLX context %p\n", gl_ctx);
-    return 0;
-  }
+    TRACE("\n");
+    return wine_wgl.p_wglGetCurrentDC();
 }
 
 /***********************************************************************
@@ -703,22 +562,10 @@ BOOL WINAPI wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
  */
 HDC WINAPI wglGetCurrentReadDCARB(void) 
 {
-  GLXDrawable gl_d;
-  HDC ret;
-
-  TRACE("()\n");
-
-  ENTER_GL();
-  gl_d = glXGetCurrentReadDrawable();
-  ret = get_hdc_from_Drawable(gl_d);
-  LEAVE_GL();
-
-  TRACE(" returning %p (GL drawable %lu)\n", ret, gl_d);
-  return ret;
+    TRACE("\n");
+    return wine_wgl.p_wglGetCurrentReadDCARB();
 }
 
-
-
 /***********************************************************************
  *		wglRealizeLayerPalette (OPENGL32.@)
  */
@@ -1240,29 +1087,10 @@ const GLubyte * internal_glGetString(GLenum name) {
 }
 
 void internal_glGetIntegerv(GLenum pname, GLint* params) {
+  TRACE("pname: 0x%x, params %p\n", pname, params);
   glGetIntegerv(pname, params);
-  if (pname == GL_DEPTH_BITS) { 
-    GLXContext gl_ctx = glXGetCurrentContext();
-    Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
-    /*TRACE("returns Wine Ctx as %p\n", ret);*/
-    /** 
-     * if we cannot find a Wine Context
-     * we only have the default wine desktop context, 
-     * so if we have only a 24 depth say we have 32
-     */
-    if (NULL == ret && 24 == *params) { 
-      *params = 32;
-    }
-    TRACE("returns GL_DEPTH_BITS as '%d'\n", *params);
-  }
-  if (pname == GL_ALPHA_BITS) {
-    GLint tmp;
-    GLXContext gl_ctx = glXGetCurrentContext();
-    Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
-    glXGetFBConfigAttrib(ret->display, ret->fb_conf, GLX_ALPHA_SIZE, &tmp);
-    TRACE("returns GL_ALPHA_BITS as '%d'\n", tmp);
-    *params = tmp;
-  }
+  /* A few parameters like GL_DEPTH_BITS differ between WGL and GLX, the wglGetIntegerv helper function handles those */
+  wine_wgl.p_wglGetIntegerv(pname, params);
 }
 
 
@@ -1378,6 +1206,14 @@ static BOOL process_attach(void)
   wine_tsx11_lock_ptr   = (void *)GetProcAddress( mod, "wine_tsx11_lock" );
   wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" );
 
+  /* Load WGL function pointers from winex11.drv */
+  wine_wgl.p_wglCreateContext = (void *)GetProcAddress(mod, "wglCreateContext");
+  wine_wgl.p_wglDeleteContext = (void *)GetProcAddress(mod, "wglDeleteContext");
+  wine_wgl.p_wglGetCurrentContext = (void *)GetProcAddress(mod, "wglGetCurrentContext");
+  wine_wgl.p_wglGetCurrentDC = (void *)GetProcAddress(mod, "wglGetCurrentDC");
+  wine_wgl.p_wglGetCurrentReadDCARB = (void *)GetProcAddress(mod, "wglGetCurrentReadDCARB");
+  wine_wgl.p_wglGetIntegerv = (void *)GetProcAddress(mod, "wglGetIntegerv");
+
   hdc = GetDC(0);
   default_display = get_display( hdc );
   ReleaseDC( 0, hdc );
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 406cfc33970..d8ba5f82950 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -59,6 +59,18 @@ WINE_DECLARE_DEBUG_CHANNEL(opengl);
 
 WINE_DECLARE_DEBUG_CHANNEL(fps);
 
+typedef struct wine_glcontext {
+  HDC hdc;
+  Display *display;
+  XVisualInfo *vis;
+  GLXFBConfig fb_conf;
+  GLXContext ctx;
+  BOOL do_escape;
+  struct wine_glcontext *next;
+  struct wine_glcontext *prev;
+} Wine_GLContext;
+static Wine_GLContext *context_list;
+
 static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) {
   TRACE("  - size / version : %d / %d\n", ppfd->nSize, ppfd->nVersion);
   TRACE("  - dwFlags : ");
@@ -125,8 +137,13 @@ MAKE_FUNCPTR(glXQueryExtension)
 MAKE_FUNCPTR(glXGetFBConfigs)
 MAKE_FUNCPTR(glXChooseFBConfig)
 MAKE_FUNCPTR(glXGetFBConfigAttrib)
+MAKE_FUNCPTR(glXGetVisualFromFBConfig)
 MAKE_FUNCPTR(glXCreateGLXPixmap)
 MAKE_FUNCPTR(glXDestroyGLXPixmap)
+MAKE_FUNCPTR(glXCreateContext)
+MAKE_FUNCPTR(glXDestroyContext)
+MAKE_FUNCPTR(glXGetCurrentContext)
+MAKE_FUNCPTR(glXGetCurrentReadDrawable)
 /* MAKE_FUNCPTR(glXQueryDrawable) */
 #undef MAKE_FUNCPTR
 
@@ -153,8 +170,13 @@ LOAD_FUNCPTR(glXQueryExtension)
 LOAD_FUNCPTR(glXGetFBConfigs)
 LOAD_FUNCPTR(glXChooseFBConfig)
 LOAD_FUNCPTR(glXGetFBConfigAttrib)
+LOAD_FUNCPTR(glXGetVisualFromFBConfig)
 LOAD_FUNCPTR(glXCreateGLXPixmap)
 LOAD_FUNCPTR(glXDestroyGLXPixmap)
+LOAD_FUNCPTR(glXCreateContext)
+LOAD_FUNCPTR(glXDestroyContext)
+LOAD_FUNCPTR(glXGetCurrentContext)
+LOAD_FUNCPTR(glXGetCurrentReadDrawable)
 #undef LOAD_FUNCPTR
 
     wine_tsx11_lock();
@@ -173,6 +195,66 @@ sym_not_found:
     return FALSE;
 }
 
+static inline Wine_GLContext *alloc_context(void)
+{
+    Wine_GLContext *ret;
+
+    if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLContext))))
+    {
+        ret->next = context_list;
+        if (context_list) context_list->prev = ret;
+        context_list = ret;
+    }
+    return ret;
+}
+
+static inline void free_context(Wine_GLContext *context)
+{
+    if (context->next != NULL) context->next->prev = context->prev;
+    if (context->prev != NULL) context->prev->next = context->next;
+    else context_list = context->next;
+
+    HeapFree(GetProcessHeap(), 0, context);
+}
+
+static inline Wine_GLContext *get_context_from_GLXContext(GLXContext ctx)
+{
+    Wine_GLContext *ret;
+    if (!ctx) return NULL;
+    for (ret = context_list; ret; ret = ret->next) if (ctx == ret->ctx) break;
+    return ret;
+}
+
+/* retrieve the GLX drawable to use on a given DC */
+inline static Drawable get_drawable( HDC hdc )
+{
+    GLXDrawable drawable;
+    enum x11drv_escape_codes escape = X11DRV_GET_GLX_DRAWABLE;
+
+    if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
+                    sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
+    return drawable;
+}
+
+/** for use of wglGetCurrentReadDCARB */
+inline static HDC get_hdc_from_Drawable(GLXDrawable d)
+{
+    Wine_GLContext *ret;
+    for (ret = context_list; ret; ret = ret->next) {
+        if (d == get_drawable( ret->hdc )) {
+            return ret->hdc;
+        }
+    }
+    return NULL;
+}
+
+inline static BOOL is_valid_context( Wine_GLContext *ctx )
+{
+    Wine_GLContext *ptr;
+    for (ptr = context_list; ptr; ptr = ptr->next) if (ptr == ctx) break;
+    return (ptr != NULL);
+}
+
 /* GLX can advertise dozens of different pixelformats including offscreen and onscreen ones.
  * In our WGL implementation we only support a subset of these formats namely the format of
  * Wine's main visual and offscreen formats (if they are available).
@@ -530,7 +612,7 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
   }
 
   physDev->current_pf = iPixelFormat;
-  
+
   if (TRACE_ON(opengl)) {
     int nCfgs_fmt = 0;
     GLXFBConfig* cfgs_fmt = NULL;
@@ -578,6 +660,177 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
   return TRUE;
 }
 
+/* OpenGL32 wglCreateContext */
+HGLRC WINAPI X11DRV_wglCreateContext(HDC hdc)
+{
+    Wine_GLContext *ret;
+    GLXFBConfig* cfgs_fmt = NULL;
+    GLXFBConfig cur_cfg;
+    int hdcPF = 1; /* We can only use the Wine's main visual which has an index of 1 */
+    int tmp = 0;
+    int fmt_index = 0;
+    int nCfgs_fmt = 0;
+    int value = 0;
+    int gl_test = 0;
+
+    TRACE("(%p)->(PF:%d)\n", hdc, hdcPF);
+
+    /* First, get the visual in use by the X11DRV */
+    if (!gdi_display) return 0;
+
+    /* We can only render using the iPixelFormat (1) of Wine's Main visual, we need to get the correspondig GLX format.
+    * If this fails something is very wrong on the system. */
+    if(!ConvertPixelFormatWGLtoGLX(gdi_display, hdcPF, &tmp, &fmt_index)) {
+        ERR("Cannot get FB Config for main iPixelFormat 1, expect problems!\n");
+        SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+        return NULL;
+    }
+
+    cfgs_fmt = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs_fmt);
+    if (NULL == cfgs_fmt || 0 == nCfgs_fmt) {
+        ERR("Cannot get FB Configs, expect problems.\n");
+        SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+        return NULL;
+    }
+
+    if (nCfgs_fmt < fmt_index) {
+        ERR("(%p): unexpected pixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, fmt_index, nCfgs_fmt);
+        SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+        return NULL;
+    }
+
+    cur_cfg = cfgs_fmt[fmt_index];
+    gl_test = pglXGetFBConfigAttrib(gdi_display, cur_cfg, GLX_FBCONFIG_ID, &value);
+    if (gl_test) {
+        ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
+        SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+        return NULL;
+    }
+    XFree(cfgs_fmt);
+
+    /* The context will be allocated in the wglMakeCurrent call */
+    wine_tsx11_lock();
+    ret = alloc_context();
+    wine_tsx11_unlock();
+    ret->hdc = hdc;
+    ret->display = gdi_display;
+    ret->fb_conf = cur_cfg;
+    /*ret->vis = vis;*/
+    ret->vis = pglXGetVisualFromFBConfig(gdi_display, cur_cfg);
+
+    TRACE(" creating context %p (GL context creation delayed)\n", ret);
+    return (HGLRC) ret;
+}
+
+/* OpenGL32 wglDeleteContext */
+BOOL WINAPI X11DRV_wglDeleteContext(HGLRC hglrc)
+{
+    Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
+    BOOL ret = TRUE;
+
+    TRACE("(%p)\n", hglrc);
+
+    wine_tsx11_lock();
+    /* A game (Half Life not to name it) deletes twice the same context,
+    * so make sure it is valid first */
+    if (is_valid_context( ctx ))
+    {
+        if (ctx->ctx) pglXDestroyContext(ctx->display, ctx->ctx);
+        free_context(ctx);
+    }
+    else
+    {
+        WARN("Error deleting context !\n");
+        SetLastError(ERROR_INVALID_HANDLE);
+        ret = FALSE;
+    }
+    wine_tsx11_unlock();
+
+    return ret;
+}
+
+/* OpenGL32 wglGetCurrentContext() */
+HGLRC WINAPI X11DRV_wglGetCurrentContext(void) {
+    GLXContext gl_ctx;
+    Wine_GLContext *ret;
+
+    TRACE("()\n");
+
+    wine_tsx11_lock();
+    gl_ctx = pglXGetCurrentContext();
+    ret = get_context_from_GLXContext(gl_ctx);
+    wine_tsx11_unlock();
+
+    TRACE(" returning %p (GL context %p)\n", ret, gl_ctx);
+
+    return (HGLRC)ret;
+}
+
+/* OpenGL32 wglGetCurrentDC */
+HDC WINAPI X11DRV_wglGetCurrentDC(void) {
+    GLXContext gl_ctx;
+    Wine_GLContext *ret;
+
+    TRACE("()\n");
+
+    wine_tsx11_lock();
+    gl_ctx = pglXGetCurrentContext();
+    ret = get_context_from_GLXContext(gl_ctx);
+    wine_tsx11_unlock();
+
+    if (ret) {
+        TRACE(" returning %p (GL context %p - Wine context %p)\n", ret->hdc, gl_ctx, ret);
+        return ret->hdc;
+    } else {
+        TRACE(" no Wine context found for GLX context %p\n", gl_ctx);
+        return 0;
+    }
+}
+
+/* OpenGL32 wglGetCurrentReadDCARB */
+HDC WINAPI X11DRV_wglGetCurrentReadDCARB(void) 
+{
+    GLXDrawable gl_d;
+    HDC ret;
+
+    TRACE("()\n");
+
+    wine_tsx11_lock();
+    gl_d = pglXGetCurrentReadDrawable();
+    ret = get_hdc_from_Drawable(gl_d);
+    wine_tsx11_unlock();
+
+    TRACE(" returning %p (GL drawable %lu)\n", ret, gl_d);
+    return ret;
+}
+
+/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */ 
+void X11DRV_wglGetIntegerv(GLenum pname, GLint* params) {
+    TRACE("pname: 0x%x, params: %p\n", pname, params);
+    if (pname == GL_DEPTH_BITS) { 
+        GLXContext gl_ctx = pglXGetCurrentContext();
+        Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
+        /*TRACE("returns Wine Ctx as %p\n", ret);*/
+        /** 
+        * if we cannot find a Wine Context
+        * we only have the default wine desktop context, 
+        * so if we have only a 24 depth say we have 32
+        */
+        if (NULL == ret && 24 == *params) { 
+            *params = 32;
+        }
+        TRACE("returns GL_DEPTH_BITS as '%d'\n", *params);
+    }
+    if (pname == GL_ALPHA_BITS) {
+        GLint tmp;
+        GLXContext gl_ctx = pglXGetCurrentContext();
+        Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
+        pglXGetFBConfigAttrib(ret->display, ret->fb_conf, GLX_ALPHA_SIZE, &tmp);
+        TRACE("returns GL_ALPHA_BITS as '%d'\n", tmp);
+        *params = tmp;
+    }
+}
+
 static XID create_glxpixmap(X11DRV_PDEVICE *physDev)
 {
     GLXPixmap ret;
@@ -765,6 +1018,35 @@ BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) {
   return FALSE;
 }
 
+/* OpenGL32 wglCreateContext */
+HGLRC WINAPI X11DRV_wglCreateContext(HDC hdc) {
+    ERR_(opengl)("No OpenGL support compiled in.\n");
+    return NULL;
+}
+
+/* OpenGL32 wglDeleteContext */
+BOOL WINAPI X11DRV_wglDeleteContext(HGLRC hglrc) {
+    ERR_(opengl)("No OpenGL support compiled in.\n");
+    return FALSE;
+}
+
+/* OpenGL32 wglGetCurrentContext() */
+HGLRC WINAPI X11DRV_wglGetCurrentContext(void) {
+    ERR_(opengl)("No OpenGL support compiled in.\n");
+    return NULL;
+}
+
+/* OpenGL32 wglGetCurrentDC */
+HDC WINAPI X11DRV_wglGetCurrentDC(void) {
+    ERR_(opengl)("No OpenGL support compiled in.\n");
+    return 0;
+}
+
+/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */ 
+void X11DRV_wglGetIntegerv(GLenum pname, GLint* params) {
+    ERR_(opengl)("No OpenGL support compiled in.\n");
+}
+
 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
 {
   return NULL;
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 072295deefe..5d5126f9a8e 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -127,3 +127,11 @@
 
 # XIM
 @ cdecl ForceXIMReset(long) X11DRV_ForceXIMReset
+
+# OpenGL
+@ cdecl wglCreateContext(long) X11DRV_wglCreateContext
+@ cdecl wglDeleteContext(long) X11DRV_wglDeleteContext
+@ cdecl wglGetCurrentContext() X11DRV_wglGetCurrentContext
+@ cdecl wglGetCurrentDC() X11DRV_wglGetCurrentDC
+@ cdecl wglGetCurrentReadDCARB() X11DRV_wglGetCurrentReadDCARB
+@ cdecl wglGetIntegerv(long ptr) X11DRV_wglGetIntegerv
-- 
GitLab