hw-cursor-on-demand-gnome-3-28.patch

This commit is contained in:
Ray Strode 2019-02-11 13:40:04 -05:00
parent dcfaf95ff4
commit ac1dcec926
23 changed files with 386 additions and 1078 deletions

View File

@ -114,6 +114,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/meta-cursor-tracker-private.h \ backends/meta-cursor-tracker-private.h \
backends/meta-cursor-renderer.c \ backends/meta-cursor-renderer.c \
backends/meta-cursor-renderer.h \ backends/meta-cursor-renderer.h \
backends/meta-cursor-sprite-xcursor.c \
backends/meta-cursor-sprite-xcursor.h \
backends/meta-dnd-private.h \ backends/meta-dnd-private.h \
backends/meta-egl.c \ backends/meta-egl.c \
backends/meta-egl.h \ backends/meta-egl.h \
@ -176,6 +178,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/x11/meta-gpu-xrandr.h \ backends/x11/meta-gpu-xrandr.h \
backends/x11/cm/meta-backend-x11-cm.c \ backends/x11/cm/meta-backend-x11-cm.c \
backends/x11/cm/meta-backend-x11-cm.h \ backends/x11/cm/meta-backend-x11-cm.h \
backends/x11/cm/meta-cursor-sprite-xfixes.c \
backends/x11/cm/meta-cursor-sprite-xfixes.h \
backends/x11/cm/meta-renderer-x11-cm.c \ backends/x11/cm/meta-renderer-x11-cm.c \
backends/x11/cm/meta-renderer-x11-cm.h \ backends/x11/cm/meta-renderer-x11-cm.h \
backends/x11/nested/meta-backend-x11-nested.c \ backends/x11/nested/meta-backend-x11-nested.c \
@ -370,6 +374,8 @@ if HAVE_WAYLAND
libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES += \ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES += \
compositor/meta-surface-actor-wayland.c \ compositor/meta-surface-actor-wayland.c \
compositor/meta-surface-actor-wayland.h \ compositor/meta-surface-actor-wayland.h \
wayland/meta-cursor-sprite-wayland.c \
wayland/meta-cursor-sprite-wayland.h \
wayland/meta-wayland.c \ wayland/meta-wayland.c \
wayland/meta-wayland.h \ wayland/meta-wayland.h \
wayland/meta-wayland-private.h \ wayland/meta-wayland-private.h \
@ -431,10 +437,10 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES += \
wayland/meta-wayland-touch.h \ wayland/meta-wayland-touch.h \
wayland/meta-wayland-surface.c \ wayland/meta-wayland-surface.c \
wayland/meta-wayland-surface.h \ wayland/meta-wayland-surface.h \
wayland/meta-wayland-surface-role-cursor.c \ wayland/meta-wayland-cursor-surface.c \
wayland/meta-wayland-surface-role-cursor.h \ wayland/meta-wayland-cursor-surface.h \
wayland/meta-wayland-surface-role-tablet-cursor.c \ wayland/meta-wayland-tablet-cursor-surface.c \
wayland/meta-wayland-surface-role-tablet-cursor.h \ wayland/meta-wayland-tablet-cursor-surface.h \
wayland/meta-wayland-actor-surface.c \ wayland/meta-wayland-actor-surface.c \
wayland/meta-wayland-actor-surface.h \ wayland/meta-wayland-actor-surface.h \
wayland/meta-wayland-subsurface.c \ wayland/meta-wayland-subsurface.c \

View File

@ -193,7 +193,7 @@ meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
} }
static void static void
update_cursor (MetaCursorRenderer *renderer, meta_cursor_renderer_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite) MetaCursorSprite *cursor_sprite)
{ {
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
@ -237,7 +237,7 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
return; return;
priv->displayed_cursor = cursor_sprite; priv->displayed_cursor = cursor_sprite;
update_cursor (renderer, cursor_sprite); meta_cursor_renderer_update_cursor (renderer, cursor_sprite);
} }
void void
@ -246,7 +246,7 @@ meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
MetaCursorRendererPrivate *priv = MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer); meta_cursor_renderer_get_instance_private (renderer);
update_cursor (renderer, priv->displayed_cursor); meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor);
} }
void void
@ -261,7 +261,7 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
priv->current_x = x; priv->current_x = x;
priv->current_y = y; priv->current_y = y;
update_cursor (renderer, priv->displayed_cursor); meta_cursor_renderer_update_cursor (renderer, priv->displayed_cursor);
} }
ClutterPoint ClutterPoint
@ -283,28 +283,3 @@ meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
return priv->displayed_cursor; return priv->displayed_cursor;
} }
#ifdef HAVE_WAYLAND
void
meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
struct wl_resource *buffer)
{
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
if (renderer_class->realize_cursor_from_wl_buffer)
renderer_class->realize_cursor_from_wl_buffer (renderer, cursor_sprite, buffer);
}
#endif
void
meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
XcursorImage *xc_image)
{
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
if (renderer_class->realize_cursor_from_xcursor)
renderer_class->realize_cursor_from_xcursor (renderer, cursor_sprite, xc_image);
}

View File

@ -26,10 +26,6 @@
#define META_CURSOR_RENDERER_H #define META_CURSOR_RENDERER_H
#include <glib-object.h> #include <glib-object.h>
#include <X11/Xcursor/Xcursor.h>
#ifdef HAVE_WAYLAND
#include <wayland-server.h>
#endif
#include <meta/screen.h> #include <meta/screen.h>
#include "meta-cursor.h" #include "meta-cursor.h"
@ -44,14 +40,6 @@ struct _MetaCursorRendererClass
gboolean (* update_cursor) (MetaCursorRenderer *renderer, gboolean (* update_cursor) (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite); MetaCursorSprite *cursor_sprite);
#ifdef HAVE_WAYLAND
void (* realize_cursor_from_wl_buffer) (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
struct wl_resource *buffer);
#endif
void (* realize_cursor_from_xcursor) (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
XcursorImage *xc_image);
}; };
MetaCursorRenderer * meta_cursor_renderer_new (void); MetaCursorRenderer * meta_cursor_renderer_new (void);
@ -70,16 +58,6 @@ MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer
ClutterRect meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer, ClutterRect meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite); MetaCursorSprite *cursor_sprite);
#ifdef HAVE_WAYLAND
void meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
struct wl_resource *buffer);
#endif
void meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
XcursorImage *xc_image);
void meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer, void meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite); MetaCursorSprite *cursor_sprite);

View File

