[gnome-settings-daemon] cursor: Hide cursor on tablets with only a touchscreen



commit 3d2f33aa46f2c524fbd0c00def12fa1c7178a71c
Author: Bastien Nocera <hadess hadess net>
Date:   Tue Jun 7 18:09:02 2011 +0100

    cursor: Hide cursor on tablets with only a touchscreen
    
    When a tablet is available and no external pointer devices are
    available, hide the cursor.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=650604

 configure.ac                                       |    7 +
 ...gnome.settings-daemon.plugins.gschema.xml.in.in |   13 +
 plugins/Makefile.am                                |    1 +
 plugins/cursor/Makefile.am                         |   47 +++
 plugins/cursor/cursor.gnome-settings-plugin.in     |    8 +
 plugins/cursor/gsd-cursor-manager.c                |  409 ++++++++++++++++++++
 plugins/cursor/gsd-cursor-manager.h                |   57 +++
 plugins/cursor/gsd-cursor-plugin.c                 |  110 ++++++
 plugins/cursor/gsd-cursor-plugin.h                 |   59 +++
 9 files changed, 711 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 07b8b6d..46e11cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -204,6 +204,12 @@ dnl ---------------------------------------------------------------------------
 PKG_CHECK_MODULES(XINPUT, xi)
 
 dnl ---------------------------------------------------------------------------
+dnl - XFixes
+dnl ---------------------------------------------------------------------------
+
+PKG_CHECK_MODULES(XINPUT, xfixes)
+
+dnl ---------------------------------------------------------------------------
 dnl - Fontconfig
 dnl ---------------------------------------------------------------------------
 
@@ -549,6 +555,7 @@ plugins/background/Makefile
 plugins/clipboard/Makefile
 plugins/color/Makefile
 plugins/common/Makefile
+plugins/cursor/Makefile
 plugins/datetime/Makefile
 plugins/dummy/Makefile
 plugins/gconf/Makefile
diff --git a/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in b/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in
index 52606cc..e2cf641 100644
--- a/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in
+++ b/data/org.gnome.settings-daemon.plugins.gschema.xml.in.in
@@ -5,6 +5,7 @@
     <child name="automount" schema="org.gnome.settings-daemon.plugins.automount"/>
     <child name="background" schema="org.gnome.settings-daemon.plugins.background"/>
     <child name="clipboard" schema="org.gnome.settings-daemon.plugins.clipboard"/>
+    <child name="cursor" schema="org.gnome.settings-daemon.plugins.cursor"/>
     <child name="font" schema="org.gnome.settings-daemon.plugins.font"/>
     <child name="keybindings" schema="org.gnome.settings-daemon.plugins.keybindings"/>
     <child name="mouse" schema="org.gnome.settings-daemon.plugins.mouse"/>
@@ -72,6 +73,18 @@
       <_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
     </key>
   </schema>
+  <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.cursor" path="/org/gnome/settings-daemon/plugins/cursor/">
+    <key name="active" type="b">
+      <default>true</default>
+      <_summary>Activation of this plugin</_summary>
+      <_description>Whether this plugin would be activated by gnome-settings-daemon or not</_description>
+    </key>
+    <key name="priority" type="i">
+      <default>99</default>
+      <_summary>Priority to use for this plugin</_summary>
+      <_description>Priority to use for this plugin in gnome-settings-daemon startup queue</_description>
+    </key>
+  </schema>
   <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.font" path="/org/gnome/settings-daemon/plugins/font/">
     <key name="active" type="b">
       <default>true</default>
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 4436a42..082f051 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -7,6 +7,7 @@ enabled_plugins =	\
 	background	\
 	clipboard	\
 	color		\
+	cursor		\
 	datetime	\
 	dummy		\
 	housekeeping    \
