diff --git a/js/ui/magnifier.js b/js/ui/magnifier.js index f4c46e7ee..7c68ea8ec 100644 --- a/js/ui/magnifier.js +++ b/js/ui/magnifier.js @@ -7,6 +7,7 @@ const Shell = imports.gi.Shell; const St = imports.gi.St; const Lang = imports.lang; const Mainloop = imports.mainloop; +const Meta = imports.gi.Meta; const Signals = imports.signals; const Main = imports.ui.main; @@ -53,9 +54,9 @@ const Magnifier = new Lang.Class({ this._zoomRegions = []; // Create small clutter tree for the magnified mouse. - let xfixesCursor = Shell.XFixesCursor.get_for_stage(global.stage); + let cursorTracker = Meta.CursorTracker.get_for_screen(global.screen); this._mouseSprite = new Clutter.Texture(); - xfixesCursor.update_texture_image(this._mouseSprite); + Shell.util_cursor_tracker_to_clutter(cursorTracker, this._mouseSprite); this._cursorRoot = new Clutter.Actor(); this._cursorRoot.add_actor(this._mouseSprite); @@ -70,8 +71,8 @@ const Magnifier = new Lang.Class({ let showAtLaunch = this._settingsInit(aZoomRegion); aZoomRegion.scrollContentsTo(this.xMouse, this.yMouse); - xfixesCursor.connect('cursor-change', Lang.bind(this, this._updateMouseSprite)); - this._xfixesCursor = xfixesCursor; + cursorTracker.connect('cursor-changed', Lang.bind(this, this._updateMouseSprite)); + this._cursorTracker = cursorTracker; // Export to dbus. magDBusService = new MagnifierDBus.ShellMagnifier(); @@ -83,7 +84,7 @@ const Magnifier = new Lang.Class({ * Show the system mouse pointer. */ showSystemCursor: function() { - this._xfixesCursor.show(); + global.stage.show_cursor(); }, /** @@ -91,7 +92,7 @@ const Magnifier = new Lang.Class({ * Hide the system mouse pointer. */ hideSystemCursor: function() { - this._xfixesCursor.hide(); + global.stage.hide_cursor(); }, /** @@ -112,7 +113,7 @@ const Magnifier = new Lang.Class({ // Make sure system mouse pointer is shown when all zoom regions are // invisible. if (!activate) - this._xfixesCursor.show(); + global.stage.show_cursor(); // Notify interested parties of this change this.emit('active-changed', activate); @@ -422,9 +423,8 @@ const Magnifier = new Lang.Class({ //// Private methods //// _updateMouseSprite: function() { - this._xfixesCursor.update_texture_image(this._mouseSprite); - let xHot = this._xfixesCursor.get_hot_x(); - let yHot = this._xfixesCursor.get_hot_y(); + Shell.util_cursor_tracker_to_clutter(this._cursorTracker, this._mouseSprite); + let [xHot, yHot] = this._cursorTracker.get_hot(); this._mouseSprite.set_anchor_point(xHot, yHot); }, diff --git a/src/Makefile.am b/src/Makefile.am index 13e0cbb2c..74c6c299b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -126,8 +126,7 @@ shell_public_headers_h = \ shell-tray-manager.h \ shell-util.h \ shell-window-tracker.h \ - shell-wm.h \ - shell-xfixes-cursor.h + shell-wm.h shell_private_sources = \ gtkactionmuxer.h \ @@ -181,7 +180,6 @@ libgnome_shell_la_SOURCES = \ shell-util.c \ shell-window-tracker.c \ shell-wm.c \ - shell-xfixes-cursor.c \ $(NULL) libgnome_shell_la_gir_sources = \ diff --git a/src/shell-util.c b/src/shell-util.c index 84adad9aa..92fc3dad6 100644 --- a/src/shell-util.c +++ b/src/shell-util.c @@ -431,3 +431,13 @@ shell_util_wake_up_screen (void) first_keycode = !first_keycode; gdk_error_trap_pop_ignored (); } + +void +shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker, + ClutterTexture *texture) +{ + CoglTexture *sprite; + + sprite = meta_cursor_tracker_get_sprite (tracker); + clutter_texture_set_cogl_texture (texture, sprite); +} diff --git a/src/shell-util.h b/src/shell-util.h index 2d462c1c5..95271d05a 100644 --- a/src/shell-util.h +++ b/src/shell-util.h @@ -7,6 +7,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -46,6 +47,9 @@ GdkPixbuf *shell_util_create_pixbuf_from_data (const guchar *data, void shell_util_wake_up_screen (void); +void shell_util_cursor_tracker_to_clutter (MetaCursorTracker *tracker, + ClutterTexture *texture); + G_END_DECLS #endif /* __SHELL_UTIL_H__ */ diff --git a/src/shell-xfixes-cursor.c b/src/shell-xfixes-cursor.c deleted file mode 100644 index 828925f88..000000000 --- a/src/shell-xfixes-cursor.c +++ /dev/null @@ -1,426 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -#include -#include - -#include "shell-xfixes-cursor.h" - -#include -#include - -/** - * SECTION:shell-xfixes-cursor - * @short_description: Capture/manipulate system mouse cursor. - * - * The #ShellXFixesCursor object uses the XFixes extension to show/hide the - * the system mouse pointer, to grab its image as it changes, and emit a - * notification when its image changes. - */ - -struct _ShellXFixesCursorClass -{ - GObjectClass parent_class; -}; - -struct _ShellXFixesCursor { - GObject parent; - - ClutterStage *stage; - - gboolean have_xfixes; - int xfixes_event_base; - - gboolean is_showing; - - CoglHandle *cursor_sprite; - int cursor_hot_x; - int cursor_hot_y; -}; - -static void xfixes_cursor_show (ShellXFixesCursor *xfixes_cursor); -static void xfixes_cursor_hide (ShellXFixesCursor *xfixes_cursor); - -static void xfixes_cursor_set_stage (ShellXFixesCursor *xfixes_cursor, - ClutterStage *stage); - -static void xfixes_cursor_reset_image (ShellXFixesCursor *xfixes_cursor); - -enum { - PROP_0, - PROP_STAGE, -}; - -G_DEFINE_TYPE(ShellXFixesCursor, shell_xfixes_cursor, G_TYPE_OBJECT); - -enum { - CURSOR_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static void -shell_xfixes_cursor_init (ShellXFixesCursor *xfixes_cursor) -{ - // (JS) Best (?) that can be assumed since XFixes doesn't provide a way of - // detecting if the system mouse cursor is showing or not. - xfixes_cursor->is_showing = TRUE; -} - -static void -shell_xfixes_cursor_finalize (GObject *object) -{ - ShellXFixesCursor *xfixes_cursor = SHELL_XFIXES_CURSOR (object); - - // Make sure the system cursor is showing before leaving the stage. - xfixes_cursor_show (xfixes_cursor); - xfixes_cursor_set_stage (xfixes_cursor, NULL); - if (xfixes_cursor->cursor_sprite != NULL) - cogl_handle_unref (xfixes_cursor->cursor_sprite); - - G_OBJECT_CLASS (shell_xfixes_cursor_parent_class)->finalize (object); -} - -static void -xfixes_cursor_on_stage_destroy (ClutterActor *actor, - ShellXFixesCursor *xfixes_cursor) -{ - xfixes_cursor_set_stage (xfixes_cursor, NULL); -} - -static ClutterX11FilterReturn -xfixes_cursor_event_filter (XEvent *xev, - ClutterEvent *cev, - gpointer data) -{ - ShellXFixesCursor *xfixes_cursor = data; - - if (xev->xany.window != clutter_x11_get_stage_window (xfixes_cursor->stage)) - return CLUTTER_X11_FILTER_CONTINUE; - - if (xev->xany.type == xfixes_cursor->xfixes_event_base + XFixesCursorNotify) - { - XFixesCursorNotifyEvent *notify_event = (XFixesCursorNotifyEvent *)xev; - if (notify_event->subtype == XFixesDisplayCursorNotify) - xfixes_cursor_reset_image (xfixes_cursor); - } - return CLUTTER_X11_FILTER_CONTINUE; -} - -static void -xfixes_cursor_set_stage (ShellXFixesCursor *xfixes_cursor, - ClutterStage *stage) -{ - if (xfixes_cursor->stage == stage) - return; - - if (xfixes_cursor->stage) - { - g_signal_handlers_disconnect_by_func (xfixes_cursor->stage, - (void *)xfixes_cursor_on_stage_destroy, - xfixes_cursor); - - clutter_x11_remove_filter (xfixes_cursor_event_filter, xfixes_cursor); - } - xfixes_cursor->stage = stage; - if (xfixes_cursor->stage) - { - int error_base; - - xfixes_cursor->stage = stage; - g_signal_connect (xfixes_cursor->stage, "destroy", - G_CALLBACK (xfixes_cursor_on_stage_destroy), xfixes_cursor); - - clutter_x11_add_filter (xfixes_cursor_event_filter, xfixes_cursor); - - xfixes_cursor->have_xfixes = XFixesQueryExtension (clutter_x11_get_default_display (), - &xfixes_cursor->xfixes_event_base, - &error_base); - if (xfixes_cursor->have_xfixes) - XFixesSelectCursorInput (clutter_x11_get_default_display (), - clutter_x11_get_stage_window (stage), - XFixesDisplayCursorNotifyMask); - - xfixes_cursor_reset_image (xfixes_cursor); - } -} - -static void -xfixes_cursor_show (ShellXFixesCursor *xfixes_cursor) -{ - int minor, major; - Display *xdisplay; - Window xwindow; - - if (xfixes_cursor->is_showing == TRUE) - return; - - if (!xfixes_cursor->have_xfixes || !xfixes_cursor->stage) - return; - - xdisplay = clutter_x11_get_default_display (); - xwindow = clutter_x11_get_stage_window (xfixes_cursor->stage); - XFixesQueryVersion (xdisplay, &major, &minor); - if (major >= 4) - { - XFixesShowCursor (xdisplay, xwindow); - xfixes_cursor->is_showing = TRUE; - } -} - -static void -xfixes_cursor_hide (ShellXFixesCursor *xfixes_cursor) -{ - int minor, major; - Display *xdisplay; - Window xwindow; - - if (xfixes_cursor->is_showing == FALSE) - return; - - if (!xfixes_cursor->have_xfixes || !xfixes_cursor->stage) - return; - - xdisplay = clutter_x11_get_default_display (); - xwindow = clutter_x11_get_stage_window (xfixes_cursor->stage); - XFixesQueryVersion (xdisplay, &major, &minor); - if (major >= 4) - { - XFixesHideCursor (xdisplay, xwindow); - xfixes_cursor->is_showing = FALSE; - } -} - -static void -xfixes_cursor_reset_image (ShellXFixesCursor *xfixes_cursor) -{ - XFixesCursorImage *cursor_image; - CoglHandle sprite = COGL_INVALID_HANDLE; - guint8 *cursor_data; - gboolean free_cursor_data; - - if (!xfixes_cursor->have_xfixes) - return; - - cursor_image = XFixesGetCursorImage (clutter_x11_get_default_display ()); - 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; - } - - sprite = cogl_texture_new_from_data (cursor_image->width, - cursor_image->height, - COGL_TEXTURE_NONE, - CLUTTER_CAIRO_FORMAT_ARGB32, - COGL_PIXEL_FORMAT_ANY, - cursor_image->width * 4, /* stride */ - cursor_data); - - if (free_cursor_data) - g_free (cursor_data); - - if (sprite != COGL_INVALID_HANDLE) - { - if (xfixes_cursor->cursor_sprite != NULL) - cogl_handle_unref (xfixes_cursor->cursor_sprite); - - xfixes_cursor->cursor_sprite = sprite; - xfixes_cursor->cursor_hot_x = cursor_image->xhot; - xfixes_cursor->cursor_hot_y = cursor_image->yhot; - g_signal_emit (xfixes_cursor, signals[CURSOR_CHANGED], 0); - } - XFree (cursor_image); -} - -static void -shell_xfixes_cursor_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ShellXFixesCursor *xfixes_cursor = SHELL_XFIXES_CURSOR (object); - - switch (prop_id) - { - case PROP_STAGE: - xfixes_cursor_set_stage (xfixes_cursor, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -shell_xfixes_cursor_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ShellXFixesCursor *xfixes_cursor = SHELL_XFIXES_CURSOR (object); - - switch (prop_id) - { - case PROP_STAGE: - g_value_set_object (value, G_OBJECT (xfixes_cursor->stage)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -shell_xfixes_cursor_class_init (ShellXFixesCursorClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = shell_xfixes_cursor_finalize; - - signals[CURSOR_CHANGED] = g_signal_new ("cursor-change", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 0); - - gobject_class->get_property = shell_xfixes_cursor_get_property; - gobject_class->set_property = shell_xfixes_cursor_set_property; - - g_object_class_install_property (gobject_class, - PROP_STAGE, - g_param_spec_object ("stage", - "Stage", - "Stage for mouse cursor", - CLUTTER_TYPE_STAGE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); -} - -/** - * shell_xfixes_cursor_get_for_stage: - * @stage: (transfer none): The #ClutterStage to get the cursor for - * - * Return value: (transfer none): A #ShellXFixesCursor instance - */ -ShellXFixesCursor * -shell_xfixes_cursor_get_for_stage (ClutterStage *stage) -{ - ShellXFixesCursor *instance; - static GQuark xfixes_cursor_quark; - - if (G_UNLIKELY (xfixes_cursor_quark == 0)) - xfixes_cursor_quark = g_quark_from_static_string ("gnome-shell-xfixes-cursor"); - - instance = g_object_get_qdata (G_OBJECT (stage), xfixes_cursor_quark); - - if (instance == NULL) - { - instance = g_object_new (SHELL_TYPE_XFIXES_CURSOR, - "stage", stage, - NULL); - g_object_set_qdata (G_OBJECT (stage), xfixes_cursor_quark, instance); - } - - return instance; -} - -/** - * shell_xfixes_cursor_hide: - * @xfixes_cursor: the #ShellXFixesCursor - * - * Hide the system mouse cursor. - */ -void -shell_xfixes_cursor_hide (ShellXFixesCursor *xfixes_cursor) -{ - g_return_if_fail (SHELL_IS_XFIXES_CURSOR (xfixes_cursor)); - - xfixes_cursor_hide (xfixes_cursor); -} - -/** - * shell_xfixes_cursor_show: - * @xfixes_cursor: the #ShellXFixesCursor - * - * Show the system mouse cursor to show - */ -void -shell_xfixes_cursor_show (ShellXFixesCursor *xfixes_cursor) -{ - g_return_if_fail (SHELL_IS_XFIXES_CURSOR (xfixes_cursor)); - - xfixes_cursor_show (xfixes_cursor); -} - -/** - * shell_xfixes_cursor_update_texture_image: - * @xfixes_cursor: the #ShellXFixesCursor - * @texture: ClutterTexture to update with the current sprite image. - */ -void -shell_xfixes_cursor_update_texture_image (ShellXFixesCursor *xfixes_cursor, - ClutterTexture *texture) -{ - CoglHandle *old_sprite; - g_return_if_fail (SHELL_IS_XFIXES_CURSOR (xfixes_cursor)); - - if (texture == NULL) - return; - - old_sprite = clutter_texture_get_cogl_texture (texture); - if (xfixes_cursor->cursor_sprite == old_sprite) - return; - - clutter_texture_set_cogl_texture (texture, xfixes_cursor->cursor_sprite); -} - -/** - * shell_xfixes_cursor_get_hot_x: - * @xfixes_cursor: the #ShellXFixesCursor - * - * Returns: the current mouse cursor's hot x-coordinate. - */ -int -shell_xfixes_cursor_get_hot_x (ShellXFixesCursor *xfixes_cursor) -{ - g_return_val_if_fail (SHELL_IS_XFIXES_CURSOR (xfixes_cursor), 0); - - return xfixes_cursor->cursor_hot_x; -} - -/** - * shell_xfixes_cursor_get_hot_y: - * @xfixes_cursor: the #ShellXFixesCursor - * - * Returns: the current mouse cursor's hot y-coordinate. - */ -int -shell_xfixes_cursor_get_hot_y (ShellXFixesCursor *xfixes_cursor) -{ - g_return_val_if_fail (SHELL_IS_XFIXES_CURSOR (xfixes_cursor), 0); - - return xfixes_cursor->cursor_hot_y; -} diff --git a/src/shell-xfixes-cursor.h b/src/shell-xfixes-cursor.h deleted file mode 100644 index d84d5aa4b..000000000 --- a/src/shell-xfixes-cursor.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -#ifndef __SHELL_XFIXES_CURSOR_H__ -#define __SHELL_XFIXES_CURSOR_H__ - -#include -#include - -G_BEGIN_DECLS - -typedef struct _ShellXFixesCursor ShellXFixesCursor; -typedef struct _ShellXFixesCursorClass ShellXFixesCursorClass; - -#define SHELL_TYPE_XFIXES_CURSOR (shell_xfixes_cursor_get_type ()) -#define SHELL_XFIXES_CURSOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_XFIXES_CURSOR, ShellXFixesCursor)) -#define SHELL_XFIXES_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_XFIXES_CURSOR, ShellXFixesCursorClass)) -#define SHELL_IS_XFIXES_CURSOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_XFIXES_CURSOR)) -#define SHELL_IS_XFIXES_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_XFIXES_CURSOR)) -#define SHELL_XFIXES_CURSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_XFIXES_CURSOR, ShellXFixesCursorClass)) - -GType shell_xfixes_cursor_get_type (void) G_GNUC_CONST; - -ShellXFixesCursor *shell_xfixes_cursor_get_for_stage (ClutterStage *stage); - -void shell_xfixes_cursor_show (ShellXFixesCursor *xfixes_cursor); -void shell_xfixes_cursor_hide (ShellXFixesCursor *xfixes_cursor); -int shell_xfixes_cursor_get_hot_x (ShellXFixesCursor *xfixes_cursor); -int shell_xfixes_cursor_get_hot_y (ShellXFixesCursor *xfixes_cursor); -void shell_xfixes_cursor_update_texture_image (ShellXFixesCursor *xfixes_cursor, - ClutterTexture *texture); - -G_END_DECLS - -#endif /* __SHELL_XFIXES_CURSOR_H__ */