Compare commits
	
		
			2 Commits
		
	
	
		
			benzea/fix
			...
			wip/split-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					b9d798c213 | ||
| 
						 | 
					5abf41ab5a | 
@@ -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	\
 | 
			
		||||
 
 | 
			
		||||
@@ -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 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -49,9 +46,15 @@ struct _MetaCursorTracker {
 | 
			
		||||
   */
 | 
			
		||||
  MetaCursorReference *displayed_cursor;
 | 
			
		||||
 | 
			
		||||
  /* This is the cursor that would be displayed if we hadn't been
 | 
			
		||||
   * asked to hide it. i.e. it's the same as displayed_cursor unless
 | 
			
		||||
   * is_showing is false.
 | 
			
		||||
   */
 | 
			
		||||
  MetaCursorReference *current_cursor;
 | 
			
		||||
 | 
			
		||||
  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 +65,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 +104,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
 | 
			
		||||
 
 | 
			
		||||
@@ -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,14 +74,32 @@ 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
 | 
			
		||||
default_do_nothing (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
default_load_cursor_pixels (MetaCursorTracker   *tracker,
 | 
			
		||||
                            MetaCursorReference *cursor,
 | 
			
		||||
                            uint8_t             *pixels,
 | 
			
		||||
                            int                  width,
 | 
			
		||||
                            int                  height,
 | 
			
		||||
                            int                  rowstride,
 | 
			
		||||
                            uint32_t             format)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
default_load_cursor_buffer (MetaCursorTracker   *tracker,
 | 
			
		||||
                            MetaCursorReference *cursor,
 | 
			
		||||
                            struct wl_resource  *buffer)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
 | 
			
		||||
{
 | 
			
		||||
@@ -103,6 +107,11 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = meta_cursor_tracker_finalize;
 | 
			
		||||
 | 
			
		||||
  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,
 | 
			
		||||
@@ -111,81 +120,6 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
 | 
			
		||||
                                          G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_monitors_changed (MetaMonitorManager *monitors,
 | 
			
		||||
                     MetaCursorTracker  *tracker)
 | 
			
		||||
{
 | 
			
		||||
  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)
 | 
			
		||||
{
 | 
			
		||||
  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)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorTracker *self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
 | 
			
		||||
  self->screen = screen;
 | 
			
		||||
 | 
			
		||||
  XFixesSelectCursorInput (screen->display->xdisplay,
 | 
			
		||||
                           screen->xroot,
 | 
			
		||||
                           XFixesDisplayCursorNotifyMask);
 | 
			
		||||
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_cursor_tracker_get_for_screen:
 | 
			
		||||
 * @screen: the #MetaScreen
 | 
			
		||||
@@ -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,11 +155,10 @@ 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);
 | 
			
		||||
  if (tracker->current_cursor)
 | 
			
		||||
    return meta_cursor_reference_get_cogl_texture (tracker->current_cursor, NULL, NULL);
 | 
			
		||||
  else
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -357,11 +177,10 @@ 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);
 | 
			
		||||
  if (tracker->current_cursor)
 | 
			
		||||
    meta_cursor_reference_get_cogl_texture (tracker->current_cursor, x, y);
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (x)
 | 
			
		||||
@@ -371,6 +190,32 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_meta_cursor_tracker_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;
 | 
			
		||||
 | 
			
		||||
  _meta_cursor_tracker_sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker   *tracker,
 | 
			
		||||
                                       MetaCursorReference *cursor)
 | 
			
		||||
{
 | 
			
		||||
  _meta_cursor_tracker_set_window_cursor (tracker, TRUE, cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  _meta_cursor_tracker_set_window_cursor (tracker, FALSE, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_set_grab_cursor (MetaCursorTracker   *tracker,
 | 
			
		||||
                                     MetaCursorReference *cursor)
 | 
			
		||||
@@ -379,20 +224,7 @@ meta_cursor_tracker_set_grab_cursor (MetaCursorTracker   *tracker,
 | 
			
		||||
  if (cursor)
 | 
			
		||||
    tracker->grab_cursor = meta_cursor_reference_ref (cursor);
 | 
			
		||||
 | 
			
		||||
  sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker   *tracker,
 | 
			
		||||
                                       MetaCursorReference *cursor)
 | 
			
		||||
{
 | 
			
		||||
  set_window_cursor (tracker, TRUE, cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  set_window_cursor (tracker, FALSE, NULL);
 | 
			
		||||
  _meta_cursor_tracker_sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -403,78 +235,12 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker   *tracker,
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
      if (has || crtcs[i].has_hw_cursor)
 | 
			
		||||
        meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
move_hw_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
      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 *
 | 
			
		||||
get_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
get_current_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  if (!tracker->is_showing)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (tracker->grab_cursor)
 | 
			
		||||
    return tracker->grab_cursor;
 | 
			
		||||
 | 
			
		||||
@@ -484,208 +250,38 @@ get_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
  return tracker->root_cursor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
static MetaCursorReference *
 | 
			
		||||
get_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);
 | 
			
		||||
  if (!tracker->is_showing)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
      update_hw_cursor (tracker);
 | 
			
		||||
    }
 | 
			
		||||
  return get_current_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
sync_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
void
 | 
			
		||||
_meta_cursor_tracker_sync_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorReference *current_cursor = get_current_cursor (tracker);
 | 
			
		||||
  MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
 | 
			
		||||
 | 
			
		||||
  if (tracker->displayed_cursor == displayed_cursor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
 | 
			
		||||
  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)
 | 
			
		||||
  if (tracker->displayed_cursor != displayed_cursor)
 | 
			
		||||
    {
 | 
			
		||||
      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;
 | 
			
		||||
      g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
 | 
			
		||||
      if (displayed_cursor)
 | 
			
		||||
        tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
 | 
			
		||||
 | 
			
		||||
      META_CURSOR_TRACKER_GET_CLASS (tracker)->sync_cursor (tracker);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  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)
 | 
			
		||||
  if (tracker->current_cursor != current_cursor)
 | 
			
		||||
    {
 | 
			
		||||
      CoglTexture *texture;
 | 
			
		||||
      int hot_x, hot_y;
 | 
			
		||||
      g_clear_pointer (&tracker->current_cursor, meta_cursor_reference_unref);
 | 
			
		||||
      if (current_cursor)
 | 
			
		||||
        tracker->current_cursor = meta_cursor_reference_ref (current_cursor);
 | 
			
		||||
 | 
			
		||||
      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));
 | 
			
		||||
      g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      tracker->current_rect.x = 0;
 | 
			
		||||
      tracker->current_rect.y = 0;
 | 
			
		||||
      tracker->current_rect.width = 0;
 | 
			
		||||
      tracker->current_rect.height = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      if (tracker->has_hw_cursor)
 | 
			
		||||
        move_hw_cursor (tracker);
 | 
			
		||||
      else
 | 
			
		||||
        meta_cursor_tracker_queue_redraw (tracker);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
 | 
			
		||||
                                     int                new_x,
 | 
			
		||||
                                     int                new_y)
 | 
			
		||||
{
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  tracker->current_x = new_x;
 | 
			
		||||
  tracker->current_y = new_y;
 | 
			
		||||
 | 
			
		||||
  sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_paint (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  if (tracker->has_hw_cursor || !tracker->displayed_cursor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
 | 
			
		||||
                                            MetaCRTC          *crtc,
 | 
			
		||||
                                            gboolean           has)
 | 
			
		||||
{
 | 
			
		||||
  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 (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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -694,15 +290,7 @@ meta_cursor_tracker_get_pointer (MetaCursorTracker   *tracker,
 | 
			
		||||
                                 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);
 | 
			
		||||
  META_CURSOR_TRACKER_GET_CLASS (tracker)->get_pointer (tracker, x, y, mods);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -713,26 +301,51 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
  _meta_cursor_tracker_sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_force_update (MetaCursorTracker *tracker)
 | 
			
		||||
MetaCursorReference *
 | 
			
		||||
meta_cursor_tracker_get_cursor_from_theme (MetaCursorTracker   *tracker,
 | 
			
		||||
                                           MetaCursor           meta_cursor)
 | 
			
		||||
{
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
  MetaCursorReference *cursor;
 | 
			
		||||
  XcursorImage *xc_image;
 | 
			
		||||
 | 
			
		||||
  update_hw_cursor (tracker);
 | 
			
		||||
  sync_cursor (tracker);
 | 
			
		||||
  if (tracker->theme_cursors[meta_cursor])
 | 
			
		||||
    return meta_cursor_reference_ref (tracker->theme_cursors[meta_cursor]);
 | 
			
		||||
 | 
			
		||||
  xc_image = meta_display_load_x_cursor (meta_get_display (), meta_cursor);
 | 
			
		||||
  if (!xc_image)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  cursor = meta_cursor_reference_from_xcursor_image (xc_image);
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
  tracker->theme_cursors[meta_cursor] = cursor;
 | 
			
		||||
 | 
			
		||||
  return meta_cursor_reference_ref (cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursorReference *
 | 
			
		||||
meta_cursor_tracker_get_cursor_from_buffer (MetaCursorTracker  *tracker,
 | 
			
		||||
                                            struct wl_resource *buffer,
 | 
			
		||||
                                            int                 hot_x,
 | 
			
		||||
                                            int                 hot_y)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorReference *cursor;
 | 
			
		||||
 | 
			
		||||
  cursor = meta_cursor_reference_from_buffer (buffer, hot_x, hot_y);
 | 
			
		||||
 | 
			
		||||
  META_CURSOR_TRACKER_GET_CLASS (tracker)->load_cursor_buffer (tracker,
 | 
			
		||||
                                                               cursor,
 | 
			
		||||
                                                               buffer);
 | 
			
		||||
  return cursor;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
  cursor->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));
 | 
			
		||||
 | 
			
		||||
  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 *
 | 
			
		||||
 
 | 
			
		||||
@@ -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 */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										443
									
								
								src/backends/native/meta-cursor-tracker-native.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										443
									
								
								src/backends/native/meta-cursor-tracker-native.c
									
									
									
									
									
										Normal file
									
								
							@@ -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));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								src/backends/native/meta-cursor-tracker-native.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/backends/native/meta-cursor-tracker-native.h
									
									
									
									
									
										Normal file
									
								
							@@ -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 */
 | 
			
		||||
@@ -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));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										138
									
								
								src/backends/x11/meta-cursor-tracker-x11.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/backends/x11/meta-cursor-tracker-x11.c
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								src/backends/x11/meta-cursor-tracker-x11.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/backends/x11/meta-cursor-tracker-x11.h
									
									
									
									
									
										Normal file
									
								
							@@ -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 */
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user