Alexandre Julliard wrote:
> Tomas Carnecky <[EMAIL PROTECTED]> writes:
>> As far as I understand, the only way to access x11drv is through GDI
>> (which implements ExtEscape), would your proposed change require new
>> functions for opengl32 <-> x11drv communication through GDI? Or is it
>> somehow possible to bypass GDI and access x11drv directly from opengl32?
> 
> The DC access will have to be done through GDI, yes, but that can be a
> simple wrapper that calls the corresponding driver entry point. For
> functions that don't need to access the DC, opengl could call x11drv
> directly, though of course if everything goes through GDI it will make
> it easier to support opengl with a different driver.
> 

Based on your ideas, I did the following:
 - added a new gdi driver function: 'wglMakeCurrent'
 - move wglMakeCurernt to x11drv
 - new function wrapper_wglMakeCurrent in gdi/driver.c
 - wglMakeCurrent in opengl32 just calls wrapper_wglMakeCurrent

and it works, though I had to add -lGL to the x11drv Makefile, I don't
know how you see a libGL.so requirement for x11drv, maybe load libGL.so
 and the required entry points at runtime like in opengl32/wgl.c

I had to simplify wglMakeCurrent, I didn't spend much time on this hack,
and I had to copy the Wine_GLContext structure to x11drv/opengl.c, quite
ugly.. I know

I also had to comment out calls to 'NtCurrentTeb()' because it wouldn't
compile otherwise, I don't know what that function does, but World of
Warcraft works without it (and as a sidenote, I think it runs much faster).

I didn't know how much logic to put into opengl32/gdi or x11drv, gdi
extracts the PHYSDEV from the HDC and passes it as the first argument to
the x11drv function implementation, along with the original arguments
(Is is ok to pass HDC to the x11drv?).

And I don't know if the function naming is ok, x11drv exports a function
named wglMakeCurrent, maybe that should be changed to
wine_wglMakeCurrent and I don't know if the gdi wrapper and exported
function names (both wrapper_wglMakeCurrent) are ok.

If we can sort out the naming I could start adding the driver entry
points to both GDI and x11drv, without migrating the actual function
implementation, and than start migrating function by function to x11drv.

The attached patch is what came up by my hacking, just so you have an
idea what I've done ;)

tom
diff --git a/dlls/gdi/driver.c b/dlls/gdi/driver.c
index 9f40a8d..8903752 100644
--- a/dlls/gdi/driver.c
+++ b/dlls/gdi/driver.c
@@ -194,6 +194,9 @@ #define GET_FUNC(name) driver->funcs.p##
         GET_FUNC(StrokePath);
         GET_FUNC(SwapBuffers);
         GET_FUNC(WidenPath);
+
+        /* OpenGL wrapper functions */
+        GET_FUNC(wglMakeCurrent);
 #undef GET_FUNC
     }
     else memset( &driver->funcs, 0, sizeof(driver->funcs) );
@@ -705,3 +708,20 @@ INT WINAPI DrawEscape(HDC hdc, INT nEsca
     FIXME("DrawEscape, stub\n");
     return 0;
 }
+
+
+
+/* OpenGL wrapper functions */
+
+BOOL WINAPI wrapper_wglMakeCurrent(HDC hdc, HGLRC hglrc)
+{
+    BOOL ret = FALSE;
+    DC * dc = DC_GetDCPtr( hdc );
+    if (dc)
+    {
+        if (dc->funcs->pwglMakeCurrent)
+            ret = dc->funcs->pwglMakeCurrent( dc->physDev, hdc, hglrc );
+        GDI_ReleaseObj( hdc );
+    }
+    return ret;
+}
diff --git a/dlls/gdi/gdi32.spec b/dlls/gdi/gdi32.spec
index 1c245d8..bb9701d 100644
--- a/dlls/gdi/gdi32.spec
+++ b/dlls/gdi/gdi32.spec
@@ -522,3 +522,6 @@ #
 @ cdecl DIB_CreateDIBSection(long ptr long ptr long long long)
 @ cdecl GDI_GetObjPtr(long long)
 @ cdecl GDI_ReleaseObj(long)
