Ulrich Czekalla wrote:
This patch override glViewport and glScissor to correctly position and size opengl child windows.
I've only tested this patch with Google Earth and Google Sketchup so I'd like to get some feedback to see if this solves the problem for your application.
Roderick: I realize you're currently reworking opengl32 so let me know if this conflicts with what you are doing.
Thanks,
/Ulrich
dlls/opengl32/make_opengl | 15 +++++++ dlls/opengl32/opengl_ext.h | 5 ++ dlls/opengl32/opengl_norm.c | 10 ++--- dlls/opengl32/wgl.c | 78 +++++++++++++++++++++++++++++++++++++ dlls/winex11.drv/opengl.c | 72 ++++++++++++++++++++++++++++++++-- dlls/winex11.drv/winex11.drv.spec | 1 6 files changed, 172 insertions(+), 9 deletions(-)
6b6a26ef714827017c5ae438b2f843766d711cb2 diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 837b8d9..bfb0191 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -266,6 +266,21 @@ sub GenerateThunk($$$$$) if ( $func_ref->[0] eq "glGetIntegerv" ) { $wine_func_ref_name = "internal_glGetIntegerv"; }
- if ( $func_ref->[0] eq "glEnable" ) {
- $wine_func_ref_name = "internal_glEnable";
- }
- if ( $func_ref->[0] eq "glIsEnable" ) {
- $wine_func_ref_name = "internal_glIsEnable";
- }
- if ( $func_ref->[0] eq "glDisable" ) {
- $wine_func_ref_name = "internal_glDisable";
- }
- if ( $func_ref->[0] eq "glScissorr" ) {
- $wine_func_ref_name = "internal_glScissorr";
- }
- if ( $func_ref->[0] eq "glViewport" ) {
- $wine_func_ref_name = "internal_glViewport";
- } $ret = "$ret$prefix$wine_func_ref_name( $call_arg);\n"; if ($thread_safe) { $ret = "$ret LEAVE_GL();\n";
diff --git a/dlls/opengl32/opengl_ext.h b/dlls/opengl32/opengl_ext.h index a7fe233..b7263df 100644 --- a/dlls/opengl32/opengl_ext.h +++ b/dlls/opengl32/opengl_ext.h @@ -75,5 +75,10 @@ extern const int extension_registry_size
const GLubyte* internal_glGetString(GLenum name); void internal_glGetIntegerv(GLenum pname, GLint* params); +void internal_glDisable(GLenum cap); +void internal_glEnable(GLenum cap); +GLboolean internal_glIsEnabled(GLenum cap); +void internal_glScissor(GLint x, GLint y, GLsizei width, GLsizei height); +void internal_glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
#endif /* __DLLS_OPENGL32_OPENGL_EXT_H */ diff --git a/dlls/opengl32/opengl_norm.c b/dlls/opengl32/opengl_norm.c index 8374a86..047770f 100644 --- a/dlls/opengl32/opengl_norm.c +++ b/dlls/opengl32/opengl_norm.c @@ -815,7 +815,7 @@ void WINAPI wine_glDepthRange( GLclampd void WINAPI wine_glDisable( GLenum cap ) { TRACE("(%d)\n", cap ); ENTER_GL();
- glDisable( cap );
- internal_glDisable( cap ); LEAVE_GL();
}
@@ -915,7 +915,7 @@ void WINAPI wine_glEdgeFlagv( GLboolean* void WINAPI wine_glEnable( GLenum cap ) { TRACE("(%d)\n", cap ); ENTER_GL();
- glEnable( cap );
- internal_glEnable( cap ); LEAVE_GL();
}
@@ -1772,7 +1772,7 @@ GLboolean WINAPI wine_glIsEnabled( GLenu GLboolean ret_value; TRACE("(%d)\n", cap ); ENTER_GL();
- ret_value = glIsEnabled( cap );
- ret_value = internal_glIsEnabled( cap ); LEAVE_GL(); return ret_value;
} @@ -2889,7 +2889,7 @@ void WINAPI wine_glScalef( GLfloat x, GL void WINAPI wine_glScissor( GLint x, GLint y, GLsizei width, GLsizei height ) { TRACE("(%d, %d, %d, %d)\n", x, y, width, height ); ENTER_GL();
- glScissor( x, y, width, height );
- internal_glScissor( x, y, width, height ); LEAVE_GL();
}
@@ -3759,6 +3759,6 @@ void WINAPI wine_glVertexPointer( GLint void WINAPI wine_glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) { TRACE("(%d, %d, %d, %d)\n", x, y, width, height ); ENTER_GL();
- glViewport( x, y, width, height );
- internal_glViewport( x, y, width, height ); LEAVE_GL();
} diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index 1c3973c..76785d7 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -84,6 +84,7 @@ static Display *default_display; /* dis static HMODULE opengl32_handle;
static void* (*p_glXGetProcAddressARB)(const GLubyte *); +static void (*p_SyncCurrentDrawable)();
static char internal_gl_disabled_extensions[512]; static char* internal_gl_extensions = NULL; @@ -95,6 +96,9 @@ typedef struct wine_glcontext { GLXFBConfig fb_conf; GLXContext ctx; BOOL do_escape;
- RECT viewport;
- RECT scissor;
- BOOL scissor_enabled; struct wine_glcontext *next; struct wine_glcontext *prev;
} Wine_GLContext; @@ -124,6 +128,7 @@ inline static Display *get_display( HDC return display; }
/***********************************************************************
wglCreateLayerContext (OPENGL32.@)
*/ @@ -563,6 +568,72 @@ BOOL WINAPI wglUseFontOutlinesW(HDC hdc, return wglUseFontOutlines_common(hdc, first, count, listBase, deviation, extrusion, format, lpgmf, TRUE); }
+void internal_glEnable(GLenum cap) +{
- if (cap == GL_SCISSOR_TEST)
- {
Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
ctx->scissor_enabled = TRUE;
- }
- else
- {
glEnable(cap);
- }
+}
+GLboolean internal_glIsEnabled(GLenum cap) +{
- GLboolean enabled;
- if (cap == GL_SCISSOR_TEST)
- {
Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
enabled = ctx->scissor_enabled;
- }
- else
- {
enabled = glIsEnabled(cap);
- }
- return enabled;
+}
+void internal_glDisable(GLenum cap) +{
- if (cap == GL_SCISSOR_TEST)
- {
Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
ctx->scissor_enabled = FALSE;
- }
- else
- {
glDisable(cap);
- }
+}
+void internal_glScissor( GLint x, GLint y, GLsizei width, GLsizei height ) +{
- Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
- ctx->scissor.left = x;
- ctx->scissor.top = y;
- ctx->scissor.right = x + width;
- ctx->scissor.bottom = y + height;
- p_SyncCurrentDrawable();
+}
+void internal_glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) +{
- Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
- ctx->viewport.left = x;
- ctx->viewport.top = y;
- ctx->viewport.right = x + width;
- ctx->viewport.bottom = y + height;
- p_SyncCurrentDrawable();
+}
const GLubyte * internal_glGetString(GLenum name) { const char* GL_Extensions = NULL;
@@ -658,6 +729,13 @@ static BOOL process_attach(void) /* Interal WGL function */ wine_wgl.p_wglGetIntegerv = (void *)GetProcAddress(mod, "wglGetIntegerv");
- p_SyncCurrentDrawable = (void *)GetProcAddress(mod, "SyncCurrentDrawable");
- if (!p_SyncCurrentDrawable)
- {
ERR("Using incompatible version of winex11drv\n");
return FALSE;
- }
- 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 64b1166..c8650a1 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -74,6 +74,9 @@ typedef struct wine_glcontext { GLXFBConfig fb_conf; GLXContext ctx; BOOL do_escape;
- RECT viewport;
- RECT scissor;
- BOOL scissor_enabled; struct wine_glcontext *next; struct wine_glcontext *prev;
} Wine_GLContext; @@ -240,12 +243,15 @@ MAKE_FUNCPTR(glBitmap) MAKE_FUNCPTR(glCopyTexSubImage1D) MAKE_FUNCPTR(glCopyTexSubImage2D) MAKE_FUNCPTR(glDrawBuffer) +MAKE_FUNCPTR(glEnable) MAKE_FUNCPTR(glEndList) MAKE_FUNCPTR(glGetError) MAKE_FUNCPTR(glGetIntegerv) MAKE_FUNCPTR(glGetString) MAKE_FUNCPTR(glNewList) MAKE_FUNCPTR(glPixelStorei) +MAKE_FUNCPTR(glScissor) +MAKE_FUNCPTR(glViewport) #undef MAKE_FUNCPTR
BOOL X11DRV_WineGL_InitOpenglInfo() @@ -363,15 +369,18 @@ LOAD_FUNCPTR(glXGetFBConfigs) /* Standard OpenGL calls */ LOAD_FUNCPTR(glBindTexture) LOAD_FUNCPTR(glBitmap) -LOAD_FUNCPTR(glEndList) LOAD_FUNCPTR(glCopyTexSubImage1D) LOAD_FUNCPTR(glCopyTexSubImage2D) LOAD_FUNCPTR(glDrawBuffer) +LOAD_FUNCPTR(glEnable) +LOAD_FUNCPTR(glEndList) LOAD_FUNCPTR(glGetError) LOAD_FUNCPTR(glGetIntegerv) LOAD_FUNCPTR(glGetString) LOAD_FUNCPTR(glNewList) LOAD_FUNCPTR(glPixelStorei) +LOAD_FUNCPTR(glScissor) +LOAD_FUNCPTR(glViewport) #undef LOAD_FUNCPTR
if(!X11DRV_WineGL_InitOpenglInfo()) {
@@ -1353,6 +1362,54 @@ PROC X11DRV_wglGetProcAddress(LPCSTR lps return NULL; }
+/***********************************************************************
X11DRV_SyncCurrentDrawable
- Adjust the current viewport and stencil in order to position
- and size the current drawable correctly on the parent window.
- */
+void X11DRV_SyncCurrentDrawable() +{
- RECT rc;
- RECT rootrc;
- HWND hwnd;
- HWND roothwnd;
- int width, height;
- int rheight;
- Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
- if (ctx && (hwnd = WindowFromDC(ctx->hdc)) != 0)
- {
roothwnd = GetAncestor(hwnd, GA_ROOT);
if (roothwnd != hwnd)
{
GetClientRect(roothwnd, &rootrc);
rheight = rootrc.bottom - rootrc.top;
GetWindowRect(hwnd, &rc);
width = rc.right - rc.left;
height = rc.bottom - rc.top;
MapWindowPoints(0, roothwnd, (LPPOINT)&rc, 2);
pglViewport(rc.left + ctx->viewport.left, rheight - rc.bottom + ctx->viewport.top,
ctx->viewport.right ? (ctx->viewport.right - ctx->viewport.left) : width,
ctx->viewport.bottom ? (ctx->viewport.bottom - ctx->viewport.top) : height);
pglEnable(GL_SCISSOR_TEST);
if (ctx->scissor_enabled)
pglScissor(rc.left + min(width, max(0, ctx->scissor.left)),
rheight - rc.bottom + min(height, max(0, ctx->scissor.top)),
min(width, max(0, ctx->scissor.right - ctx->scissor.left)),
min(height, max(0, ctx->scissor.bottom - ctx->scissor.top)));
else
pglScissor(rc.left, rheight - rc.bottom, width, height);
}
- }
+}
/* OpenGL32 wglMakeCurrent */ BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) { @@ -1397,10 +1454,17 @@ BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVIC TRACE(" make current for dis %p, drawable %p, ctx %p\n", ctx->display, (void*) drawable, ctx->ctx); ret = pglXMakeCurrent(ctx->display, drawable, ctx->ctx); NtCurrentTeb()->glContext = ctx;
if(ret && type == OBJ_MEMDC)
if(ret) {
ctx->do_escape = TRUE;
pglDrawBuffer(GL_FRONT_LEFT);
if (type == OBJ_MEMDC)
{
ctx->do_escape = TRUE;
pglDrawBuffer(GL_FRONT_LEFT);
}
else
{
X11DRV_SyncCurrentDrawable();
} wine_tsx11_unlock();} }
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec index 4e4dcbf..62e3197 100644 --- a/dlls/winex11.drv/winex11.drv.spec +++ b/dlls/winex11.drv/winex11.drv.spec @@ -139,3 +139,4 @@ @ cdecl wglShareLists(long long) X11DRV_wglShareLists @ cdecl wglUseFontBitmapsA(long long long long) X11DRV_wglUseFontBitmapsA @ cdecl wglUseFontBitmapsW(long long long long) X11DRV_wglUseFontBitmapsW +@ cdecl SyncCurrentDrawable() X11DRV_SyncCurrentDrawable
Unfortunately, this doesn't seem to fix Valve Hammer Editor. On top of that, hammer never spit out any errors to the console before, now the console is filled with:
err:syslevel:_EnterSysLevel (0x7ed4a220, level 2): Holding 0x7ec3d9e0, level 3. Expect deadlock!