@ -26,6 +26,7 @@
#include "meta-cursor.h" #include "meta-cursor.h"
#include "meta-cursor-renderer.h" #include "meta-cursor-renderer.h"
#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
struct _MetaCursorTracker { struct _MetaCursorTracker {
GObject parent_instance; GObject parent_instance;
@ -46,7 +47,7 @@ struct _MetaCursorTracker {
MetaCursorSprite *root_cursor; MetaCursorSprite *root_cursor;
/* The cursor from the X11 server. */ /* The cursor from the X11 server. */
MetaCursorSprite *xfixes_cursor; MetaCursorSpriteXfixes *xfixes_cursor;
}; };
struct _MetaCursorTrackerClass { struct _MetaCursorTrackerClass {

View File

@ -40,9 +40,9 @@
#include <gdk/gdk.h> #include <gdk/gdk.h>
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#include <X11/extensions/Xfixes.h>
#include "meta-backend-private.h" #include "meta-backend-private.h"
#include "backends/x11/cm/meta-cursor-sprite-xfixes.h"
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT); G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
@ -218,75 +218,14 @@ static void
ensure_xfixes_cursor (MetaCursorTracker *tracker) ensure_xfixes_cursor (MetaCursorTracker *tracker)
{ {
MetaDisplay *display = meta_get_display (); MetaDisplay *display = meta_get_display ();
XFixesCursorImage *cursor_image; g_autoptr (GError) error = NULL;
CoglTexture2D *sprite;
guint8 *cursor_data;
gboolean free_cursor_data;
CoglContext *ctx;
CoglError *error = NULL;
if (tracker->xfixes_cursor) if (tracker->xfixes_cursor)
return; return;
cursor_image = XFixesGetCursorImage (display->xdisplay); tracker->xfixes_cursor = meta_cursor_sprite_xfixes_new (display, &error);
if (!cursor_image) if (!tracker->xfixes_cursor)
return; g_warning ("Failed to create XFIXES cursor: %s", error->message);
/* Like all X APIs, XFixesGetCursorImage() returns arrays of 32-bit
* quantities as arrays of long; we need to convert on 64 bit */
if (sizeof(long) == 4)
{
cursor_data = (guint8 *)cursor_image->pixels;
free_cursor_data = FALSE;
}
else
{
int i, j;
guint32 *cursor_words;
gulong *p;
guint32 *q;
cursor_words = g_new (guint32, cursor_image->width * cursor_image->height);
cursor_data = (guint8 *)cursor_words;
p = cursor_image->pixels;
q = cursor_words;
for (j = 0; j < cursor_image->height; j++)
for (i = 0; i < cursor_image->width; i++)
*(q++) = *(p++);
free_cursor_data = TRUE;
}
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
sprite = cogl_texture_2d_new_from_data (ctx,
cursor_image->width,
cursor_image->height,
CLUTTER_CAIRO_FORMAT_ARGB32,
cursor_image->width * 4, /* stride */
cursor_data,
&error);
if (free_cursor_data)
g_free (cursor_data);
if (error != NULL)
{
meta_warning ("Failed to allocate cursor sprite texture: %s\n", error->message);
cogl_error_free (error);
}
if (sprite != NULL)
{
MetaCursorSprite *cursor_sprite = meta_cursor_sprite_new ();
meta_cursor_sprite_set_texture (cursor_sprite,
COGL_TEXTURE (sprite),
cursor_image->xhot,
cursor_image->yhot);
cogl_object_unref (sprite);
tracker->xfixes_cursor = cursor_sprite;
}
XFree (cursor_image);
} }
/** /**
@ -308,7 +247,7 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
else else
{ {
ensure_xfixes_cursor (tracker); ensure_xfixes_cursor (tracker);
cursor_sprite = tracker->xfixes_cursor; cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor);
} }
if (cursor_sprite) if (cursor_sprite)
@ -345,7 +284,7 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
else else
{ {
ensure_xfixes_cursor (tracker); ensure_xfixes_cursor (tracker);
cursor_sprite = tracker->xfixes_cursor; cursor_sprite = META_CURSOR_SPRITE (tracker->xfixes_cursor);
} }
if (cursor_sprite) if (cursor_sprite)

View File

@ -23,19 +23,12 @@
#include "meta-cursor.h" #include "meta-cursor.h"
#include <meta/errors.h> #include "backends/meta-backend-private.h"
#include "cogl/cogl.h"
#include "meta/common.h"
#include "display-private.h" enum
#include "screen-private.h" {
#include "meta-backend-private.h"
#include <string.h>
#include <X11/cursorfont.h>
#include <X11/extensions/Xfixes.h>
#include <X11/Xcursor/Xcursor.h>
enum {
PREPARE_AT, PREPARE_AT,
TEXTURE_CHANGED, TEXTURE_CHANGED,
@ -44,316 +37,148 @@ enum {
static guint signals[LAST_SIGNAL]; static guint signals[LAST_SIGNAL];
struct _MetaCursorSprite typedef struct _MetaCursorSpritePrivate
{ {
GObject parent; GObject parent;
MetaCursor cursor;
CoglTexture2D *texture; CoglTexture2D *texture;
float texture_scale; float texture_scale;
int hot_x, hot_y; int hot_x, hot_y;
} MetaCursorSpritePrivate;
int current_frame; G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCursorSprite,
XcursorImages *xcursor_images; meta_cursor_sprite,
G_TYPE_OBJECT)
int theme_scale;
gboolean theme_dirty;
};
G_DEFINE_TYPE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT)
static const char *
translate_meta_cursor (MetaCursor cursor)
{
switch (cursor)
{
case META_CURSOR_DEFAULT:
return "left_ptr";
case META_CURSOR_NORTH_RESIZE:
return "top_side";
case META_CURSOR_SOUTH_RESIZE:
return "bottom_side";
case META_CURSOR_WEST_RESIZE:
return "left_side";
case META_CURSOR_EAST_RESIZE:
return "right_side";
case META_CURSOR_SE_RESIZE:
return "bottom_right_corner";
case META_CURSOR_SW_RESIZE:
return "bottom_left_corner";
case META_CURSOR_NE_RESIZE:
return "top_right_corner";
case META_CURSOR_NW_RESIZE:
return "top_left_corner";
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
return "fleur";
case META_CURSOR_BUSY:
return "watch";
case META_CURSOR_DND_IN_DRAG:
return "dnd-none";
case META_CURSOR_DND_MOVE:
return "dnd-move";
case META_CURSOR_DND_COPY:
return "dnd-copy";
case META_CURSOR_DND_UNSUPPORTED_TARGET:
return "dnd-none";
case META_CURSOR_POINTING_HAND:
return "hand2";
case META_CURSOR_CROSSHAIR:
return "crosshair";
case META_CURSOR_IBEAM:
return "xterm";
default:
break;
}
g_assert_not_reached ();
}
Cursor
meta_cursor_create_x_cursor (Display *xdisplay,
MetaCursor cursor)
{
return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
}
static XcursorImages *
load_cursor_on_client (MetaCursor cursor, int scale)
{
return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
meta_prefs_get_cursor_theme (),
meta_prefs_get_cursor_size () * scale);
}
static void
meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
XcursorImage *xc_image)
{
MetaBackend *meta_backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
uint width, height, rowstride;
CoglPixelFormat cogl_format;
ClutterBackend *clutter_backend;
CoglContext *cogl_context;
CoglTexture2D *texture;
CoglError *error = NULL;
g_assert (self->texture == NULL);
width = xc_image->width;
height = xc_image->height;
rowstride = width * 4;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
#else
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
#endif
clutter_backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
texture = cogl_texture_2d_new_from_data (cogl_context,
width, height,
cogl_format,
rowstride,
(uint8_t *) xc_image->pixels,
&error);
if (error)
{
meta_warning ("Failed to allocate cursor texture: %s\n", error->message);
cogl_error_free (error);
}
meta_cursor_sprite_set_texture (self, COGL_TEXTURE (texture),
xc_image->xhot, xc_image->yhot);
if (texture)
cogl_object_unref (texture);
meta_cursor_renderer_realize_cursor_from_xcursor (renderer, self, xc_image);
}
static XcursorImage *
meta_cursor_sprite_get_current_frame_image (MetaCursorSprite *self)
{
return self->xcursor_images->images[self->current_frame];
}
void
meta_cursor_sprite_tick_frame (MetaCursorSprite *self)
{
XcursorImage *image;
if (!meta_cursor_sprite_is_animated (self))
return;
self->current_frame++;
if (self->current_frame >= self->xcursor_images->nimage)
self->current_frame = 0;
image = meta_cursor_sprite_get_current_frame_image (self);
g_clear_pointer (&self->texture, cogl_object_unref);
meta_cursor_sprite_load_from_xcursor_image (self, image);
}
guint
meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self)
{
if (!meta_cursor_sprite_is_animated (self))
return 0;
return self->xcursor_images->images[self->current_frame]->delay;
}
gboolean gboolean
meta_cursor_sprite_is_animated (MetaCursorSprite *self) meta_cursor_sprite_is_animated (MetaCursorSprite *sprite)
{ {
return (self->xcursor_images && MetaCursorSpriteClass *klass = META_CURSOR_SPRITE_GET_CLASS (sprite);
self->xcursor_images->nimage > 1);
}
MetaCursorSprite * if (klass->is_animated)
meta_cursor_sprite_new (void) return klass->is_animated (sprite);
{ else
return g_object_new (META_TYPE_CURSOR_SPRITE, NULL); return FALSE;
}
static void
meta_cursor_sprite_load_from_theme (MetaCursorSprite *self)
{
XcursorImage *image;
g_assert (self->cursor != META_CURSOR_NONE);
self->theme_dirty = FALSE;
/* We might be reloading with a different scale. If so clear the old data. */
if (self->xcursor_images)
{
g_clear_pointer (&self->texture, cogl_object_unref);
XcursorImagesDestroy (self->xcursor_images);
}
self->current_frame = 0;
self->xcursor_images = load_cursor_on_client (self->cursor,
self->theme_scale);
if (!self->xcursor_images)
meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
image = meta_cursor_sprite_get_current_frame_image (self);
meta_cursor_sprite_load_from_xcursor_image (self, image);
}
MetaCursorSprite *
meta_cursor_sprite_from_theme (MetaCursor cursor)
{
MetaCursorSprite *self;
self = meta_cursor_sprite_new ();
self->cursor = cursor;
self->theme_dirty = TRUE;
return self;
} }
void void
meta_cursor_sprite_set_texture (MetaCursorSprite *self, 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, CoglTexture *texture,
int hot_x, int hot_x,
int hot_y) int hot_y)
{ {
if (self->texture == COGL_TEXTURE_2D (texture) && MetaCursorSpritePrivate *priv =
self->hot_x == hot_x && meta_cursor_sprite_get_instance_private (sprite);
self->hot_y == hot_y)
if (priv->texture == COGL_TEXTURE_2D (texture) &&
priv->hot_x == hot_x &&
priv->hot_y == hot_y)
return; return;
g_clear_pointer (&self->texture, cogl_object_unref); g_clear_pointer (&priv->texture, cogl_object_unref);
if (texture) if (texture)
self->texture = cogl_object_ref (texture); priv->texture = cogl_object_ref (texture);
self->hot_x = hot_x; priv->hot_x = hot_x;
self->hot_y = hot_y; priv->hot_y = hot_y;
g_signal_emit (self, signals[TEXTURE_CHANGED], 0); g_signal_emit (sprite, signals[TEXTURE_CHANGED], 0);
} }
void void
meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self, meta_cursor_sprite_set_texture_scale (MetaCursorSprite *sprite,
float scale) float scale)
{ {
self->texture_scale = scale; MetaCursorSpritePrivate *priv =
} meta_cursor_sprite_get_instance_private (sprite);
void priv->texture_scale = scale;
meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
int theme_scale)
{
if (self->theme_scale != theme_scale)
self->theme_dirty = TRUE;
self->theme_scale = theme_scale;
} }
CoglTexture * CoglTexture *
meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self) meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *sprite)
{ {
return COGL_TEXTURE (self->texture); MetaCursorSpritePrivate *priv =
} meta_cursor_sprite_get_instance_private (sprite);
MetaCursor return COGL_TEXTURE (priv->texture);
meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self)
{
return self->cursor;
} }
void void
meta_cursor_sprite_get_hotspot (MetaCursorSprite *self, meta_cursor_sprite_get_hotspot (MetaCursorSprite *sprite,
int *hot_x, int *hot_x,
int *hot_y) int *hot_y)
{ {
*hot_x = self->hot_x; MetaCursorSpritePrivate *priv =
*hot_y = self->hot_y; meta_cursor_sprite_get_instance_private (sprite);
*hot_x = priv->hot_x;
*hot_y = priv->hot_y;
} }
float float
meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self) meta_cursor_sprite_get_texture_scale (MetaCursorSprite *sprite)
{ {
return self->texture_scale; MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
return priv->texture_scale;
} }
void void
meta_cursor_sprite_prepare_at (MetaCursorSprite *self, meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
int x, int x,
int y) int y)
{ {
g_signal_emit (self, signals[PREPARE_AT], 0, x, y); g_signal_emit (sprite, signals[PREPARE_AT], 0, x, y);
} }
void void
meta_cursor_sprite_realize_texture (MetaCursorSprite *self) meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite)
{ {
if (self->theme_dirty) MetaCursorSpriteClass *klass = META_CURSOR_SPRITE_GET_CLASS (sprite);
meta_cursor_sprite_load_from_theme (self);
if (klass->realize_texture)
klass->realize_texture (sprite);
} }
static void static void
meta_cursor_sprite_init (MetaCursorSprite *self) meta_cursor_sprite_init (MetaCursorSprite *sprite)
{ {
self->texture_scale = 1.0f; MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
priv->texture_scale = 1.0f;
} }
static void static void
meta_cursor_sprite_finalize (GObject *object) meta_cursor_sprite_finalize (GObject *object)
{ {
MetaCursorSprite *self = META_CURSOR_SPRITE (object); MetaCursorSprite *sprite = META_CURSOR_SPRITE (object);
MetaCursorSpritePrivate *priv =
meta_cursor_sprite_get_instance_private (sprite);
if (self->xcursor_images) g_clear_pointer (&priv->texture, cogl_object_unref);
XcursorImagesDestroy (self->xcursor_images);
g_clear_pointer (&self->texture, cogl_object_unref);
G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object); G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object);
} }