+
+# OpenGL wrapper function 
+@ stdcall wrapper_wglMakeCurrent(long long)
diff --git a/dlls/gdi/gdi_private.h b/dlls/gdi/gdi_private.h
index dfdb008..fd02a57 100644
--- a/dlls/gdi/gdi_private.h
+++ b/dlls/gdi/gdi_private.h
@@ -182,6 +182,9 @@ typedef struct tagDC_FUNCS
     BOOL     (*pStrokePath)(PHYSDEV);
     BOOL     (*pSwapBuffers)(PHYSDEV);
     BOOL     (*pWidenPath)(PHYSDEV);
+
+    /* OpenGL wrapper functions */
+    BOOL     (*pwglMakeCurrent)(PHYSDEV,HDC,HGLRC);
 } DC_FUNCTIONS;
 
 /* It should not be necessary to access the contents of the GdiPath
@@ -449,3 +452,4 @@ #define DIB_PAL_MONO 2
 #endif /* __WINE_GDI_PRIVATE_H */
 
 BOOL WINAPI FontIsLinked(HDC);
+
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c
index 2e3cac7..b450959 100644
--- a/dlls/opengl32/wgl.c
+++ b/dlls/opengl32/wgl.c
@@ -539,56 +539,9 @@ static int describeDrawable(Wine_GLConte
 /***********************************************************************
  *		wglMakeCurrent (OPENGL32.@)
  */
-BOOL WINAPI wglMakeCurrent(HDC hdc,
-			   HGLRC hglrc) {
-  BOOL ret;
-  DWORD type = GetObjectType(hdc);
-
-  TRACE("(%p,%p)\n", hdc, hglrc);
-
-  ENTER_GL();
-  if (hglrc == NULL) {
-      ret = glXMakeCurrent(default_display, None, NULL);
-      NtCurrentTeb()->glContext = NULL;
-  } else {
-      Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
-      Drawable drawable = get_drawable( hdc );
-      if (ctx->ctx == NULL) {
-	int draw_vis_id, ctx_vis_id;
-        VisualID visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
-	TRACE(" Wine desktop VISUAL_ID is 0x%x\n", (unsigned int) visualid);
-	draw_vis_id = describeDrawable(ctx, drawable);
-	ctx_vis_id = describeContext(ctx);
-
-	if (-1 == draw_vis_id || (draw_vis_id == visualid && draw_vis_id != ctx_vis_id)) {
-	  /**
-	   * Inherits from root window so reuse desktop visual
-	   */
-	  XVisualInfo template;
-	  XVisualInfo *vis;
-	  int num;
-	  template.visualid = visualid;
-	  vis = XGetVisualInfo(ctx->display, VisualIDMask, &template, &num);
-
-	  TRACE(" Creating GLX Context\n");
-	  ctx->ctx = glXCreateContext(ctx->display, vis, NULL, type == OBJ_MEMDC ? False : True);
-	} else {
-	  TRACE(" Creating GLX Context\n");
-	  ctx->ctx = glXCreateContext(ctx->display, ctx->vis, NULL, type == OBJ_MEMDC ? False : True);
-	}
-	TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
-      }
-      TRACE(" make current for dis %p, drawable %p, ctx %p\n", ctx->display, (void*) drawable, ctx->ctx);
-      ret = glXMakeCurrent(ctx->display, drawable, ctx->ctx);
-      NtCurrentTeb()->glContext = ctx;
-      if(ret && type == OBJ_MEMDC && !is_pbuffer(hdc)) {
-          ctx->do_escape = TRUE;
-          glDrawBuffer(GL_FRONT);
-      }
-  }
-  LEAVE_GL();
-  TRACE(" returning %s\n", (ret ? "True" : "False"));
-  return ret;
+BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
+{
+	return wrapper_wglMakeCurrent(hdc, hglrc);
 }
 
 /***********************************************************************
diff --git a/dlls/x11drv/opengl.c b/dlls/x11drv/opengl.c
index 780d599..4ab0d59 100644
--- a/dlls/x11drv/opengl.c
+++ b/dlls/x11drv/opengl.c
@@ -53,6 +53,9 @@ #undef APIENTRY
 #undef CALLBACK
 #undef WINAPI
 
+#define ENTER_GL() wine_tsx11_lock()
+#define LEAVE_GL() wine_tsx11_unlock()
+
 /* Redefines the constants */
 #define CALLBACK    __stdcall
 #define WINAPI      __stdcall
@@ -69,6 +72,21 @@ inline static Drawable get_drawable( HDC
     return drawable;
 }
 
+inline static Drawable get_drawable_from_physdev( X11DRV_PDEVICE *physDev )
+{
+	if(physDev->bitmap) {
+		if (physDev->bitmap->hbitmap == BITMAP_stock_phys_bitmap.hbitmap) {
+			return physDev->drawable; /* PBuffer */
+		} else {
+ 			if(!physDev->bitmap->glxpixmap)
+				physDev->bitmap->glxpixmap = create_glxpixmap(physDev);
+				return physDev->bitmap->glxpixmap;
+		}
+	} else {
+		return physDev->drawable;
+	}
+}
+
 /* mark the darwable in this DC as damaged, used for Pbuffers */
 inline static BOOL mark_damaged( HDC hdc )
 {
@@ -656,6 +674,48 @@ void X11DRV_GLX_Event( HWND hwnd, XEvent
     }
 }
 
+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;
+
+BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HDC hdc, HGLRC hglrc)
+{
+  BOOL ret;
+  DWORD type = GetObjectType(hdc);
+
+  TRACE("(%p,%p,%p)\n", physDev, hdc, hglrc);
+
+  ENTER_GL();
+  if (hglrc == NULL) {
+      ret = glXMakeCurrent(None, None, NULL);
+     /* NtCurrentTeb()->glContext = NULL; */
+  } else {
+      Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
+      Drawable drawable = get_drawable_from_physdev( physDev );
+      if (ctx->ctx == NULL) {
+	     ctx->ctx = glXCreateContext(ctx->display, ctx->vis, NULL, type == OBJ_MEMDC ? False : True);
+	     TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
+      }
+      TRACE(" make current for dis %p, drawable %p, ctx %p\n", ctx->display, (void*) drawable, ctx->ctx);
+      ret = glXMakeCurrent(ctx->display, drawable, ctx->ctx);
+      /* NtCurrentTeb()->glContext = ctx; */
+      if(ret && type == OBJ_MEMDC) {
+          ctx->do_escape = TRUE;
+          glDrawBuffer(GL_FRONT);
+      }
+  }
+  LEAVE_GL();
+  TRACE(" returning %s\n", (ret ? "True" : "False"));
+  return ret;
+}
+
 #else  /* no OpenGL includes */
 
 void X11DRV_OpenGL_Init(Display *display)
@@ -732,4 +792,8 @@ void X11DRV_GLX_Event( HWND hwnd, XEvent
 {
 }
 
+BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physdev)
+{
+}
+
 #endif /* defined(HAVE_OPENGL) */
diff --git a/dlls/x11drv/winex11.drv.spec b/dlls/x11drv/winex11.drv.spec
index 1a835a9..49e18a7 100644
--- a/dlls/x11drv/winex11.drv.spec
+++ b/dlls/x11drv/winex11.drv.spec
@@ -128,3 +128,6 @@ # Desktop
 
 # XIM
 @ cdecl ForceXIMReset(long) X11DRV_ForceXIMReset
+
+# OpenGL implementation
+@ cdecl wglMakeCurrent(long long long) X11DRV_wglMakeCurrent
diff --git a/include/wingdi.h b/include/wingdi.h
index f2fcd21..b7de4af 100644
--- a/include/wingdi.h
+++ b/include/wingdi.h
@@ -3704,6 +3704,9 @@ BOOL    WINAPI wglSwapLayerBuffers(HDC,U
 BOOL    WINAPI wglUseFontBitmaps(HDC,DWORD,DWORD,DWORD);
 BOOL    WINAPI wglUseFontOutlines(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,INT,LPGLYPHMETRICSFLOAT);
 
+/* OpenGL wrapper */
+BOOL	WINAPI wrapper_wglMakeCurrent(HDC hdc, HGLRC hglrc);
+
 #ifdef __cplusplus
 }
 #endif


Reply via email to