diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build index 05de6f21d..879ea1664 100644 --- a/clutter/clutter/meson.build +++ b/clutter/clutter/meson.build @@ -277,7 +277,6 @@ if have_x11 'x11/clutter-keymap-x11.c', 'x11/clutter-stage-x11.c', 'x11/clutter-virtual-input-device-x11.c', - 'x11/clutter-x11-texture-pixmap.c', ] clutter_backend_sources += clutter_x11_sources @@ -288,7 +287,6 @@ if have_x11 clutter_x11_headers = [ 'x11/clutter-x11.h', - 'x11/clutter-x11-texture-pixmap.h', ] clutter_backend_headers += clutter_x11_headers diff --git a/clutter/clutter/x11/clutter-x11-texture-pixmap.c b/clutter/clutter/x11/clutter-x11-texture-pixmap.c deleted file mode 100644 index edb3e499f..000000000 --- a/clutter/clutter/x11/clutter-x11-texture-pixmap.c +++ /dev/null @@ -1,1262 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2007 OpenedHand - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Authors: - * Johan Bilien - * Neil Roberts - */ - -/** - * SECTION:clutter-x11-texture-pixmap - * @Title: ClutterX11TexturePixmap - * @short_description: A texture which displays the content of an X Pixmap. - * - * #ClutterX11TexturePixmap is a class for displaying the content of an - * X Pixmap as a ClutterActor. Used together with the X Composite extension, - * it allows to display the content of X Windows inside Clutter. - * - * The class uses the GLX_EXT_texture_from_pixmap OpenGL extension - * (http://people.freedesktop.org/~davidr/GLX_EXT_texture_from_pixmap.txt) - * if available - */ - -#include "clutter-build-config.h" - -#define CLUTTER_ENABLE_EXPERIMENTAL_API -#define CLUTTER_DISABLE_DEPRECATION_WARNINGS - -#include "clutter-x11-texture-pixmap.h" -#include "clutter-x11.h" -#include "clutter-backend-x11.h" - -#include "clutter-actor-private.h" -#include "clutter-marshal.h" -#include "clutter-paint-volume-private.h" -#include "clutter-private.h" - -#include - -#include - -#include -#include - -enum -{ - PROP_PIXMAP = 1, - PROP_PIXMAP_WIDTH, - PROP_PIXMAP_HEIGHT, - PROP_DEPTH, - PROP_AUTO, - PROP_WINDOW, - PROP_WINDOW_REDIRECT_AUTOMATIC, - PROP_WINDOW_MAPPED, - PROP_DESTROYED, - PROP_WINDOW_X, - PROP_WINDOW_Y, - PROP_WINDOW_OVERRIDE_REDIRECT -}; - -enum -{ - UPDATE_AREA, - QUEUE_DAMAGE_REDRAW, - - /* FIXME: Pixmap lost signal? */ - LAST_SIGNAL -}; - -static ClutterX11FilterReturn -on_x_event_filter (XEvent *xev, ClutterEvent *cev, gpointer data); - -static void -clutter_x11_texture_pixmap_update_area_real (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height); -static void -clutter_x11_texture_pixmap_sync_window_internal (ClutterX11TexturePixmap *texture, - int x, - int y, - int width, - int height, - gboolean override_redirect); -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, }; - -struct _ClutterX11TexturePixmapPrivate -{ - Window window; - Pixmap pixmap; - guint pixmap_width, pixmap_height; - guint depth; - - Damage damage; - - gint window_x, window_y; - gint window_width, window_height; - - guint window_redirect_automatic : 1; - /* FIXME: this is inconsistently either whether the window is mapped or whether - * it is viewable, and isn't updated correctly. */ - guint window_mapped : 1; - guint destroyed : 1; - guint owns_pixmap : 1; - guint override_redirect : 1; - guint automatic_updates : 1; -}; - -static int _damage_event_base = 0; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterX11TexturePixmap, - clutter_x11_texture_pixmap, - CLUTTER_TYPE_TEXTURE) - -static gboolean -check_extensions (ClutterX11TexturePixmap *texture) -{ - int damage_error; - Display *dpy; - - if (_damage_event_base) - return TRUE; - - dpy = clutter_x11_get_default_display(); - - if (!XDamageQueryExtension (dpy, &_damage_event_base, &damage_error)) - { - g_warning ("No Damage extension"); - return FALSE; - } - - return TRUE; -} - -static void -process_damage_event (ClutterX11TexturePixmap *texture, - XDamageNotifyEvent *damage_event) -{ - /* Cogl will deal with updating the texture and subtracting from the - damage region so we only need to queue a redraw */ - g_signal_emit (texture, signals[QUEUE_DAMAGE_REDRAW], - 0, - damage_event->area.x, - damage_event->area.y, - damage_event->area.width, - damage_event->area.height); -} - -static ClutterX11FilterReturn -on_x_event_filter (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->type == _damage_event_base + XDamageNotify) - { - XDamageNotifyEvent *dev = (XDamageNotifyEvent*)xev; - - if (dev->damage != priv->damage) - return CLUTTER_X11_FILTER_CONTINUE; - - process_damage_event (texture, dev); - } - - 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: - clutter_x11_texture_pixmap_sync_window_internal (texture, - priv->window_x, - priv->window_y, - priv->window_width, - priv->window_height, - priv->override_redirect); - break; - case ConfigureNotify: - clutter_x11_texture_pixmap_sync_window_internal (texture, - xev->xconfigure.x, - xev->xconfigure.y, - xev->xconfigure.width, - xev->xconfigure.height, - xev->xconfigure.override_redirect); - 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 -update_pixmap_damage_object (ClutterX11TexturePixmap *texture) -{ - ClutterX11TexturePixmapPrivate *priv = texture->priv; - CoglHandle cogl_texture; - - /* If we already have a CoglTexturePixmapX11 then update its - damage object */ - cogl_texture = - clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (texture)); - - if (cogl_texture && cogl_is_texture_pixmap_x11 (cogl_texture)) - { - if (priv->damage) - { - const CoglTexturePixmapX11ReportLevel report_level = - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX; - cogl_texture_pixmap_x11_set_damage_object (cogl_texture, - priv->damage, - report_level); - } - else - cogl_texture_pixmap_x11_set_damage_object (cogl_texture, 0, 0); - } -} - -static void -create_damage_resources (ClutterX11TexturePixmap *texture) -{ - ClutterX11TexturePixmapPrivate *priv; - Display *dpy; - - priv = texture->priv; - dpy = clutter_x11_get_default_display(); - - if (!priv->pixmap) - return; - - clutter_x11_trap_x_errors (); - - priv->damage = XDamageCreate (dpy, - priv->pixmap, - XDamageReportBoundingBox); - - /* Errors here might occur if the window is already destroyed, we - * simply skip processing damage and assume that the texture pixmap - * will be cleaned up by the app when it gets a DestroyNotify. - */ - XSync (dpy, FALSE); - clutter_x11_untrap_x_errors (); - - if (priv->damage) - { - clutter_x11_add_filter (on_x_event_filter, (gpointer)texture); - - update_pixmap_damage_object (texture); - } -} - -static void -free_damage_resources (ClutterX11TexturePixmap *texture) -{ - ClutterX11TexturePixmapPrivate *priv; - Display *dpy; - - priv = texture->priv; - dpy = clutter_x11_get_default_display(); - - if (priv->damage) - { - clutter_x11_trap_x_errors (); - XDamageDestroy (dpy, priv->damage); - XSync (dpy, FALSE); - clutter_x11_untrap_x_errors (); - priv->damage = None; - - clutter_x11_remove_filter (on_x_event_filter, (gpointer)texture); - - update_pixmap_damage_object (texture); - } -} - -static gboolean -clutter_x11_texture_pixmap_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) -{ - return clutter_paint_volume_set_from_allocation (volume, self); -} - -static void -clutter_x11_texture_pixmap_real_queue_damage_redraw ( - ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height) -{ - ClutterX11TexturePixmapPrivate *priv = texture->priv; - ClutterActor *self = CLUTTER_ACTOR (texture); - ClutterActorBox allocation; - float scale_x, scale_y; - cairo_rectangle_int_t clip; - - /* NB: clutter_actor_queue_clipped_redraw expects a box in the actor's - * coordinate space so we need to convert from pixmap coordinates to - * actor coordinates... - */ - - /* Calling clutter_actor_get_allocation_box() is enormously expensive - * if the actor has an out-of-date allocation, since it triggers - * a full redraw. clutter_actor_queue_clipped_redraw() would redraw - * the whole stage anyways in that case, so just go ahead and do - * it here. - */ - if (!clutter_actor_has_allocation (self)) - { - clutter_actor_queue_redraw (self); - return; - } - - if (priv->pixmap_width == 0 || priv->pixmap_height == 0) - return; - - clutter_actor_get_allocation_box (self, &allocation); - - scale_x = (allocation.x2 - allocation.x1) / priv->pixmap_width; - scale_y = (allocation.y2 - allocation.y1) / priv->pixmap_height; - - clip.x = x * scale_x; - clip.y = y * scale_y; - clip.width = width * scale_x; - clip.height = height * scale_y; - clutter_actor_queue_redraw_with_clip (self, &clip); -} - -static void -clutter_x11_texture_pixmap_init (ClutterX11TexturePixmap *self) -{ - self->priv = clutter_x11_texture_pixmap_get_instance_private (self); - - if (!check_extensions (self)) - { - /* FIMXE: means display lacks needed extensions for at least auto. - * - a _can_autoupdate() method ? - */ - } - - self->priv->automatic_updates = FALSE; - self->priv->damage = None; - self->priv->window = None; - self->priv->pixmap = None; - self->priv->pixmap_height = 0; - self->priv->pixmap_width = 0; - 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 -clutter_x11_texture_pixmap_dispose (GObject *object) -{ - ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object); - - free_damage_resources (texture); - - clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture); - clutter_x11_texture_pixmap_set_pixmap (texture, None); - - G_OBJECT_CLASS (clutter_x11_texture_pixmap_parent_class)->dispose (object); -} - -static void -clutter_x11_texture_pixmap_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object); - ClutterX11TexturePixmapPrivate *priv = texture->priv; - - switch (prop_id) - { - case PROP_PIXMAP: - clutter_x11_texture_pixmap_set_pixmap (texture, - g_value_get_ulong (value)); - break; - case PROP_AUTO: - clutter_x11_texture_pixmap_set_automatic (texture, - g_value_get_boolean (value)); - break; - case PROP_WINDOW: - clutter_x11_texture_pixmap_set_window (texture, - g_value_get_ulong (value), - priv->window_redirect_automatic); - break; - case PROP_WINDOW_REDIRECT_AUTOMATIC: - { - gboolean new; - new = g_value_get_boolean (value); - - /* Change the update mode.. */ - if (new != priv->window_redirect_automatic && priv->window) - clutter_x11_texture_pixmap_set_window (texture, priv->window, new); - - priv->window_redirect_automatic = new; - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_x11_texture_pixmap_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterX11TexturePixmap *texture = CLUTTER_X11_TEXTURE_PIXMAP (object); - ClutterX11TexturePixmapPrivate *priv = texture->priv; - - switch (prop_id) - { - case PROP_PIXMAP: - g_value_set_ulong (value, priv->pixmap); - break; - case PROP_PIXMAP_WIDTH: - g_value_set_uint (value, priv->pixmap_width); - break; - case PROP_PIXMAP_HEIGHT: - g_value_set_uint (value, priv->pixmap_height); - break; - case PROP_DEPTH: - g_value_set_uint (value, priv->depth); - break; - case PROP_AUTO: - g_value_set_boolean (value, priv->automatic_updates); - break; - case PROP_WINDOW: - g_value_set_ulong (value, priv->window); - break; - case PROP_WINDOW_REDIRECT_AUTOMATIC: - g_value_set_boolean (value, priv->window_redirect_automatic); - 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: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -clutter_x11_texture_pixmap_class_init (ClutterX11TexturePixmapClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - GParamSpec *pspec; - - actor_class->get_paint_volume = clutter_x11_texture_pixmap_get_paint_volume; - - object_class->dispose = clutter_x11_texture_pixmap_dispose; - object_class->set_property = clutter_x11_texture_pixmap_set_property; - object_class->get_property = clutter_x11_texture_pixmap_get_property; - - klass->update_area = clutter_x11_texture_pixmap_update_area_real; - - pspec = g_param_spec_ulong ("pixmap", - P_("Pixmap"), - P_("The X11 Pixmap to be bound"), - 0, G_MAXULONG, - None, - G_PARAM_READWRITE); - - g_object_class_install_property (object_class, PROP_PIXMAP, pspec); - - pspec = g_param_spec_uint ("pixmap-width", - P_("Pixmap width"), - P_("The width of the pixmap bound to this texture"), - 0, G_MAXUINT, - 0, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, PROP_PIXMAP_WIDTH, pspec); - - pspec = g_param_spec_uint ("pixmap-height", - P_("Pixmap height"), - P_("The height of the pixmap bound to this texture"), - 0, G_MAXUINT, - 0, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, PROP_PIXMAP_HEIGHT, pspec); - - pspec = g_param_spec_uint ("pixmap-depth", - P_("Pixmap Depth"), - P_("The depth (in number of bits) of the pixmap bound to this texture"), - 0, G_MAXUINT, - 0, - G_PARAM_READABLE); - - g_object_class_install_property (object_class, PROP_DEPTH, pspec); - - pspec = g_param_spec_boolean ("automatic-updates", - P_("Automatic Updates"), - P_("If the texture should be kept in " - "sync with any pixmap changes."), - FALSE, - G_PARAM_READWRITE); - - g_object_class_install_property (object_class, PROP_AUTO, pspec); - - pspec = g_param_spec_ulong ("window", - P_("Window"), - P_("The X11 Window to be bound"), - 0, G_MAXULONG, - None, - G_PARAM_READWRITE); - - g_object_class_install_property (object_class, PROP_WINDOW, pspec); - - pspec = g_param_spec_boolean ("window-redirect-automatic", - P_("Window Redirect Automatic"), - P_("If composite window redirects are set to " - "Automatic (or Manual if false)"), - TRUE, - G_PARAM_READWRITE); - - g_object_class_install_property (object_class, - PROP_WINDOW_REDIRECT_AUTOMATIC, pspec); - - - pspec = g_param_spec_boolean ("window-mapped", - P_("Window Mapped"), - P_("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", - P_("Destroyed"), - P_("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", - P_("Window X"), - P_("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", - P_("Window Y"), - P_("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", - P_("Window Override Redirect"), - P_("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: - * @texture: the object which received the signal - * @x: X coordinate of the area to update - * @y: Y coordinate of the area to update - * @width: width of the area to update - * @height: height of the area to update - * - * The ::update-area signal is emitted to ask the texture to update its - * content from its source pixmap. - * - * Since: 0.8 - */ - signals[UPDATE_AREA] = - g_signal_new (g_intern_static_string ("update-area"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (ClutterX11TexturePixmapClass, \ - update_area), - NULL, NULL, - _clutter_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - - /** - * ClutterX11TexturePixmap::queue-damage-redraw: - * @texture: the object which received the signal - * @x: The top left x position of the damage region - * @y: The top left y position of the damage region - * @width: The width of the damage region - * @height: The height of the damage region - * - * ::queue-damage-redraw is emitted to notify that some sub-region - * of the texture has been changed (either by an automatic damage - * update or by an explicit call to - * clutter_x11_texture_pixmap_update_area). This usually means a - * redraw needs to be queued for the actor. - * - * The default handler will queue a clipped redraw in response to - * the damage, using the assumption that the pixmap is being painted - * to a rectangle covering the transformed allocation of the actor. - * If you sub-class and change the paint method so this isn't true - * then you must also provide your own damage signal handler to - * queue a redraw that blocks this default behaviour. - * - * Since: 1.2 - */ - signals[QUEUE_DAMAGE_REDRAW] = - g_signal_new (g_intern_static_string ("queue-damage-redraw"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - _clutter_marshal_VOID__INT_INT_INT_INT, - G_TYPE_NONE, 4, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INT); - - g_signal_override_class_handler ("queue-damage-redraw", - CLUTTER_X11_TYPE_TEXTURE_PIXMAP, - G_CALLBACK (clutter_x11_texture_pixmap_real_queue_damage_redraw)); -} - -static void -clutter_x11_texture_pixmap_update_area_real (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height) -{ - CoglHandle cogl_texture; - - cogl_texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (texture)); - - if (cogl_texture) - cogl_texture_pixmap_x11_update_area (cogl_texture, x, y, width, height); -} - -/** - * clutter_x11_texture_pixmap_new: - * - * Creates a new #ClutterX11TexturePixmap which can be used to display the - * contents of an X11 Pixmap inside a Clutter scene graph - * - * Return value: A new #ClutterX11TexturePixmap - * - * Since: 0.8 - */ -ClutterActor * -clutter_x11_texture_pixmap_new (void) -{ - ClutterActor *actor; - - actor = g_object_new (CLUTTER_X11_TYPE_TEXTURE_PIXMAP, NULL); - - return actor; -} - -/** - * clutter_x11_texture_pixmap_new_with_pixmap: - * @pixmap: the X Pixmap to which this texture should be bound - * - * Creates a new #ClutterX11TexturePixmap for @pixmap - * - * Return value: A new #ClutterX11TexturePixmap bound to the given X Pixmap - * - * Since: 0.8 - */ -ClutterActor * -clutter_x11_texture_pixmap_new_with_pixmap (Pixmap pixmap) -{ - ClutterActor *actor; - - actor = g_object_new (CLUTTER_X11_TYPE_TEXTURE_PIXMAP, - "pixmap", pixmap, - NULL); - - return actor; -} - -/** - * clutter_x11_texture_pixmap_new_with_window: - * @window: the X window to which this texture should be bound - * - * Creates a new #ClutterX11TexturePixmap for @window - * - * Return value: A new #ClutterX11TexturePixmap bound to the given X window. - * - * Since: 0.8 - **/ -ClutterActor * -clutter_x11_texture_pixmap_new_with_window (Window window) -{ - ClutterActor *actor; - - actor = g_object_new (CLUTTER_X11_TYPE_TEXTURE_PIXMAP, - "window", window, - NULL); - - return actor; -} - -/** - * clutter_x11_texture_pixmap_set_pixmap: - * @texture: the texture to bind - * @pixmap: the X Pixmap to which the texture should be bound - * - * Sets the X Pixmap to which the texture should be bound. - * - * Since: 0.8 - */ -void -clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture, - Pixmap pixmap) -{ - Window root; - int x, y; - unsigned int width, height, border_width, depth; - Status status = 0; - gboolean new_pixmap = FALSE, new_pixmap_width = FALSE; - gboolean new_pixmap_height = FALSE, new_pixmap_depth = FALSE; - CoglPipeline *pipeline; - - ClutterX11TexturePixmapPrivate *priv; - - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - priv = texture->priv; - - /* Get rid of the existing Cogl texture early because it may try to - use the pixmap which we might destroy */ - pipeline = (CoglPipeline *) - clutter_texture_get_cogl_material (CLUTTER_TEXTURE (texture)); - if (pipeline) - cogl_pipeline_set_layer_texture (pipeline, 0, NULL); - - if (pixmap != None) - { - clutter_x11_trap_x_errors (); - status = XGetGeometry (clutter_x11_get_default_display(), - (Drawable)pixmap, - &root, - &x, - &y, - &width, - &height, - &border_width, - &depth); - - if (clutter_x11_untrap_x_errors () || status == 0) - { - g_warning ("Unable to query pixmap: %lx", pixmap); - pixmap = None; - width = height = depth = 0; - } - } - else - { - width = height = depth = 0; - } - - if (priv->pixmap != pixmap) - { - if (priv->pixmap && priv->owns_pixmap) - XFreePixmap (clutter_x11_get_default_display (), priv->pixmap); - - priv->pixmap = pixmap; - new_pixmap = TRUE; - - /* The damage object is created on the pixmap, so it needs to be - * recreated with a change in pixmap. - */ - if (priv->automatic_updates) - { - free_damage_resources (texture); - create_damage_resources (texture); - } - } - - if (priv->pixmap_width != width) - { - priv->pixmap_width = width; - new_pixmap_width = TRUE; - } - - if (priv->pixmap_height != height) - { - priv->pixmap_height = height; - new_pixmap_height = TRUE; - } - - if (priv->depth != depth) - { - priv->depth = depth; - new_pixmap_depth = TRUE; - } - - /* NB: We defer sending the signals until updating all the - * above members so the values are all available to the - * signal handlers. */ - g_object_ref (texture); - - if (new_pixmap) - g_object_notify (G_OBJECT (texture), "pixmap"); - if (new_pixmap_width) - g_object_notify (G_OBJECT (texture), "pixmap-width"); - if (new_pixmap_height) - g_object_notify (G_OBJECT (texture), "pixmap-height"); - if (new_pixmap_depth) - g_object_notify (G_OBJECT (texture), "pixmap-depth"); - - if (pixmap) - { - CoglContext *ctx = - clutter_backend_get_cogl_context (clutter_get_default_backend ()); - GError *error = NULL; - CoglTexturePixmapX11 *texture_pixmap = - cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, &error); - if (texture_pixmap) - { - clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (texture), - COGL_TEXTURE (texture_pixmap)); - cogl_object_unref (texture_pixmap); - update_pixmap_damage_object (texture); - } - else - { - g_warning ("Failed to create CoglTexturePixmapX11: %s", - error->message); - g_error_free (error); - } - } - - /* - * 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); -} - -/** - * clutter_x11_texture_pixmap_set_window: - * @texture: the texture to bind - * @window: the X window to which the texture should be bound - * @automatic: %TRUE for automatic window updates, %FALSE for manual. - * - * Sets up a suitable pixmap for the window, using the composite and damage - * extensions if possible, and then calls - * clutter_x11_texture_pixmap_set_pixmap(). - * - * If you want to display a window in a #ClutterTexture, you probably want - * this function, or its older sister, clutter_glx_texture_pixmap_set_window(). - * - * This function has no effect unless the XComposite extension is available. - * - * Since: 0.8 - */ -void -clutter_x11_texture_pixmap_set_window (ClutterX11TexturePixmap *texture, - Window window, - gboolean automatic) -{ - ClutterX11TexturePixmapPrivate *priv; - XWindowAttributes attr; - Display *dpy; - - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - if (!clutter_x11_has_composite_extension ()) - return; - - dpy = clutter_x11_get_default_display (); - if (dpy == NULL) - return; - - priv = texture->priv; - - if (priv->window == window && automatic == priv->window_redirect_automatic) - return; - - if (priv->window) - { - clutter_x11_remove_filter (on_x_event_filter_too, (gpointer)texture); - clutter_x11_trap_x_errors (); - XCompositeUnredirectWindow(clutter_x11_get_default_display (), - priv->window, - priv->window_redirect_automatic ? - CompositeRedirectAutomatic : CompositeRedirectManual); - XSync (clutter_x11_get_default_display (), False); - clutter_x11_untrap_x_errors (); - - clutter_x11_texture_pixmap_set_pixmap (texture, None); - } - - priv->window = window; - priv->window_redirect_automatic = automatic; - priv->window_mapped = FALSE; - priv->destroyed = FALSE; - - if (window == None) - return; - - 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); - } - - clutter_x11_untrap_x_errors (); - - 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_notify (G_OBJECT (texture), "window"); - - clutter_x11_texture_pixmap_set_mapped (texture, - attr.map_state == IsViewable); - - clutter_x11_texture_pixmap_sync_window_internal (texture, - attr.x, attr.y, - attr.width, attr.height, - attr.override_redirect); - g_object_unref (texture); -} - -static void -clutter_x11_texture_pixmap_sync_window_internal (ClutterX11TexturePixmap *texture, - int x, - int y, - int width, - int height, - gboolean override_redirect) -{ - ClutterX11TexturePixmapPrivate *priv; - Pixmap pixmap = None; - gboolean mapped = FALSE; - gboolean notify_x = FALSE; - gboolean notify_y = FALSE; - gboolean notify_override_redirect = FALSE; - - priv = texture->priv; - - if (priv->destroyed) - return; - - notify_x = x != priv->window_x; - notify_y = y != priv->window_y; - notify_override_redirect = override_redirect != priv->override_redirect; - priv->window_x = x; - priv->window_y = y; - priv->window_width = width; - priv->window_height = height; - priv->override_redirect = override_redirect; - - if (!clutter_x11_has_composite_extension ()) - { - /* FIXME: this should just be an error, this is unlikely to work worth anything */ - clutter_x11_texture_pixmap_set_pixmap (texture, priv->window); - return; - } - - if (priv->pixmap == None || width != priv->pixmap_width || height != priv->pixmap_height) - { - /* Note that we're checking the size from the event against the size we obtained - * from the last XCompositeNameWindowPixmap/XGetGeometry pair. This will always - * end up right in the end, but we can have a series like: - * - * Window sized to 100x100 - * Window sized to 110x110 - * Window sized to 120x120 - * Configure received for 100x100 - NameWindowPixmap - * Configure received for 110x110 - NameWindowPixmap - * Configure received for 120x120 - last size OK - * - * Where we NameWindowPixmap several times in a row. (Using pixmap_width/pixmap_height - * rather than window_width/window_height saves the last one.) - */ - - Display *dpy = clutter_x11_get_default_display (); - - /* NB: It's only valid to name a pixmap if the window is viewable. - * - * We don't explicitly check this though since there would be a race - * between checking and naming unless we use a server grab which is - * undesireable. - * - * Instead we gracefully handle any error with naming the pixmap. - */ - clutter_x11_trap_x_errors (); - - pixmap = XCompositeNameWindowPixmap (dpy, priv->window); - - /* Possible improvement: combine with the XGetGeometry in - * clutter_x11_texture_pixmap_set_pixmap() */ - XSync(dpy, False); - - if (clutter_x11_untrap_x_errors ()) - pixmap = None; - } - - g_object_ref (texture); /* guard against unparent */ - g_object_freeze_notify (G_OBJECT (texture)); - - /* FIXME: mapped is always FALSE */ - clutter_x11_texture_pixmap_set_mapped (texture, mapped); - - if (pixmap) - { - clutter_x11_texture_pixmap_set_pixmap (texture, pixmap); - priv->owns_pixmap = TRUE; - } - - 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_thaw_notify (G_OBJECT (texture)); - g_object_unref (texture); -} - -/** - * clutter_x11_texture_pixmap_sync_window: - * @texture: the texture to bind - * - * Resets the texture's pixmap from its window, perhaps in response to the - * pixmap's invalidation as the window changed size. - * - * Since: 0.8 - */ -void -clutter_x11_texture_pixmap_sync_window (ClutterX11TexturePixmap *texture) -{ - ClutterX11TexturePixmapPrivate *priv; - - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - priv = texture->priv; - - if (priv->destroyed) - return; - - if (priv->window != None) - { - Display *dpy = clutter_x11_get_default_display (); - XWindowAttributes attr; - Status status; - - if (dpy == NULL) - return; - - clutter_x11_trap_x_errors (); - - status = XGetWindowAttributes (dpy, priv->window, &attr); - if (status != 0) - clutter_x11_texture_pixmap_sync_window_internal (texture, - attr.x, attr.y, - attr.width, attr.height, - attr.override_redirect); - - clutter_x11_untrap_x_errors (); - } -} - -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: - * @texture: The texture whose content shall be updated. - * @x: the X coordinate of the area to update - * @y: the Y coordinate of the area to update - * @width: the width of the area to update - * @height: the height of the area to update - * - * Performs the actual binding of texture to the current content of - * the pixmap. Can be called to update the texture if the pixmap - * content has changed. - * - * Since: 0.8 - **/ -void -clutter_x11_texture_pixmap_update_area (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height) -{ - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - g_signal_emit (texture, signals[UPDATE_AREA], 0, x, y, width, height); - - /* The default handler for the "queue-damage-redraw" signal is - * clutter_x11_texture_pixmap_real_queue_damage_redraw which will queue a - * clipped redraw. */ - g_signal_emit (texture, signals[QUEUE_DAMAGE_REDRAW], - 0, x, y, width, height); -} - -/** - * clutter_x11_texture_pixmap_set_automatic: - * @texture: a #ClutterX11TexturePixmap - * @setting: %TRUE to enable automatic updates - * - * Enables or disables the automatic updates ot @texture in case the backing - * pixmap or window is damaged - * - * Since: 0.8 - */ -void -clutter_x11_texture_pixmap_set_automatic (ClutterX11TexturePixmap *texture, - gboolean setting) -{ - ClutterX11TexturePixmapPrivate *priv; - - g_return_if_fail (CLUTTER_X11_IS_TEXTURE_PIXMAP (texture)); - - priv = texture->priv; - - setting = !!setting; - if (setting == priv->automatic_updates) - return; - - if (setting) - create_damage_resources (texture); - else - free_damage_resources (texture); - - priv->automatic_updates = setting; -} diff --git a/clutter/clutter/x11/clutter-x11-texture-pixmap.h b/clutter/clutter/x11/clutter-x11-texture-pixmap.h deleted file mode 100644 index 4b2e894b4..000000000 --- a/clutter/clutter/x11/clutter-x11-texture-pixmap.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Johan Bilien - * - * Copyright (C) 2007 OpenedHand - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * - */ - -#ifndef __CLUTTER_X11_TEXTURE_PIXMAP_H__ -#define __CLUTTER_X11_TEXTURE_PIXMAP_H__ - -#include -#include -#include - -#include - -G_BEGIN_DECLS - -#define CLUTTER_X11_TYPE_TEXTURE_PIXMAP (clutter_x11_texture_pixmap_get_type ()) -#define CLUTTER_X11_TEXTURE_PIXMAP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_X11_TYPE_TEXTURE_PIXMAP, ClutterX11TexturePixmap)) -#define CLUTTER_X11_TEXTURE_PIXMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_X11_TYPE_TEXTURE_PIXMAP, ClutterX11TexturePixmapClass)) -#define CLUTTER_X11_IS_TEXTURE_PIXMAP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_X11_TYPE_TEXTURE_PIXMAP)) -#define CLUTTER_X11_IS_TEXTURE_PIXMAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_X11_TYPE_TEXTURE_PIXMAP)) -#define CLUTTER_X11_TEXTURE_PIXMAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_X11_TYPE_TEXTURE_PIXMAP, ClutterX11TexturePixmapClass)) - -typedef struct _ClutterX11TexturePixmap ClutterX11TexturePixmap; -typedef struct _ClutterX11TexturePixmapClass ClutterX11TexturePixmapClass; -typedef struct _ClutterX11TexturePixmapPrivate ClutterX11TexturePixmapPrivate; - -/** - * ClutterX11TexturePixmap: - * - * The #ClutterX11TexturePixmap structure contains only private data - * - * Since: 0.8 - */ -struct _ClutterX11TexturePixmap -{ - /*< private >*/ - ClutterTexture parent; - - ClutterX11TexturePixmapPrivate *priv; -}; - -/** - * ClutterX11TexturePixmapClass: - * @update_area: virtual function for updating the area of the texture - * - * The #ClutterX11TexturePixmapClass structure contains only private data - * - * Since: 0.8 - */ -struct _ClutterX11TexturePixmapClass -{ - /*< private >*/ - ClutterTextureClass parent_class; - - /*< public >*/ - void (* update_area) (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height); -}; - -CLUTTER_EXPORT -GType clutter_x11_texture_pixmap_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterActor *clutter_x11_texture_pixmap_new (void); -CLUTTER_EXPORT -ClutterActor *clutter_x11_texture_pixmap_new_with_pixmap (Pixmap pixmap); -CLUTTER_EXPORT -ClutterActor *clutter_x11_texture_pixmap_new_with_window (Window window); - -CLUTTER_EXPORT -void clutter_x11_texture_pixmap_set_automatic (ClutterX11TexturePixmap *texture, - gboolean setting); -CLUTTER_EXPORT -void clutter_x11_texture_pixmap_set_pixmap (ClutterX11TexturePixmap *texture, - Pixmap pixmap); -CLUTTER_EXPORT -void clutter_x11_texture_pixmap_set_window (ClutterX11TexturePixmap *texture, - Window window, - gboolean automatic); - -CLUTTER_EXPORT -void clutter_x11_texture_pixmap_sync_window (ClutterX11TexturePixmap *texture); -CLUTTER_EXPORT -void clutter_x11_texture_pixmap_update_area (ClutterX11TexturePixmap *texture, - gint x, - gint y, - gint width, - gint height); - -G_END_DECLS - -#endif diff --git a/clutter/clutter/x11/clutter-x11.h b/clutter/clutter/x11/clutter-x11.h index b0c3932bf..6c622c6b0 100644 --- a/clutter/clutter/x11/clutter-x11.h +++ b/clutter/clutter/x11/clutter-x11.h @@ -42,7 +42,6 @@ #include #include #include -#include G_BEGIN_DECLS