Commit 514eb695 authored by Alexandre Julliard's avatar Alexandre Julliard

winex11: Store the rectangle of the GL drawable and use it when updating the window size.

parent ea07c310
...@@ -200,6 +200,7 @@ struct gl_drawable ...@@ -200,6 +200,7 @@ struct gl_drawable
Colormap colormap; /* colormap used for the drawable */ Colormap colormap; /* colormap used for the drawable */
int pixel_format; /* pixel format for the drawable */ int pixel_format; /* pixel format for the drawable */
XVisualInfo *visual; /* information about the GL visual */ XVisualInfo *visual; /* information about the GL visual */
RECT rect; /* drawable rect, relative to whole window drawable */
}; };
/* X context to associate a struct gl_drawable to an hwnd */ /* X context to associate a struct gl_drawable to an hwnd */
...@@ -1170,14 +1171,11 @@ static void free_gl_drawable( struct gl_drawable *gl ) ...@@ -1170,14 +1171,11 @@ static void free_gl_drawable( struct gl_drawable *gl )
BOOL set_win_format( HWND hwnd, XID fbconfig_id ) BOOL set_win_format( HWND hwnd, XID fbconfig_id )
{ {
XSetWindowAttributes attrib; XSetWindowAttributes attrib;
struct x11drv_win_data *data;
struct gl_drawable *gl, *prev; struct gl_drawable *gl, *prev;
int format, w, h; int format;
if (!(format = pixelformat_from_fbconfig_id( fbconfig_id ))) return FALSE; if (!(format = pixelformat_from_fbconfig_id( fbconfig_id ))) return FALSE;
if (!(data = X11DRV_get_win_data(hwnd))) return FALSE;
gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) ); gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) );
gl->pixel_format = format; gl->pixel_format = format;
gl->visual = pglXGetVisualFromFBConfig( gdi_display, pixel_formats[format - 1].fbconfig ); gl->visual = pglXGetVisualFromFBConfig( gdi_display, pixel_formats[format - 1].fbconfig );
...@@ -1187,11 +1185,14 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -1187,11 +1185,14 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
return FALSE; return FALSE;
} }
w = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 ); GetClientRect( hwnd, &gl->rect );
h = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 ); gl->rect.right = min( max( 1, gl->rect.right ), 65535 );
gl->rect.bottom = min( max( 1, gl->rect.bottom ), 65535 );
if (data->whole_window) if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */
{ {
Window parent = X11DRV_get_whole_window( hwnd );
gl->type = DC_GL_WINDOW; gl->type = DC_GL_WINDOW;
gl->colormap = XCreateColormap( gdi_display, root_window, gl->visual->visual, gl->colormap = XCreateColormap( gdi_display, root_window, gl->visual->visual,
(gl->visual->class == PseudoColor || (gl->visual->class == PseudoColor ||
...@@ -1201,13 +1202,14 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -1201,13 +1202,14 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
attrib.bit_gravity = NorthWestGravity; attrib.bit_gravity = NorthWestGravity;
attrib.win_gravity = NorthWestGravity; attrib.win_gravity = NorthWestGravity;
attrib.backing_store = NotUseful; attrib.backing_store = NotUseful;
/* put the initial rect outside of the window, it will be moved into place by SetWindowPos */
gl->drawable = XCreateWindow( gdi_display, data->whole_window, OffsetRect( &gl->rect, gl->rect.right, gl->rect.bottom );
data->client_rect.left - data->whole_rect.left, if (parent)
data->client_rect.top - data->whole_rect.top, gl->drawable = XCreateWindow( gdi_display, parent, gl->rect.left, gl->rect.top,
w, h, 0, screen_depth, InputOutput, gl->visual->visual, gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top,
CWBitGravity | CWWinGravity | CWBackingStore | CWColormap, 0, screen_depth, InputOutput, gl->visual->visual,
&attrib ); CWBitGravity | CWWinGravity | CWBackingStore | CWColormap,
&attrib );
if (gl->drawable) if (gl->drawable)
XMapWindow( gdi_display, gl->drawable ); XMapWindow( gdi_display, gl->drawable );
else else
...@@ -1234,8 +1236,9 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -1234,8 +1236,9 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
XInstallColormap(gdi_display, attrib.colormap); XInstallColormap(gdi_display, attrib.colormap);
gl->type = DC_GL_CHILD_WIN; gl->type = DC_GL_CHILD_WIN;
gl->drawable = XCreateWindow( gdi_display, dummy_parent, 0, 0, w, h, 0, gl->drawable = XCreateWindow( gdi_display, dummy_parent, 0, 0,
gl->visual->depth, InputOutput, gl->visual->visual, gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top,
0, gl->visual->depth, InputOutput, gl->visual->visual,
CWColormap | CWOverrideRedirect, &attrib ); CWColormap | CWOverrideRedirect, &attrib );
if (gl->drawable) if (gl->drawable)
{ {
...@@ -1250,7 +1253,9 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -1250,7 +1253,9 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
WARN("XComposite is not available, using GLXPixmap hack\n"); WARN("XComposite is not available, using GLXPixmap hack\n");
gl->type = DC_GL_PIXMAP_WIN; gl->type = DC_GL_PIXMAP_WIN;
gl->pixmap = XCreatePixmap(gdi_display, root_window, w, h, gl->visual->depth); gl->pixmap = XCreatePixmap( gdi_display, root_window,
gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top,
gl->visual->depth );
if (gl->pixmap) if (gl->pixmap)
{ {
gl->drawable = pglXCreateGLXPixmap( gdi_display, gl->visual, gl->pixmap ); gl->drawable = pglXCreateGLXPixmap( gdi_display, gl->visual, gl->pixmap );
...@@ -1285,29 +1290,41 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -1285,29 +1290,41 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
/*********************************************************************** /***********************************************************************
* sync_gl_drawable * sync_gl_drawable
*/ */
void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes ) void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_rect )
{ {
struct gl_drawable *gl; struct gl_drawable *gl;
Drawable glxp; Drawable glxp;
Pixmap pix; Pixmap pix;
int mask = 0;
XWindowChanges changes;
changes.x = client_rect->left - visible_rect->left;
changes.y = client_rect->top - visible_rect->top;
changes.width = min( max( 1, client_rect->right - client_rect->left ), 65535 );
changes.height = min( max( 1, client_rect->bottom - client_rect->top ), 65535 );
EnterCriticalSection( &context_section ); EnterCriticalSection( &context_section );
if (XFindContext( gdi_display, (XID)hwnd, gl_drawable_context, (char **)&gl )) goto done; if (XFindContext( gdi_display, (XID)hwnd, gl_drawable_context, (char **)&gl )) goto done;
TRACE( "setting drawable %lx pos %d,%d,%dx%d changes=%x\n", if (changes.width != gl->rect.right - gl->rect.left) mask |= CWWidth;
gl->drawable, changes->x, changes->y, changes->width, changes->height, mask ); if (changes.height != gl->rect.bottom - gl->rect.top) mask |= CWHeight;
TRACE( "setting drawable %lx pos %d,%d,%dx%d\n",
gl->drawable, changes.x, changes.y, changes.width, changes.height );
switch (gl->type) switch (gl->type)
{ {
case DC_GL_CHILD_WIN:
if (!(mask &= CWWidth | CWHeight)) break;
/* fall through */
case DC_GL_WINDOW: case DC_GL_WINDOW:
XConfigureWindow( gdi_display, gl->drawable, mask, changes ); if (changes.x != gl->rect.left) mask |= CWX;
if (changes.y != gl->rect.top) mask |= CWY;
/* fallthrough */
case DC_GL_CHILD_WIN:
if (mask) XConfigureWindow( gdi_display, gl->drawable, mask, &changes );
break; break;
case DC_GL_PIXMAP_WIN: case DC_GL_PIXMAP_WIN:
pix = XCreatePixmap(gdi_display, root_window, changes->width, changes->height, gl->visual->depth); if (!mask) break;
pix = XCreatePixmap(gdi_display, root_window, changes.width, changes.height, gl->visual->depth);
if (!pix) goto done; if (!pix) goto done;
glxp = pglXCreateGLXPixmap(gdi_display, gl->visual, pix); glxp = pglXCreateGLXPixmap(gdi_display, gl->visual, pix);
if (!glxp) if (!glxp)
...@@ -1328,6 +1345,7 @@ void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes ) ...@@ -1328,6 +1345,7 @@ void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes )
default: default:
break; break;
} }
SetRect( &gl->rect, changes.x, changes.y, changes.x + changes.width, changes.y + changes.height );
done: done:
LeaveCriticalSection( &context_section ); LeaveCriticalSection( &context_section );
} }
...@@ -3394,7 +3412,7 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id ) ...@@ -3394,7 +3412,7 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
return FALSE; return FALSE;
} }
void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes ) void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_rect )
{ {
} }
......
...@@ -449,41 +449,6 @@ static void sync_window_text( Display *display, Window win, const WCHAR *text ) ...@@ -449,41 +449,6 @@ static void sync_window_text( Display *display, Window win, const WCHAR *text )
/*********************************************************************** /***********************************************************************
* get_window_changes
*
* fill the window changes structure
*/
static int get_window_changes( XWindowChanges *changes, const RECT *old, const RECT *new )
{
int mask = 0;
if (old->right - old->left != new->right - new->left )
{
if ((changes->width = new->right - new->left) <= 0) changes->width = 1;
else if (changes->width > 65535) changes->width = 65535;
mask |= CWWidth;
}
if (old->bottom - old->top != new->bottom - new->top)
{
if ((changes->height = new->bottom - new->top) <= 0) changes->height = 1;
else if (changes->height > 65535) changes->height = 65535;
mask |= CWHeight;
}
if (old->left != new->left)
{
changes->x = new->left;
mask |= CWX;
}
if (old->top != new->top)
{
changes->y = new->top;
mask |= CWY;
}
return mask;
}
/***********************************************************************
* create_icon_window * create_icon_window
*/ */
static Window create_icon_window( Display *display, struct x11drv_win_data *data ) static Window create_icon_window( Display *display, struct x11drv_win_data *data )
...@@ -1315,27 +1280,6 @@ static void sync_window_position( Display *display, struct x11drv_win_data *data ...@@ -1315,27 +1280,6 @@ static void sync_window_position( Display *display, struct x11drv_win_data *data
/*********************************************************************** /***********************************************************************
* sync_client_position
*
* Synchronize the X client window position with the Windows one
*/
static void sync_client_position( Display *display, struct x11drv_win_data *data,
UINT swp_flags, const RECT *old_client_rect,
const RECT *old_whole_rect )
{
int mask;
XWindowChanges changes;
RECT old = *old_client_rect;
RECT new = data->client_rect;
OffsetRect( &old, -old_whole_rect->left, -old_whole_rect->top );
OffsetRect( &new, -data->whole_rect.left, -data->whole_rect.top );
if (!(mask = get_window_changes( &changes, &old, &new ))) return;
sync_gl_drawable( data->hwnd, mask, &changes );
}
/***********************************************************************
* move_window_bits * move_window_bits
* *
* Move the window bits when a window is moved. * Move the window bits when a window is moved.
...@@ -2140,7 +2084,7 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags ...@@ -2140,7 +2084,7 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
XFlush( gdi_display ); /* make sure painting is done before we move the window */ XFlush( gdi_display ); /* make sure painting is done before we move the window */
sync_client_position( display, data, swp_flags, &old_client_rect, &old_whole_rect ); sync_gl_drawable( data->hwnd, visible_rect, rectClient );
if (!data->whole_window) return; if (!data->whole_window) return;
......
...@@ -555,7 +555,7 @@ extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN; ...@@ -555,7 +555,7 @@ extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN; extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN;
extern BOOL set_win_format( HWND hwnd, XID fbconfig_id ) DECLSPEC_HIDDEN; extern BOOL set_win_format( HWND hwnd, XID fbconfig_id ) DECLSPEC_HIDDEN;
extern void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes ) DECLSPEC_HIDDEN; extern void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_rect ) DECLSPEC_HIDDEN;
extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN; extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
extern void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set ) DECLSPEC_HIDDEN; extern void wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set ) DECLSPEC_HIDDEN;
......
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