diff --git a/plugins/cursor/Makefile.am b/plugins/cursor/Makefile.am
new file mode 100644
index 0000000..4808558
--- /dev/null
+++ b/plugins/cursor/Makefile.am
@@ -0,0 +1,47 @@
+plugin_name = cursor
+
+plugin_LTLIBRARIES = \
+	libcursor.la
+
+libcursor_la_SOURCES =		\
+	gsd-cursor-manager.c	\
+	gsd-cursor-manager.h	\
+	gsd-cursor-plugin.c	\
+	gsd-cursor-plugin.h
+
+libcursor_la_CPPFLAGS = \
+	-I$(top_srcdir)/gnome-settings-daemon			\
+	-I$(top_srcdir)/plugins/common/				\
+	-DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\"	\
+	$(AM_CPPFLAGS)
+
+libcursor_la_CFLAGS = \
+	$(PLUGIN_CFLAGS)		\
+	$(XFIXES_CFLAGS)		\
+	$(SETTINGS_PLUGIN_CFLAGS)	\
+	$(AM_CFLAGS)
+
+libcursor_la_LDFLAGS =		\
+	$(GSD_PLUGIN_LDFLAGS)
+
+libcursor_la_LIBADD  =					\
+	$(top_builddir)/plugins/common/libcommon.la	\
+	$(XFIXES_LIBS)					\
+	$(SETTINGS_PLUGIN_LIBS)
+
+plugin_in_files = 		\
+	cursor.gnome-settings-plugin.in
+
+plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin)
+
+EXTRA_DIST = 			\
+	$(plugin_in_files)
+
+CLEANFILES = 			\
+	$(plugin_DATA)
+
+DISTCLEANFILES =		\
+	$(plugin_DATA)
+
+ GSD_INTLTOOL_PLUGIN_RULE@
+
diff --git a/plugins/cursor/cursor.gnome-settings-plugin.in b/plugins/cursor/cursor.gnome-settings-plugin.in
new file mode 100644
index 0000000..2d9c96c
--- /dev/null
+++ b/plugins/cursor/cursor.gnome-settings-plugin.in
@@ -0,0 +1,8 @@
+[GNOME Settings Plugin]
+Module=cursor
+IAge=0
+_Name=Cursor
+_Description=Show/hide cursor on tablet devices
+Authors=Bastien Nocera <hadess hadess net>
+Copyright=Copyright © 2011 Red Hat, Inc.
+Website=
diff --git a/plugins/cursor/gsd-cursor-manager.c b/plugins/cursor/gsd-cursor-manager.c
new file mode 100644
index 0000000..36897ad
--- /dev/null
+++ b/plugins/cursor/gsd-cursor-manager.c
@@ -0,0 +1,409 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+
+#include <X11/Xatom.h>
+#include <X11/extensions/Xfixes.h>
+
+#include "gnome-settings-profile.h"
+#include "gsd-cursor-manager.h"
+#include "gsd-input-helper.h"
+
+#define GSD_CURSOR_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_CURSOR_MANAGER, GsdCursorManagerPrivate))
+
+struct GsdCursorManagerPrivate
+{
+        guint start_idle_id;
+        guint added_id;
+        guint removed_id;
+        gboolean cursor_shown;
+};
+
+enum {
+        PROP_0,
+};
+
+static void     gsd_cursor_manager_class_init  (GsdCursorManagerClass *klass);
+static void     gsd_cursor_manager_init        (GsdCursorManager      *cursor_manager);
+static void     gsd_cursor_manager_finalize    (GObject               *object);
+
+G_DEFINE_TYPE (GsdCursorManager, gsd_cursor_manager, G_TYPE_OBJECT)
+
+static gpointer manager_object = NULL;
+
+static gboolean
+device_is_xtest (XDevice *xdevice)
+{
+        Atom realtype, prop;
+        int realformat;
+        unsigned long nitems, bytes_after;
+        unsigned char *data;
+
+        prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "XTEST Device", False);
+        if (!prop)
+                return FALSE;
+
+        gdk_error_trap_push ();
+        if ((XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdevice, prop, 0, 1, False,
+                                XA_INTEGER, &realtype, &realformat, &nitems,
+                                &bytes_after, &data) == Success) && (realtype != None)) {
+                gdk_error_trap_pop_ignored ();
+                XFree (data);
+                return TRUE;
+        }
+        gdk_error_trap_pop_ignored ();
+
+        return FALSE;
+}
+
+static void
+set_cursor_visibility (GsdCursorManager *manager,
+                       gboolean          visible)
+{
+        Display *xdisplay;
+        GdkDisplay *display;
+        guint n_screens;
+        guint i;
+
+        display = gdk_display_get_default ();
+        xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+        n_screens = gdk_display_get_n_screens (display);
+
+        gdk_error_trap_push ();
+
+        for (i = 0; i < n_screens; i++) {
+                GdkScreen *screen;
+
+                screen = gdk_display_get_screen (display, i);
+
+                if (visible)
+                        XFixesShowCursor (xdisplay, GDK_WINDOW_XID (gdk_screen_get_root_window (screen)));
+                else
+                        XFixesHideCursor (xdisplay, GDK_WINDOW_XID (gdk_screen_get_root_window (screen)));
+        }
+        if (gdk_error_trap_pop ()) {
+                g_warning ("An error occurred trying to %s the cursor",
+                           visible ? "show" : "hide");
+        }
+
+        manager->priv->cursor_shown = visible;
+}
+
+static void
+update_cursor_for_current (GsdCursorManager *manager)
+{
+        XDeviceInfo *device_info;
+        guint num_mice;
+        int n_devices;
+        guint i;
+
+        /* List all the pointer devices
+         * ignore the touchscreens
+         * ignore the XTest devices
+         * see if there's anything left */
+
+        device_info = XListInputDevices (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &n_devices);
+        if (device_info == NULL)
+                return;
+
+        num_mice = 0;
+
+        for (i = 0; i < n_devices; i++) {
+                XDevice *device;
+
+                if (device_info[i].use != IsXExtensionPointer)
+                        return;
+
+                if (device_info_is_touchscreen (&device_info[i]))
+                        continue;
+
+                gdk_error_trap_push ();
+                device = XOpenDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device_info[i].id);
+                if (gdk_error_trap_pop () || (device == NULL))
+                        continue;
+
+                if (device_is_xtest (device)) {
+                        XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), device);
+                        continue;
+                }
+
+                num_mice++;
+        }
+        XFreeDeviceList (device_info);
+
+        g_debug ("Found %d devices that aren't touchscreens or fake devices", num_mice);
+
+        if (num_mice > 0) {
+                g_debug ("Mice are present");
+
+                if (manager->priv->cursor_shown == FALSE) {
+                        set_cursor_visibility (manager, TRUE);
+                }
+        } else {
+                g_debug ("No mice present");
+                if (manager->priv->cursor_shown == FALSE) {
+                        set_cursor_visibility (manager, FALSE);
+                }
+        }
+}
+
+static void
+devices_added_cb (GdkDeviceManager *device_manager,
+                  GdkDevice        *device,
+                  GsdCursorManager *manager)
+{
+        update_cursor_for_current (manager);
+}
+
+static void
+devices_removed_cb (GdkDeviceManager *device_manager,
+                    GdkDevice        *device,
+                    GsdCursorManager *manager)
+{
+        /* If devices are removed, then it's unlikely
+         * a mouse appeared */
+        if (manager->priv->cursor_shown == FALSE)
+                return;
+
+        update_cursor_for_current (manager);
+}
+
+static gboolean
+supports_xfixes (void)
+{
+        gint op_code, event, error;
+
+        return XQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+                                "XFIXES",
+                                &op_code,
+                                &event,
+                                &error);
+}
+
+static gboolean
+supports_cursor_xfixes (void)
+{
+        int major = XFIXES_MAJOR;
+        int minor = XFIXES_MINOR;
+
+        gdk_error_trap_push ();
+
+        if (!supports_xfixes ()) {
+                gdk_error_trap_pop_ignored ();
+                return FALSE;
+        }
+
+        if (XFixesQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor) != Success) {
+                gdk_error_trap_pop_ignored ();
+                return FALSE;
+        }
+        gdk_error_trap_pop_ignored ();
+
+        if (major >= 4)
+                return TRUE;
+
+        return FALSE;
+}
+
+static gboolean
+gsd_cursor_manager_idle_cb (GsdCursorManager *manager)
+{
+        GdkDeviceManager *device_manager;
+
+        gnome_settings_profile_start (NULL);
+
+        if (supports_cursor_xfixes () == FALSE) {
+                g_debug ("XFixes cursor extension not available, will not hide the cursor");
+                return FALSE;
+        }
+
+        if (supports_xinput_devices () == FALSE) {
+                g_debug ("XInput support not available, will not hide the cursor");
+                return FALSE;
+        }
+
+        /* We assume that the touchscreen is builtin and
+         * won't be appearing in the middle of the session... */
+        if (touchscreen_is_present () == FALSE) {
+                g_debug ("Did not find a touchscreen, will not hide the cursor");
+                gnome_settings_profile_end (NULL);
+                return FALSE;
+        }
+
+        update_cursor_for_current (manager);
+
+        device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
+        manager->priv->added_id = g_signal_connect (G_OBJECT (device_manager), "device-added",
+                                                    G_CALLBACK (devices_added_cb), manager);
+        manager->priv->removed_id = g_signal_connect (G_OBJECT (device_manager), "device-removed",
+                                                      G_CALLBACK (devices_removed_cb), manager);
+
+        gnome_settings_profile_end (NULL);
+
+        return FALSE;
+}
+
+gboolean
+gsd_cursor_manager_start (GsdCursorManager *manager,
+                          GError               **error)
+{
+        g_debug ("Starting cursor manager");
+        gnome_settings_profile_start (NULL);
+
+        manager->priv->start_idle_id = g_idle_add ((GSourceFunc) gsd_cursor_manager_idle_cb, manager);
+
+        gnome_settings_profile_end (NULL);
+
+        return TRUE;
+}
+
+void
+gsd_cursor_manager_stop (GsdCursorManager *manager)
+{
+        GdkDeviceManager *device_manager;
+
+        g_debug ("Stopping cursor manager");
+
+        device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
+
+        if (manager->priv->added_id > 0) {
+                g_signal_handler_disconnect (G_OBJECT (device_manager), manager->priv->added_id);
+                manager->priv->added_id = 0;
+        }
+
+        if (manager->priv->removed_id > 0) {
+                g_signal_handler_disconnect (G_OBJECT (device_manager), manager->priv->removed_id);
+                manager->priv->removed_id = 0;
+        }
+}
+
+static void
+gsd_cursor_manager_set_property (GObject        *object,
+                                 guint           prop_id,
+                                 const GValue   *value,
+                                 GParamSpec     *pspec)
+{
+        switch (prop_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gsd_cursor_manager_get_property (GObject        *object,
+                                 guint           prop_id,
+                                 GValue         *value,
+                                 GParamSpec     *pspec)
+{
+        switch (prop_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static GObject *
+gsd_cursor_manager_constructor (GType                  type,
+                                guint                  n_construct_properties,
+                                GObjectConstructParam *construct_properties)
+{
+        GsdCursorManager      *cursor_manager;
+
+        cursor_manager = GSD_CURSOR_MANAGER (G_OBJECT_CLASS (gsd_cursor_manager_parent_class)->constructor (type,
+                                                                                                            n_construct_properties,
+                                                                                                            construct_properties));
+
+        return G_OBJECT (cursor_manager);
+}
+
+static void
+gsd_cursor_manager_dispose (GObject *object)
+{
+        G_OBJECT_CLASS (gsd_cursor_manager_parent_class)->dispose (object);
+}
+
+static void
+gsd_cursor_manager_class_init (GsdCursorManagerClass *klass)
+{
+        GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->get_property = gsd_cursor_manager_get_property;
+        object_class->set_property = gsd_cursor_manager_set_property;
+        object_class->constructor = gsd_cursor_manager_constructor;
+        object_class->dispose = gsd_cursor_manager_dispose;
+        object_class->finalize = gsd_cursor_manager_finalize;
+
+        g_type_class_add_private (klass, sizeof (GsdCursorManagerPrivate));
+}
+
+static void
+gsd_cursor_manager_init (GsdCursorManager *manager)
+{
+        manager->priv = GSD_CURSOR_MANAGER_GET_PRIVATE (manager);
+        manager->priv->cursor_shown = TRUE;
+
+}
+
+static void
+gsd_cursor_manager_finalize (GObject *object)
+{
+        GsdCursorManager *cursor_manager;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GSD_IS_CURSOR_MANAGER (object));
+
+        cursor_manager = GSD_CURSOR_MANAGER (object);
+
+        g_return_if_fail (cursor_manager->priv != NULL);
+
+        G_OBJECT_CLASS (gsd_cursor_manager_parent_class)->finalize (object);
+}
+
+GsdCursorManager *
+gsd_cursor_manager_new (void)
+{
+        if (manager_object != NULL) {
+                g_object_ref (manager_object);
+        } else {
+                manager_object = g_object_new (GSD_TYPE_CURSOR_MANAGER, NULL);
+                g_object_add_weak_pointer (manager_object,
+                                           (gpointer *) &manager_object);
+        }
+
+        return GSD_CURSOR_MANAGER (manager_object);
+}
diff --git a/plugins/cursor/gsd-cursor-manager.h b/plugins/cursor/gsd-cursor-manager.h
new file mode 100644
index 0000000..9bfed2d
--- /dev/null
+++ b/plugins/cursor/gsd-cursor-manager.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __GSD_CURSOR_MANAGER_H
+#define __GSD_CURSOR_MANAGER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GSD_TYPE_CURSOR_MANAGER         (gsd_cursor_manager_get_type ())
+#define GSD_CURSOR_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_CURSOR_MANAGER, GsdCursorManager))
+#define GSD_CURSOR_MANAGER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_CURSOR_MANAGER, GsdCursorManagerClass))
+#define GSD_IS_CURSOR_MANAGER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_CURSOR_MANAGER))
+#define GSD_IS_CURSOR_MANAGER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_CURSOR_MANAGER))
+#define GSD_CURSOR_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_CURSOR_MANAGER, GsdCursorManagerClass))
+
+typedef struct GsdCursorManagerPrivate GsdCursorManagerPrivate;
+
+typedef struct
+{
+        GObject                     parent;
+        GsdCursorManagerPrivate *priv;
+} GsdCursorManager;
+
+typedef struct
+{
+        GObjectClass   parent_class;
+} GsdCursorManagerClass;
+
+GType                   gsd_cursor_manager_get_type            (void);
+
+GsdCursorManager *       gsd_cursor_manager_new                 (void);
+gboolean                gsd_cursor_manager_start               (GsdCursorManager *manager,
+                                                               GError         **error);
+void                    gsd_cursor_manager_stop                (GsdCursorManager *manager);
+
+G_END_DECLS
+
+#endif /* __GSD_CURSOR_MANAGER_H */
diff --git a/plugins/cursor/gsd-cursor-plugin.c b/plugins/cursor/gsd-cursor-plugin.c
new file mode 100644
index 0000000..79a236d
--- /dev/null
+++ b/plugins/cursor/gsd-cursor-plugin.c
@@ -0,0 +1,110 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+
+#include "gnome-settings-plugin.h"
+#include "gsd-cursor-plugin.h"
+#include "gsd-cursor-manager.h"
+
+struct GsdCursorPluginPrivate {
+        GsdCursorManager *manager;
+};
+
+#define GSD_CURSOR_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_CURSOR_PLUGIN, GsdCursorPluginPrivate))
+
+GNOME_SETTINGS_PLUGIN_REGISTER (GsdCursorPlugin, gsd_cursor_plugin)
+
+static void
+gsd_cursor_plugin_init (GsdCursorPlugin *plugin)
+{
+        plugin->priv = GSD_CURSOR_PLUGIN_GET_PRIVATE (plugin);
+
+        g_debug ("GsdCursorPlugin initializing");
+
+        plugin->priv->manager = gsd_cursor_manager_new ();
+}
+
+static void
+gsd_cursor_plugin_finalize (GObject *object)
+{
+        GsdCursorPlugin *plugin;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GSD_IS_CURSOR_PLUGIN (object));
+
+        g_debug ("GsdCursorPlugin finalizing");
+
+        plugin = GSD_CURSOR_PLUGIN (object);
+
+        g_return_if_fail (plugin->priv != NULL);
+
+        if (plugin->priv->manager != NULL) {
+                g_object_unref (plugin->priv->manager);
+        }
+
+        G_OBJECT_CLASS (gsd_cursor_plugin_parent_class)->finalize (object);
+}
+
+static void
+impl_activate (GnomeSettingsPlugin *plugin)
+{
+        gboolean res;
+        GError  *error;
+
+        g_debug ("Activating cursor plugin");
+
+        error = NULL;
+        res = gsd_cursor_manager_start (GSD_CURSOR_PLUGIN (plugin)->priv->manager, &error);
+        if (! res) {
+                g_warning ("Unable to start cursor manager: %s", error->message);
+                g_error_free (error);
+        }
+}
+
+static void
+impl_deactivate (GnomeSettingsPlugin *plugin)
+{
+        g_debug ("Deactivating cursor plugin");
+        gsd_cursor_manager_stop (GSD_CURSOR_PLUGIN (plugin)->priv->manager);
+}
+
+static void
+gsd_cursor_plugin_class_init (GsdCursorPluginClass *klass)
+{
+        GObjectClass           *object_class = G_OBJECT_CLASS (klass);
+        GnomeSettingsPluginClass *plugin_class = GNOME_SETTINGS_PLUGIN_CLASS (klass);
+
+        object_class->finalize = gsd_cursor_plugin_finalize;
+
+        plugin_class->activate = impl_activate;
+        plugin_class->deactivate = impl_deactivate;
+
+        g_type_class_add_private (klass, sizeof (GsdCursorPluginPrivate));
+}
+
+static void
+gsd_cursor_plugin_class_finalize (GsdCursorPluginClass *klass)
+{
+}
+
diff --git a/plugins/cursor/gsd-cursor-plugin.h b/plugins/cursor/gsd-cursor-plugin.h
new file mode 100644
index 0000000..e2729da
--- /dev/null
+++ b/plugins/cursor/gsd-cursor-plugin.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann jhu edu>
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __GSD_CURSOR_PLUGIN_H__
+#define __GSD_CURSOR_PLUGIN_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gmodule.h>
+
+#include "gnome-settings-plugin.h"
+
+G_BEGIN_DECLS
+
+#define GSD_TYPE_CURSOR_PLUGIN                (gsd_cursor_plugin_get_type ())
+#define GSD_CURSOR_PLUGIN(o)                  (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_CURSOR_PLUGIN, GsdCursorPlugin))
+#define GSD_CURSOR_PLUGIN_CLASS(k)            (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_CURSOR_PLUGIN, GsdCursorPluginClass))
+#define GSD_IS_CURSOR_PLUGIN(o)               (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_CURSOR_PLUGIN))
+#define GSD_IS_CURSOR_PLUGIN_CLASS(k)         (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_CURSOR_PLUGIN))
+#define GSD_CURSOR_PLUGIN_GET_CLASS(o)        (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_CURSOR_PLUGIN, GsdCursorPluginClass))
+
+typedef struct GsdCursorPluginPrivate GsdCursorPluginPrivate;
+
+typedef struct
+{
+        GnomeSettingsPlugin    parent;
+        GsdCursorPluginPrivate *priv;
+} GsdCursorPlugin;
+
+typedef struct
+{
+        GnomeSettingsPluginClass parent_class;
+} GsdCursorPluginClass;
+
+GType   gsd_cursor_plugin_get_type            (void) G_GNUC_CONST;
+
+/* All the plugins must implement this function */
+G_MODULE_EXPORT GType register_gnome_settings_plugin (GTypeModule *module);
+
+G_END_DECLS
+
+#endif /* __GSD_CURSOR_PLUGIN_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]