winex11.drv: Correctly position and clip opengl child windows.
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 657617a..1f4de68 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl
@@ -266,6 +266,21 @@ 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 "glIsEnabled" ) { + $wine_func_ref_name = "internal_glIsEnabled"; + } + if ( $func_ref->[0] eq "glDisable" ) { + $wine_func_ref_name = "internal_glDisable"; + } + if ( $func_ref->[0] eq "glScissor" ) { + $wine_func_ref_name = "internal_glScissor"; + } + 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 580df22..d700187 100644 --- a/dlls/opengl32/opengl_ext.h +++ b/dlls/opengl32/opengl_ext.h
@@ -64,5 +64,10 @@ 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_glDisable( GLenum cap ) { TRACE("(%d)\n", cap ); ENTER_GL(); - glDisable( cap ); + internal_glDisable( cap ); LEAVE_GL(); } @@ -915,7 +915,7 @@ void WINAPI wine_glEnable( GLenum cap ) { TRACE("(%d)\n", cap ); ENTER_GL(); - glEnable( cap ); + internal_glEnable( cap ); LEAVE_GL(); } @@ -1772,7 +1772,7 @@ 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_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_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 1191850..51cc71c 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c
@@ -49,7 +49,12 @@ typedef struct wine_wgl_s { PROC WINAPI (*p_wglGetProcAddress)(LPCSTR lpszProc); + void WINAPI (*p_wglDisable)(GLenum cap); + void WINAPI (*p_wglEnable)(GLenum cap); void WINAPI (*p_wglGetIntegerv)(GLenum pname, GLint* params); + GLboolean WINAPI (*p_wglIsEnabled)(GLenum cap); + void WINAPI (*p_wglScissor)(GLint x, GLint y, GLsizei width, GLsizei height); + void WINAPI (*p_wglViewport)(GLint x, GLint y, GLsizei width, GLsizei height); } wine_wgl_t; /** global wgl object */ @@ -86,8 +91,7 @@ GLXFBConfig fb_conf; GLXContext ctx; BOOL do_escape; - struct wine_glcontext *next; - struct wine_glcontext *prev; + /* ... more stuff here */ } Wine_GLContext; void enter_gl(void) @@ -557,9 +561,34 @@ return wglUseFontOutlines_common(hdc, first, count, listBase, deviation, extrusion, format, lpgmf, TRUE); } +void internal_glEnable(GLenum cap) +{ + wine_wgl.p_wglEnable(cap); +} + +GLboolean internal_glIsEnabled(GLenum cap) +{ + return wine_wgl.p_wglIsEnabled(cap); +} + +void internal_glDisable(GLenum cap) +{ + wine_wgl.p_wglDisable(cap); +} + +void internal_glScissor( GLint x, GLint y, GLsizei width, GLsizei height ) +{ + wine_wgl.p_wglScissor(x, y, width, height); +} + +void internal_glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) +{ + wine_wgl.p_wglViewport(x, y, width, height); +} + const GLubyte * internal_glGetString(GLenum name) { const char* GL_Extensions = NULL; - + if (GL_EXTENSIONS != name) { return glGetString(name); } @@ -641,7 +670,12 @@ wine_wgl.p_wglGetProcAddress = (void *)GetProcAddress(mod_gdi32, "wglGetProcAddress"); /* Interal WGL function */ + wine_wgl.p_wglDisable = (void *)wine_wgl.p_wglGetProcAddress("wglDisable"); + wine_wgl.p_wglEnable = (void *)wine_wgl.p_wglGetProcAddress("wglEnable"); wine_wgl.p_wglGetIntegerv = (void *)wine_wgl.p_wglGetProcAddress("wglGetIntegerv"); + wine_wgl.p_wglIsEnabled = (void *)wine_wgl.p_wglGetProcAddress("wglIsEnabled"); + wine_wgl.p_wglScissor = (void *)wine_wgl.p_wglGetProcAddress("wglScissor"); + wine_wgl.p_wglViewport = (void *)wine_wgl.p_wglGetProcAddress("wglViewport"); internal_gl_disabled_extensions[0] = 0; if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\OpenGL", &hkey)) {
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 3b67c79..927abfc 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c
@@ -74,6 +74,10 @@ GLXFBConfig fb_conf; GLXContext ctx; BOOL do_escape; + X11DRV_PDEVICE *physDev; + RECT viewport; + RECT scissor; + BOOL scissor_enabled; struct wine_glcontext *next; struct wine_glcontext *prev; } Wine_GLContext; @@ -253,13 +257,18 @@ MAKE_FUNCPTR(glBitmap) MAKE_FUNCPTR(glCopyTexSubImage1D) MAKE_FUNCPTR(glCopyTexSubImage2D) +MAKE_FUNCPTR(glDisable) MAKE_FUNCPTR(glDrawBuffer) +MAKE_FUNCPTR(glEnable) MAKE_FUNCPTR(glEndList) MAKE_FUNCPTR(glGetError) MAKE_FUNCPTR(glGetIntegerv) MAKE_FUNCPTR(glGetString) +MAKE_FUNCPTR(glIsEnabled) MAKE_FUNCPTR(glNewList) MAKE_FUNCPTR(glPixelStorei) +MAKE_FUNCPTR(glScissor) +MAKE_FUNCPTR(glViewport) #undef MAKE_FUNCPTR static BOOL X11DRV_WineGL_InitOpenglInfo(void) @@ -377,15 +386,20 @@ /* Standard OpenGL calls */ LOAD_FUNCPTR(glBindTexture) LOAD_FUNCPTR(glBitmap) -LOAD_FUNCPTR(glEndList) LOAD_FUNCPTR(glCopyTexSubImage1D) LOAD_FUNCPTR(glCopyTexSubImage2D) +LOAD_FUNCPTR(glDisable) LOAD_FUNCPTR(glDrawBuffer) +LOAD_FUNCPTR(glEnable) +LOAD_FUNCPTR(glEndList) LOAD_FUNCPTR(glGetError) LOAD_FUNCPTR(glGetIntegerv) LOAD_FUNCPTR(glGetString) +LOAD_FUNCPTR(glIsEnabled) LOAD_FUNCPTR(glNewList) LOAD_FUNCPTR(glPixelStorei) +LOAD_FUNCPTR(glScissor) +LOAD_FUNCPTR(glViewport) #undef LOAD_FUNCPTR /* It doesn't matter if these fail. They'll only be used if the driver reports @@ -539,7 +553,7 @@ { Wine_GLContext *ret; for (ret = context_list; ret; ret = ret->next) { - if (d == get_drawable( ret->hdc )) { + if (d == ret->physDev->drawable) { return ret->hdc; } } @@ -1318,6 +1332,7 @@ ret = alloc_context(); wine_tsx11_unlock(); ret->hdc = hdc; + ret->physDev = physDev; ret->display = gdi_display; ret->fb_conf = cur_cfg; /*ret->vis = vis;*/ @@ -1424,6 +1439,47 @@ return NULL; } +/*********************************************************************** + * sync_current_drawable + * + * Adjust the current viewport and scissor in order to position + * and size the current drawable correctly on the parent window. + */ +static void sync_current_drawable(void) +{ + int dy; + int width; + int height; + RECT rc; + Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; + + TRACE("\n"); + + if (ctx && ctx->physDev) + { + GetClipBox(ctx->physDev->hdc, &rc); /* Make sure physDev is up to date */ + + dy = ctx->physDev->drawable_rect.bottom - ctx->physDev->dc_rect.bottom; + width = ctx->physDev->dc_rect.right - ctx->physDev->dc_rect.left; + height = ctx->physDev->dc_rect.bottom - ctx->physDev->dc_rect.top; + + pglViewport(ctx->physDev->dc_rect.left + ctx->viewport.left, + dy + 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(ctx->physDev->dc_rect.left + min(width, max(0, ctx->scissor.left)), + dy + 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(ctx->physDev->dc_rect.left, dy, width, height); + + } +} /** * X11DRV_wglMakeCurrent @@ -1466,10 +1522,19 @@ 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); + ctx->physDev = physDev; + + if (type == OBJ_MEMDC) + { + ctx->do_escape = TRUE; + pglDrawBuffer(GL_FRONT_LEFT); + } + else + { + sync_current_drawable(); + } } } wine_tsx11_unlock(); @@ -1541,7 +1606,7 @@ if (org->ctx == NULL) { wine_tsx11_lock(); describeContext(org); - org->ctx = pglXCreateContext(org->display, org->vis, NULL, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True); + org->ctx = pglXCreateContext(org->display, org->vis, NULL, GetObjectType(org->physDev->hdc) == OBJ_MEMDC ? False : True); wine_tsx11_unlock(); TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org); } @@ -1549,7 +1614,7 @@ wine_tsx11_lock(); describeContext(dest); /* Create the destination context with display lists shared */ - dest->ctx = pglXCreateContext(org->display, dest->vis, org->ctx, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True); + dest->ctx = pglXCreateContext(org->display, dest->vis, org->ctx, GetObjectType(org->physDev->hdc) == OBJ_MEMDC ? False : True); wine_tsx11_unlock(); TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx); return TRUE; @@ -1722,7 +1787,33 @@ return TRUE; } -/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */ +static void WINAPI X11DRV_wglDisable(GLenum cap) +{ + if (cap == GL_SCISSOR_TEST) + { + Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; + ctx->scissor_enabled = FALSE; + } + else + { + pglDisable(cap); + } +} + +static void WINAPI X11DRV_wglEnable(GLenum cap) +{ + if (cap == GL_SCISSOR_TEST) + { + Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; + ctx->scissor_enabled = TRUE; + } + else + { + pglEnable(cap); + } +} + +/* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */ static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params) { TRACE("pname: 0x%x, params: %p\n", pname, params); if (pname == GL_DEPTH_BITS) { @@ -1749,6 +1840,47 @@ } } +static GLboolean WINAPI X11DRV_wglIsEnabled(GLenum cap) +{ + GLboolean enabled; + + if (cap == GL_SCISSOR_TEST) + { + Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext; + enabled = ctx->scissor_enabled; + } + else + { + enabled = pglIsEnabled(cap); + } + + return enabled; +} + +static void WINAPI X11DRV_wglScissor(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; + + sync_current_drawable(); +} + +static void WINAPI X11DRV_wglViewport(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; + + sync_current_drawable(); +} + /** * X11DRV_wglGetExtensionsStringARB * @@ -2673,7 +2805,12 @@ { "", { + { "wglDisable", X11DRV_wglDisable }, + { "wglEnable", X11DRV_wglEnable }, { "wglGetIntegerv", X11DRV_wglGetIntegerv }, + { "wglIsEnabled", X11DRV_wglIsEnabled }, + { "wglScissor", X11DRV_wglScissor }, + { "wglViewport", X11DRV_wglViewport }, } };