View File

@ -25,51 +25,50 @@
#include <meta/common.h> #include <meta/common.h>
#include <meta/boxes.h> #include <meta/boxes.h>
typedef struct _MetaCursorSprite MetaCursorSprite;
#define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ()) #define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ())
G_DECLARE_FINAL_TYPE (MetaCursorSprite, G_DECLARE_DERIVABLE_TYPE (MetaCursorSprite,
meta_cursor_sprite, meta_cursor_sprite,
META, CURSOR_SPRITE, META, CURSOR_SPRITE,
GObject); GObject)
MetaCursorSprite * meta_cursor_sprite_new (void); struct _MetaCursorSpriteClass
{
GObjectClass parent_class;
MetaCursorSprite * meta_cursor_sprite_from_theme (MetaCursor cursor); void (* realize_texture) (MetaCursorSprite *sprite);
gboolean (* is_animated) (MetaCursorSprite *sprite);
void (* tick_frame) (MetaCursorSprite *sprite);
unsigned int (* get_current_frame_time) (MetaCursorSprite *sprite);
};
void meta_cursor_sprite_prepare_at (MetaCursorSprite *sprite,
void meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
int scale);
MetaCursor meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self);
Cursor meta_cursor_create_x_cursor (Display *xdisplay,
MetaCursor cursor);
void meta_cursor_sprite_prepare_at (MetaCursorSprite *self,
int x, int x,
int y); int y);
void meta_cursor_sprite_realize_texture (MetaCursorSprite *self); void meta_cursor_sprite_realize_texture (MetaCursorSprite *sprite);
void meta_cursor_sprite_set_texture (MetaCursorSprite *self, void meta_cursor_sprite_clear_texture (MetaCursorSprite *sprite);
void meta_cursor_sprite_set_texture (MetaCursorSprite *sprite,
CoglTexture *texture, CoglTexture *texture,
int hot_x, int hot_x,
int hot_y); int hot_y);
void meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self, void meta_cursor_sprite_set_texture_scale (MetaCursorSprite *sprite,
float scale); float scale);
CoglTexture *meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self); CoglTexture *meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *sprite);
void meta_cursor_sprite_get_hotspot (MetaCursorSprite *self, void meta_cursor_sprite_get_hotspot (MetaCursorSprite *sprite,
int *hot_x, int *hot_x,
int *hot_y); int *hot_y);
float meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self); float meta_cursor_sprite_get_texture_scale (MetaCursorSprite *sprite);
gboolean meta_cursor_sprite_is_animated (MetaCursorSprite *self); gboolean meta_cursor_sprite_is_animated (MetaCursorSprite *sprite);
void meta_cursor_sprite_tick_frame (MetaCursorSprite *self);
guint meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self); void meta_cursor_sprite_tick_frame (MetaCursorSprite *sprite);
unsigned int meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *sprite);
#endif /* META_CURSOR_H */ #endif /* META_CURSOR_H */

View File

@ -645,8 +645,6 @@ void meta_backend_native_resume (MetaBackendNative *native)
meta_backend_get_monitor_manager (backend); meta_backend_get_monitor_manager (backend);
MetaMonitorManagerKms *monitor_manager_kms = MetaMonitorManagerKms *monitor_manager_kms =
META_MONITOR_MANAGER_KMS (monitor_manager); META_MONITOR_MANAGER_KMS (monitor_manager);
MetaCursorRenderer *cursor_renderer;
MetaCursorRendererNative *cursor_renderer_native;
ClutterActor *stage; ClutterActor *stage;
MetaIdleMonitor *idle_monitor; MetaIdleMonitor *idle_monitor;
@ -658,10 +656,6 @@ void meta_backend_native_resume (MetaBackendNative *native)
stage = meta_backend_get_stage (backend); stage = meta_backend_get_stage (backend);
clutter_actor_queue_redraw (stage); clutter_actor_queue_redraw (stage);
cursor_renderer = meta_backend_get_cursor_renderer (backend);
cursor_renderer_native = META_CURSOR_RENDERER_NATIVE (cursor_renderer);
meta_cursor_renderer_native_force_update (cursor_renderer_native);
idle_monitor = meta_backend_get_idle_monitor (backend, 0); idle_monitor = meta_backend_get_idle_monitor (backend, 0);
meta_idle_monitor_reset_idletime (idle_monitor); meta_idle_monitor_reset_idletime (idle_monitor);
} }

View File

