diff --git a/src/Makefile.am b/src/Makefile.am index bfc2a7fa0..1544f1482 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -105,6 +105,8 @@ metacity_SOURCES= \ if WITH_CLUTTER metacity_SOURCES += compositor/compositor-clutter.c \ compositor/compositor-clutter.h \ + compositor/tidy-texture-frame.c \ + compositor/tidy-texture-frame.h \ compositor/shaped-texture.c \ compositor/shaped-texture.h \ include/compositor-clutter-plugin.h \ diff --git a/src/compositor/compositor-clutter.c b/src/compositor/compositor-clutter.c index bdee11bf4..e1ca7dff5 100644 --- a/src/compositor/compositor-clutter.c +++ b/src/compositor/compositor-clutter.c @@ -2518,376 +2518,4 @@ shadow_gaussian_make_tile () return data; } -#define TIDY_TYPE_TEXTURE_FRAME (tidy_texture_frame_get_type ()) -#define TIDY_TEXTURE_FRAME(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrame)) - -#define TIDY_TEXTURE_FRAME_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass)) - -#define TIDY_IS_TEXTURE_FRAME(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - TIDY_TYPE_TEXTURE_FRAME)) - -#define TIDY_IS_TEXTURE_FRAME_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - TIDY_TYPE_TEXTURE_FRAME)) - -#define TIDY_TEXTURE_FRAME_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass)) - -typedef struct _TidyTextureFrame TidyTextureFrame; -typedef struct _TidyTextureFramePrivate TidyTextureFramePrivate; -typedef struct _TidyTextureFrameClass TidyTextureFrameClass; - -struct _TidyTextureFrame -{ - ClutterCloneTexture parent; - - /*< priv >*/ - TidyTextureFramePrivate *priv; -}; - -struct _TidyTextureFrameClass -{ - ClutterCloneTextureClass parent_class; - - /* padding for future expansion */ - void (*_clutter_box_1) (void); - void (*_clutter_box_2) (void); - void (*_clutter_box_3) (void); - void (*_clutter_box_4) (void); -}; - -GType tidy_texture_frame_get_type (void) G_GNUC_CONST; - -#define TIDY_PARAM_READABLE \ - (G_PARAM_READABLE | \ - G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB) - -#define TIDY_PARAM_READWRITE \ - (G_PARAM_READABLE | G_PARAM_WRITABLE | \ - G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB) - - -enum -{ - PROP_0, - PROP_LEFT, - PROP_TOP, - PROP_RIGHT, - PROP_BOTTOM -}; - -G_DEFINE_TYPE (TidyTextureFrame, - tidy_texture_frame, - CLUTTER_TYPE_CLONE_TEXTURE); - -#define TIDY_TEXTURE_FRAME_GET_PRIVATE(obj) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFramePrivate)) - -struct _TidyTextureFramePrivate -{ - gint left, top, right, bottom; -}; - -static void -tidy_texture_frame_paint (ClutterActor *self) -{ - TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv; - ClutterCloneTexture *clone_texture = CLUTTER_CLONE_TEXTURE (self); - ClutterTexture *parent_texture; - guint width, height; - guint tex_width, tex_height; - guint ex, ey; - ClutterFixed tx1, ty1, tx2, ty2; - ClutterColor col = { 0xff, 0xff, 0xff, 0xff }; - CoglHandle cogl_texture; - - priv = TIDY_TEXTURE_FRAME (self)->priv; - - /* no need to paint stuff if we don't have a texture */ - parent_texture = clutter_clone_texture_get_parent_texture (clone_texture); - if (!parent_texture) - return; - - /* parent texture may have been hidden, so need to make sure it gets - * realized - */ - if (!CLUTTER_ACTOR_IS_REALIZED (parent_texture)) - clutter_actor_realize (CLUTTER_ACTOR (parent_texture)); - - cogl_texture = clutter_texture_get_cogl_texture (parent_texture); - if (cogl_texture == COGL_INVALID_HANDLE) - return; - - cogl_push_matrix (); - - tex_width = cogl_texture_get_width (cogl_texture); - tex_height = cogl_texture_get_height (cogl_texture); - - clutter_actor_get_size (self, &width, &height); - - tx1 = CLUTTER_INT_TO_FIXED (priv->left) / tex_width; - tx2 = CLUTTER_INT_TO_FIXED (tex_width - priv->right) / tex_width; - ty1 = CLUTTER_INT_TO_FIXED (priv->top) / tex_height; - ty2 = CLUTTER_INT_TO_FIXED (tex_height - priv->bottom) / tex_height; - - col.alpha = clutter_actor_get_paint_opacity (self); - cogl_color (&col); - - ex = width - priv->right; - if (ex < 0) - ex = priv->right; /* FIXME ? */ - - ey = height - priv->bottom; - if (ey < 0) - ey = priv->bottom; /* FIXME ? */ - -#define FX(x) CLUTTER_INT_TO_FIXED(x) - - /* top left corner */ - cogl_texture_rectangle (cogl_texture, - 0, - 0, - FX(priv->left), /* FIXME: clip if smaller */ - FX(priv->top), - 0, - 0, - tx1, - ty1); - - /* top middle */ - cogl_texture_rectangle (cogl_texture, - FX(priv->left), - FX(priv->top), - FX(ex), - 0, - tx1, - 0, - tx2, - ty1); - - /* top right */ - cogl_texture_rectangle (cogl_texture, - FX(ex), - 0, - FX(width), - FX(priv->top), - tx2, - 0, - CFX_ONE, - ty1); - - /* mid left */ - cogl_texture_rectangle (cogl_texture, - 0, - FX(priv->top), - FX(priv->left), - FX(ey), - 0, - ty1, - tx1, - ty2); - - /* center */ - cogl_texture_rectangle (cogl_texture, - FX(priv->left), - FX(priv->top), - FX(ex), - FX(ey), - tx1, - ty1, - tx2, - ty2); - - /* mid right */ - cogl_texture_rectangle (cogl_texture, - FX(ex), - FX(priv->top), - FX(width), - FX(ey), - tx2, - ty1, - CFX_ONE, - ty2); - - /* bottom left */ - cogl_texture_rectangle (cogl_texture, - 0, - FX(ey), - FX(priv->left), - FX(height), - 0, - ty2, - tx1, - CFX_ONE); - - /* bottom center */ - cogl_texture_rectangle (cogl_texture, - FX(priv->left), - FX(ey), - FX(ex), - FX(height), - tx1, - ty2, - tx2, - CFX_ONE); - - /* bottom right */ - cogl_texture_rectangle (cogl_texture, - FX(ex), - FX(ey), - FX(width), - FX(height), - tx2, - ty2, - CFX_ONE, - CFX_ONE); - - - cogl_pop_matrix (); -} - - -static void -tidy_texture_frame_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - TidyTextureFrame *ctexture = TIDY_TEXTURE_FRAME (object); - TidyTextureFramePrivate *priv = ctexture->priv; - - switch (prop_id) - { - case PROP_LEFT: - priv->left = g_value_get_int (value); - break; - case PROP_TOP: - priv->top = g_value_get_int (value); - break; - case PROP_RIGHT: - priv->right = g_value_get_int (value); - break; - case PROP_BOTTOM: - priv->bottom = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -tidy_texture_frame_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TidyTextureFrame *ctexture = TIDY_TEXTURE_FRAME (object); - TidyTextureFramePrivate *priv = ctexture->priv; - - switch (prop_id) - { - case PROP_LEFT: - g_value_set_int (value, priv->left); - break; - case PROP_TOP: - g_value_set_int (value, priv->top); - break; - case PROP_RIGHT: - g_value_set_int (value, priv->right); - break; - case PROP_BOTTOM: - g_value_set_int (value, priv->bottom); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -tidy_texture_frame_class_init (TidyTextureFrameClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); - - actor_class->paint = tidy_texture_frame_paint; - - gobject_class->set_property = tidy_texture_frame_set_property; - gobject_class->get_property = tidy_texture_frame_get_property; - - g_object_class_install_property - (gobject_class, - PROP_LEFT, - g_param_spec_int ("left", - "left", - "", - 0, G_MAXINT, - 0, - TIDY_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_TOP, - g_param_spec_int ("top", - "top", - "", - 0, G_MAXINT, - 0, - TIDY_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_BOTTOM, - g_param_spec_int ("bottom", - "bottom", - "", - 0, G_MAXINT, - 0, - TIDY_PARAM_READWRITE)); - - g_object_class_install_property - (gobject_class, - PROP_RIGHT, - g_param_spec_int ("right", - "right", - "", - 0, G_MAXINT, - 0, - TIDY_PARAM_READWRITE)); - - g_type_class_add_private (gobject_class, sizeof (TidyTextureFramePrivate)); -} - -static void -tidy_texture_frame_init (TidyTextureFrame *self) -{ - TidyTextureFramePrivate *priv; - - self->priv = priv = TIDY_TEXTURE_FRAME_GET_PRIVATE (self); -} - -static ClutterActor* -tidy_texture_frame_new (ClutterTexture *texture, - gint left, - gint top, - gint right, - gint bottom) -{ - g_return_val_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture), NULL); - - return g_object_new (TIDY_TYPE_TEXTURE_FRAME, - "parent-texture", texture, - "left", left, - "top", top, - "right", right, - "bottom", bottom, - NULL); -} diff --git a/src/compositor/tidy-texture-frame.c b/src/compositor/tidy-texture-frame.c new file mode 100644 index 000000000..2b613a7b6 --- /dev/null +++ b/src/compositor/tidy-texture-frame.c @@ -0,0 +1,358 @@ +/* tidy-texture-frame.h: Expandible texture actor + * + * 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:tidy-texture-frame + * @short_description: Stretch a texture to fit the entire allocation + * + * #TidyTextureFrame + * + */ + +#include + +#include "tidy-texture-frame.h" + +#define TIDY_PARAM_READABLE \ + (G_PARAM_READABLE | \ + G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB) + +#define TIDY_PARAM_READWRITE \ + (G_PARAM_READABLE | G_PARAM_WRITABLE | \ + G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB) + +enum +{ + PROP_0, + PROP_LEFT, + PROP_TOP, + PROP_RIGHT, + PROP_BOTTOM +}; + +G_DEFINE_TYPE (TidyTextureFrame, + tidy_texture_frame, + CLUTTER_TYPE_CLONE_TEXTURE); + +#define TIDY_TEXTURE_FRAME_GET_PRIVATE(obj) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFramePrivate)) + +struct _TidyTextureFramePrivate +{ + gint left, top, right, bottom; +}; + +static void +tidy_texture_frame_paint (ClutterActor *self) +{ + TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv; + ClutterCloneTexture *clone_texture = CLUTTER_CLONE_TEXTURE (self); + ClutterTexture *parent_texture; + guint width, height; + guint tex_width, tex_height; + guint ex, ey; + ClutterFixed tx1, ty1, tx2, ty2; + ClutterColor col = { 0xff, 0xff, 0xff, 0xff }; + CoglHandle cogl_texture; + + priv = TIDY_TEXTURE_FRAME (self)->priv; + + /* no need to paint stuff if we don't have a texture */ + parent_texture = clutter_clone_texture_get_parent_texture (clone_texture); + if (!parent_texture) + return; + + /* parent texture may have been hidden, so need to make sure it gets + * realized + */ + if (!CLUTTER_ACTOR_IS_REALIZED (parent_texture)) + clutter_actor_realize (CLUTTER_ACTOR (parent_texture)); + + cogl_texture = clutter_texture_get_cogl_texture (parent_texture); + if (cogl_texture == COGL_INVALID_HANDLE) + return; + + cogl_push_matrix (); + + tex_width = cogl_texture_get_width (cogl_texture); + tex_height = cogl_texture_get_height (cogl_texture); + + clutter_actor_get_size (self, &width, &height); + + tx1 = CLUTTER_INT_TO_FIXED (priv->left) / tex_width; + tx2 = CLUTTER_INT_TO_FIXED (tex_width - priv->right) / tex_width; + ty1 = CLUTTER_INT_TO_FIXED (priv->top) / tex_height; + ty2 = CLUTTER_INT_TO_FIXED (tex_height - priv->bottom) / tex_height; + + col.alpha = clutter_actor_get_paint_opacity (self); + cogl_color (&col); + + ex = width - priv->right; + if (ex < 0) + ex = priv->right; /* FIXME ? */ + + ey = height - priv->bottom; + if (ey < 0) + ey = priv->bottom; /* FIXME ? */ + +#define FX(x) CLUTTER_INT_TO_FIXED(x) + + /* top left corner */ + cogl_texture_rectangle (cogl_texture, + 0, + 0, + FX(priv->left), /* FIXME: clip if smaller */ + FX(priv->top), + 0, + 0, + tx1, + ty1); + + /* top middle */ + cogl_texture_rectangle (cogl_texture, + FX(priv->left), + FX(priv->top), + FX(ex), + 0, + tx1, + 0, + tx2, + ty1); + + /* top right */ + cogl_texture_rectangle (cogl_texture, + FX(ex), + 0, + FX(width), + FX(priv->top), + tx2, + 0, + CFX_ONE, + ty1); + + /* mid left */ + cogl_texture_rectangle (cogl_texture, + 0, + FX(priv->top), + FX(priv->left), + FX(ey), + 0, + ty1, + tx1, + ty2); + + /* center */ + cogl_texture_rectangle (cogl_texture, + FX(priv->left), + FX(priv->top), + FX(ex), + FX(ey), + tx1, + ty1, + tx2, + ty2); + + /* mid right */ + cogl_texture_rectangle (cogl_texture, + FX(ex), + FX(priv->top), + FX(width), + FX(ey), + tx2, + ty1, + CFX_ONE, + ty2); + + /* bottom left */ + cogl_texture_rectangle (cogl_texture, + 0, + FX(ey), + FX(priv->left), + FX(height), + 0, + ty2, + tx1, + CFX_ONE); + + /* bottom center */ + cogl_texture_rectangle (cogl_texture, + FX(priv->left), + FX(ey), + FX(ex), + FX(height), + tx1, + ty2, + tx2, + CFX_ONE); + + /* bottom right */ + cogl_texture_rectangle (cogl_texture, + FX(ex), + FX(ey), + FX(width), + FX(height), + tx2, + ty2, + CFX_ONE, + CFX_ONE); + + + cogl_pop_matrix (); +} + + +static void +tidy_texture_frame_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + TidyTextureFrame *ctexture = TIDY_TEXTURE_FRAME (object); + TidyTextureFramePrivate *priv = ctexture->priv; + + switch (prop_id) + { + case PROP_LEFT: + priv->left = g_value_get_int (value); + break; + case PROP_TOP: + priv->top = g_value_get_int (value); + break; + case PROP_RIGHT: + priv->right = g_value_get_int (value); + break; + case PROP_BOTTOM: + priv->bottom = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +tidy_texture_frame_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + TidyTextureFrame *ctexture = TIDY_TEXTURE_FRAME (object); + TidyTextureFramePrivate *priv = ctexture->priv; + + switch (prop_id) + { + case PROP_LEFT: + g_value_set_int (value, priv->left); + break; + case PROP_TOP: + g_value_set_int (value, priv->top); + break; + case PROP_RIGHT: + g_value_set_int (value, priv->right); + break; + case PROP_BOTTOM: + g_value_set_int (value, priv->bottom); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +tidy_texture_frame_class_init (TidyTextureFrameClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); + + actor_class->paint = tidy_texture_frame_paint; + + gobject_class->set_property = tidy_texture_frame_set_property; + gobject_class->get_property = tidy_texture_frame_get_property; + + g_object_class_install_property + (gobject_class, + PROP_LEFT, + g_param_spec_int ("left", + "left", + "", + 0, G_MAXINT, + 0, + TIDY_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, + PROP_TOP, + g_param_spec_int ("top", + "top", + "", + 0, G_MAXINT, + 0, + TIDY_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, + PROP_BOTTOM, + g_param_spec_int ("bottom", + "bottom", + "", + 0, G_MAXINT, + 0, + TIDY_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, + PROP_RIGHT, + g_param_spec_int ("right", + "right", + "", + 0, G_MAXINT, + 0, + TIDY_PARAM_READWRITE)); + + g_type_class_add_private (gobject_class, sizeof (TidyTextureFramePrivate)); +} + +static void +tidy_texture_frame_init (TidyTextureFrame *self) +{ + TidyTextureFramePrivate *priv; + + self->priv = priv = TIDY_TEXTURE_FRAME_GET_PRIVATE (self); +} + +ClutterActor * +tidy_texture_frame_new (ClutterTexture *texture, + gint left, + gint top, + gint right, + gint bottom) +{ + g_return_val_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture), NULL); + + return g_object_new (TIDY_TYPE_TEXTURE_FRAME, + "parent-texture", texture, + "left", left, + "top", top, + "right", right, + "bottom", bottom, + NULL); +} + diff --git a/src/compositor/tidy-texture-frame.h b/src/compositor/tidy-texture-frame.h new file mode 100644 index 000000000..e28432a2c --- /dev/null +++ b/src/compositor/tidy-texture-frame.h @@ -0,0 +1,82 @@ +/* tidy-texture-frame.h: Expandible texture actor + * + * 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, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _HAVE_TIDY_TEXTURE_FRAME_H +#define _HAVE_TIDY_TEXTURE_FRAME_H + +#include + +G_BEGIN_DECLS + +#define TIDY_TYPE_TEXTURE_FRAME (tidy_texture_frame_get_type ()) + +#define TIDY_TEXTURE_FRAME(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrame)) + +#define TIDY_TEXTURE_FRAME_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), \ + TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass)) + +#define TIDY_IS_TEXTURE_FRAME(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + TIDY_TYPE_TEXTURE_FRAME)) + +#define TIDY_IS_TEXTURE_FRAME_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + TIDY_TYPE_TEXTURE_FRAME)) + +#define TIDY_TEXTURE_FRAME_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass)) + +typedef struct _TidyTextureFrame TidyTextureFrame; +typedef struct _TidyTextureFramePrivate TidyTextureFramePrivate; +typedef struct _TidyTextureFrameClass TidyTextureFrameClass; + +struct _TidyTextureFrame +{ + ClutterCloneTexture parent; + + /*< priv >*/ + TidyTextureFramePrivate *priv; +}; + +struct _TidyTextureFrameClass +{ + ClutterCloneTextureClass parent_class; + + /* padding for future expansion */ + void (*_clutter_box_1) (void); + void (*_clutter_box_2) (void); + void (*_clutter_box_3) (void); + void (*_clutter_box_4) (void); +}; + +GType tidy_texture_frame_get_type (void) G_GNUC_CONST; +ClutterActor *tidy_texture_frame_new (ClutterTexture *texture, + gint left, + gint top, + gint right, + gint bottom); + +G_END_DECLS + +#endif /* _HAVE_TIDY_TEXTURE_FRAME_H */