2010-11-14 12:37:17 -05:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
/*
|
|
|
|
* meta-background-actor.c: Actor for painting the root window background
|
|
|
|
*
|
|
|
|
* Copyright 2009 Sander Dijkhuis
|
|
|
|
* Copyright 2010 Red Hat, Inc.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* Portions adapted from gnome-shell/src/shell-global.c
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <cogl/cogl-texture-pixmap-x11.h>
|
|
|
|
|
2012-02-21 11:31:53 -05:00
|
|
|
#include <clutter/clutter.h>
|
|
|
|
|
2010-11-14 12:37:17 -05:00
|
|
|
#include <X11/Xatom.h>
|
|
|
|
|
|
|
|
#include "cogl-utils.h"
|
|
|
|
#include "compositor-private.h"
|
2011-03-05 19:29:12 -05:00
|
|
|
#include <meta/errors.h>
|
2013-01-23 15:54:41 -05:00
|
|
|
#include <meta/meta-background.h>
|
2011-08-28 21:20:29 -04:00
|
|
|
#include "meta-background-actor-private.h"
|
2010-11-14 12:37:17 -05:00
|
|
|
|
2011-08-28 21:20:29 -04:00
|
|
|
struct _MetaBackgroundActorPrivate
|
2010-11-14 12:37:17 -05:00
|
|
|
{
|
|
|
|
cairo_region_t *visible_region;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_background_actor_dispose (GObject *object)
|
|
|
|
{
|
|
|
|
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
|
|
|
|
|
|
|
|
meta_background_actor_set_visible_region (self, NULL);
|
|
|
|
|
2012-02-16 15:53:21 -05:00
|
|
|
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
|
2010-11-14 12:37:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_background_actor_get_preferred_width (ClutterActor *actor,
|
|
|
|
gfloat for_height,
|
|
|
|
gfloat *min_width_p,
|
|
|
|
gfloat *natural_width_p)
|
|
|
|
{
|
2013-01-23 15:54:41 -05:00
|
|
|
ClutterContent *content;
|
|
|
|
gfloat width;
|
|
|
|
|
|
|
|
content = clutter_actor_get_content (actor);
|
2010-11-14 12:37:17 -05:00
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
if (content)
|
|
|
|
clutter_content_get_preferred_size (content, &width, NULL);
|
|
|
|
else
|
|
|
|
width = 0;
|
2010-11-14 12:37:17 -05:00
|
|
|
|
|
|
|
if (min_width_p)
|
|
|
|
*min_width_p = width;
|
|
|
|
if (natural_width_p)
|
2011-08-28 22:03:57 -04:00
|
|
|
*natural_width_p = width;
|
2010-11-14 12:37:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_background_actor_get_preferred_height (ClutterActor *actor,
|
|
|
|
gfloat for_width,
|
|
|
|
gfloat *min_height_p,
|
|
|
|
gfloat *natural_height_p)
|
|
|
|
|
|
|
|
{
|
2013-01-23 15:54:41 -05:00
|
|
|
ClutterContent *content;
|
|
|
|
gfloat height;
|
2010-11-14 12:37:17 -05:00
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
content = clutter_actor_get_content (actor);
|
|
|
|
|
|
|
|
if (content)
|
|
|
|
clutter_content_get_preferred_size (content, NULL, &height);
|
|
|
|
else
|
|
|
|
height = 0;
|
2010-11-14 12:37:17 -05:00
|
|
|
|
|
|
|
if (min_height_p)
|
|
|
|
*min_height_p = height;
|
|
|
|
if (natural_height_p)
|
|
|
|
*natural_height_p = height;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
meta_background_actor_get_paint_volume (ClutterActor *actor,
|
|
|
|
ClutterPaintVolume *volume)
|
|
|
|
{
|
2013-01-23 15:54:41 -05:00
|
|
|
ClutterContent *content;
|
|
|
|
gfloat width, height;
|
|
|
|
|
|
|
|
content = clutter_actor_get_content (actor);
|
2010-11-14 12:37:17 -05:00
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
if (!content)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
clutter_content_get_preferred_size (content, &width, &height);
|
2010-11-14 12:37:17 -05:00
|
|
|
|
|
|
|
clutter_paint_volume_set_width (volume, width);
|
|
|
|
clutter_paint_volume_set_height (volume, height);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
|
|
|
|
2011-08-28 21:20:29 -04:00
|
|
|
g_type_class_add_private (klass, sizeof (MetaBackgroundActorPrivate));
|
|
|
|
|
2010-11-14 12:37:17 -05:00
|
|
|
object_class->dispose = meta_background_actor_dispose;
|
|
|
|
|
|
|
|
actor_class->get_preferred_width = meta_background_actor_get_preferred_width;
|
|
|
|
actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
|
|
|
|
actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-08-26 14:01:00 -04:00
|
|
|
meta_background_actor_init (MetaBackgroundActor *self)
|
2010-11-14 12:37:17 -05:00
|
|
|
{
|
2013-01-23 15:54:41 -05:00
|
|
|
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
|
|
|
META_TYPE_BACKGROUND_ACTOR,
|
|
|
|
MetaBackgroundActorPrivate);
|
2010-11-14 12:37:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_background_actor_new:
|
|
|
|
*
|
2013-01-23 15:54:41 -05:00
|
|
|
* Creates a new actor to draw the background for the given monitor.
|
|
|
|
* This actor should be associated with a #MetaBackground using
|
|
|
|
* clutter_actor_set_content()
|
2010-11-14 12:37:17 -05:00
|
|
|
*
|
2011-08-28 21:20:29 -04:00
|
|
|
* Return value: the newly created background actor
|
2010-11-14 12:37:17 -05:00
|
|
|
*/
|
|
|
|
ClutterActor *
|
2013-01-23 15:54:41 -05:00
|
|
|
meta_background_actor_new (void)
|
2010-11-14 12:37:17 -05:00
|
|
|
{
|
|
|
|
MetaBackgroundActor *self;
|
|
|
|
|
|
|
|
self = g_object_new (META_TYPE_BACKGROUND_ACTOR, NULL);
|
|
|
|
|
|
|
|
return CLUTTER_ACTOR (self);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* meta_background_actor_set_visible_region:
|
|
|
|
* @self: a #MetaBackgroundActor
|
|
|
|
* @visible_region: (allow-none): the area of the actor (in allocate-relative
|
|
|
|
* coordinates) that is visible.
|
|
|
|
*
|
|
|
|
* Sets the area of the background that is unobscured by overlapping windows.
|
|
|
|
* This is used to optimize and only paint the visible portions.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
meta_background_actor_set_visible_region (MetaBackgroundActor *self,
|
|
|
|
cairo_region_t *visible_region)
|
|
|
|
{
|
2011-08-28 21:20:29 -04:00
|
|
|
MetaBackgroundActorPrivate *priv;
|
|
|
|
|
2010-11-14 12:37:17 -05:00
|
|
|
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
|
|
|
|
|
2011-08-28 21:20:29 -04:00
|
|
|
priv = self->priv;
|
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
g_clear_pointer (&priv->visible_region,
|
|
|
|
(GDestroyNotify)
|
|
|
|
cairo_region_destroy);
|
2010-11-14 12:37:17 -05:00
|
|
|
|
|
|
|
if (visible_region)
|
2013-01-23 15:54:41 -05:00
|
|
|
priv->visible_region = cairo_region_copy (visible_region);
|
2010-11-15 16:19:28 -05:00
|
|
|
}
|
2012-08-29 19:45:17 -04:00
|
|
|
|
|
|
|
/**
|
2013-01-23 15:54:41 -05:00
|
|
|
* meta_background_actor_get_visible_region:
|
|
|
|
* @self: a #MetaBackgroundActor
|
2012-08-29 19:45:17 -04:00
|
|
|
*
|
2013-01-23 15:54:41 -05:00
|
|
|
* Return value (transfer full): a #cairo_region_t that represents the part of
|
|
|
|
* the background not obscured by other #MetaBackgroundActor or
|
|
|
|
* #MetaWindowActor objects.
|
2012-08-29 19:45:17 -04:00
|
|
|
*/
|
2013-01-23 15:54:41 -05:00
|
|
|
cairo_region_t *
|
|
|
|
meta_background_actor_get_visible_region (MetaBackgroundActor *self)
|
2012-08-29 19:45:17 -04:00
|
|
|
{
|
2013-01-23 15:54:41 -05:00
|
|
|
MetaBackgroundActorPrivate *priv = self->priv;
|
|
|
|
ClutterActorBox content_box;
|
|
|
|
cairo_rectangle_int_t content_area = { 0 };
|
|
|
|
cairo_region_t *visible_region;
|
2012-08-29 19:45:17 -04:00
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
g_return_val_if_fail (META_IS_BACKGROUND_ACTOR (self), NULL);
|
2012-08-29 19:45:17 -04:00
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
if (!priv->visible_region)
|
|
|
|
return NULL;
|
2012-11-07 13:00:25 -05:00
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
clutter_actor_get_content_box (CLUTTER_ACTOR (self), &content_box);
|
2012-11-07 13:00:25 -05:00
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
content_area.x = content_box.x1;
|
|
|
|
content_area.y = content_box.y1;
|
|
|
|
content_area.width = content_box.x2 - content_box.x1;
|
|
|
|
content_area.height = content_box.y2 - content_box.y1;
|
2012-11-07 13:00:25 -05:00
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
visible_region = cairo_region_create_rectangle (&content_area);
|
|
|
|
cairo_region_intersect (visible_region, priv->visible_region);
|
2012-11-07 13:00:25 -05:00
|
|
|
|
2013-01-23 15:54:41 -05:00
|
|
|
return visible_region;
|
2012-11-07 13:00:25 -05:00
|
|
|
}
|