2008-09-16 Tomas Frydrych <tf@linux.intel.com>
* clutter/glx/clutter-glx-texture-pixmap.c: * clutter/x11/clutter-x11-texture-pixmap.c: TFP resyncing on MapNotify/ConfigureNotify (bug 1020; patch by Andy Wingo <wingo@pobox.com>).
This commit is contained in:
parent
7294239d64
commit
8be7e29a6b
@ -1,3 +1,10 @@
|
|||||||
|
2008-09-16 Tomas Frydrych <tf@linux.intel.com>
|
||||||
|
|
||||||
|
* clutter/glx/clutter-glx-texture-pixmap.c:
|
||||||
|
* clutter/x11/clutter-x11-texture-pixmap.c:
|
||||||
|
TFP resyncing on MapNotify/ConfigureNotify (bug 1020; patch by
|
||||||
|
Andy Wingo <wingo@pobox.com>).
|
||||||
|
|
||||||
2008-09-15 Øyvind Kolås <pippin@linux.intel.com>
|
2008-09-15 Øyvind Kolås <pippin@linux.intel.com>
|
||||||
|
|
||||||
* clutter/clutter-main.c: amended typo in gtk-doc.
|
* clutter/clutter-main.c: amended typo in gtk-doc.
|
||||||
|
@ -536,12 +536,7 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture)
|
|||||||
{
|
{
|
||||||
priv->glx_pixmap = glx_pixmap;
|
priv->glx_pixmap = glx_pixmap;
|
||||||
|
|
||||||
if (!clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (texture)))
|
create_cogl_texture (CLUTTER_TEXTURE (texture), pixmap_width, pixmap_height);
|
||||||
{
|
|
||||||
create_cogl_texture (CLUTTER_TEXTURE (texture),
|
|
||||||
pixmap_width,
|
|
||||||
pixmap_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
CLUTTER_NOTE (TEXTURE, "Created GLXPixmap");
|
CLUTTER_NOTE (TEXTURE, "Created GLXPixmap");
|
||||||
|
|
||||||
|
@ -63,7 +63,12 @@ enum
|
|||||||
PROP_DEPTH,
|
PROP_DEPTH,
|
||||||
PROP_AUTO,
|
PROP_AUTO,
|
||||||
PROP_WINDOW,
|
PROP_WINDOW,
|
||||||
PROP_WINDOW_REDIRECT_AUTOMATIC
|
PROP_WINDOW_REDIRECT_AUTOMATIC,
|
||||||
|
PROP_WINDOW_MAPPED,
|
||||||
|
PROP_DESTROYED,
|
||||||
|
PROP_WINDOW_X,
|
||||||
|
PROP_WINDOW_Y,
|
||||||
|
PROP_WINDOW_OVERRIDE_REDIRECT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -73,7 +78,7 @@ enum
|
|||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
static ClutterX11FilterReturn
|
static ClutterX11FilterReturn
|
||||||
on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data);
|
on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -82,6 +87,10 @@ clutter_x11_texture_pixmap_update_area_real (ClutterX11TexturePixmap *texture,
|
|||||||
gint y,
|
gint y,
|
||||||
gint width,
|
gint width,
|
||||||
gint height);
|
gint height);
|
||||||
|
static void
|
||||||
|
clutter_x11_texture_pixmap_set_mapped (ClutterX11TexturePixmap *texture, gboolean mapped);
|
||||||
|
static void
|
||||||
|
clutter_x11_texture_pixmap_destroyed (ClutterX11TexturePixmap *texture);
|
||||||
|
|
||||||
static guint signals[LAST_SIGNAL] = { 0, };
|
static guint signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
@ -95,12 +104,18 @@ struct _ClutterX11TexturePixmapPrivate
|
|||||||
XImage *image;
|
XImage *image;
|
||||||
XShmSegmentInfo shminfo;
|
XShmSegmentInfo shminfo;
|
||||||
|
|
||||||
gboolean automatic_updates;
|
gboolean automatic_updates;
|
||||||
Damage damage;
|
Damage damage;
|
||||||
Drawable damage_drawable;
|
Drawable damage_drawable;
|
||||||
|
|
||||||
|
/* FIXME: lots of gbooleans. coalesce into bitfields */
|
||||||
gboolean have_shm;
|
gboolean have_shm;
|
||||||
gboolean window_redirect_automatic;
|
gboolean window_redirect_automatic;
|
||||||
|
gboolean window_mapped;
|
||||||
|
gboolean destroyed;
|
||||||
|
gboolean owns_pixmap;
|
||||||
|
gboolean override_redirect;
|
||||||
|
gint window_x, window_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int _damage_event_base = 0;
|
static int _damage_event_base = 0;
|
||||||
@ -236,7 +251,7 @@ failed_image_create:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterX11FilterReturn
|
static ClutterX11FilterReturn
|
||||||
on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data)
|
on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data)
|
||||||
{
|
{
|
||||||
ClutterX11TexturePixmap *texture;
|
ClutterX11TexturePixmap *texture;
|
||||||
@ -244,13 +259,13 @@ on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data)
|
|||||||
Display *dpy;
|
Display *dpy;
|
||||||
|
|
||||||
texture = CLUTTER_X11_TEXTURE_PIXMAP (data);
|
texture = CLUTTER_X11_TEXTURE_PIXMAP (data);
|
||||||
|
|
||||||
g_return_val_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture), \
|
g_return_val_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture), \
|
||||||
CLUTTER_X11_FILTER_CONTINUE);
|
CLUTTER_X11_FILTER_CONTINUE);
|
||||||
|
|
||||||
dpy = clutter_x11_get_default_display();
|
dpy = clutter_x11_get_default_display();
|
||||||
priv = texture->priv;
|
priv = texture->priv;
|
||||||
|
|
||||||
if (xev->type == _damage_event_base + XDamageNotify)
|
if (xev->type == _damage_event_base + XDamageNotify)
|
||||||
{
|
{
|
||||||
XserverRegion parts;
|
XserverRegion parts;
|
||||||
@ -258,7 +273,7 @@ on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data)
|
|||||||
XRectangle *r_damage;
|
XRectangle *r_damage;
|
||||||
XRectangle r_bounds;
|
XRectangle r_bounds;
|
||||||
XDamageNotifyEvent *dev = (XDamageNotifyEvent*)xev;
|
XDamageNotifyEvent *dev = (XDamageNotifyEvent*)xev;
|
||||||
|
|
||||||
if (dev->drawable != priv->damage_drawable)
|
if (dev->drawable != priv->damage_drawable)
|
||||||
return CLUTTER_X11_FILTER_CONTINUE;
|
return CLUTTER_X11_FILTER_CONTINUE;
|
||||||
|
|
||||||
@ -271,7 +286,7 @@ on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data)
|
|||||||
parts = XFixesCreateRegion (dpy, 0, 0);
|
parts = XFixesCreateRegion (dpy, 0, 0);
|
||||||
XDamageSubtract (dpy, priv->damage, None, parts);
|
XDamageSubtract (dpy, priv->damage, None, parts);
|
||||||
|
|
||||||
r_damage = XFixesFetchRegionAndBounds (dpy,
|
r_damage = XFixesFetchRegionAndBounds (dpy,
|
||||||
parts,
|
parts,
|
||||||
&r_count,
|
&r_count,
|
||||||
&r_bounds);
|
&r_bounds);
|
||||||
@ -295,6 +310,40 @@ on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data)
|
|||||||
return CLUTTER_X11_FILTER_CONTINUE;
|
return CLUTTER_X11_FILTER_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ClutterX11FilterReturn
|
||||||
|
on_x_event_filter_too (XEvent *xev, ClutterEvent *cev, gpointer data)
|
||||||
|
{
|
||||||
|
ClutterX11TexturePixmap *texture;
|
||||||
|
ClutterX11TexturePixmapPrivate *priv;
|
||||||
|
|
||||||
|
texture = CLUTTER_X11_TEXTURE_PIXMAP (data);
|
||||||
|
|
||||||
|
g_return_val_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture), \
|
||||||
|
CLUTTER_X11_FILTER_CONTINUE);
|
||||||
|
|
||||||
|
priv = texture->priv;
|
||||||
|
|
||||||
|
if (xev->xany.window != priv->window)
|
||||||
|
return CLUTTER_X11_FILTER_CONTINUE;
|
||||||
|
|
||||||
|
switch (xev->type) {
|
||||||
|
case MapNotify:
|
||||||
|
case ConfigureNotify:
|
||||||
|
clutter_x11_texture_pixmap_sync_window (texture);
|
||||||
|
break;
|
||||||
|
case UnmapNotify:
|
||||||
|
clutter_x11_texture_pixmap_set_mapped (texture, FALSE);
|
||||||
|
break;
|
||||||
|
case DestroyNotify:
|
||||||
|
clutter_x11_texture_pixmap_destroyed (texture);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CLUTTER_X11_FILTER_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_damage_resources (ClutterX11TexturePixmap *texture)
|
free_damage_resources (ClutterX11TexturePixmap *texture)
|
||||||
@ -329,7 +378,7 @@ clutter_x11_texture_pixmap_init (ClutterX11TexturePixmap *self)
|
|||||||
|
|
||||||
if (!check_extensions (self))
|
if (!check_extensions (self))
|
||||||
{
|
{
|
||||||
/* FIMXE: means display lacks needed extensions for at least auto.
|
/* FIMXE: means display lacks needed extensions for at least auto.
|
||||||
* - a _can_autoupdate() method ?
|
* - a _can_autoupdate() method ?
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
@ -344,6 +393,11 @@ clutter_x11_texture_pixmap_init (ClutterX11TexturePixmap *self)
|
|||||||
self->priv->pixmap_width = 0;
|
self->priv->pixmap_width = 0;
|
||||||
self->priv->shminfo.shmid = -1;
|
self->priv->shminfo.shmid = -1;
|
||||||
self->priv->window_redirect_automatic = TRUE;
|
self->priv->window_redirect_automatic = TRUE;
|
||||||
|
self->priv->window_mapped = FALSE;
|
||||||
|
self->priv->destroyed = FALSE;
|
||||||
|
self->priv->override_redirect = FALSE;
|
||||||
|
self->priv->window_x = 0;
|
||||||
|
self->priv->window_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -354,6 +408,14 @@ clutter_x11_texture_pixmap_dispose (GObject *object)
|
|||||||
|
|
||||||
free_damage_resources (texture);
|
free_damage_resources (texture);
|
||||||
|
|
||||||
|
clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture);
|
||||||
|
|
||||||
|
if (priv->owns_pixmap && priv->pixmap)
|
||||||
|
{
|
||||||
|
XFreePixmap (clutter_x11_get_default_display (), priv->pixmap);
|
||||||
|
priv->pixmap = None;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->image)
|
if (priv->image)
|
||||||
{
|
{
|
||||||
XDestroyImage (priv->image);
|
XDestroyImage (priv->image);
|
||||||
@ -439,6 +501,21 @@ clutter_x11_texture_pixmap_get_property (GObject *object,
|
|||||||
case PROP_WINDOW_REDIRECT_AUTOMATIC:
|
case PROP_WINDOW_REDIRECT_AUTOMATIC:
|
||||||
g_value_set_boolean (value, priv->window_redirect_automatic);
|
g_value_set_boolean (value, priv->window_redirect_automatic);
|
||||||
break;
|
break;
|
||||||
|
case PROP_WINDOW_MAPPED:
|
||||||
|
g_value_set_boolean (value, priv->window_mapped);
|
||||||
|
break;
|
||||||
|
case PROP_DESTROYED:
|
||||||
|
g_value_set_boolean (value, priv->destroyed);
|
||||||
|
break;
|
||||||
|
case PROP_WINDOW_X:
|
||||||
|
g_value_set_int (value, priv->window_x);
|
||||||
|
break;
|
||||||
|
case PROP_WINDOW_Y:
|
||||||
|
g_value_set_int (value, priv->window_y);
|
||||||
|
break;
|
||||||
|
case PROP_WINDOW_OVERRIDE_REDIRECT:
|
||||||
|
g_value_set_boolean (value, priv->override_redirect);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -544,10 +621,56 @@ clutter_x11_texture_pixmap_class_init (ClutterX11TexturePixmapClass *klass)
|
|||||||
TRUE,
|
TRUE,
|
||||||
G_PARAM_READWRITE);
|
G_PARAM_READWRITE);
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_WINDOW_REDIRECT_AUTOMATIC, pspec);
|
PROP_WINDOW_REDIRECT_AUTOMATIC, pspec);
|
||||||
|
|
||||||
|
|
||||||
|
pspec = g_param_spec_boolean ("window-mapped",
|
||||||
|
"Window Mapped",
|
||||||
|
"If window is mapped",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READABLE);
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_WINDOW_MAPPED, pspec);
|
||||||
|
|
||||||
|
|
||||||
|
pspec = g_param_spec_boolean ("destroyed",
|
||||||
|
"Destroyed",
|
||||||
|
"If window has been destroyed",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READABLE);
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_DESTROYED, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_int ("window-x",
|
||||||
|
"Window X",
|
||||||
|
"X position of window on screen according to X11",
|
||||||
|
G_MININT, G_MAXINT, 0, G_PARAM_READABLE);
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_WINDOW_X, pspec);
|
||||||
|
|
||||||
|
|
||||||
|
pspec = g_param_spec_int ("window-y",
|
||||||
|
"Window Y",
|
||||||
|
"Y position of window on screen according to X11",
|
||||||
|
G_MININT, G_MAXINT, 0, G_PARAM_READABLE);
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_WINDOW_Y, pspec);
|
||||||
|
|
||||||
|
pspec = g_param_spec_boolean ("window-override-redirect",
|
||||||
|
"Window Override Redirect",
|
||||||
|
"If this is an override-redirect window",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READABLE);
|
||||||
|
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_WINDOW_OVERRIDE_REDIRECT, pspec);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterX11TexturePixmap::update-area:
|
* ClutterX11TexturePixmap::update-area:
|
||||||
* @texture: the object which received the signal
|
* @texture: the object which received the signal
|
||||||
@ -608,7 +731,7 @@ clutter_x11_texture_pixmap_update_area_real (ClutterX11TexturePixmap *texture,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (priv->shminfo.shmid == -1)
|
if (priv->shminfo.shmid == -1)
|
||||||
try_alloc_shm (texture);
|
try_alloc_shm (texture);
|
||||||
|
|
||||||
clutter_x11_trap_x_errors ();
|
clutter_x11_trap_x_errors ();
|
||||||
|
|
||||||
@ -855,7 +978,7 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
|
|||||||
Pixmap pixmap)
|
Pixmap pixmap)
|
||||||
{
|
{
|
||||||
Window root;
|
Window root;
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned int width, height, border_width, depth;
|
unsigned int width, height, border_width, depth;
|
||||||
Status status = 0;
|
Status status = 0;
|
||||||
gboolean new_pixmap = FALSE, new_pixmap_width = FALSE;
|
gboolean new_pixmap = FALSE, new_pixmap_width = FALSE;
|
||||||
@ -870,21 +993,21 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
|
|||||||
clutter_x11_trap_x_errors ();
|
clutter_x11_trap_x_errors ();
|
||||||
|
|
||||||
status = XGetGeometry (clutter_x11_get_default_display(),
|
status = XGetGeometry (clutter_x11_get_default_display(),
|
||||||
(Drawable)pixmap,
|
(Drawable)pixmap,
|
||||||
&root,
|
&root,
|
||||||
&x,
|
&x,
|
||||||
&y,
|
&y,
|
||||||
&width,
|
&width,
|
||||||
&height,
|
&height,
|
||||||
&border_width,
|
&border_width,
|
||||||
&depth);
|
&depth);
|
||||||
|
|
||||||
if (clutter_x11_untrap_x_errors () || status == 0)
|
if (clutter_x11_untrap_x_errors () || status == 0)
|
||||||
{
|
{
|
||||||
if (pixmap != None)
|
if (pixmap != None)
|
||||||
g_warning ("Unable to query pixmap: %lx", pixmap);
|
g_warning ("Unable to query pixmap: %lx", pixmap);
|
||||||
pixmap = None;
|
pixmap = None;
|
||||||
width = height = depth = 0;
|
width = height = depth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->image)
|
if (priv->image)
|
||||||
@ -892,9 +1015,12 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
|
|||||||
XDestroyImage (priv->image);
|
XDestroyImage (priv->image);
|
||||||
priv->image = NULL;
|
priv->image = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->pixmap != pixmap)
|
if (priv->pixmap != pixmap)
|
||||||
{
|
{
|
||||||
|
if (priv->pixmap && priv->owns_pixmap)
|
||||||
|
XFreePixmap (clutter_x11_get_default_display (), priv->pixmap);
|
||||||
|
|
||||||
priv->pixmap = pixmap;
|
priv->pixmap = pixmap;
|
||||||
new_pixmap = TRUE;
|
new_pixmap = TRUE;
|
||||||
}
|
}
|
||||||
@ -929,7 +1055,6 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
|
|||||||
g_object_notify (G_OBJECT (texture), "pixmap-height");
|
g_object_notify (G_OBJECT (texture), "pixmap-height");
|
||||||
if (new_pixmap_depth)
|
if (new_pixmap_depth)
|
||||||
g_object_notify (G_OBJECT (texture), "pixmap-depth");
|
g_object_notify (G_OBJECT (texture), "pixmap-depth");
|
||||||
g_object_unref (texture);
|
|
||||||
|
|
||||||
free_shm_resources (texture);
|
free_shm_resources (texture);
|
||||||
|
|
||||||
@ -945,6 +1070,13 @@ clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture,
|
|||||||
priv->pixmap_height);
|
priv->pixmap_height);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keep ref until here in case a notify causes removal from the scene; can't
|
||||||
|
* lower the notifies because glx's notify handler needs to run before
|
||||||
|
* update_area
|
||||||
|
*/
|
||||||
|
g_object_unref (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -967,6 +1099,8 @@ clutter_x11_texture_pixmap_set_window (ClutterX11TexturePixmap *texture,
|
|||||||
gboolean automatic)
|
gboolean automatic)
|
||||||
{
|
{
|
||||||
ClutterX11TexturePixmapPrivate *priv;
|
ClutterX11TexturePixmapPrivate *priv;
|
||||||
|
XWindowAttributes attr;
|
||||||
|
Display *dpy = clutter_x11_get_default_display ();
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture));
|
g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture));
|
||||||
|
|
||||||
@ -980,6 +1114,7 @@ clutter_x11_texture_pixmap_set_window (ClutterX11TexturePixmap *texture,
|
|||||||
|
|
||||||
if (priv->window)
|
if (priv->window)
|
||||||
{
|
{
|
||||||
|
clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture);
|
||||||
clutter_x11_trap_x_errors ();
|
clutter_x11_trap_x_errors ();
|
||||||
XCompositeUnredirectWindow(clutter_x11_get_default_display (),
|
XCompositeUnredirectWindow(clutter_x11_get_default_display (),
|
||||||
priv->window,
|
priv->window,
|
||||||
@ -989,28 +1124,50 @@ clutter_x11_texture_pixmap_set_window (ClutterX11TexturePixmap *texture,
|
|||||||
clutter_x11_untrap_x_errors ();
|
clutter_x11_untrap_x_errors ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
priv->window = window;
|
priv->window = window;
|
||||||
priv->window_redirect_automatic = automatic;
|
priv->window_redirect_automatic = automatic;
|
||||||
|
priv->window_mapped = FALSE;
|
||||||
|
priv->destroyed = FALSE;
|
||||||
|
|
||||||
if (window == None)
|
if (window == None)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clutter_x11_trap_x_errors ();
|
clutter_x11_trap_x_errors ();
|
||||||
|
{
|
||||||
|
if (!XGetWindowAttributes (dpy, window, &attr))
|
||||||
|
{
|
||||||
|
XSync (dpy, False);
|
||||||
|
clutter_x11_untrap_x_errors ();
|
||||||
|
g_warning ("bad window 0x%x", (guint32)window);
|
||||||
|
priv->window = None;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
XCompositeRedirectWindow
|
||||||
|
(dpy,
|
||||||
|
window,
|
||||||
|
automatic ?
|
||||||
|
CompositeRedirectAutomatic : CompositeRedirectManual);
|
||||||
|
XSync (dpy, False);
|
||||||
|
}
|
||||||
|
|
||||||
XCompositeRedirectWindow
|
|
||||||
(clutter_x11_get_default_display (),
|
|
||||||
window,
|
|
||||||
automatic ?
|
|
||||||
CompositeRedirectAutomatic : CompositeRedirectManual);
|
|
||||||
XSync (clutter_x11_get_default_display (), False);
|
|
||||||
clutter_x11_untrap_x_errors ();
|
clutter_x11_untrap_x_errors ();
|
||||||
|
|
||||||
|
if (priv->window)
|
||||||
|
{
|
||||||
|
XSelectInput (dpy, priv->window,
|
||||||
|
attr.your_event_mask | StructureNotifyMask);
|
||||||
|
clutter_x11_add_filter (on_x_event_filter_too, (gpointer)texture);
|
||||||
|
}
|
||||||
|
|
||||||
g_object_ref (texture);
|
g_object_ref (texture);
|
||||||
g_object_notify (G_OBJECT (texture), "window");
|
g_object_notify (G_OBJECT (texture), "window");
|
||||||
g_object_unref (texture);
|
|
||||||
|
clutter_x11_texture_pixmap_set_mapped (texture,
|
||||||
|
attr.map_state == IsViewable);
|
||||||
|
|
||||||
clutter_x11_texture_pixmap_sync_window (texture);
|
clutter_x11_texture_pixmap_sync_window (texture);
|
||||||
|
g_object_unref (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1026,36 +1183,104 @@ void
|
|||||||
clutter_x11_texture_pixmap_sync_window (ClutterX11TexturePixmap *texture)
|
clutter_x11_texture_pixmap_sync_window (ClutterX11TexturePixmap *texture)
|
||||||
{
|
{
|
||||||
ClutterX11TexturePixmapPrivate *priv;
|
ClutterX11TexturePixmapPrivate *priv;
|
||||||
Pixmap pixmap, prev_pixmap;
|
Pixmap pixmap;
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture));
|
g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture));
|
||||||
|
|
||||||
priv = texture->priv;
|
priv = texture->priv;
|
||||||
|
|
||||||
|
if (priv->destroyed)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!clutter_x11_has_composite_extension())
|
if (!clutter_x11_has_composite_extension())
|
||||||
{
|
{
|
||||||
clutter_x11_texture_pixmap_set_pixmap (texture, priv->window);
|
clutter_x11_texture_pixmap_set_pixmap (texture, priv->window);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we own the pixmap */
|
|
||||||
prev_pixmap = priv->pixmap;
|
|
||||||
|
|
||||||
if (priv->window)
|
if (priv->window)
|
||||||
{
|
{
|
||||||
|
XWindowAttributes attr;
|
||||||
Display *dpy = clutter_x11_get_default_display ();
|
Display *dpy = clutter_x11_get_default_display ();
|
||||||
|
gboolean mapped, notify_x, notify_y, notify_override_redirect;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure the window is mapped when getting the pixmap -- it's what
|
||||||
|
* compiz does.
|
||||||
|
*/
|
||||||
|
|
||||||
clutter_x11_trap_x_errors ();
|
clutter_x11_trap_x_errors ();
|
||||||
pixmap = XCompositeNameWindowPixmap (dpy, priv->window);
|
XGrabServer (dpy);
|
||||||
|
|
||||||
|
XGetWindowAttributes (dpy, priv->window, &attr);
|
||||||
|
mapped = attr.map_state == IsViewable;
|
||||||
|
if (mapped)
|
||||||
|
pixmap = XCompositeNameWindowPixmap (dpy, priv->window);
|
||||||
|
else
|
||||||
|
pixmap = None;
|
||||||
|
|
||||||
|
XUngrabServer (dpy);
|
||||||
clutter_x11_untrap_x_errors ();
|
clutter_x11_untrap_x_errors ();
|
||||||
|
|
||||||
clutter_x11_texture_pixmap_set_pixmap (texture, pixmap);
|
notify_x = attr.x != priv->window_x;
|
||||||
|
notify_y = attr.y != priv->window_y;
|
||||||
|
notify_override_redirect = attr.override_redirect != priv->override_redirect;
|
||||||
|
priv->window_x = attr.x;
|
||||||
|
priv->window_y = attr.y;
|
||||||
|
priv->override_redirect = attr.override_redirect;
|
||||||
|
|
||||||
if (prev_pixmap)
|
g_object_ref (texture); /* guard against unparent */
|
||||||
XFreePixmap (dpy, prev_pixmap);
|
if (pixmap)
|
||||||
|
{
|
||||||
|
clutter_x11_texture_pixmap_set_pixmap (texture, pixmap);
|
||||||
|
priv->owns_pixmap = TRUE;
|
||||||
|
}
|
||||||
|
clutter_x11_texture_pixmap_set_mapped (texture, mapped);
|
||||||
|
/* could do more clever things with a signal, i guess.. */
|
||||||
|
if (notify_override_redirect)
|
||||||
|
g_object_notify (G_OBJECT (texture), "window-override-redirect");
|
||||||
|
if (notify_x)
|
||||||
|
g_object_notify (G_OBJECT (texture), "window-x");
|
||||||
|
if (notify_y)
|
||||||
|
g_object_notify (G_OBJECT (texture), "window-y");
|
||||||
|
g_object_unref (texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_x11_texture_pixmap_set_mapped (ClutterX11TexturePixmap *texture,
|
||||||
|
gboolean mapped)
|
||||||
|
{
|
||||||
|
ClutterX11TexturePixmapPrivate *priv;
|
||||||
|
|
||||||
|
priv = texture->priv;
|
||||||
|
|
||||||
|
if (mapped != priv->window_mapped)
|
||||||
|
{
|
||||||
|
priv->window_mapped = mapped;
|
||||||
|
g_object_notify (G_OBJECT (texture), "window-mapped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_x11_texture_pixmap_destroyed (ClutterX11TexturePixmap *texture)
|
||||||
|
{
|
||||||
|
ClutterX11TexturePixmapPrivate *priv;
|
||||||
|
|
||||||
|
priv = texture->priv;
|
||||||
|
|
||||||
|
if (!priv->destroyed)
|
||||||
|
{
|
||||||
|
priv->destroyed = TRUE;
|
||||||
|
g_object_notify (G_OBJECT (texture), "destroyed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't set window to None, that would destroy the pixmap, which might still
|
||||||
|
* be useful e.g. for destroy animations -- app's responsibility.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clutter_x11_texture_pixmap_update_area:
|
* clutter_x11_texture_pixmap_update_area:
|
||||||
* @texture: The texture whose content shall be updated.
|
* @texture: The texture whose content shall be updated.
|
||||||
@ -1103,13 +1328,13 @@ clutter_x11_texture_pixmap_set_automatic (ClutterX11TexturePixmap *texture,
|
|||||||
clutter_x11_add_filter (on_x_event_filter, (gpointer)texture);
|
clutter_x11_add_filter (on_x_event_filter, (gpointer)texture);
|
||||||
|
|
||||||
clutter_x11_trap_x_errors ();
|
clutter_x11_trap_x_errors ();
|
||||||
|
|
||||||
if (priv->window)
|
if (priv->window)
|
||||||
priv->damage_drawable = priv->window;
|
priv->damage_drawable = priv->window;
|
||||||
else
|
else
|
||||||
priv->damage_drawable = priv->pixmap;
|
priv->damage_drawable = priv->pixmap;
|
||||||
|
|
||||||
priv->damage = XDamageCreate (dpy,
|
priv->damage = XDamageCreate (dpy,
|
||||||
priv->damage_drawable,
|
priv->damage_drawable,
|
||||||
XDamageReportNonEmpty);
|
XDamageReportNonEmpty);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user