From 480a853263da43497fc02ae24ba0eeec1bb0d347 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 27 Apr 2014 10:49:29 -0400 Subject: [PATCH] x11: Add simple cursor renderer --- src/Makefile.am | 2 + src/backends/meta-cursor-tracker.c | 19 +--- src/backends/x11/meta-backend-x11.c | 34 ++++--- src/backends/x11/meta-backend-x11.h | 2 + src/backends/x11/meta-cursor-renderer-x11.c | 99 +++++++++++++++++++++ src/backends/x11/meta-cursor-renderer-x11.h | 52 +++++++++++ 6 files changed, 178 insertions(+), 30 deletions(-) create mode 100644 src/backends/x11/meta-cursor-renderer-x11.c create mode 100644 src/backends/x11/meta-cursor-renderer-x11.h diff --git a/src/Makefile.am b/src/Makefile.am index f60158fa1..e2b342e65 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -82,6 +82,8 @@ libmutter_la_SOURCES = \ backends/native/meta-launcher.h \ backends/x11/meta-backend-x11.c \ backends/x11/meta-backend-x11.h \ + backends/x11/meta-cursor-renderer-x11.c \ + backends/x11/meta-cursor-renderer-x11.h \ backends/x11/meta-idle-monitor-xsync.c \ backends/x11/meta-idle-monitor-xsync.h \ backends/x11/meta-monitor-manager-xrandr.c \ diff --git a/src/backends/meta-cursor-tracker.c b/src/backends/meta-cursor-tracker.c index 6005e5965..16e876d45 100644 --- a/src/backends/meta-cursor-tracker.c +++ b/src/backends/meta-cursor-tracker.c @@ -97,11 +97,6 @@ sync_cursor (MetaCursorTracker *tracker) static void meta_cursor_tracker_init (MetaCursorTracker *self) { - /* (JS) Best (?) that can be assumed since XFixes doesn't provide a way of - detecting if the system mouse cursor is showing or not. - - On wayland we start with the cursor showing - */ self->is_showing = TRUE; } @@ -473,19 +468,7 @@ 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); - } + sync_cursor (tracker); } MetaCursorReference * diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c index 7716780f6..923963bef 100644 --- a/src/backends/x11/meta-backend-x11.c +++ b/src/backends/x11/meta-backend-x11.c @@ -33,6 +33,7 @@ #include "meta-idle-monitor-xsync.h" #include "meta-monitor-manager-xrandr.h" #include "backends/meta-monitor-manager-dummy.h" +#include "meta-cursor-renderer-x11.h" #include #include "display-private.h" @@ -66,21 +67,11 @@ handle_alarm_notify (MetaBackend *backend, meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*) event); } -static Window -get_stage_window (MetaBackendX11 *x11) -{ - MetaDisplay *display = meta_get_display (); - MetaCompositor *compositor = display->compositor; - ClutterStage *stage = CLUTTER_STAGE (compositor->stage); - - return clutter_x11_get_stage_window (stage); -} - static void translate_device_event (MetaBackendX11 *x11, XIDeviceEvent *device_event) { - Window stage_window = get_stage_window (x11); + Window stage_window = meta_backend_x11_get_xwindow (x11); if (device_event->event != stage_window) { @@ -305,6 +296,12 @@ meta_backend_x11_create_monitor_manager (MetaBackend *backend) return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL); } +static MetaCursorRenderer * +meta_backend_x11_create_cursor_renderer (MetaBackend *backend) +{ + return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL); +} + static gboolean meta_backend_x11_grab_device (MetaBackend *backend, int device_id, @@ -325,7 +322,7 @@ meta_backend_x11_grab_device (MetaBackend *backend, XISetMask (mask.mask, XI_KeyRelease); ret = XIGrabDevice (priv->xdisplay, device_id, - get_stage_window (x11), + meta_backend_x11_get_xwindow (x11), timestamp, None, XIGrabModeAsync, XIGrabModeAsync, @@ -357,6 +354,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass) backend_class->post_init = meta_backend_x11_post_init; backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor; backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager; + backend_class->create_cursor_renderer = meta_backend_x11_create_cursor_renderer; backend_class->grab_device = meta_backend_x11_grab_device; backend_class->ungrab_device = meta_backend_x11_ungrab_device; @@ -377,3 +375,15 @@ meta_backend_x11_get_xdisplay (MetaBackendX11 *x11) return priv->xdisplay; } +Window +meta_backend_x11_get_xwindow (MetaBackendX11 *x11) +{ + MetaDisplay *display = meta_get_display (); + MetaCompositor *compositor = display->compositor; + + if (compositor == NULL) + return None; + + ClutterStage *stage = CLUTTER_STAGE (compositor->stage); + return clutter_x11_get_stage_window (stage); +} diff --git a/src/backends/x11/meta-backend-x11.h b/src/backends/x11/meta-backend-x11.h index 204654ea5..040f927d3 100644 --- a/src/backends/x11/meta-backend-x11.h +++ b/src/backends/x11/meta-backend-x11.h @@ -53,4 +53,6 @@ GType meta_backend_x11_get_type (void) G_GNUC_CONST; Display * meta_backend_x11_get_xdisplay (MetaBackendX11 *backend); +Window meta_backend_x11_get_xwindow (MetaBackendX11 *backend); + #endif /* META_BACKEND_X11_H */ diff --git a/src/backends/x11/meta-cursor-renderer-x11.c b/src/backends/x11/meta-cursor-renderer-x11.c new file mode 100644 index 000000000..051afb52e --- /dev/null +++ b/src/backends/x11/meta-cursor-renderer-x11.c @@ -0,0 +1,99 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre + */ + +#include "config.h" + +#include "meta-cursor-renderer-x11.h" + +#include "meta-backend-x11.h" +#include "meta-stage.h" + +struct _MetaCursorRendererX11Private +{ + gboolean server_cursor_visible; +}; +typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private; + +G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER); + +static gboolean +meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer) +{ + MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer); + MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11); + + MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); + Window xwindow = meta_backend_x11_get_xwindow (backend); + + if (xwindow == None) + return FALSE; + + Display *xdisplay = meta_backend_x11_get_xdisplay (backend); + + MetaCursorReference *cursor_ref = meta_cursor_renderer_get_cursor (renderer); + gboolean has_server_cursor = FALSE; + + if (cursor_ref) + { + MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref); + if (cursor != META_CURSOR_NONE) + { + Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor); + XDefineCursor (xdisplay, xwindow, xcursor); + XFlush (xdisplay); + XFreeCursor (xdisplay, xcursor); + + has_server_cursor = TRUE; + } + } + + if (has_server_cursor != priv->server_cursor_visible) + { + if (has_server_cursor) + XFixesShowCursor (xdisplay, xwindow); + else + XFixesHideCursor (xdisplay, xwindow); + + priv->server_cursor_visible = has_server_cursor; + } + + return priv->server_cursor_visible; +} + +static void +meta_cursor_renderer_x11_class_init (MetaCursorRendererX11Class *klass) +{ + MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass); + + renderer_class->update_cursor = meta_cursor_renderer_x11_update_cursor; +} + +static void +meta_cursor_renderer_x11_init (MetaCursorRendererX11 *x11) +{ + MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11); + + /* XFixes has no way to retrieve the current cursor visibility. */ + priv->server_cursor_visible = TRUE; +} diff --git a/src/backends/x11/meta-cursor-renderer-x11.h b/src/backends/x11/meta-cursor-renderer-x11.h new file mode 100644 index 000000000..398a32ec8 --- /dev/null +++ b/src/backends/x11/meta-cursor-renderer-x11.h @@ -0,0 +1,52 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2014 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef META_CURSOR_RENDERER_X11_H +#define META_CURSOR_RENDERER_X11_H + +#include "meta-cursor-renderer.h" + +#define META_TYPE_CURSOR_RENDERER_X11 (meta_cursor_renderer_x11_get_type ()) +#define META_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11)) +#define META_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class)) +#define META_IS_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER_X11)) +#define META_IS_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_CURSOR_RENDERER_X11)) +#define META_CURSOR_RENDERER_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class)) + +typedef struct _MetaCursorRendererX11 MetaCursorRendererX11; +typedef struct _MetaCursorRendererX11Class MetaCursorRendererX11Class; + +struct _MetaCursorRendererX11 +{ + MetaCursorRenderer parent; +}; + +struct _MetaCursorRendererX11Class +{ + MetaCursorRendererClass parent_class; +}; + +GType meta_cursor_renderer_x11_get_type (void) G_GNUC_CONST; + +#endif /* META_CURSOR_RENDERER_X11_H */