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

This commit is contained in:
Alexandre Julliard 2012-09-04 15:03:04 +02:00
parent ea07c310ec
commit 514eb69584
3 changed files with 46 additions and 84 deletions

View File

@ -200,6 +200,7 @@ struct gl_drawable
Colormap colormap; /* colormap used for the drawable */
int pixel_format; /* pixel format for the drawable */
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 */
@ -1170,14 +1171,11 @@ static void free_gl_drawable( struct gl_drawable *gl )
BOOL set_win_format( HWND hwnd, XID fbconfig_id )
{
XSetWindowAttributes attrib;
struct x11drv_win_data *data;
struct gl_drawable *gl, *prev;
int format, w, h;
int format;
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->pixel_format = format;
gl->visual = pglXGetVisualFromFBConfig( gdi_display, pixel_formats[format - 1].fbconfig );
@ -1187,11 +1185,14 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
return FALSE;
}
w = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
h = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
GetClientRect( hwnd, &gl->rect );
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->colormap = XCreateColormap( gdi_display, root_window, gl->visual->visual,
(gl->visual->class == PseudoColor ||
@ -1201,13 +1202,14 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
attrib.bit_gravity = NorthWestGravity;
attrib.win_gravity = NorthWestGravity;
attrib.backing_store = NotUseful;
gl->drawable = XCreateWindow( gdi_display, data->whole_window,
data->client_rect.left - data->whole_rect.left,
data->client_rect.top - data->whole_rect.top,
w, h, 0, screen_depth, InputOutput, gl->visual->visual,
CWBitGravity | CWWinGravity | CWBackingStore | CWColormap,
&attrib );
/* put the initial rect outside of the window, it will be moved into place by SetWindowPos */
OffsetRect( &gl->rect, gl->rect.right, gl->rect.bottom );
if (parent)
gl->drawable = XCreateWindow( gdi_display, parent, gl->rect.left, gl->rect.top,
gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top,
0, screen_depth, InputOutput, gl->visual->visual,
CWBitGravity | CWWinGravity | CWBackingStore | CWColormap,
&attrib );
if (gl->drawable)
XMapWindow( gdi_display, gl->drawable );
else
@ -1234,8 +1236,9 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
XInstallColormap(gdi_display, attrib.colormap);
gl->type = DC_GL_CHILD_WIN;
gl->drawable = XCreateWindow( gdi_display, dummy_parent, 0, 0, w, h, 0,
gl->visual->depth, InputOutput, gl->visual->visual,
gl->drawable = XCreateWindow( gdi_display, dummy_parent, 0, 0,
gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top,
0, gl->visual->depth, InputOutput, gl->visual->visual,
CWColormap | CWOverrideRedirect, &attrib );
if (gl->drawable)
{
@ -1250,7 +1253,9 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
WARN("XComposite is not available, using GLXPixmap hack\n");
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)
{
gl->drawable = pglXCreateGLXPixmap( gdi_display, gl->visual, gl->pixmap );
@ -1285,29 +1290,41 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
/***********************************************************************
* 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;
Drawable glxp;
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 );
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",
gl->drawable, changes->x, changes->y, changes->width, changes->height, mask );
if (changes.width != gl->rect.right - gl->rect.left) mask |= CWWidth;
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)
{
case DC_GL_CHILD_WIN:
if (!(mask &= CWWidth | CWHeight)) break;
/* fall through */
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;
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;
glxp = pglXCreateGLXPixmap(gdi_display, gl->visual, pix);
if (!glxp)
@ -1328,6 +1345,7 @@ void sync_gl_drawable( HWND hwnd, int mask, XWindowChanges *changes )
default:
break;
}
SetRect( &gl->rect, changes.x, changes.y, changes.x + changes.width, changes.y + changes.height );
done:
LeaveCriticalSection( &context_section );
}
@ -3394,7 +3412,7 @@ BOOL set_win_format( HWND hwnd, XID fbconfig_id )
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 )
{
}

View File

@ -448,41 +448,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
*/
@ -1314,27 +1279,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
*
@ -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 */
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;

View File

@ -555,7 +555,7 @@ extern Window X11DRV_get_whole_window( 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 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 wait_for_withdrawn_state( Display *display, struct x11drv_win_data *data, BOOL set ) DECLSPEC_HIDDEN;