@ -35,6 +35,7 @@
#include <meta/meta-backend.h> #include <meta/meta-backend.h>
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/meta-cursor-sprite-xcursor.h"
#include "backends/meta-logical-monitor.h" #include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor.h" #include "backends/meta-monitor.h"
#include "backends/meta-monitor-manager-private.h" #include "backends/meta-monitor-manager-private.h"
@ -43,6 +44,11 @@
#include "core/boxes-private.h" #include "core/boxes-private.h"
#include "meta/boxes.h" #include "meta/boxes.h"
#ifdef HAVE_WAYLAND
#include "wayland/meta-cursor-sprite-wayland.h"
#include "wayland/meta-wayland-buffer.h"
#endif
#ifndef DRM_CAP_CURSOR_WIDTH #ifndef DRM_CAP_CURSOR_WIDTH
#define DRM_CAP_CURSOR_WIDTH 0x8 #define DRM_CAP_CURSOR_WIDTH 0x8
#endif #endif
@ -113,6 +119,11 @@ static GQuark quark_cursor_renderer_native_gpu_data = 0;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER); G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER);
static void
realize_cursor_sprite (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
GList *gpus);
static MetaCursorNativeGpuState * static MetaCursorNativeGpuState *
get_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv, get_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
MetaGpuKms *gpu_kms); MetaGpuKms *gpu_kms);
@ -152,7 +163,8 @@ static void
meta_cursor_renderer_native_finalize (GObject *object) meta_cursor_renderer_native_finalize (GObject *object)
{ {
MetaCursorRendererNative *renderer = META_CURSOR_RENDERER_NATIVE (object); MetaCursorRendererNative *renderer = META_CURSOR_RENDERER_NATIVE (object);
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (renderer); MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (renderer);
if (priv->animation_timeout_id) if (priv->animation_timeout_id)
g_source_remove (priv->animation_timeout_id); g_source_remove (priv->animation_timeout_id);
@ -203,7 +215,8 @@ set_crtc_cursor (MetaCursorRendererNative *native,
MetaCrtc *crtc, MetaCrtc *crtc,
MetaCursorSprite *cursor_sprite) MetaCursorSprite *cursor_sprite)
{ {
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
MetaGpuKms *gpu_kms; MetaGpuKms *gpu_kms;
int kms_fd; int kms_fd;
@ -371,7 +384,8 @@ static void
update_hw_cursor (MetaCursorRendererNative *native, update_hw_cursor (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite) MetaCursorSprite *cursor_sprite)
{ {
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native); MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
MetaMonitorManager *monitor_manager = priv->monitor_manager; MetaMonitorManager *monitor_manager = priv->monitor_manager;
GList *logical_monitors; GList *logical_monitors;
@ -564,18 +578,15 @@ can_draw_cursor_unscaled (MetaCursorRenderer *renderer,
static gboolean static gboolean
should_have_hw_cursor (MetaCursorRenderer *renderer, should_have_hw_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite) MetaCursorSprite *cursor_sprite,
GList *gpus)
{ {
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
GList *gpus;
GList *l; GList *l;
CoglTexture *texture; CoglTexture *texture;
if (!cursor_sprite) if (!cursor_sprite)
return FALSE; return FALSE;
gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
for (l = gpus; l; l = l->next) for (l = gpus; l; l = l->next)
{ {
MetaGpuKms *gpu_kms = l->data; MetaGpuKms *gpu_kms = l->data;
@ -609,7 +620,8 @@ should_have_hw_cursor (MetaCursorRenderer *renderer,
static gboolean static gboolean
meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native) meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native)
{ {
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native); MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
MetaCursorSprite *cursor_sprite = meta_cursor_renderer_get_cursor (renderer); MetaCursorSprite *cursor_sprite = meta_cursor_renderer_get_cursor (renderer);
@ -621,10 +633,11 @@ meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native)
} }
static void static void
meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native, maybe_schedule_cursor_sprite_animation_frame (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite) MetaCursorSprite *cursor_sprite)
{ {
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
gboolean cursor_change; gboolean cursor_change;
guint delay; guint delay;
@ -656,21 +669,78 @@ meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native,
} }
} }
static GList *
calculate_cursor_sprite_gpus (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
MetaMonitorManager *monitor_manager = priv->monitor_manager;
GList *gpus = NULL;
GList *logical_monitors;
GList *l;
ClutterRect cursor_rect;
cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
logical_monitors =
meta_monitor_manager_get_logical_monitors (monitor_manager);
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
MetaRectangle logical_monitor_layout;
ClutterRect logical_monitor_rect;
GList *monitors, *l_mon;
logical_monitor_layout =
meta_logical_monitor_get_layout (logical_monitor);
logical_monitor_rect =
meta_rectangle_to_clutter_rect (&logical_monitor_layout);
if (!clutter_rect_intersection (&cursor_rect, &logical_monitor_rect,
NULL))
continue;
monitors = meta_logical_monitor_get_monitors (logical_monitor);
for (l_mon = monitors; l_mon; l_mon = l_mon->next)
{
MetaMonitor *monitor = l_mon->data;
MetaGpu *gpu;
gpu = meta_monitor_get_gpu (monitor);
if (!g_list_find (gpus, gpu))
gpus = g_list_prepend (gpus, gpu);
}
}
return gpus;
}
static gboolean static gboolean
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer, meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite) MetaCursorSprite *cursor_sprite)
{ {
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer); MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native); MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
g_autoptr (GList) gpus = NULL;
if (cursor_sprite) if (cursor_sprite)
{
meta_cursor_sprite_realize_texture (cursor_sprite); meta_cursor_sprite_realize_texture (cursor_sprite);
gpus = calculate_cursor_sprite_gpus (renderer, cursor_sprite);
realize_cursor_sprite (renderer, cursor_sprite, gpus);
}
meta_cursor_renderer_native_trigger_frame (native, cursor_sprite); maybe_schedule_cursor_sprite_animation_frame (native, cursor_sprite);
priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite); priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite, gpus);
update_hw_cursor (native, cursor_sprite); update_hw_cursor (native, cursor_sprite);
return priv->has_hw_cursor;
return (priv->has_hw_cursor ||
!cursor_sprite ||
!meta_cursor_sprite_get_cogl_texture (cursor_sprite));
} }
static void static void
@ -706,6 +776,24 @@ ensure_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
return cursor_gpu_state; return cursor_gpu_state;
} }
static void
on_cursor_sprite_texture_changed (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv = get_cursor_priv (cursor_sprite);
GHashTableIter iter;
MetaCursorNativeGpuState *cursor_gpu_state;
g_hash_table_iter_init (&iter, cursor_priv->gpu_states);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &cursor_gpu_state))
{
guint pending_bo;
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_gpu_state);
g_clear_pointer (&cursor_gpu_state->bos[pending_bo],
(GDestroyNotify) gbm_bo_destroy);
cursor_gpu_state->pending_bo_state = META_CURSOR_GBM_BO_STATE_INVALIDATED;
}
}
static void static void
cursor_priv_free (MetaCursorNativePrivate *cursor_priv) cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
{ {
@ -738,6 +826,9 @@ ensure_cursor_priv (MetaCursorSprite *cursor_sprite)
cursor_priv, cursor_priv,
(GDestroyNotify) cursor_priv_free); (GDestroyNotify) cursor_priv_free);
g_signal_connect (cursor_sprite, "texture-changed",
G_CALLBACK (on_cursor_sprite_texture_changed), NULL);
return cursor_priv; return cursor_priv;
} }
@ -805,57 +896,71 @@ load_cursor_sprite_gbm_buffer_for_gpu (MetaCursorRendererNative *native,
} }
} }
static void static gboolean
invalidate_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite, is_cursor_hw_state_valid (MetaCursorSprite *cursor_sprite,
MetaGpuKms *gpu_kms) MetaGpuKms *gpu_kms)
{ {
MetaCursorNativePrivate *cursor_priv; MetaCursorNativePrivate *cursor_priv;
MetaCursorNativeGpuState *cursor_gpu_state; MetaCursorNativeGpuState *cursor_gpu_state;
guint pending_bo;
cursor_priv = get_cursor_priv (cursor_sprite); cursor_priv = get_cursor_priv (cursor_sprite);
if (!cursor_priv) if (!cursor_priv)
return; return FALSE;
cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms); cursor_gpu_state = get_cursor_gpu_state (cursor_priv, gpu_kms);
if (!cursor_gpu_state) if (!cursor_gpu_state)
return; return FALSE;
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_gpu_state); switch (cursor_gpu_state->pending_bo_state)
g_clear_pointer (&cursor_gpu_state->bos[pending_bo], {
(GDestroyNotify) gbm_bo_destroy); case META_CURSOR_GBM_BO_STATE_SET:
cursor_gpu_state->pending_bo_state = META_CURSOR_GBM_BO_STATE_INVALIDATED; case META_CURSOR_GBM_BO_STATE_NONE:
return TRUE;
case META_CURSOR_GBM_BO_STATE_INVALIDATED:
return FALSE;
}
g_assert_not_reached ();
} }
#ifdef HAVE_WAYLAND #ifdef HAVE_WAYLAND
static void static void
meta_cursor_renderer_native_realize_cursor_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer, realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer,
MetaGpuKms *gpu_kms, MetaGpuKms *gpu_kms,
MetaCursorSprite *cursor_sprite, MetaCursorSpriteWayland *sprite_wayland)
struct wl_resource *buffer)
{ {
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer); MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_wayland);
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
uint32_t gbm_format; uint32_t gbm_format;
uint64_t cursor_width, cursor_height; uint64_t cursor_width, cursor_height;
CoglTexture *texture; CoglTexture *texture;
uint width, height; uint width, height;
MetaWaylandBuffer *buffer;
struct wl_resource *buffer_resource;
struct wl_shm_buffer *shm_buffer;
cursor_renderer_gpu_data = cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken) if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken)
return; return;
/* Destroy any previous pending cursor buffer; we'll always either fail (which if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms))
* should unset, or succeed, which will set new buffer. return;
*/
invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms);
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite); texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
width = cogl_texture_get_width (texture); width = cogl_texture_get_width (texture);
height = cogl_texture_get_height (texture); height = cogl_texture_get_height (texture);
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer); buffer = meta_cursor_sprite_wayland_get_buffer (sprite_wayland);
if (!buffer)
return;
buffer_resource = meta_wayland_buffer_get_resource (buffer);
if (!buffer_resource)
return;
shm_buffer = wl_shm_buffer_get (buffer_resource);
if (shm_buffer) if (shm_buffer)
{ {
int rowstride = wl_shm_buffer_get_stride (shm_buffer); int rowstride = wl_shm_buffer_get_stride (shm_buffer);
@ -929,47 +1034,27 @@ meta_cursor_renderer_native_realize_cursor_from_wl_buffer_for_gpu (MetaCursorRen
set_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms, bo); set_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms, bo);
} }
} }
static void
meta_cursor_renderer_native_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
struct wl_resource *buffer)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
GList *gpus;
GList *l;
gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
for (l = gpus; l; l = l->next)
{
MetaGpuKms *gpu_kms = l->data;
meta_cursor_renderer_native_realize_cursor_from_wl_buffer_for_gpu (
renderer,
gpu_kms,
cursor_sprite,
buffer);
}
}
#endif #endif
static void static void
meta_cursor_renderer_native_realize_cursor_from_xcursor_for_gpu (MetaCursorRenderer *renderer, realize_cursor_sprite_from_xcursor_for_gpu (MetaCursorRenderer *renderer,
MetaGpuKms *gpu_kms, MetaGpuKms *gpu_kms,
MetaCursorSprite *cursor_sprite, MetaCursorSpriteXcursor *sprite_xcursor)
XcursorImage *xc_image)
{ {
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer); MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data; MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
XcursorImage *xc_image;
cursor_renderer_gpu_data = cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms); meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken) if (!cursor_renderer_gpu_data || cursor_renderer_gpu_data->hw_cursor_broken)
return; return;
invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms); if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms))
return;
xc_image = meta_cursor_sprite_xcursor_get_current_image (sprite_xcursor);
load_cursor_sprite_gbm_buffer_for_gpu (native, load_cursor_sprite_gbm_buffer_for_gpu (native,
gpu_kms, gpu_kms,
@ -982,26 +1067,45 @@ meta_cursor_renderer_native_realize_cursor_from_xcursor_for_gpu (MetaCursorRende
} }
static void static void
meta_cursor_renderer_native_realize_cursor_from_xcursor (MetaCursorRenderer *renderer, realize_cursor_sprite_for_gpu (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite, MetaGpuKms *gpu_kms,
XcursorImage *xc_image) MetaCursorSprite *cursor_sprite)
{
#ifdef HAVE_WAYLAND
if (META_IS_CURSOR_SPRITE_WAYLAND (cursor_sprite))
{
MetaCursorSpriteWayland *sprite_wayland =
META_CURSOR_SPRITE_WAYLAND (cursor_sprite);
realize_cursor_sprite_from_wl_buffer_for_gpu (renderer,
gpu_kms,
sprite_wayland);
}
else
#endif
if (META_IS_CURSOR_SPRITE_XCURSOR (cursor_sprite))
{
MetaCursorSpriteXcursor *sprite_xcursor =
META_CURSOR_SPRITE_XCURSOR (cursor_sprite);
realize_cursor_sprite_from_xcursor_for_gpu (renderer,
gpu_kms,
sprite_xcursor);
}
}
static void
realize_cursor_sprite (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
GList *gpus)
{ {
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
GList *gpus;
GList *l; GList *l;
gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
for (l = gpus; l; l = l->next) for (l = gpus; l; l = l->next)
{ {
MetaGpuKms *gpu_kms = l->data; MetaGpuKms *gpu_kms = l->data;
meta_cursor_renderer_native_realize_cursor_from_xcursor_for_gpu ( realize_cursor_sprite_for_gpu (renderer, gpu_kms, cursor_sprite);
renderer,
gpu_kms,
cursor_sprite,
xc_image);
} }
} }
@ -1013,12 +1117,6 @@ meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
object_class->finalize = meta_cursor_renderer_native_finalize; object_class->finalize = meta_cursor_renderer_native_finalize;
renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor; renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor;
#ifdef HAVE_WAYLAND
renderer_class->realize_cursor_from_wl_buffer =
meta_cursor_renderer_native_realize_cursor_from_wl_buffer;
#endif
renderer_class->realize_cursor_from_xcursor =
meta_cursor_renderer_native_realize_cursor_from_xcursor;
quark_cursor_sprite = g_quark_from_static_string ("-meta-cursor-native"); quark_cursor_sprite = g_quark_from_static_string ("-meta-cursor-native");
quark_cursor_renderer_native_gpu_data = quark_cursor_renderer_native_gpu_data =
@ -1033,14 +1131,13 @@ force_update_hw_cursor (MetaCursorRendererNative *native)
meta_cursor_renderer_native_get_instance_private (native); meta_cursor_renderer_native_get_instance_private (native);
priv->hw_state_invalidated = TRUE; priv->hw_state_invalidated = TRUE;
update_hw_cursor (native, meta_cursor_renderer_get_cursor (renderer)); meta_cursor_renderer_force_update (renderer);
} }
static void static void
on_monitors_changed (MetaMonitorManager *monitors, on_monitors_changed (MetaMonitorManager *monitors,
MetaCursorRendererNative *native) MetaCursorRendererNative *native)
{ {
/* Our tracking is all messed up, so force an update. */
force_update_hw_cursor (native); force_update_hw_cursor (native);
} }
@ -1112,9 +1209,3 @@ static void
meta_cursor_renderer_native_init (MetaCursorRendererNative *native) meta_cursor_renderer_native_init (MetaCursorRendererNative *native)
{ {
} }
void
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
{
force_update_hw_cursor (native);
}

