Commit 715d0e84 authored by Ulrich Czekalla's avatar Ulrich Czekalla Committed by Alexandre Julliard

winex11.drv: Correctly position and clip opengl child windows.

parent 0ab55904
......@@ -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 "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";
......
......@@ -64,5 +64,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 */
......@@ -815,7 +815,7 @@ void WINAPI wine_glDepthRange( GLclampd nearParam, GLclampd farParam ) {
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* flag ) {
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( GLenum cap ) {
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, GLfloat y, GLfloat z ) {
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 size, GLenum type, GLsizei stride, GLvoi
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();
}
......@@ -49,7 +49,12 @@ WINE_DECLARE_DEBUG_CHANNEL(opengl);
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 @@ typedef struct wine_glcontext {
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 @@ BOOL WINAPI wglUseFontOutlinesW(HDC hdc,
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 @@ static BOOL process_attach(void)
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)) {
......
......@@ -74,6 +74,10 @@ typedef struct wine_glcontext {
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(glBindTexture)
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 @@ LOAD_FUNCPTR(glXGetFBConfigs)
/* 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 @@ 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 )) {
if (d == ret->physDev->drawable) {
return ret->hdc;
}
}
......@@ -1318,6 +1332,7 @@ HGLRC X11DRV_wglCreateContext(X11DRV_PDEVICE *physDev)
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 @@ PROC X11DRV_wglGetProcAddress(LPCSTR lpszProc)
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 @@ BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) {
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 @@ BOOL X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
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 @@ BOOL X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
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 @@ BOOL X11DRV_wglUseFontBitmapsW(X11DRV_PDEVICE *physDev, DWORD first, DWORD count
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 void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params) {
}
}
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 @@ static const WineGLExtension WGL_internal_functions =
{
"",
{
{ "wglDisable", X11DRV_wglDisable },
{ "wglEnable", X11DRV_wglEnable },
{ "wglGetIntegerv", X11DRV_wglGetIntegerv },
{ "wglIsEnabled", X11DRV_wglIsEnabled },
{ "wglScissor", X11DRV_wglScissor },
{ "wglViewport", X11DRV_wglViewport },
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment