mutter/src/backends/meta-cursor.c
Robert Mader 1fc7935858 backends/cursor: Add API to set and get the texture buffer transform
In Wayland clients can commit transformed surfaces, so the compositor
can directly use them on hardware planes. We already support that
for other surfaces, this is the first step to also support it on
cursor sprites.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/526
2020-02-28 10:22:11 +00:00

224 lines
6.1 KiB
C

/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright 2013 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, see <http://www.gnu.org/licenses/>.
*
* Author: Giovanni Campagna <gcampagn@redhat.com>
*/
#include "config.h"
#include "backends/meta-cursor.h"
#include "backends/meta-backend-private.h"
#include "cogl/cogl.h"
#include "meta/common.h"
enum
{
PREPARE_AT,
TEXTURE_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
typedef struct _MetaCursorSpritePrivate
{
GObject parent;
CoglTexture2D *texture;
float texture_scale;
MetaMonitorTransform texture_transform;
int hot_x, hot_y;
} MetaCursorSpritePrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCursorSprite,
meta_cursor_sprite,
G_TYPE_OBJECT)
gboolean
meta_cursor_sprite_is_animated (MetaCursorSprite *sprite)
{
MetaCursorSpriteClass *klass = META_CURSOR_SPRITE_GET_CLASS (sprite);
if (klass->is_animated)
return klass->is_animated (sprite);
else
return FALSE;
}
void
meta_cursor_sprite_tick_frame (MetaCursorSprite *sprite)
{
return META_CURSOR_SPRITE_GET_CLASS (sprite)->tick_frame (sprite);
}
unsigned int
meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *sprite)
{
return META_CURSOR_SPRITE_GET_CLASS (sprite)->get_current_frame_time (sprite);
}
void
meta_cursor_sprite_clear_texture (MetaCursorSprite *sprite)
{
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
g_clear_pointer (&priv->texture, cogl_object_unref);
}
void
meta_cursor_sprite_set_texture (MetaCursorSprite *sprite,
CoglTexture *texture,
int hot_x,
int hot_y)
{
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
g_clear_pointer (&priv->texture, cogl_object_unref);
if (texture)
priv->texture = cogl_object_ref (texture);
priv->hot_x = hot_x;
priv->hot_y = hot_y;
g_signal_emit (sprite, signals[TEXTURE_CHANGED], 0);
}
void
meta_cursor_sprite_set_texture_scale (MetaCursorSprite *sprite,
float scale)
{
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
priv->texture_scale = scale;
}
void
meta_cursor_sprite_set_texture_transform (MetaCursorSprite *sprite,
MetaMonitorTransform transform)
{
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
priv->texture_transform = transform;
}
CoglTexture *
meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *sprite)
{
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
return COGL_TEXTURE (priv->texture);
}
void
meta_cursor_sprite_get_hotspot (MetaCursorSprite *sprite,
int *hot_x,
int *hot_y)
{
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
*hot_x = priv->hot_x;
*hot_y = priv->hot_y;
}
float
meta_cursor_sprite_get_texture_scale (MetaCursorSprite *sprite)
{
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
return priv->texture_scale;
}
MetaMonitorTransform
meta_cursor_sprite_get_texture_transform (MetaCursorSprite *sprite)
{
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
return priv->texture_transform;
}
void
meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
int x,
int y)
{
g_signal_emit (sprite, signals[PREPARE_AT], 0, x, y);
}
void
meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite)
{
MetaCursorSpriteClass *klass = META_CURSOR_SPRITE_GET_CLASS (sprite);
if (klass->realize_texture)
klass->realize_texture (sprite);
}
static void
meta_cursor_sprite_init (MetaCursorSprite *sprite)
{
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
priv->texture_scale = 1.0f;
priv->texture_transform = META_MONITOR_TRANSFORM_NORMAL;
}
static void
meta_cursor_sprite_finalize (GObject *object)
{
MetaCursorSprite *sprite = META_CURSOR_SPRITE (object);
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
g_clear_pointer (&priv->texture, cogl_object_unref);
G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object);
}
static void
meta_cursor_sprite_class_init (MetaCursorSpriteClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_cursor_sprite_finalize;
signals[PREPARE_AT] = g_signal_new ("prepare-at",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 2,
G_TYPE_INT,
G_TYPE_INT);
signals[TEXTURE_CHANGED] = g_signal_new ("texture-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}