View File

@ -32,8 +32,6 @@ G_DECLARE_FINAL_TYPE (MetaCursorRendererNative, meta_cursor_renderer_native,
META, CURSOR_RENDERER_NATIVE, META, CURSOR_RENDERER_NATIVE,
MetaCursorRenderer) MetaCursorRenderer)
void meta_cursor_renderer_native_force_update (MetaCursorRendererNative *renderer);
MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend); MetaCursorRendererNative * meta_cursor_renderer_native_new (MetaBackend *backend);
#endif /* META_CURSOR_RENDERER_NATIVE_H */ #endif /* META_CURSOR_RENDERER_NATIVE_H */

View File

@ -30,6 +30,7 @@
#include "meta-backend-x11.h" #include "meta-backend-x11.h"
#include "meta-stage-private.h" #include "meta-stage-private.h"
#include "backends/meta-cursor-sprite-xcursor.h"
struct _MetaCursorRendererX11Private struct _MetaCursorRendererX11Private
{ {
@ -59,13 +60,18 @@ meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
gboolean has_server_cursor = FALSE; gboolean has_server_cursor = FALSE;
if (cursor_sprite) if (cursor_sprite && META_IS_CURSOR_SPRITE_XCURSOR (cursor_sprite))
{ {
MetaCursor cursor = meta_cursor_sprite_get_meta_cursor (cursor_sprite); MetaCursorSpriteXcursor *sprite_xcursor =
META_CURSOR_SPRITE_XCURSOR (cursor_sprite);
MetaCursor cursor;
cursor = meta_cursor_sprite_xcursor_get_cursor (sprite_xcursor);
if (cursor != META_CURSOR_NONE) if (cursor != META_CURSOR_NONE)
{ {
Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor); Cursor xcursor;
xcursor = meta_create_x_cursor (xdisplay, cursor);
XDefineCursor (xdisplay, xwindow, xcursor); XDefineCursor (xdisplay, xwindow, xcursor);
XFlush (xdisplay); XFlush (xdisplay);
XFreeCursor (xdisplay, xcursor); XFreeCursor (xdisplay, xcursor);

View File

@ -26,6 +26,8 @@
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h" #include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
#include <X11/Xcursor/Xcursor.h>
#include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-backend-x11.h"
struct _MetaCursorRendererX11Nested struct _MetaCursorRendererX11Nested

View File

@ -3018,7 +3018,7 @@ Cursor
meta_display_create_x_cursor (MetaDisplay *display, meta_display_create_x_cursor (MetaDisplay *display,
MetaCursor cursor) MetaCursor cursor)
{ {
return meta_cursor_create_x_cursor (display->xdisplay, cursor); return meta_create_x_cursor (display->xdisplay, cursor);
} }
MetaGestureTracker * MetaGestureTracker *

View File

@ -60,6 +60,7 @@
#include "x11/xprops.h" #include "x11/xprops.h"
#include "backends/x11/meta-backend-x11.h" #include "backends/x11/meta-backend-x11.h"
#include "backends/meta-cursor-sprite-xcursor.h"
static char* get_screen_name (MetaDisplay *display, static char* get_screen_name (MetaDisplay *display,
int number); int number);
@ -1323,12 +1324,13 @@ find_highest_logical_monitor_scale (MetaBackend *backend,
} }
static void static void
root_cursor_prepare_at (MetaCursorSprite *cursor_sprite, root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
int x, int x,
int y, int y,
MetaScreen *screen) MetaScreen *screen)
{ {
MetaBackend *backend = meta_get_backend (); MetaBackend *backend = meta_get_backend ();
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
if (meta_is_stage_views_scaled ()) if (meta_is_stage_views_scaled ())
{ {
@ -1337,7 +1339,7 @@ root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
scale = find_highest_logical_monitor_scale (backend, cursor_sprite); scale = find_highest_logical_monitor_scale (backend, cursor_sprite);
if (scale != 0.0) if (scale != 0.0)
{ {
meta_cursor_sprite_set_theme_scale (cursor_sprite, scale); meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor, scale);
meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0 / scale); meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0 / scale);
} }
} }
@ -1353,7 +1355,7 @@ root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
/* Reload the cursor texture if the scale has changed. */ /* Reload the cursor texture if the scale has changed. */
if (logical_monitor) if (logical_monitor)
{ {
meta_cursor_sprite_set_theme_scale (cursor_sprite, meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
logical_monitor->scale); logical_monitor->scale);
meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0); meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0);
} }
@ -1362,9 +1364,9 @@ root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
static void static void
manage_root_cursor_sprite_scale (MetaScreen *screen, manage_root_cursor_sprite_scale (MetaScreen *screen,
MetaCursorSprite *cursor_sprite) MetaCursorSpriteXcursor *sprite_xcursor)
{ {
g_signal_connect_object (cursor_sprite, g_signal_connect_object (sprite_xcursor,
"prepare-at", "prepare-at",
G_CALLBACK (root_cursor_prepare_at), G_CALLBACK (root_cursor_prepare_at),
screen, screen,
@ -1377,17 +1379,18 @@ meta_screen_update_cursor (MetaScreen *screen)
MetaDisplay *display = screen->display; MetaDisplay *display = screen->display;
MetaCursor cursor = screen->current_cursor; MetaCursor cursor = screen->current_cursor;
Cursor xcursor; Cursor xcursor;
MetaCursorSprite *cursor_sprite; MetaCursorSpriteXcursor *sprite_xcursor;
MetaBackend *backend = meta_get_backend (); MetaBackend *backend = meta_get_backend ();
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
cursor_sprite = meta_cursor_sprite_from_theme (cursor); sprite_xcursor = meta_cursor_sprite_xcursor_new (cursor);
if (meta_is_wayland_compositor ()) if (meta_is_wayland_compositor ())
manage_root_cursor_sprite_scale (screen, cursor_sprite); manage_root_cursor_sprite_scale (screen, sprite_xcursor);
meta_cursor_tracker_set_root_cursor (cursor_tracker, cursor_sprite); meta_cursor_tracker_set_root_cursor (cursor_tracker,
g_object_unref (cursor_sprite); META_CURSOR_SPRITE (sprite_xcursor));
g_object_unref (sprite_xcursor);
/* Set a cursor for X11 applications that don't specify their own */ /* Set a cursor for X11 applications that don't specify their own */
xcursor = meta_display_create_x_cursor (display, cursor); xcursor = meta_display_create_x_cursor (display, cursor);

View File

@ -88,6 +88,12 @@ meta_wayland_buffer_from_resource (struct wl_resource *resource)
return buffer; return buffer;
} }
struct wl_resource *
meta_wayland_buffer_get_resource (MetaWaylandBuffer *buffer)
{
return buffer->resource;
}
static gboolean static gboolean
meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer) meta_wayland_buffer_is_realized (MetaWaylandBuffer *buffer)
{ {

View File

@ -68,6 +68,7 @@ G_DECLARE_FINAL_TYPE (MetaWaylandBuffer, meta_wayland_buffer,
META, WAYLAND_BUFFER, GObject); META, WAYLAND_BUFFER, GObject);
MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource); MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource);
struct wl_resource * meta_wayland_buffer_get_resource (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer, gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
GError **error); GError **error);
CoglTexture * meta_wayland_buffer_get_texture (MetaWaylandBuffer *buffer); CoglTexture * meta_wayland_buffer_get_texture (MetaWaylandBuffer *buffer);

