Commit 1ce36987 authored by Alexandre Julliard's avatar Alexandre Julliard

winex11: Use the client window support also for XComposite child windows.

parent ac4f2ac3
......@@ -259,7 +259,6 @@ struct gl_drawable
GLXDrawable drawable; /* drawable for rendering with GL */
Window window; /* window if drawable is a GLXWindow */
Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */
Colormap colormap; /* colormap used for the drawable */
const struct wgl_pixel_format *format; /* pixel format for the drawable */
SIZE pixmap_size; /* pixmap size for GLXPixmap drawables */
int swap_interval;
......@@ -1234,7 +1233,6 @@ static void release_gl_drawable( struct gl_drawable *gl )
TRACE( "destroying %lx drawable %lx\n", gl->window, gl->drawable );
pglXDestroyWindow( gdi_display, gl->drawable );
XDestroyWindow( gdi_display, gl->window );
if (gl->colormap) XFreeColormap( gdi_display, gl->colormap );
break;
case DC_GL_PIXMAP_WIN:
TRACE( "destroying pixmap %lx drawable %lx\n", gl->pixmap, gl->drawable );
......@@ -1398,56 +1396,22 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */
{
struct x11drv_win_data *data = get_win_data( hwnd );
if (data)
{
gl->type = DC_GL_WINDOW;
gl->window = create_client_window( data, visual );
gl->window = create_client_window( hwnd, visual );
if (gl->window)
gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL );
release_win_data( data );
TRACE( "%p created client %lx drawable %lx\n", hwnd, gl->window, gl->drawable );
}
}
#ifdef SONAME_LIBXCOMPOSITE
else if(usexcomposite)
{
static Window dummy_parent;
XSetWindowAttributes attrib;
attrib.override_redirect = True;
attrib.border_pixel = 0;
if (!dummy_parent)
{
attrib.colormap = default_colormap;
dummy_parent = XCreateWindow( gdi_display, root_window, -1, -1, 1, 1, 0, default_visual.depth,
InputOutput, default_visual.visual,
CWColormap | CWBorderPixel | CWOverrideRedirect, &attrib );
XMapWindow( gdi_display, dummy_parent );
}
gl->colormap = XCreateColormap(gdi_display, dummy_parent, visual->visual,
(visual->class == PseudoColor ||
visual->class == GrayScale ||
visual->class == DirectColor) ?
AllocAll : AllocNone);
attrib.colormap = gl->colormap;
XInstallColormap(gdi_display, attrib.colormap);
gl->type = DC_GL_CHILD_WIN;
gl->window = XCreateWindow( gdi_display, dummy_parent, 0, 0, width, height,
0, visual->depth, InputOutput, visual->visual,
CWColormap | CWBorderPixel | CWOverrideRedirect, &attrib );
gl->window = create_client_window( hwnd, visual );
if (gl->window)
{
gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL );
if (gl->drawable)
{
pXCompositeRedirectWindow(gdi_display, gl->window, CompositeRedirectManual);
XMapWindow(gdi_display, gl->window);
}
pXCompositeRedirectWindow( gdi_display, gl->window, CompositeRedirectManual );
}
else XFreeColormap( gdi_display, gl->colormap );
TRACE( "%p created child %lx drawable %lx\n", hwnd, gl->window, gl->drawable );
}
#endif
......@@ -1552,22 +1516,14 @@ static BOOL set_pixel_format(HDC hdc, int format, BOOL allow_change)
/***********************************************************************
* sync_gl_drawable
*/
void sync_gl_drawable( HWND hwnd, int width, int height )
void sync_gl_drawable( HWND hwnd )
{
struct gl_drawable *old, *new;
XWindowChanges changes;
if (!(old = get_gl_drawable( hwnd, 0 ))) return;
TRACE( "setting drawable %lx size %dx%d\n", old->drawable, width, height );
switch (old->type)
{
case DC_GL_CHILD_WIN:
changes.width = min( max( 1, width ), 65535 );
changes.height = min( max( 1, height ), 65535 );
XConfigureWindow( gdi_display, old->window, CWWidth | CWHeight, &changes );
break;
case DC_GL_PIXMAP_WIN:
if (!(new = create_gl_drawable( hwnd, old->format ))) break;
mark_drawable_dirty( old, new );
......@@ -3452,7 +3408,7 @@ struct opengl_funcs *get_glx_driver( UINT version )
return NULL;
}
void sync_gl_drawable( HWND hwnd, int width, int height )
void sync_gl_drawable( HWND hwnd )
{
}
......
......@@ -196,6 +196,26 @@ static BOOL has_owned_popups( HWND hwnd )
return result.found;
}
/***********************************************************************
* alloc_win_data
*/
static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd )
{
struct x11drv_win_data *data;
if ((data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data))))
{
data->display = display;
data->vis = default_visual;
data->hwnd = hwnd;
EnterCriticalSection( &win_data_section );
XSaveContext( gdi_display, (XID)hwnd, win_data_context, (char *)data );
}
return data;
}
/***********************************************************************
* is_window_managed
*
......@@ -1418,14 +1438,23 @@ static Window get_dummy_parent(void)
/**********************************************************************
* create_client_window
*/
Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *visual )
Window create_client_window( HWND hwnd, const XVisualInfo *visual )
{
Window dummy_parent = get_dummy_parent();
struct x11drv_win_data *data = get_win_data( hwnd );
XSetWindowAttributes attr;
int x = data->client_rect.left - data->whole_rect.left;
int y = data->client_rect.top - data->whole_rect.top;
int cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
int cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
Window ret;
int x, y, cx, cy;
if (!data)
{
/* explicitly create data for HWND_MESSAGE windows since they can be used for OpenGL */
HWND parent = GetAncestor( hwnd, GA_PARENT );
if (parent == GetDesktopWindow() || GetAncestor( parent, GA_PARENT )) return 0;
if (!(data = alloc_win_data( thread_init_display(), hwnd ))) return 0;
GetClientRect( hwnd, &data->client_rect );
data->window_rect = data->whole_rect = data->client_rect;
}
if (data->client_window)
{
......@@ -1445,18 +1474,26 @@ Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *vi
attr.backing_store = NotUseful;
attr.border_pixel = 0;
data->client_window = XCreateWindow( gdi_display, data->whole_window, x, y, cx, cy,
0, default_visual.depth, InputOutput, visual->visual,
CWBitGravity | CWWinGravity | CWBackingStore |
CWColormap | CWBorderPixel, &attr );
if (!data->client_window) return 0;
TRACE( "%p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window );
x = data->client_rect.left - data->whole_rect.left;
y = data->client_rect.top - data->whole_rect.top;
cx = min( max( 1, data->client_rect.right - data->client_rect.left ), 65535 );
cy = min( max( 1, data->client_rect.bottom - data->client_rect.top ), 65535 );
ret = data->client_window = XCreateWindow( gdi_display,
data->whole_window ? data->whole_window : dummy_parent,
x, y, cx, cy, 0, default_visual.depth, InputOutput,
visual->visual, CWBitGravity | CWWinGravity |
CWBackingStore | CWColormap | CWBorderPixel, &attr );
if (data->client_window)
{
XSaveContext( data->display, data->client_window, winContext, (char *)data->hwnd );
XMapWindow( gdi_display, data->client_window );
XSync( gdi_display, False );
XSelectInput( data->display, data->client_window, ExposureMask );
return data->client_window;
if (data->whole_window) XSelectInput( data->display, data->client_window, ExposureMask );
TRACE( "%p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window );
}
release_win_data( data );
return ret;
}
......@@ -1540,6 +1577,10 @@ done:
*/
static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_destroyed )
{
TRACE( "win %p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window );
if (data->client_window) XDeleteContext( data->display, data->client_window, winContext );
if (!data->whole_window)
{
if (data->embedded)
......@@ -1551,23 +1592,20 @@ static void destroy_whole_window( struct x11drv_win_data *data, BOOL already_des
XDeleteContext( data->display, xwin, winContext );
RemovePropA( data->hwnd, foreign_window_prop );
}
}
return;
}
TRACE( "win %p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window );
XDeleteContext( data->display, data->whole_window, winContext );
if (data->client_window)
}
else
{
XDeleteContext( data->display, data->client_window, winContext );
if (!already_destroyed)
if (data->client_window && !already_destroyed)
{
XSelectInput( data->display, data->client_window, 0 );
XReparentWindow( data->display, data->client_window, get_dummy_parent(), 0, 0 );
XSync( data->display, False );
}
}
XDeleteContext( data->display, data->whole_window, winContext );
if (!already_destroyed) XDestroyWindow( data->display, data->whole_window );
}
if (data->colormap) XFreeColormap( data->display, data->colormap );
data->whole_window = data->client_window = 0;
data->colormap = 0;
......@@ -1703,22 +1741,6 @@ BOOL X11DRV_DestroyNotify( HWND hwnd, XEvent *event )
}
static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd )
{
struct x11drv_win_data *data;
if ((data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data))))
{
data->display = display;
data->vis = default_visual;
data->hwnd = hwnd;
EnterCriticalSection( &win_data_section );
XSaveContext( gdi_display, (XID)hwnd, win_data_context, (char *)data );
}
return data;
}
/* initialize the desktop window id in the desktop manager process */
BOOL create_desktop_win_data( Window win )
{
......@@ -2342,13 +2364,13 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
if (!data->whole_window)
{
int width = data->client_rect.right - data->client_rect.left;
int height = data->client_rect.bottom - data->client_rect.top;
BOOL needs_resize = (!data->client_window &&
(data->client_rect.right - data->client_rect.left !=
old_client_rect.right - old_client_rect.left ||
data->client_rect.bottom - data->client_rect.top !=
old_client_rect.bottom - old_client_rect.top));
release_win_data( data );
if (width != old_client_rect.right - old_client_rect.left ||
height != old_client_rect.bottom - old_client_rect.top)
sync_gl_drawable( hwnd, width, height );
if (needs_resize) sync_gl_drawable( hwnd );
return;
}
......
......@@ -579,7 +579,7 @@ extern void release_win_data( struct x11drv_win_data *data ) DECLSPEC_HIDDEN;
extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN;
extern void sync_gl_drawable( HWND hwnd, int width, int height ) DECLSPEC_HIDDEN;
extern void sync_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
extern void set_gl_drawable_parent( HWND hwnd, HWND parent ) DECLSPEC_HIDDEN;
extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
......@@ -589,7 +589,7 @@ extern void update_user_time( Time time ) DECLSPEC_HIDDEN;
extern void read_net_wm_states( Display *display, struct x11drv_win_data *data ) DECLSPEC_HIDDEN;
extern void update_net_wm_states( struct x11drv_win_data *data ) DECLSPEC_HIDDEN;
extern void make_window_embedded( struct x11drv_win_data *data ) DECLSPEC_HIDDEN;
extern Window create_client_window( struct x11drv_win_data *data, const XVisualInfo *visual ) DECLSPEC_HIDDEN;
extern Window create_client_window( HWND hwnd, const XVisualInfo *visual ) DECLSPEC_HIDDEN;
extern void set_window_visual( struct x11drv_win_data *data, const XVisualInfo *vis, BOOL use_alpha ) DECLSPEC_HIDDEN;
extern void change_systray_owner( Display *display, Window systray_window ) DECLSPEC_HIDDEN;
extern void update_systray_balloon_position(void) 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