[mutter/wip/split-cursor-tracker: 1/2] split cursor_tracker
- From: Rui Matos <rtcm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/split-cursor-tracker: 1/2] split cursor_tracker
- Date: Mon, 7 Apr 2014 17:31:00 +0000 (UTC)
commit 5abf41ab5a2156b8c4075ffd8de0db9d405f8a15
Author: Rui Matos <tiagomatos gmail com>
Date: Fri Apr 4 16:46:24 2014 +0200
split cursor_tracker
src/Makefile.am | 4 +
src/backends/meta-cursor-private.h | 27 +
src/backends/meta-cursor-tracker-private.h | 56 ++-
src/backends/meta-cursor-tracker.c | 599 ++++------------------
src/backends/meta-cursor.c | 280 +++++------
src/backends/meta-cursor.h | 12 -
src/backends/native/meta-cursor-tracker-native.c | 443 ++++++++++++++++
src/backends/native/meta-cursor-tracker-native.h | 43 ++
src/backends/native/meta-weston-launch.c | 3 +-
src/backends/x11/meta-cursor-tracker-x11.c | 138 +++++
src/backends/x11/meta-cursor-tracker-x11.h | 40 ++
src/core/display-private.h | 3 +
src/core/display.c | 2 +-
src/core/screen.c | 8 +-
src/wayland/meta-wayland-seat.c | 15 +-
src/wayland/meta-wayland-stage.c | 3 +-
16 files changed, 984 insertions(+), 692 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index aacec18..e001eb5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -70,12 +70,16 @@ libmutter_wayland_la_SOURCES = \
backends/meta-monitor-manager-dummy.h \
backends/edid-parse.c \
backends/edid.h \
+ backends/native/meta-cursor-tracker-native.c \
+ backends/native/meta-cursor-tracker-native.h \
backends/native/meta-idle-monitor-native.c \
backends/native/meta-idle-monitor-native.h \
backends/native/meta-monitor-manager-kms.c \
backends/native/meta-monitor-manager-kms.h \
backends/native/meta-weston-launch.c \
backends/native/meta-weston-launch.h \
+ backends/x11/meta-cursor-tracker-x11.c \
+ backends/x11/meta-cursor-tracker-x11.h \
backends/x11/meta-idle-monitor-xsync.c \
backends/x11/meta-idle-monitor-xsync.h \
backends/x11/meta-monitor-manager-xrandr.c \
diff --git a/src/backends/meta-cursor-private.h b/src/backends/meta-cursor-private.h
index b149021..dd28cf5 100644
--- a/src/backends/meta-cursor-private.h
+++ b/src/backends/meta-cursor-private.h
@@ -27,6 +27,11 @@
#include <cogl/cogl.h>
#include <gbm.h>
+#include <X11/cursorfont.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/Xcursor/Xcursor.h>
+#include <wayland-server.h>
+
typedef struct {
CoglTexture2D *texture;
struct gbm_bo *bo;
@@ -47,4 +52,26 @@ struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *hot_x,
int *hot_y);
+void meta_cursor_reference_load_gbm_buffer (MetaCursorReference *cursor,
+ struct gbm_device *gbm,
+ uint8_t *pixels,
+ int width,
+ int height,
+ int rowstride,
+ uint32_t gbm_format);
+
+void meta_cursor_reference_import_gbm_buffer (MetaCursorReference *cursor,
+ struct gbm_device *gbm,
+ struct wl_resource *buffer,
+ int width,
+ int height);
+
+MetaCursorReference *meta_cursor_reference_from_xfixes_cursor_image (XFixesCursorImage *cursor_image);
+
+MetaCursorReference *meta_cursor_reference_from_xcursor_image (XcursorImage *xc_image);
+
+MetaCursorReference *meta_cursor_reference_from_buffer (struct wl_resource *buffer,
+ int hot_x,
+ int hot_y);
+
#endif /* META_CURSOR_PRIVATE_H */
diff --git a/src/backends/meta-cursor-tracker-private.h b/src/backends/meta-cursor-tracker-private.h
index ef8de4b..c2a25e9 100644
--- a/src/backends/meta-cursor-tracker-private.h
+++ b/src/backends/meta-cursor-tracker-private.h
@@ -30,10 +30,7 @@
struct _MetaCursorTracker {
GObject parent_instance;
- MetaScreen *screen;
-
gboolean is_showing;
- gboolean has_hw_cursor;
/* The cursor tracker stores the cursor for the current grab
* operation, the cursor for the window with pointer focus, and
@@ -51,7 +48,7 @@ struct _MetaCursorTracker {
MetaCursorReference *grab_cursor;
- /* Wayland clients can set a NULL buffer as their cursor
+ /* Wayland clients can set a NULL buffer as their cursor
* explicitly, which means that we shouldn't display anything.
* So, we can't simply store a NULL in window_cursor to
* determine an unset window cursor; we need an extra boolean.
@@ -62,23 +59,37 @@ struct _MetaCursorTracker {
MetaCursorReference *root_cursor;
MetaCursorReference *theme_cursors[META_CURSOR_LAST];
-
- int current_x, current_y;
- MetaRectangle current_rect;
- MetaRectangle previous_rect;
- gboolean previous_is_valid;
-
- CoglPipeline *pipeline;
- int drm_fd;
- struct gbm_device *gbm;
};
struct _MetaCursorTrackerClass {
GObjectClass parent_class;
+
+ void (*get_pointer) (MetaCursorTracker *tracker,
+ int *x,
+ int *y,
+ ClutterModifierType *mods);
+
+ void (*sync_cursor) (MetaCursorTracker *tracker);
+
+ void (*ensure_cursor) (MetaCursorTracker *tracker);
+
+ void (*load_cursor_pixels) (MetaCursorTracker *tracker,
+ MetaCursorReference *cursor,
+ uint8_t *pixels,
+ int width,
+ int height,
+ int rowstride,
+ uint32_t format);
+
+ void (*load_cursor_buffer) (MetaCursorTracker *tracker,
+ MetaCursorReference *cursor,
+ struct wl_resource *buffer);
};
-gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
- XEvent *xevent);
+void _meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
+ gboolean has_cursor,
+ MetaCursorReference *cursor);
+void _meta_cursor_tracker_sync_cursor (MetaCursorTracker *tracker);
void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor);
@@ -87,12 +98,13 @@ void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor);
-
-void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
- int new_x,
- int new_y);
-void meta_cursor_tracker_paint (MetaCursorTracker *tracker);
-
-void meta_cursor_tracker_force_update (MetaCursorTracker *tracker);
+MetaCursorReference *
+meta_cursor_tracker_get_cursor_from_theme (MetaCursorTracker *tracker,
+ MetaCursor cursor);
+MetaCursorReference *
+meta_cursor_tracker_get_cursor_from_buffer (MetaCursorTracker *tracker,
+ struct wl_resource *buffer,
+ int hot_x,
+ int hot_y);
#endif
diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c
index 28a6af2..c0d5072 100644
--- a/src/backends/meta-cursor-tracker.c
+++ b/src/backends/meta-cursor-tracker.c
@@ -33,20 +33,11 @@
#include <meta/util.h>
#include <meta/errors.h>
-#include <cogl/cogl.h>
-#include <cogl/cogl-wayland-server.h>
-#include <clutter/clutter.h>
-#include <gbm.h>
-
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-
#include "meta-cursor-private.h"
#include "meta-cursor-tracker-private.h"
+#include "backends/native/meta-cursor-tracker-native.h"
+#include "backends/x11/meta-cursor-tracker-x11.h"
#include "screen-private.h"
-#include "meta-monitor-manager.h"
-
-#include "wayland/meta-wayland-private.h"
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
@@ -57,11 +48,6 @@ enum {
static guint signals[LAST_SIGNAL];
-static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
- MetaCRTC *crtc,
- gboolean has_hw_cursor);
-static void sync_cursor (MetaCursorTracker *tracker);
-
static void
meta_cursor_tracker_init (MetaCursorTracker *self)
{
@@ -88,102 +74,50 @@ meta_cursor_tracker_finalize (GObject *object)
if (self->theme_cursors[i])
meta_cursor_reference_unref (self->theme_cursors[i]);
- if (self->pipeline)
- cogl_object_unref (self->pipeline);
- if (self->gbm)
- gbm_device_destroy (self->gbm);
-
G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object);
}
static void
-meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
+default_do_nothing (MetaCursorTracker *tracker)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = meta_cursor_tracker_finalize;
-
- signals[CURSOR_CHANGED] = g_signal_new ("cursor-changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
}
static void
-on_monitors_changed (MetaMonitorManager *monitors,
- MetaCursorTracker *tracker)
+default_load_cursor_pixels (MetaCursorTracker *tracker,
+ MetaCursorReference *cursor,
+ uint8_t *pixels,
+ int width,
+ int height,
+ int rowstride,
+ uint32_t format)
{
- MetaCRTC *crtcs;
- unsigned int i, n_crtcs;
-
- if (!tracker->has_hw_cursor)
- return;
-
- /* Go through the new list of monitors, find out where the cursor is */
- meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
-
- for (i = 0; i < n_crtcs; i++)
- {
- MetaRectangle *rect = &crtcs[i].rect;
- gboolean has;
-
- has = meta_rectangle_overlap (&tracker->current_rect, rect);
-
- /* Need to do it unconditionally here, our tracking is
- wrong because we reloaded the CRTCs */
- meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
- }
}
-static MetaCursorTracker *
-make_wayland_cursor_tracker (MetaScreen *screen)
+static void
+default_load_cursor_buffer (MetaCursorTracker *tracker,
+ MetaCursorReference *cursor,
+ struct wl_resource *buffer)
{
- MetaWaylandCompositor *compositor;
- CoglContext *ctx;
- MetaMonitorManager *monitors;
- MetaCursorTracker *self;
-
- self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
- self->screen = screen;
-
- ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
- self->pipeline = cogl_pipeline_new (ctx);
-
- compositor = meta_wayland_compositor_get_default ();
- compositor->seat->cursor_tracker = self;
- meta_cursor_tracker_update_position (self,
- wl_fixed_to_int (compositor->seat->pointer.x),
- wl_fixed_to_int (compositor->seat->pointer.y));
-
-#if defined(CLUTTER_WINDOWING_EGL)
- if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
- {
- CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx));
- self->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
- self->gbm = gbm_create_device (self->drm_fd);
- }
-#endif
-
- monitors = meta_monitor_manager_get ();
- g_signal_connect_object (monitors, "monitors-changed",
- G_CALLBACK (on_monitors_changed), self, 0);
-
- return self;
}
-static MetaCursorTracker *
-make_x11_cursor_tracker (MetaScreen *screen)
+static void
+meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
{
- MetaCursorTracker *self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
- self->screen = screen;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- XFixesSelectCursorInput (screen->display->xdisplay,
- screen->xroot,
- XFixesDisplayCursorNotifyMask);
+ object_class->finalize = meta_cursor_tracker_finalize;
- return self;
+ klass->sync_cursor = default_do_nothing;
+ klass->ensure_cursor = default_do_nothing;
+ klass->load_cursor_pixels = default_load_cursor_pixels;
+ klass->load_cursor_buffer = default_load_cursor_buffer;
+
+ signals[CURSOR_CHANGED] = g_signal_new ("cursor-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
}
/**
@@ -203,127 +137,14 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen)
return screen->cursor_tracker;
if (meta_is_wayland_compositor ())
- self = make_wayland_cursor_tracker (screen);
+ self = g_object_new (META_TYPE_CURSOR_TRACKER_NATIVE, NULL);
else
- self = make_x11_cursor_tracker (screen);
+ self = g_object_new (META_TYPE_CURSOR_TRACKER_X11, NULL);
screen->cursor_tracker = self;
return self;
}
-static void
-set_window_cursor (MetaCursorTracker *tracker,
- gboolean has_cursor,
- MetaCursorReference *cursor)
-{
- g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref);
- if (cursor)
- tracker->window_cursor = meta_cursor_reference_ref (cursor);
- tracker->has_window_cursor = has_cursor;
- sync_cursor (tracker);
-}
-
-gboolean
-meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
- XEvent *xevent)
-{
- XFixesCursorNotifyEvent *notify_event;
-
- if (meta_is_wayland_compositor ())
- return FALSE;
-
- if (xevent->xany.type != tracker->screen->display->xfixes_event_base + XFixesCursorNotify)
- return FALSE;
-
- notify_event = (XFixesCursorNotifyEvent *)xevent;
- if (notify_event->subtype != XFixesDisplayCursorNotify)
- return FALSE;
-
- set_window_cursor (tracker, FALSE, NULL);
-
- return TRUE;
-}
-
-static MetaCursorReference *
-meta_cursor_reference_take_texture (CoglTexture2D *texture,
- int hot_x,
- int hot_y)
-{
- MetaCursorReference *self;
-
- self = g_slice_new0 (MetaCursorReference);
- self->ref_count = 1;
- self->image.texture = texture;
- self->image.hot_x = hot_x;
- self->image.hot_y = hot_y;
-
- return self;
-}
-
-static void
-ensure_xfixes_cursor (MetaCursorTracker *tracker)
-{
- XFixesCursorImage *cursor_image;
- CoglTexture2D *sprite;
- guint8 *cursor_data;
- gboolean free_cursor_data;
- CoglContext *ctx;
-
- if (tracker->has_window_cursor)
- return;
-
- cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
- if (!cursor_image)
- return;
-
- /* 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,
- NULL);
-
- if (free_cursor_data)
- g_free (cursor_data);
-
- if (sprite != NULL)
- {
- MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite,
- cursor_image->xhot,
- cursor_image->yhot);
- set_window_cursor (tracker, TRUE, cursor);
- }
- XFree (cursor_image);
-}
-
/**
* meta_cursor_tracker_get_sprite:
*
@@ -334,8 +155,7 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
{
g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL);
- if (!meta_is_wayland_compositor ())
- ensure_xfixes_cursor (tracker);
+ META_CURSOR_TRACKER_GET_CLASS (tracker)->ensure_cursor (tracker);
if (tracker->displayed_cursor)
return meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, NULL, NULL);
@@ -357,8 +177,7 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
{
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
- if (!meta_is_wayland_compositor ())
- ensure_xfixes_cursor (tracker);
+ META_CURSOR_TRACKER_GET_CLASS (tracker)->ensure_cursor (tracker);
if (tracker->displayed_cursor)
meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, x, y);
@@ -372,101 +191,51 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
}
void
-meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
- MetaCursorReference *cursor)
+_meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
+ gboolean has_cursor,
+ MetaCursorReference *cursor)
{
- g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref);
+ g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref);
if (cursor)
- tracker->grab_cursor = meta_cursor_reference_ref (cursor);
+ tracker->window_cursor = meta_cursor_reference_ref (cursor);
+ tracker->has_window_cursor = has_cursor;
- sync_cursor (tracker);
+ _meta_cursor_tracker_sync_cursor (tracker);
}
void
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor)
{
- set_window_cursor (tracker, TRUE, cursor);
+ _meta_cursor_tracker_set_window_cursor (tracker, TRUE, cursor);
}
void
meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker)
{
- set_window_cursor (tracker, FALSE, NULL);
+ _meta_cursor_tracker_set_window_cursor (tracker, FALSE, NULL);
}
void
-meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
+meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor)
{
- g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref);
+ g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref);
if (cursor)
- tracker->root_cursor = meta_cursor_reference_ref (cursor);
-
- sync_cursor (tracker);
-}
-
-static gboolean
-should_have_hw_cursor (MetaCursorTracker *tracker)
-{
- if (tracker->displayed_cursor)
- return (meta_cursor_reference_get_gbm_bo (tracker->displayed_cursor, NULL, NULL) != NULL);
- else
- return FALSE;
-}
-
-static void
-update_hw_cursor (MetaCursorTracker *tracker)
-{
- MetaMonitorManager *monitors;
- MetaCRTC *crtcs;
- unsigned int i, n_crtcs;
- gboolean enabled;
-
- enabled = should_have_hw_cursor (tracker);
- tracker->has_hw_cursor = enabled;
-
- monitors = meta_monitor_manager_get ();
- meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
-
- for (i = 0; i < n_crtcs; i++)
- {
- MetaRectangle *rect = &crtcs[i].rect;
- gboolean has;
-
- has = enabled && meta_rectangle_overlap (&tracker->current_rect, rect);
+ tracker->grab_cursor = meta_cursor_reference_ref (cursor);
- if (has || crtcs[i].has_hw_cursor)
- meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
- }
+ _meta_cursor_tracker_sync_cursor (tracker);
}
-static void
-move_hw_cursor (MetaCursorTracker *tracker)
+void
+meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
+ MetaCursorReference *cursor)
{
- MetaMonitorManager *monitors;
- MetaCRTC *crtcs;
- unsigned int i, n_crtcs;
-
- monitors = meta_monitor_manager_get ();
- meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
-
- g_assert (tracker->has_hw_cursor);
-
- for (i = 0; i < n_crtcs; i++)
- {
- MetaRectangle *rect = &crtcs[i].rect;
- gboolean has;
-
- has = meta_rectangle_overlap (&tracker->current_rect, rect);
+ g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref);
+ if (cursor)
+ tracker->root_cursor = meta_cursor_reference_ref (cursor);
- if (has != crtcs[i].has_hw_cursor)
- meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
- if (has)
- drmModeMoveCursor (tracker->drm_fd, crtcs[i].crtc_id,
- tracker->current_rect.x - rect->x,
- tracker->current_rect.y - rect->y);
- }
+ _meta_cursor_tracker_sync_cursor (tracker);
}
static MetaCursorReference *
@@ -484,25 +253,8 @@ get_displayed_cursor (MetaCursorTracker *tracker)
return tracker->root_cursor;
}
-static void
-update_displayed_cursor (MetaCursorTracker *tracker)
-{
- if (meta_is_wayland_compositor ())
- {
- if (tracker->displayed_cursor)
- {
- CoglTexture *texture = meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, NULL,
NULL);
- cogl_pipeline_set_layer_texture (tracker->pipeline, 0, texture);
- }
- else
- cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL);
-
- update_hw_cursor (tracker);
- }
-}
-
-static void
-sync_displayed_cursor (MetaCursorTracker *tracker)
+void
+_meta_cursor_tracker_sync_cursor (MetaCursorTracker *tracker)
{
MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
@@ -513,226 +265,73 @@ sync_displayed_cursor (MetaCursorTracker *tracker)
if (displayed_cursor)
tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
- update_displayed_cursor (tracker);
- g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
-}
-
-static void
-meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker)
-{
- MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
- ClutterActor *stage = compositor->stage;
- cairo_rectangle_int_t clip;
-
- g_assert (meta_is_wayland_compositor ());
-
- /* Clear the location the cursor was at before, if we need to. */
- if (tracker->previous_is_valid)
- {
- clip.x = tracker->previous_rect.x;
- clip.y = tracker->previous_rect.y;
- clip.width = tracker->previous_rect.width;
- clip.height = tracker->previous_rect.height;
- clutter_actor_queue_redraw_with_clip (stage, &clip);
- tracker->previous_is_valid = FALSE;
- }
-
- if (tracker->has_hw_cursor || !tracker->displayed_cursor)
- return;
-
- clip.x = tracker->current_rect.x;
- clip.y = tracker->current_rect.y;
- clip.width = tracker->current_rect.width;
- clip.height = tracker->current_rect.height;
- clutter_actor_queue_redraw_with_clip (stage, &clip);
-}
-
-static void
-sync_cursor (MetaCursorTracker *tracker)
-{
- MetaCursorReference *displayed_cursor;
-
- sync_displayed_cursor (tracker);
- displayed_cursor = tracker->displayed_cursor;
-
- if (displayed_cursor)
- {
- CoglTexture *texture;
- int hot_x, hot_y;
-
- texture = meta_cursor_reference_get_cogl_texture (displayed_cursor, &hot_x, &hot_y);
-
- tracker->current_rect.x = tracker->current_x - hot_x;
- tracker->current_rect.y = tracker->current_y - hot_y;
- tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
- tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
- }
- else
- {
- tracker->current_rect.x = 0;
- tracker->current_rect.y = 0;
- tracker->current_rect.width = 0;
- tracker->current_rect.height = 0;
- }
+ META_CURSOR_TRACKER_GET_CLASS (tracker)->sync_cursor (tracker);
- if (meta_is_wayland_compositor ())
- {
- if (tracker->has_hw_cursor)
- move_hw_cursor (tracker);
- else
- meta_cursor_tracker_queue_redraw (tracker);
- }
+ g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
}
void
-meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
- int new_x,
- int new_y)
+meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker,
+ int *x,
+ int *y,
+ ClutterModifierType *mods)
{
- g_assert (meta_is_wayland_compositor ());
-
- tracker->current_x = new_x;
- tracker->current_y = new_y;
-
- sync_cursor (tracker);
+ META_CURSOR_TRACKER_GET_CLASS (tracker)->get_pointer (tracker, x, y, mods);
}
void
-meta_cursor_tracker_paint (MetaCursorTracker *tracker)
+meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
+ gboolean visible)
{
- g_assert (meta_is_wayland_compositor ());
-
- if (tracker->has_hw_cursor || !tracker->displayed_cursor)
+ if (visible == tracker->is_showing)
return;
+ tracker->is_showing = visible;
- cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
- tracker->pipeline,
- tracker->current_rect.x,
- tracker->current_rect.y,
- tracker->current_rect.x +
- tracker->current_rect.width,
- tracker->current_rect.y +
- tracker->current_rect.height);
-
- tracker->previous_rect = tracker->current_rect;
- tracker->previous_is_valid = TRUE;
+ _meta_cursor_tracker_sync_cursor (tracker);
}
-static void
-meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
- MetaCRTC *crtc,
- gboolean has)
+MetaCursorReference *
+meta_cursor_tracker_get_cursor_from_theme (MetaCursorTracker *tracker,
+ MetaCursor meta_cursor)
{
- if (has)
- {
- MetaCursorReference *displayed_cursor = tracker->displayed_cursor;
- struct gbm_bo *bo;
- union gbm_bo_handle handle;
- int width, height;
- int hot_x, hot_y;
+ MetaCursorReference *cursor;
+ XcursorImage *xc_image;
- bo = meta_cursor_reference_get_gbm_bo (displayed_cursor, &hot_x, &hot_y);
+ if (tracker->theme_cursors[meta_cursor])
+ return meta_cursor_reference_ref (tracker->theme_cursors[meta_cursor]);
- handle = gbm_bo_get_handle (bo);
- width = gbm_bo_get_width (bo);
- height = gbm_bo_get_height (bo);
+ xc_image = meta_display_load_x_cursor (meta_get_display (), meta_cursor);
+ if (!xc_image)
+ return NULL;
- drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, handle.u32,
- width, height, hot_x, hot_y);
- crtc->has_hw_cursor = TRUE;
- }
- else
- {
- drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
- crtc->has_hw_cursor = FALSE;
- }
-}
+ cursor = meta_cursor_reference_from_xcursor_image (xc_image);
-static void
-get_pointer_position_gdk (int *x,
- int *y,
- int *mods)
-{
- GdkDeviceManager *gmanager;
- GdkDevice *gdevice;
- GdkScreen *gscreen;
-
- gmanager = gdk_display_get_device_manager (gdk_display_get_default ());
- gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
-
- gdk_device_get_position (gdevice, &gscreen, x, y);
- if (mods)
- gdk_device_get_state (gdevice,
- gdk_screen_get_root_window (gscreen),
- NULL, (GdkModifierType*)mods);
-}
+ META_CURSOR_TRACKER_GET_CLASS (tracker)->load_cursor_pixels (tracker,
+ cursor,
+ (uint8_t *) xc_image->pixels,
+ xc_image->width,
+ xc_image->height,
+ xc_image->width * 4,
+ GBM_FORMAT_ARGB8888);
+ XcursorImageDestroy (xc_image);
-static void
-get_pointer_position_clutter (int *x,
- int *y,
- int *mods)
-{
- ClutterDeviceManager *cmanager;
- ClutterInputDevice *cdevice;
- ClutterPoint point;
-
- cmanager = clutter_device_manager_get_default ();
- cdevice = clutter_device_manager_get_core_device (cmanager, CLUTTER_POINTER_DEVICE);
-
- clutter_input_device_get_coords (cdevice, NULL, &point);
- if (x)
- *x = point.x;
- if (y)
- *y = point.y;
- if (mods)
- *mods = clutter_input_device_get_modifier_state (cdevice);
-}
+ tracker->theme_cursors[meta_cursor] = cursor;
-void
-meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker,
- int *x,
- int *y,
- ClutterModifierType *mods)
-{
- /* We can't use the clutter interface when not running as a wayland compositor,
- because we need to query the server, rather than using the last cached value.
- OTOH, on wayland we can't use GDK, because that only sees the events
- we forward to xwayland.
- */
- if (meta_is_wayland_compositor ())
- get_pointer_position_clutter (x, y, (int*)mods);
- else
- get_pointer_position_gdk (x, y, (int*)mods);
+ return meta_cursor_reference_ref (cursor);
}
-void
-meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
- gboolean visible)
+MetaCursorReference *
+meta_cursor_tracker_get_cursor_from_buffer (MetaCursorTracker *tracker,
+ struct wl_resource *buffer,
+ int hot_x,
+ int hot_y)
{
- if (visible == tracker->is_showing)
- return;
- tracker->is_showing = visible;
-
- if (meta_is_wayland_compositor ())
- {
- sync_cursor (tracker);
- }
- else
- {
- if (visible)
- XFixesShowCursor (tracker->screen->display->xdisplay,
- tracker->screen->xroot);
- else
- XFixesHideCursor (tracker->screen->display->xdisplay,
- tracker->screen->xroot);
- }
-}
+ MetaCursorReference *cursor;
-void
-meta_cursor_tracker_force_update (MetaCursorTracker *tracker)
-{
- g_assert (meta_is_wayland_compositor ());
+ cursor = meta_cursor_reference_from_buffer (buffer, hot_x, hot_y);
- update_hw_cursor (tracker);
- sync_cursor (tracker);
+ META_CURSOR_TRACKER_GET_CLASS (tracker)->load_cursor_buffer (tracker,
+ cursor,
+ buffer);
+ return cursor;
}
diff --git a/src/backends/meta-cursor.c b/src/backends/meta-cursor.c
index 2a78328..5551ef5 100644
--- a/src/backends/meta-cursor.c
+++ b/src/backends/meta-cursor.c
@@ -27,16 +27,23 @@
#include "display-private.h"
#include "screen-private.h"
-#include "meta-cursor-tracker-private.h" /* for tracker->gbm */
+#include "meta-cursor-tracker-private.h"
#include <string.h>
-#include <X11/cursorfont.h>
-#include <X11/extensions/Xfixes.h>
-#include <X11/Xcursor/Xcursor.h>
-
#include <cogl/cogl-wayland-server.h>
+static MetaCursorReference *
+meta_cursor_reference_new (void)
+{
+ MetaCursorReference *self;
+
+ self = g_slice_new0 (MetaCursorReference);
+ self->ref_count = 1;
+
+ return self;
+}
+
MetaCursorReference *
meta_cursor_reference_ref (MetaCursorReference *self)
{
@@ -190,14 +197,21 @@ load_cursor_on_client (MetaDisplay *display,
return image;
}
-static void
-meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
- MetaCursorImage *image,
- uint8_t *pixels,
- int width,
- int height,
- int rowstride,
- uint32_t gbm_format)
+XcursorImage *
+meta_display_load_x_cursor (MetaDisplay *display,
+ MetaCursor cursor)
+{
+ return load_cursor_on_client (display, cursor);
+}
+
+void
+meta_cursor_reference_load_gbm_buffer (MetaCursorReference *cursor,
+ struct gbm_device *gbm,
+ uint8_t *pixels,
+ int width,
+ int height,
+ int rowstride,
+ uint32_t gbm_format)
{
if (width > 64 || height > 64)
{
@@ -211,180 +225,154 @@ meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
uint8_t buf[4 * 64 * 64];
int i;
- image->bo = gbm_bo_create (gbm, 64, 64,
- gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
+ cursor->image.bo = gbm_bo_create (gbm, 64, 64,
+ gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
memset (buf, 0, sizeof(buf));
for (i = 0; i < height; i++)
memcpy (buf + i * 4 * 64, pixels + i * rowstride, width * 4);
- gbm_bo_write (image->bo, buf, 64 * 64 * 4);
+ gbm_bo_write (cursor->image.bo, buf, 64 * 64 * 4);
}
else
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
}
-static void
-meta_cursor_image_load_from_xcursor_image (MetaCursorTracker *tracker,
- MetaCursorImage *image,
- XcursorImage *xc_image)
+void
+meta_cursor_reference_import_gbm_buffer (MetaCursorReference *cursor,
+ struct gbm_device *gbm,
+ struct wl_resource *buffer,
+ int width,
+ int height)
{
+ /* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses
+ that, so themed cursors must be padded with transparent pixels to fill the
+ overlay. This is trivial if we have CPU access to the data, but it's not
+ possible if the buffer is in GPU memory (and possibly tiled too), so if we
+ don't get the right size, we fallback to GL.
+ */
+ if (width != 64 || height != 64)
+ {
+ meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
+ return;
+ }
+
+ cursor->image.bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER,
+ buffer, GBM_BO_USE_CURSOR_64X64);
+ if (!cursor->image.bo)
+ meta_warning ("Importing HW cursor from wl_buffer failed\n");
+}
+
+MetaCursorReference *
+meta_cursor_reference_from_xfixes_cursor_image (XFixesCursorImage *cursor_image)
+{
+ MetaCursorReference *cursor;
+ CoglTexture2D *sprite;
+ CoglContext *ctx;
+ guint8 *cursor_data;
+ gboolean free_cursor_data;
+
+ cursor = meta_cursor_reference_new ();
+
+ /* 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,
+ NULL);
+ if (free_cursor_data)
+ g_free (cursor_data);
+
+ cursor->image.texture = sprite;
+ cursor->image.hot_x = cursor_image->xhot;
+ cursor->image.hot_y = cursor_image->yhot;
+
+ return cursor;
+}
+
+MetaCursorReference *
+meta_cursor_reference_from_xcursor_image (XcursorImage *xc_image)
+{
+ MetaCursorReference *cursor;
int width, height, rowstride;
CoglPixelFormat cogl_format;
- uint32_t gbm_format;
ClutterBackend *clutter_backend;
CoglContext *cogl_context;
+ cursor = meta_cursor_reference_new ();
+
width = xc_image->width;
height = xc_image->height;
rowstride = width * 4;
- gbm_format = GBM_FORMAT_ARGB8888;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
#else
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
#endif
- image->hot_x = xc_image->xhot;
- image->hot_y = xc_image->yhot;
+ cursor->image.hot_x = xc_image->xhot;
+ cursor->image.hot_y = xc_image->yhot;
clutter_backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
- image->texture = cogl_texture_2d_new_from_data (cogl_context,
- width, height,
- cogl_format,
- rowstride,
- (uint8_t *) xc_image->pixels,
- NULL);
-
- if (tracker->gbm)
- meta_cursor_image_load_gbm_buffer (tracker->gbm,
- image,
- (uint8_t *) xc_image->pixels,
- width, height, rowstride,
- gbm_format);
+ cursor->image.texture = cogl_texture_2d_new_from_data (cogl_context,
+ width, height,
+ cogl_format,
+ rowstride,
+ (uint8_t *) xc_image->pixels,
+ NULL);
+ return cursor;
}
MetaCursorReference *
-meta_cursor_reference_from_theme (MetaCursorTracker *tracker,
- MetaCursor cursor)
-{
- MetaCursorReference *self;
- XcursorImage *image;
-
- if (tracker->theme_cursors[cursor])
- return meta_cursor_reference_ref (tracker->theme_cursors[cursor]);
-
- image = load_cursor_on_client (tracker->screen->display, cursor);
- if (!image)
- return NULL;
-
- self = g_slice_new0 (MetaCursorReference);
- self->ref_count = 1;
- meta_cursor_image_load_from_xcursor_image (tracker, &self->image, image);
-
- XcursorImageDestroy (image);
- return self;
-}
-
-static void
-meta_cursor_image_load_from_buffer (MetaCursorTracker *tracker,
- MetaCursorImage *image,
- struct wl_resource *buffer,
- int hot_x,
- int hot_y)
+meta_cursor_reference_from_buffer (struct wl_resource *buffer,
+ int hot_x,
+ int hot_y)
{
+ MetaCursorReference *cursor;
ClutterBackend *backend;
CoglContext *cogl_context;
- struct wl_shm_buffer *shm_buffer;
- uint32_t gbm_format;
- int width, height;
- image->hot_x = hot_x;
- image->hot_y = hot_y;
+ cursor = meta_cursor_reference_new ();
+
+ cursor->image.hot_x = hot_x;
+ cursor->image.hot_y = hot_y;
backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (backend);
- image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
-
- width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
- height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
+ cursor->image.texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
- shm_buffer = wl_shm_buffer_get (buffer);
- if (shm_buffer)
- {
- if (tracker->gbm)
- {
- int rowstride = wl_shm_buffer_get_stride (shm_buffer);
-
- switch (wl_shm_buffer_get_format (shm_buffer))
- {
-#if G_BYTE_ORDER == G_BIG_ENDIAN
- case WL_SHM_FORMAT_ARGB8888:
- gbm_format = GBM_FORMAT_ARGB8888;
- break;
- case WL_SHM_FORMAT_XRGB8888:
- gbm_format = GBM_FORMAT_XRGB8888;
- break;
-#else
- case WL_SHM_FORMAT_ARGB8888:
- gbm_format = GBM_FORMAT_ARGB8888;
- break;
- case WL_SHM_FORMAT_XRGB8888:
- gbm_format = GBM_FORMAT_XRGB8888;
- break;
-#endif
- default:
- g_warn_if_reached ();
- gbm_format = GBM_FORMAT_ARGB8888;
- }
-
- meta_cursor_image_load_gbm_buffer (tracker->gbm,
- image,
- (uint8_t *) wl_shm_buffer_get_data (shm_buffer),
- width, height, rowstride,
- gbm_format);
- }
- }
- else
- {
- /* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses
- that, so themed cursors must be padded with transparent pixels to fill the
- overlay. This is trivial if we have CPU access to the data, but it's not
- possible if the buffer is in GPU memory (and possibly tiled too), so if we
- don't get the right size, we fallback to GL.
- */
- if (width != 64 || height != 64)
- {
- meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
- return;
- }
-
- if (tracker->gbm)
- {
- image->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
- buffer, GBM_BO_USE_CURSOR_64X64);
- if (!image->bo)
- meta_warning ("Importing HW cursor from wl_buffer failed\n");
- }
- }
-}
-
-MetaCursorReference *
-meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
- struct wl_resource *buffer,
- int hot_x,
- int hot_y)
-{
- MetaCursorReference *self;
-
- self = g_slice_new0 (MetaCursorReference);
- self->ref_count = 1;
- meta_cursor_image_load_from_buffer (tracker, &self->image, buffer, hot_x, hot_y);
-
- return self;
+ return cursor;
}
CoglTexture *
diff --git a/src/backends/meta-cursor.h b/src/backends/meta-cursor.h
index 50ad086..6d5bc3e 100644
--- a/src/backends/meta-cursor.h
+++ b/src/backends/meta-cursor.h
@@ -27,16 +27,4 @@ typedef struct _MetaCursorReference MetaCursorReference;
MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor);
void meta_cursor_reference_unref (MetaCursorReference *cursor);
-#include <meta/meta-cursor-tracker.h>
-#include <meta/common.h>
-#include <wayland-server.h>
-
-MetaCursorReference * meta_cursor_reference_from_theme (MetaCursorTracker *tracker,
- MetaCursor cursor);
-
-MetaCursorReference * meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
- struct wl_resource *buffer,
- int hot_x,
- int hot_y);
-
#endif /* META_CURSOR_H */
diff --git a/src/backends/native/meta-cursor-tracker-native.c
b/src/backends/native/meta-cursor-tracker-native.c
new file mode 100644
index 0000000..e3093ed
--- /dev/null
+++ b/src/backends/native/meta-cursor-tracker-native.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2014 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/>.
+ */
+
+#include "config.h"
+
+#include <cogl/cogl.h>
+#include <cogl/cogl-wayland-server.h>
+#include <clutter/clutter.h>
+#include <gbm.h>
+
+#include "display-private.h"
+#include "meta-cursor-tracker-native.h"
+#include "meta-cursor-tracker-private.h"
+#include "meta-monitor-manager.h"
+#include "meta-cursor-private.h"
+
+#include "wayland/meta-wayland-private.h"
+
+struct _MetaCursorTrackerNative
+{
+ MetaCursorTracker parent;
+
+ gboolean has_hw_cursor;
+
+ int current_x, current_y;
+ MetaRectangle current_rect;
+ MetaRectangle previous_rect;
+ gboolean previous_is_valid;
+
+ CoglPipeline *pipeline;
+ int drm_fd;
+ struct gbm_device *gbm;
+};
+
+struct _MetaCursorTrackerNativeClass
+{
+ MetaCursorTrackerClass parent_class;
+};
+
+G_DEFINE_TYPE (MetaCursorTrackerNative, meta_cursor_tracker_native, META_TYPE_CURSOR_TRACKER);
+
+static void
+meta_cursor_tracker_native_load_cursor_pixels (MetaCursorTracker *tracker,
+ MetaCursorReference *cursor,
+ uint8_t *pixels,
+ int width,
+ int height,
+ int rowstride,
+ uint32_t format)
+{
+ MetaCursorTrackerNative *self = META_CURSOR_TRACKER_NATIVE (tracker);
+
+ if (!self->gbm)
+ return;
+
+ meta_cursor_reference_load_gbm_buffer (cursor,
+ self->gbm,
+ pixels,
+ width, height, rowstride,
+ format);
+}
+
+static void
+meta_cursor_tracker_native_load_cursor_buffer (MetaCursorTracker *tracker,
+ MetaCursorReference *cursor,
+ struct wl_resource *buffer)
+{
+ struct wl_shm_buffer *shm_buffer;
+ int width, height;
+
+ width = cogl_texture_get_width (COGL_TEXTURE (cursor->image.texture));
+ height = cogl_texture_get_height (COGL_TEXTURE (cursor->image.texture));
+
+ shm_buffer = wl_shm_buffer_get (buffer);
+ if (shm_buffer)
+ {
+ uint32_t gbm_format;
+ uint8_t *pixels = wl_shm_buffer_get_data (shm_buffer);
+ int rowstride = wl_shm_buffer_get_stride (shm_buffer);
+
+ switch (wl_shm_buffer_get_format (shm_buffer))
+ {
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+ case WL_SHM_FORMAT_ARGB8888:
+ gbm_format = GBM_FORMAT_ARGB8888;
+ break;
+ case WL_SHM_FORMAT_XRGB8888:
+ gbm_format = GBM_FORMAT_XRGB8888;
+ break;
+#else
+ case WL_SHM_FORMAT_ARGB8888:
+ gbm_format = GBM_FORMAT_ARGB8888;
+ break;
+ case WL_SHM_FORMAT_XRGB8888:
+ gbm_format = GBM_FORMAT_XRGB8888;
+ break;
+#endif
+ default:
+ g_warn_if_reached ();
+ gbm_format = GBM_FORMAT_ARGB8888;
+ }
+
+ meta_cursor_tracker_native_load_cursor_pixels (tracker,
+ cursor,
+ pixels,
+ width,
+ height,
+ rowstride,
+ gbm_format);
+ }
+ else
+ {
+ MetaCursorTrackerNative *self = META_CURSOR_TRACKER_NATIVE (tracker);
+ if (!self->gbm)
+ return;
+ meta_cursor_reference_import_gbm_buffer (cursor, self->gbm, buffer, width, height);
+ }
+}
+
+static void
+set_crtc_has_hw_cursor (MetaCursorTrackerNative *self,
+ MetaCRTC *crtc,
+ gboolean has)
+{
+ MetaCursorTracker *tracker = META_CURSOR_TRACKER (self);
+
+ if (has)
+ {
+ MetaCursorReference *displayed_cursor = tracker->displayed_cursor;
+ struct gbm_bo *bo;
+ union gbm_bo_handle handle;
+ int width, height;
+ int hot_x, hot_y;
+
+ bo = meta_cursor_reference_get_gbm_bo (displayed_cursor, &hot_x, &hot_y);
+
+ handle = gbm_bo_get_handle (bo);
+ width = gbm_bo_get_width (bo);
+ height = gbm_bo_get_height (bo);
+
+ drmModeSetCursor2 (self->drm_fd, crtc->crtc_id, handle.u32,
+ width, height, hot_x, hot_y);
+ crtc->has_hw_cursor = TRUE;
+ }
+ else
+ {
+ drmModeSetCursor2 (self->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
+ crtc->has_hw_cursor = FALSE;
+ }
+}
+
+static void
+on_monitors_changed (MetaMonitorManager *monitors,
+ MetaCursorTrackerNative *self)
+{
+ MetaCRTC *crtcs;
+ unsigned int i, n_crtcs;
+
+ if (!self->has_hw_cursor)
+ return;
+
+ /* Go through the new list of monitors, find out where the cursor is */
+ meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
+
+ for (i = 0; i < n_crtcs; i++)
+ {
+ MetaRectangle *rect = &crtcs[i].rect;
+ gboolean has;
+
+ has = meta_rectangle_overlap (&self->current_rect, rect);
+
+ /* Need to do it unconditionally here, our tracking is
+ wrong because we reloaded the CRTCs */
+ set_crtc_has_hw_cursor (self, &crtcs[i], has);
+ }
+}
+
+static gboolean
+should_have_hw_cursor (MetaCursorTrackerNative *self)
+{
+ MetaCursorTracker *tracker = META_CURSOR_TRACKER (self);
+
+ if (tracker->displayed_cursor)
+ return (meta_cursor_reference_get_gbm_bo (tracker->displayed_cursor, NULL, NULL) != NULL);
+ else
+ return FALSE;
+}
+
+static void
+update_hw_cursor (MetaCursorTrackerNative *self)
+{
+ MetaMonitorManager *monitors;
+ MetaCRTC *crtcs;
+ unsigned int i, n_crtcs;
+ gboolean enabled;
+
+ enabled = should_have_hw_cursor (self);
+ self->has_hw_cursor = enabled;
+
+ monitors = meta_monitor_manager_get ();
+ meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
+
+ for (i = 0; i < n_crtcs; i++)
+ {
+ MetaRectangle *rect = &crtcs[i].rect;
+ gboolean has;
+
+ has = enabled && meta_rectangle_overlap (&self->current_rect, rect);
+
+ if (has || crtcs[i].has_hw_cursor)
+ set_crtc_has_hw_cursor (self, &crtcs[i], has);
+ }
+}
+
+static void
+move_hw_cursor (MetaCursorTrackerNative *self)
+{
+ MetaMonitorManager *monitors;
+ MetaCRTC *crtcs;
+ unsigned int i, n_crtcs;
+
+ monitors = meta_monitor_manager_get ();
+ meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
+
+ g_assert (self->has_hw_cursor);
+
+ for (i = 0; i < n_crtcs; i++)
+ {
+ MetaRectangle *rect = &crtcs[i].rect;
+ gboolean has;
+
+ has = meta_rectangle_overlap (&self->current_rect, rect);
+
+ if (has != crtcs[i].has_hw_cursor)
+ set_crtc_has_hw_cursor (self, &crtcs[i], has);
+ if (has)
+ drmModeMoveCursor (self->drm_fd, crtcs[i].crtc_id,
+ self->current_rect.x - rect->x,
+ self->current_rect.y - rect->y);
+ }
+}
+
+static void
+queue_redraw (MetaCursorTrackerNative *self)
+{
+ MetaCursorTracker *tracker = META_CURSOR_TRACKER (self);
+ MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+ ClutterActor *stage = compositor->stage;
+ cairo_rectangle_int_t clip;
+
+ /* Clear the location the cursor was at before, if we need to. */
+ if (self->previous_is_valid)
+ {
+ clip.x = self->previous_rect.x;
+ clip.y = self->previous_rect.y;
+ clip.width = self->previous_rect.width;
+ clip.height = self->previous_rect.height;
+ clutter_actor_queue_redraw_with_clip (stage, &clip);
+ self->previous_is_valid = FALSE;
+ }
+
+ if (self->has_hw_cursor || !tracker->displayed_cursor)
+ return;
+
+ clip.x = self->current_rect.x;
+ clip.y = self->current_rect.y;
+ clip.width = self->current_rect.width;
+ clip.height = self->current_rect.height;
+ clutter_actor_queue_redraw_with_clip (stage, &clip);
+}
+
+static void
+meta_cursor_tracker_native_sync_cursor (MetaCursorTracker *tracker)
+{
+ MetaCursorTrackerNative *self = META_CURSOR_TRACKER_NATIVE (tracker);
+ MetaCursorReference *displayed_cursor;
+
+ displayed_cursor = tracker->displayed_cursor;
+
+ if (displayed_cursor)
+ {
+ CoglTexture *texture;
+ int hot_x, hot_y;
+
+ texture = meta_cursor_reference_get_cogl_texture (displayed_cursor, &hot_x, &hot_y);
+ cogl_pipeline_set_layer_texture (self->pipeline, 0, texture);
+
+ self->current_rect.x = self->current_x - hot_x;
+ self->current_rect.y = self->current_y - hot_y;
+ self->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
+ self->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
+ }
+ else
+ {
+ cogl_pipeline_set_layer_texture (self->pipeline, 0, NULL);
+
+ self->current_rect.x = 0;
+ self->current_rect.y = 0;
+ self->current_rect.width = 0;
+ self->current_rect.height = 0;
+ }
+
+ update_hw_cursor (self);
+
+ if (self->has_hw_cursor)
+ move_hw_cursor (self);
+ else
+ queue_redraw (self);
+}
+
+static void
+meta_cursor_tracker_native_get_pointer (MetaCursorTracker *tracker,
+ int *x,
+ int *y,
+ ClutterModifierType *mods)
+{
+ ClutterDeviceManager *cmanager;
+ ClutterInputDevice *cdevice;
+ ClutterPoint point;
+
+ /* On wayland we can't use GDK, because that only sees the events we
+ * forward to xwayland.
+ */
+ cmanager = clutter_device_manager_get_default ();
+ cdevice = clutter_device_manager_get_core_device (cmanager, CLUTTER_POINTER_DEVICE);
+
+ clutter_input_device_get_coords (cdevice, NULL, &point);
+ if (x)
+ *x = point.x;
+ if (y)
+ *y = point.y;
+ if (mods)
+ *mods = clutter_input_device_get_modifier_state (cdevice);
+}
+
+static void
+meta_cursor_tracker_native_finalize (GObject *object)
+{
+ MetaCursorTrackerNative *self = META_CURSOR_TRACKER_NATIVE (object);
+
+ if (self->pipeline)
+ cogl_object_unref (self->pipeline);
+ if (self->gbm)
+ gbm_device_destroy (self->gbm);
+
+ G_OBJECT_CLASS (meta_cursor_tracker_native_parent_class)->finalize (object);
+}
+
+static void
+meta_cursor_tracker_native_class_init (MetaCursorTrackerNativeClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ MetaCursorTrackerClass *cursor_tracker_class = META_CURSOR_TRACKER_CLASS (klass);
+
+ object_class->finalize = meta_cursor_tracker_native_finalize;
+
+ cursor_tracker_class->get_pointer = meta_cursor_tracker_native_get_pointer;
+ cursor_tracker_class->sync_cursor = meta_cursor_tracker_native_sync_cursor;
+ cursor_tracker_class->load_cursor_pixels = meta_cursor_tracker_native_load_cursor_pixels;
+ cursor_tracker_class->load_cursor_buffer = meta_cursor_tracker_native_load_cursor_buffer;
+}
+
+static void
+meta_cursor_tracker_native_init (MetaCursorTrackerNative *self)
+{
+ MetaWaylandCompositor *compositor;
+ CoglContext *ctx;
+ MetaMonitorManager *monitors;
+
+ ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
+ self->pipeline = cogl_pipeline_new (ctx);
+
+ compositor = meta_wayland_compositor_get_default ();
+ compositor->seat->cursor_tracker = META_CURSOR_TRACKER (self);
+ meta_cursor_tracker_native_update_position (self,
+ wl_fixed_to_int (compositor->seat->pointer.x),
+ wl_fixed_to_int (compositor->seat->pointer.y));
+
+#if defined(CLUTTER_WINDOWING_EGL)
+ if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
+ {
+ CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx));
+ self->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
+ self->gbm = gbm_create_device (self->drm_fd);
+ }
+#endif
+
+ monitors = meta_monitor_manager_get ();
+ g_signal_connect_object (monitors, "monitors-changed",
+ G_CALLBACK (on_monitors_changed), self, 0);
+}
+
+void
+meta_cursor_tracker_native_update_position (MetaCursorTrackerNative *self,
+ int new_x,
+ int new_y)
+{
+ self->current_x = new_x;
+ self->current_y = new_y;
+
+ _meta_cursor_tracker_sync_cursor (META_CURSOR_TRACKER (self));
+}
+
+void
+meta_cursor_tracker_native_paint (MetaCursorTrackerNative *self)
+{
+ MetaCursorTracker *tracker = META_CURSOR_TRACKER (self);
+
+ if (self->has_hw_cursor || !tracker->displayed_cursor)
+ return;
+
+ cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
+ self->pipeline,
+ self->current_rect.x,
+ self->current_rect.y,
+ self->current_rect.x +
+ self->current_rect.width,
+ self->current_rect.y +
+ self->current_rect.height);
+
+ self->previous_rect = self->current_rect;
+ self->previous_is_valid = TRUE;
+}
+
+void
+meta_cursor_tracker_native_force_update (MetaCursorTrackerNative *self)
+{
+ _meta_cursor_tracker_sync_cursor (META_CURSOR_TRACKER (self));
+}
diff --git a/src/backends/native/meta-cursor-tracker-native.h
b/src/backends/native/meta-cursor-tracker-native.h
new file mode 100644
index 0000000..9f969de
--- /dev/null
+++ b/src/backends/native/meta-cursor-tracker-native.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2014 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/>.
+ */
+
+#ifndef META_CURSOR_TRACKER_NATIVE_H
+#define META_CURSOR_TRACKER_NATIVE_H
+
+#include <glib-object.h>
+#include <meta/meta-cursor-tracker.h>
+
+#define META_TYPE_CURSOR_TRACKER_NATIVE (meta_cursor_tracker_native_get_type ())
+#define META_CURSOR_TRACKER_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
META_TYPE_CURSOR_TRACKER_NATIVE, MetaCursorTrackerNative))
+#define META_CURSOR_TRACKER_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
META_TYPE_CURSOR_TRACKER_NATIVE, MetaCursorTrackerNativeClass))
+#define META_IS_CURSOR_TRACKER_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
META_TYPE_CURSOR_TRACKER_NATIVE))
+#define META_IS_CURSOR_TRACKER_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
META_TYPE_CURSOR_TRACKER_NATIVE))
+#define META_CURSOR_TRACKER_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
META_TYPE_CURSOR_TRACKER_NATIVE, MetaCursorTrackerNativeClass))
+
+typedef struct _MetaCursorTrackerNative MetaCursorTrackerNative;
+typedef struct _MetaCursorTrackerNativeClass MetaCursorTrackerNativeClass;
+
+GType meta_cursor_tracker_native_get_type (void);
+
+void meta_cursor_tracker_native_update_position (MetaCursorTrackerNative *tracker,
+ int new_x,
+ int new_y);
+void meta_cursor_tracker_native_paint (MetaCursorTrackerNative *tracker);
+
+void meta_cursor_tracker_native_force_update (MetaCursorTrackerNative *tracker);
+
+#endif /* META_CURSOR_TRACKER_NATIVE_H */
diff --git a/src/backends/native/meta-weston-launch.c b/src/backends/native/meta-weston-launch.c
index a77b2ea..43d7d25 100644
--- a/src/backends/native/meta-weston-launch.c
+++ b/src/backends/native/meta-weston-launch.c
@@ -44,6 +44,7 @@
#include "wayland/meta-wayland-private.h"
#include "meta-cursor-tracker-private.h"
+#include "meta-cursor-tracker-native.h"
#include "meta-weston-launch.h"
struct _MetaLauncher
@@ -219,7 +220,7 @@ meta_launcher_enter (MetaLauncher *launcher)
* update. */
clutter_actor_queue_redraw (compositor->stage);
- meta_cursor_tracker_force_update (compositor->seat->cursor_tracker);
+ meta_cursor_tracker_native_force_update (META_CURSOR_TRACKER_NATIVE (compositor->seat->cursor_tracker));
}
}
diff --git a/src/backends/x11/meta-cursor-tracker-x11.c b/src/backends/x11/meta-cursor-tracker-x11.c
new file mode 100644
index 0000000..d775275
--- /dev/null
+++ b/src/backends/x11/meta-cursor-tracker-x11.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2014 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/>.
+ */
+
+#include "config.h"
+
+#include <gdk/gdkx.h>
+
+#include <meta/errors.h>
+
+#include "display-private.h"
+#include "meta-cursor-tracker-x11.h"
+#include "meta-cursor-tracker-private.h"
+#include "meta-cursor-private.h"
+
+struct _MetaCursorTrackerX11
+{
+ MetaCursorTracker parent;
+};
+
+struct _MetaCursorTrackerX11Class
+{
+ MetaCursorTrackerClass parent_class;
+};
+
+G_DEFINE_TYPE (MetaCursorTrackerX11, meta_cursor_tracker_x11, META_TYPE_CURSOR_TRACKER);
+
+static void
+meta_cursor_tracker_x11_get_pointer (MetaCursorTracker *tracker,
+ int *x,
+ int *y,
+ ClutterModifierType *mods)
+{
+ GdkDeviceManager *gmanager;
+ GdkDevice *gdevice;
+ GdkScreen *gscreen;
+
+ /* We can't use the clutter interface when not running as a wayland
+ * compositor, because we need to query the server, rather than
+ * using the last cached value.
+ */
+ gmanager = gdk_display_get_device_manager (gdk_display_get_default ());
+ gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
+
+ gdk_device_get_position (gdevice, &gscreen, x, y);
+ if (mods)
+ gdk_device_get_state (gdevice,
+ gdk_screen_get_root_window (gscreen),
+ NULL, (GdkModifierType*)mods);
+}
+
+static void
+meta_cursor_tracker_x11_sync_cursor (MetaCursorTracker *tracker)
+{
+ MetaDisplay *display = meta_get_display ();
+
+ meta_error_trap_push (display);
+ if (tracker->is_showing)
+ XFixesShowCursor (display->xdisplay,
+ DefaultRootWindow (display->xdisplay));
+ else
+ XFixesHideCursor (display->xdisplay,
+ DefaultRootWindow (display->xdisplay));
+ meta_error_trap_pop (display);
+}
+
+static void
+meta_cursor_tracker_x11_ensure_cursor (MetaCursorTracker *tracker)
+{
+ MetaDisplay *display = meta_get_display ();
+ XFixesCursorImage *cursor_image;
+ MetaCursorReference *cursor;
+
+ if (tracker->has_window_cursor)
+ return;
+
+ cursor_image = XFixesGetCursorImage (display->xdisplay);
+ if (!cursor_image)
+ return;
+
+ cursor = meta_cursor_reference_from_xfixes_cursor_image (cursor_image);
+
+ _meta_cursor_tracker_set_window_cursor (tracker, TRUE, cursor);
+
+ XFree (cursor_image);
+}
+
+static void
+meta_cursor_tracker_x11_class_init (MetaCursorTrackerX11Class *klass)
+{
+ MetaCursorTrackerClass *cursor_tracker_class = META_CURSOR_TRACKER_CLASS (klass);
+
+ cursor_tracker_class->get_pointer = meta_cursor_tracker_x11_get_pointer;
+ cursor_tracker_class->sync_cursor = meta_cursor_tracker_x11_sync_cursor;
+ cursor_tracker_class->ensure_cursor = meta_cursor_tracker_x11_ensure_cursor;
+}
+
+static void
+meta_cursor_tracker_x11_init (MetaCursorTrackerX11 *self)
+{
+ MetaDisplay *display = meta_get_display ();
+
+ XFixesSelectCursorInput (display->xdisplay,
+ DefaultRootWindow (display->xdisplay),
+ XFixesDisplayCursorNotifyMask);
+}
+
+gboolean
+meta_cursor_tracker_x11_handle_xevent (MetaCursorTrackerX11 *tracker,
+ XEvent *xevent)
+{
+ MetaDisplay *display = meta_get_display ();
+ XFixesCursorNotifyEvent *notify_event;
+
+ if (xevent->xany.type != display->xfixes_event_base + XFixesCursorNotify)
+ return FALSE;
+
+ notify_event = (XFixesCursorNotifyEvent *)xevent;
+ if (notify_event->subtype != XFixesDisplayCursorNotify)
+ return FALSE;
+
+ _meta_cursor_tracker_set_window_cursor (META_CURSOR_TRACKER (tracker), FALSE, NULL);
+
+ return TRUE;
+}
diff --git a/src/backends/x11/meta-cursor-tracker-x11.h b/src/backends/x11/meta-cursor-tracker-x11.h
new file mode 100644
index 0000000..30b8446
--- /dev/null
+++ b/src/backends/x11/meta-cursor-tracker-x11.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2014 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/>.
+ */
+
+#ifndef META_CURSOR_TRACKER_X11_H
+#define META_CURSOR_TRACKER_X11_H
+
+#include <glib-object.h>
+#include <meta/meta-cursor-tracker.h>
+
+#define META_TYPE_CURSOR_TRACKER_X11 (meta_cursor_tracker_x11_get_type ())
+#define META_CURSOR_TRACKER_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
META_TYPE_CURSOR_TRACKER_X11, MetaCursorTrackerX11))
+#define META_CURSOR_TRACKER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
META_TYPE_CURSOR_TRACKER_X11, MetaCursorTrackerX11Class))
+#define META_IS_CURSOR_TRACKER_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
META_TYPE_CURSOR_TRACKER_X11))
+#define META_IS_CURSOR_TRACKER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
META_TYPE_CURSOR_TRACKER_X11))
+#define META_CURSOR_TRACKER_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
META_TYPE_CURSOR_TRACKER_X11, MetaCursorTrackerX11Class))
+
+typedef struct _MetaCursorTrackerX11 MetaCursorTrackerX11;
+typedef struct _MetaCursorTrackerX11Class MetaCursorTrackerX11Class;
+
+GType meta_cursor_tracker_x11_get_type (void);
+
+gboolean
+meta_cursor_tracker_x11_handle_xevent (MetaCursorTrackerX11 *tracker,
+ XEvent *xevent);
+
+#endif /* META_CURSOR_TRACKER_X11_H */
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 1b8355c..64751d0 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -31,6 +31,7 @@
#include <glib.h>
#include <X11/Xlib.h>
+#include <X11/Xcursor/Xcursor.h>
#include <meta/common.h>
#include <meta/boxes.h>
#include <meta/display.h>
@@ -397,6 +398,8 @@ MetaDisplay* meta_get_display (void);
Cursor meta_display_create_x_cursor (MetaDisplay *display,
MetaCursor cursor);
+XcursorImage *meta_display_load_x_cursor (MetaDisplay *display,
+ MetaCursor cursor);
void meta_display_set_grab_op_cursor (MetaDisplay *display,
MetaScreen *screen,
diff --git a/src/core/display.c b/src/core/display.c
index 716f864..cb1b773 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1873,7 +1873,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display,
meta_error_trap_pop (display);
- cursor_ref = meta_cursor_reference_from_theme (screen->cursor_tracker, cursor);
+ cursor_ref = meta_cursor_tracker_get_cursor_from_theme (screen->cursor_tracker, cursor);
meta_cursor_tracker_set_grab_cursor (screen->cursor_tracker, cursor_ref);
meta_cursor_reference_unref (cursor_ref);
}
diff --git a/src/core/screen.c b/src/core/screen.c
index 030bab7..e00c4e6 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -43,6 +43,7 @@
#include "mutter-enum-types.h"
#include "core.h"
#include "meta-cursor-tracker-private.h"
+#include "backends/x11/meta-cursor-tracker-x11.h"
#include <X11/extensions/Xinerama.h>
@@ -1389,7 +1390,7 @@ meta_screen_update_cursor (MetaScreen *screen)
Cursor xcursor;
MetaCursorReference *cursor_ref;
- cursor_ref = meta_cursor_reference_from_theme (screen->cursor_tracker, cursor);
+ cursor_ref = meta_cursor_tracker_get_cursor_from_theme (screen->cursor_tracker, cursor);
meta_cursor_tracker_set_root_cursor (screen->cursor_tracker, cursor_ref);
meta_cursor_reference_unref (cursor_ref);
@@ -3305,7 +3306,10 @@ gboolean
meta_screen_handle_xevent (MetaScreen *screen,
XEvent *xevent)
{
- if (meta_cursor_tracker_handle_xevent (screen->cursor_tracker, xevent))
+ if (meta_is_wayland_compositor ())
+ return FALSE;
+
+ if (meta_cursor_tracker_x11_handle_xevent (META_CURSOR_TRACKER_X11 (screen->cursor_tracker), xevent))
return TRUE;
return FALSE;
diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
index f5e3867..eb025bc 100644
--- a/src/wayland/meta-wayland-seat.c
+++ b/src/wayland/meta-wayland-seat.c
@@ -38,6 +38,7 @@
#include "meta-shaped-texture-private.h"
#include "meta-wayland-stage.h"
#include "meta-cursor-tracker-private.h"
+#include "backends/native/meta-cursor-tracker-native.h"
#include "meta-surface-actor-wayland.h"
#define DEFAULT_AXIS_STEP_DISTANCE wl_fixed_from_int (10)
@@ -76,10 +77,10 @@ meta_wayland_seat_update_cursor_surface (MetaWaylandSeat *seat)
if (seat->cursor_surface && seat->cursor_surface->buffer)
{
struct wl_resource *buffer = seat->cursor_surface->buffer->resource;
- cursor = meta_cursor_reference_from_buffer (seat->cursor_tracker,
- buffer,
- seat->hotspot_x,
- seat->hotspot_y);
+ cursor = meta_cursor_tracker_get_cursor_from_buffer (seat->cursor_tracker,
+ buffer,
+ seat->hotspot_x,
+ seat->hotspot_y);
}
else
cursor = NULL;
@@ -386,9 +387,9 @@ meta_wayland_seat_update_pointer (MetaWaylandSeat *seat,
if (seat->cursor_tracker)
{
- meta_cursor_tracker_update_position (seat->cursor_tracker,
- wl_fixed_to_int (seat->pointer.x),
- wl_fixed_to_int (seat->pointer.y));
+ meta_cursor_tracker_native_update_position (META_CURSOR_TRACKER_NATIVE (seat->cursor_tracker),
+ wl_fixed_to_int (seat->pointer.x),
+ wl_fixed_to_int (seat->pointer.y));
if (seat->pointer.current == NULL)
meta_cursor_tracker_unset_window_cursor (seat->cursor_tracker);
diff --git a/src/wayland/meta-wayland-stage.c b/src/wayland/meta-wayland-stage.c
index b795dd5..91d7be8 100644
--- a/src/wayland/meta-wayland-stage.c
+++ b/src/wayland/meta-wayland-stage.c
@@ -30,6 +30,7 @@
#include "meta/meta-window-actor.h"
#include "meta/meta-shaped-texture.h"
#include "meta-cursor-tracker-private.h"
+#include "backends/native/meta-cursor-tracker-native.h"
G_DEFINE_TYPE (MetaWaylandStage, meta_wayland_stage, CLUTTER_TYPE_STAGE);
@@ -42,7 +43,7 @@ meta_wayland_stage_paint (ClutterActor *actor)
compositor = meta_wayland_compositor_get_default ();
if (compositor->seat->cursor_tracker)
- meta_cursor_tracker_paint (compositor->seat->cursor_tracker);
+ meta_cursor_tracker_native_paint (META_CURSOR_TRACKER_NATIVE (compositor->seat->cursor_tracker));
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]