View File

@ -55,7 +55,7 @@
#include "meta-wayland-seat.h" #include "meta-wayland-seat.h"
#include "meta-wayland-surface.h" #include "meta-wayland-surface.h"
#include "meta-wayland-buffer.h" #include "meta-wayland-buffer.h"
#include "meta-wayland-surface-role-cursor.h" #include "meta-wayland-cursor-surface.h"
#include "meta-xwayland.h" #include "meta-xwayland.h"
#include "meta-cursor.h" #include "meta-cursor.h"
#include "meta-cursor-tracker-private.h" #include "meta-cursor-tracker-private.h"
@ -1025,10 +1025,10 @@ meta_wayland_pointer_update_cursor_surface (MetaWaylandPointer *pointer)
if (pointer->cursor_surface) if (pointer->cursor_surface)
{ {
MetaWaylandSurfaceRoleCursor *cursor_role = MetaWaylandCursorSurface *cursor_surface =
META_WAYLAND_SURFACE_ROLE_CURSOR (pointer->cursor_surface->role); META_WAYLAND_CURSOR_SURFACE (pointer->cursor_surface->role);
cursor_sprite = meta_wayland_surface_role_cursor_get_sprite (cursor_role); cursor_sprite = meta_wayland_cursor_surface_get_sprite (cursor_surface);
} }
meta_cursor_tracker_set_window_cursor (cursor_tracker, cursor_sprite); meta_cursor_tracker_set_window_cursor (cursor_tracker, cursor_sprite);
@ -1102,7 +1102,7 @@ pointer_set_cursor (struct wl_client *client,
if (surface && if (surface &&
!meta_wayland_surface_assign_role (surface, !meta_wayland_surface_assign_role (surface,
META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR, META_TYPE_WAYLAND_CURSOR_SURFACE,
NULL)) NULL))
{ {
wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE, wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE,
@ -1115,12 +1115,12 @@ pointer_set_cursor (struct wl_client *client,
{ {
MetaCursorRenderer *cursor_renderer = MetaCursorRenderer *cursor_renderer =
meta_backend_get_cursor_renderer (meta_get_backend ()); meta_backend_get_cursor_renderer (meta_get_backend ());
MetaWaylandSurfaceRoleCursor *cursor_role; MetaWaylandCursorSurface *cursor_surface;
cursor_role = META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role); cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role);
meta_wayland_surface_role_cursor_set_renderer (cursor_role, meta_wayland_cursor_surface_set_renderer (cursor_surface,
cursor_renderer); cursor_renderer);
meta_wayland_surface_role_cursor_set_hotspot (cursor_role, meta_wayland_cursor_surface_set_hotspot (cursor_surface,
hot_x, hot_y); hot_x, hot_y);
} }

View File

@ -1,391 +0,0 @@
/*
* Wayland Support
*
* Copyright (C) 2015 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.
*/
#include "config.h"
#include <cogl/cogl.h>
#include <cogl/cogl-wayland-server.h>
#include "meta-wayland-surface-role-cursor.h"
#include "meta-wayland-buffer.h"
#include "meta-xwayland.h"
#include "screen-private.h"
#include "meta-wayland-private.h"
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
#include "core/boxes-private.h"
typedef struct _MetaWaylandSurfaceRoleCursorPrivate MetaWaylandSurfaceRoleCursorPrivate;
struct _MetaWaylandSurfaceRoleCursorPrivate
{
int hot_x;
int hot_y;
MetaCursorSprite *cursor_sprite;
MetaCursorRenderer *cursor_renderer;
MetaWaylandBuffer *buffer;
struct wl_list frame_callbacks;
gulong cursor_painted_handler_id;
};
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandSurfaceRoleCursor,
meta_wayland_surface_role_cursor,
META_TYPE_WAYLAND_SURFACE_ROLE)
static void
update_cursor_sprite_texture (MetaWaylandSurfaceRoleCursor *cursor_role)
{
MetaWaylandSurfaceRoleCursorPrivate *priv = meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (cursor_role));
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
MetaCursorSprite *cursor_sprite = priv->cursor_sprite;
g_return_if_fail (!buffer || buffer->texture);
if (!priv->cursor_renderer || !cursor_sprite)
return;
if (buffer)
{
meta_cursor_sprite_set_texture (cursor_sprite,
buffer->texture,
priv->hot_x * surface->scale,
priv->hot_y * surface->scale);
if (priv->buffer)
{
struct wl_resource *buffer_resource;
g_assert (priv->buffer == buffer);
buffer_resource = buffer->resource;
meta_cursor_renderer_realize_cursor_from_wl_buffer (priv->cursor_renderer,
cursor_sprite,
buffer_resource);
meta_wayland_surface_unref_buffer_use_count (surface);
g_clear_object (&priv->buffer);
}
}
else
{
meta_cursor_sprite_set_texture (cursor_sprite, NULL, 0, 0);
}
meta_cursor_renderer_force_update (priv->cursor_renderer);
}
static void
cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
int x,
int y,
MetaWaylandSurfaceRoleCursor *cursor_role)
{
MetaWaylandSurfaceRole *role = META_WAYLAND_SURFACE_ROLE (cursor_role);
MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (role);
if (!meta_xwayland_is_xwayland_surface (surface))
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaLogicalMonitor *logical_monitor;
logical_monitor =
meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
if (logical_monitor)
{
float texture_scale;
if (meta_is_stage_views_scaled ())
texture_scale = 1.0 / surface->scale;
else
texture_scale = (meta_logical_monitor_get_scale (logical_monitor) /
surface->scale);
meta_cursor_sprite_set_texture_scale (cursor_sprite, texture_scale);
}
}
meta_wayland_surface_update_outputs (surface);
}
static void
cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
{
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandSurfaceRoleCursor *cursor_role =
META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
wl_list_insert_list (&priv->frame_callbacks,
&surface->pending_frame_callback_list);
wl_list_init (&surface->pending_frame_callback_list);
}
static void
cursor_surface_role_pre_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending)
{
MetaWaylandSurfaceRoleCursor *cursor_role =
META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
if (pending->newly_attached && priv->buffer)
{
meta_wayland_surface_unref_buffer_use_count (surface);
g_clear_object (&priv->buffer);
}
}
static void
cursor_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending)
{
MetaWaylandSurfaceRoleCursor *cursor_role =
META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
if (pending->newly_attached)
{
g_set_object (&priv->buffer, buffer);
if (priv->buffer)
meta_wayland_surface_ref_buffer_use_count (surface);
}
wl_list_insert_list (&priv->frame_callbacks,
&pending->frame_callback_list);
wl_list_init (&pending->frame_callback_list);
if (pending->newly_attached)
update_cursor_sprite_texture (META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role));
}
static gboolean
cursor_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *role,
MetaLogicalMonitor *logical_monitor)
{
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (role);
MetaWaylandSurfaceRoleCursor *cursor_role =
META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role);
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
ClutterPoint point;
ClutterRect logical_monitor_rect;
logical_monitor_rect =
meta_rectangle_to_clutter_rect (&logical_monitor->rect);
point = meta_cursor_renderer_get_position (priv->cursor_renderer);
return clutter_rect_contains_point (&logical_monitor_rect, &point);
}
static void
cursor_surface_role_dispose (GObject *object)
{
MetaWaylandSurfaceRoleCursor *cursor_role =
META_WAYLAND_SURFACE_ROLE_CURSOR (object);
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (META_WAYLAND_SURFACE_ROLE (object));
MetaWaylandFrameCallback *cb, *next;
wl_list_for_each_safe (cb, next, &priv->frame_callbacks, link)
wl_resource_destroy (cb->resource);
g_signal_handlers_disconnect_by_func (priv->cursor_sprite,
cursor_sprite_prepare_at, cursor_role);
g_clear_object (&priv->cursor_renderer);
g_clear_object (&priv->cursor_sprite);
if (priv->buffer)
{
meta_wayland_surface_unref_buffer_use_count (surface);
g_clear_object (&priv->buffer);
}
G_OBJECT_CLASS (meta_wayland_surface_role_cursor_parent_class)->dispose (object);
}
static void
cursor_surface_role_constructed (GObject *object)
{
MetaWaylandSurfaceRoleCursor *cursor_role =
META_WAYLAND_SURFACE_ROLE_CURSOR (object);
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
MetaWaylandSurfaceRole *surface_role =
META_WAYLAND_SURFACE_ROLE (cursor_role);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandBuffer *buffer;
buffer = meta_wayland_surface_get_buffer (surface);
g_warn_if_fail (!buffer || buffer->resource);
if (buffer && buffer->resource)
{
g_set_object (&priv->buffer, buffer);
meta_wayland_surface_ref_buffer_use_count (surface);
}
}
static void
meta_wayland_surface_role_cursor_init (MetaWaylandSurfaceRoleCursor *role)
{
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (role);
priv->cursor_sprite = meta_cursor_sprite_new ();
g_signal_connect_object (priv->cursor_sprite,
"prepare-at",
G_CALLBACK (cursor_sprite_prepare_at),
role,
0);
wl_list_init (&priv->frame_callbacks);
}
static void
meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass *klass)
{
MetaWaylandSurfaceRoleClass *surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
surface_role_class->assigned = cursor_surface_role_assigned;
surface_role_class->pre_commit = cursor_surface_role_pre_commit;
surface_role_class->commit = cursor_surface_role_commit;
surface_role_class->is_on_logical_monitor = cursor_surface_role_is_on_logical_monitor;
object_class->constructed = cursor_surface_role_constructed;
object_class->dispose = cursor_surface_role_dispose;
}
MetaCursorSprite *
meta_wayland_surface_role_cursor_get_sprite (MetaWaylandSurfaceRoleCursor *cursor_role)
{
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
return priv->cursor_sprite;
}
void
meta_wayland_surface_role_cursor_set_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
gint hotspot_x,
gint hotspot_y)
{
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
if (priv->hot_x == hotspot_x &&
priv->hot_y == hotspot_y)
return;
priv->hot_x = hotspot_x;
priv->hot_y = hotspot_y;
update_cursor_sprite_texture (cursor_role);
}
void
meta_wayland_surface_role_cursor_get_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
gint *hotspot_x,
gint *hotspot_y)
{
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
if (hotspot_x)
*hotspot_x = priv->hot_x;
if (hotspot_y)
*hotspot_y = priv->hot_y;
}
static void
on_cursor_painted (MetaCursorRenderer *renderer,
MetaCursorSprite *displayed_sprite,
MetaWaylandSurfaceRoleCursor *cursor_role)
{
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
guint32 time = (guint32) (g_get_monotonic_time () / 1000);
if (displayed_sprite != priv->cursor_sprite)
return;
while (!wl_list_empty (&priv->frame_callbacks))
{
MetaWaylandFrameCallback *callback =
wl_container_of (priv->frame_callbacks.next, callback, link);
wl_callback_send_done (callback->resource, time);
wl_resource_destroy (callback->resource);
}
}
void
meta_wayland_surface_role_cursor_set_renderer (MetaWaylandSurfaceRoleCursor *cursor_role,
MetaCursorRenderer *renderer)
{
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
if (priv->cursor_renderer == renderer)
return;
if (priv->cursor_renderer)
{
g_signal_handler_disconnect (priv->cursor_renderer,
priv->cursor_painted_handler_id);
priv->cursor_painted_handler_id = 0;
g_object_unref (priv->cursor_renderer);
}
if (renderer)
{
priv->cursor_painted_handler_id =
g_signal_connect_object (renderer, "cursor-painted",
G_CALLBACK (on_cursor_painted), cursor_role, 0);
g_object_ref (renderer);
}
priv->cursor_renderer = renderer;
update_cursor_sprite_texture (cursor_role);
}
MetaCursorRenderer *
meta_wayland_surface_role_cursor_get_renderer (MetaWaylandSurfaceRoleCursor *cursor_role)
{
MetaWaylandSurfaceRoleCursorPrivate *priv =
meta_wayland_surface_role_cursor_get_instance_private (cursor_role);
return priv->cursor_renderer;
}

View File

@ -1,52 +0,0 @@
/*
* Wayland Support
*
* Copyright (C) 2015 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.
*/
#ifndef META_WAYLAND_SURFACE_ROLE_CURSOR_H
#define META_WAYLAND_SURFACE_ROLE_CURSOR_H
#include "meta-wayland-surface.h"
#include "backends/meta-cursor-renderer.h"
struct _MetaWaylandSurfaceRoleCursorClass
{
MetaWaylandSurfaceRoleClass parent_class;
};
#define META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR (meta_wayland_surface_role_cursor_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaWaylandSurfaceRoleCursor,
meta_wayland_surface_role_cursor,
META, WAYLAND_SURFACE_ROLE_CURSOR,
MetaWaylandSurfaceRole);
MetaCursorSprite * meta_wayland_surface_role_cursor_get_sprite (MetaWaylandSurfaceRoleCursor *cursor_role);
void meta_wayland_surface_role_cursor_set_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
gint hotspot_x,
gint hotspot_y);
void meta_wayland_surface_role_cursor_get_hotspot (MetaWaylandSurfaceRoleCursor *cursor_role,
gint *hotspot_x,
gint *hotspot_y);
void meta_wayland_surface_role_cursor_set_renderer (MetaWaylandSurfaceRoleCursor *cursor_role,
MetaCursorRenderer *renderer);
MetaCursorRenderer * meta_wayland_surface_role_cursor_get_renderer (MetaWaylandSurfaceRoleCursor *cursor_role);
#endif /* META_WAYLAND_SURFACE_ROLE_CURSOR_H */

View File

@ -1,42 +0,0 @@
/*
* Wayland Support
*
* Copyright (C) 2016 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.
*/
#include "config.h"
#include "meta-wayland-surface-role-tablet-cursor.h"
struct _MetaWaylandSurfaceRoleTabletCursor
{
MetaWaylandSurfaceRoleCursor parent;
};
G_DEFINE_TYPE (MetaWaylandSurfaceRoleTabletCursor,
meta_wayland_surface_role_tablet_cursor,
META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR)
static void
meta_wayland_surface_role_tablet_cursor_init (MetaWaylandSurfaceRoleTabletCursor *role)
{
}
static void
meta_wayland_surface_role_tablet_cursor_class_init (MetaWaylandSurfaceRoleTabletCursorClass *klass)
{
}

View File

@ -1,33 +0,0 @@
/*
* Wayland Support
*
* Copyright (C) 2016 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.
*/
#ifndef META_WAYLAND_SURFACE_ROLE_TABLET_CURSOR_H
#define META_WAYLAND_SURFACE_ROLE_TABLET_CURSOR_H
#include "meta-wayland-surface-role-cursor.h"
#define META_TYPE_WAYLAND_SURFACE_ROLE_TABLET_CURSOR (meta_wayland_surface_role_tablet_cursor_get_type ())
G_DECLARE_FINAL_TYPE (MetaWaylandSurfaceRoleTabletCursor,
meta_wayland_surface_role_tablet_cursor,
META, WAYLAND_SURFACE_ROLE_TABLET_CURSOR,
MetaWaylandSurfaceRoleCursor);
#endif /* META_WAYLAND_SURFACE_ROLE_TABLET_CURSOR_H */

View File

@ -31,7 +31,7 @@
#include <wayland-server.h> #include <wayland-server.h>
#include "tablet-unstable-v2-server-protocol.h" #include "tablet-unstable-v2-server-protocol.h"
#include "meta-wayland-private.h" #include "meta-wayland-private.h"
#include "meta-wayland-surface-role-tablet-cursor.h" #include "meta-wayland-tablet-cursor-surface.h"
#include "meta-surface-actor-wayland.h" #include "meta-surface-actor-wayland.h"
#include "meta-wayland-tablet.h" #include "meta-wayland-tablet.h"
#include "meta-wayland-tablet-seat.h" #include "meta-wayland-tablet-seat.h"
@ -90,16 +90,16 @@ meta_wayland_tablet_tool_update_cursor_surface (MetaWaylandTabletTool *tool)
if (tool->cursor_surface && if (tool->cursor_surface &&
meta_wayland_surface_get_buffer (tool->cursor_surface)) meta_wayland_surface_get_buffer (tool->cursor_surface))
{ {
MetaWaylandSurfaceRoleCursor *cursor_role = MetaWaylandCursorSurface *cursor_surface =
META_WAYLAND_SURFACE_ROLE_CURSOR (tool->cursor_surface->role); META_WAYLAND_CURSOR_SURFACE (tool->cursor_surface->role);
cursor = meta_wayland_surface_role_cursor_get_sprite (cursor_role); cursor = meta_wayland_cursor_surface_get_sprite (cursor_surface);
} }
else else
cursor = NULL; cursor = NULL;
} }
else if (tool->current_tablet) else if (tool->current_tablet)
cursor = tool->default_sprite; cursor = META_CURSOR_SPRITE (tool->default_sprite);
else else
cursor = NULL; cursor = NULL;
@ -382,7 +382,7 @@ tablet_tool_handle_cursor_surface_destroy (struct wl_listener *listener,
} }
static void static void
tool_cursor_prepare_at (MetaCursorSprite *cursor_sprite, tool_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
int x, int x,
int y, int y,
MetaWaylandTabletTool *tool) MetaWaylandTabletTool *tool)
@ -397,7 +397,8 @@ tool_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
/* Reload the cursor texture if the scale has changed. */ /* Reload the cursor texture if the scale has changed. */
if (logical_monitor) if (logical_monitor)
meta_cursor_sprite_set_theme_scale (cursor_sprite, logical_monitor->scale); meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
logical_monitor->scale);
} }
MetaWaylandTabletTool * MetaWaylandTabletTool *
@ -417,7 +418,7 @@ meta_wayland_tablet_tool_new (MetaWaylandTabletSeat *seat,
tool->focus_surface_destroy_listener.notify = tablet_tool_handle_focus_surface_destroy; tool->focus_surface_destroy_listener.notify = tablet_tool_handle_focus_surface_destroy;
tool->cursor_surface_destroy_listener.notify = tablet_tool_handle_cursor_surface_destroy; tool->cursor_surface_destroy_listener.notify = tablet_tool_handle_cursor_surface_destroy;
tool->default_sprite = meta_cursor_sprite_from_theme (META_CURSOR_CROSSHAIR); tool->default_sprite = meta_cursor_sprite_xcursor_new (META_CURSOR_CROSSHAIR);
tool->prepare_at_signal_id = tool->prepare_at_signal_id =
g_signal_connect (tool->default_sprite, "prepare-at", g_signal_connect (tool->default_sprite, "prepare-at",
G_CALLBACK (tool_cursor_prepare_at), tool); G_CALLBACK (tool_cursor_prepare_at), tool);
@ -471,7 +472,7 @@ tool_set_cursor (struct wl_client *client,
if (surface && if (surface &&
!meta_wayland_surface_assign_role (surface, !meta_wayland_surface_assign_role (surface,
META_TYPE_WAYLAND_SURFACE_ROLE_TABLET_CURSOR, META_TYPE_WAYLAND_TABLET_CURSOR_SURFACE,
NULL)) NULL))
{ {
wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE, wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE,
@ -482,12 +483,12 @@ tool_set_cursor (struct wl_client *client,
if (surface) if (surface)
{ {
MetaWaylandSurfaceRoleCursor *cursor_role; MetaWaylandCursorSurface *cursor_surface;
cursor_role = META_WAYLAND_SURFACE_ROLE_CURSOR (surface->role); cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role);
meta_wayland_surface_role_cursor_set_renderer (cursor_role, meta_wayland_cursor_surface_set_renderer (cursor_surface,
tool->cursor_renderer); tool->cursor_renderer);
meta_wayland_surface_role_cursor_set_hotspot (cursor_role, meta_wayland_cursor_surface_set_hotspot (cursor_surface,
hotspot_x, hotspot_y); hotspot_x, hotspot_y);
} }

View File

@ -28,6 +28,7 @@
#include "meta-wayland-types.h" #include "meta-wayland-types.h"
#include "meta-cursor-renderer.h" #include "meta-cursor-renderer.h"
#include "backends/meta-cursor-sprite-xcursor.h"
struct _MetaWaylandTabletTool struct _MetaWaylandTabletTool
{ {
@ -43,7 +44,7 @@ struct _MetaWaylandTabletTool
MetaWaylandSurface *cursor_surface; MetaWaylandSurface *cursor_surface;
struct wl_listener cursor_surface_destroy_listener; struct wl_listener cursor_surface_destroy_listener;
MetaCursorRenderer *cursor_renderer; MetaCursorRenderer *cursor_renderer;
MetaCursorSprite *default_sprite; MetaCursorSpriteXcursor *default_sprite;
guint prepare_at_signal_id; guint prepare_at_signal_id;
MetaWaylandSurface *current; MetaWaylandSurface *current;