mousetweaks r126 - in trunk: . data src
- From: gerdk svn gnome org
- To: svn-commits-list gnome org
- Subject: mousetweaks r126 - in trunk: . data src
- Date: Sat, 29 Mar 2008 20:33:23 +0000 (GMT)
Author: gerdk
Date: Sat Mar 29 20:33:23 2008
New Revision: 126
URL: http://svn.gnome.org/viewvc/mousetweaks?rev=126&view=rev
Log:
2008-03-29 Gerd Kohlberger <gerdk svn gnome org>
* src/mt-cusor.c/h: Initial commit.
* src/mt-cusor-manager.c/h: Initial commit.
* src/Makefile.am: Add new cursor files.
* src/mt-main.c/h: Use new objects. Add cursor drawing code.
* src/mt-common.h: New animate_cursor option.
* data/mousetwaks.schemas.in: New animate_cursor option.
Add cursor animation to give visual feedback for the internal
state of the timers. For dwell-click this means - how long the
cursor has been motionless, for secondary clicks - how long the
primary button has been pressed.
Added:
trunk/src/mt-cursor-manager.c
trunk/src/mt-cursor-manager.h
trunk/src/mt-cursor.c
trunk/src/mt-cursor.h
Modified:
trunk/ChangeLog
trunk/data/mousetweaks.schemas.in
trunk/src/Makefile.am
trunk/src/mt-common.h
trunk/src/mt-main.c
trunk/src/mt-main.h
Modified: trunk/data/mousetweaks.schemas.in
==============================================================================
--- trunk/data/mousetweaks.schemas.in (original)
+++ trunk/data/mousetweaks.schemas.in Sat Mar 29 20:33:23 2008
@@ -133,5 +133,16 @@
<long>Button style in click type window ("0" = Text, "1" = Icon, "2" = Both)</long>
</locale>
</schema>
+ <schema>
+ <key>/schemas/desktop/gnome/accessibility/mouse/animate_cursor</key>
+ <applyto>/desktop/gnome/accessibility/mouse/animate_cursor</applyto>
+ <owner>mousetweaks</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short>Animate cursor</short>
+ <long>Show elapsed time as cursor overlay.</long>
+ </locale>
+ </schema>
</schemalist>
</gconfschemafile>
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Sat Mar 29 20:33:23 2008
@@ -13,19 +13,23 @@
bin_PROGRAMS = mousetweaks $(pca_bin) $(dca_bin)
-mousetweaks_SOURCES = \
- mt-main.c \
- mt-main.h \
- mt-common.c \
- mt-common.h \
- mt-pidfile.c \
- mt-pidfile.h \
- mt-service.c \
- mt-service.h \
- mt-ctw.c \
- mt-ctw.h \
- mt-timer.c \
- mt-timer.h
+mousetweaks_SOURCES = \
+ mt-main.c \
+ mt-main.h \
+ mt-common.c \
+ mt-common.h \
+ mt-pidfile.c \
+ mt-pidfile.h \
+ mt-service.c \
+ mt-service.h \
+ mt-ctw.c \
+ mt-ctw.h \
+ mt-timer.c \
+ mt-timer.h \
+ mt-cursor.c \
+ mt-cursor.h \
+ mt-cursor-manager.c \
+ mt-cursor-manager.h
mousetweaks_LDFLAGS = $(DEPENDENCIES_LIBS)
Modified: trunk/src/mt-common.h
==============================================================================
--- trunk/src/mt-common.h (original)
+++ trunk/src/mt-common.h Sat Mar 29 20:33:23 2008
@@ -43,6 +43,7 @@
#define OPT_G_DRAG MT_GCONF_HOME "/dwell_gesture_drag"
#define OPT_G_RIGHT MT_GCONF_HOME "/dwell_gesture_secondary"
#define OPT_STYLE MT_GCONF_HOME "/button_layout"
+#define OPT_ANIMATE MT_GCONF_HOME "/animate_cursor"
enum {
DWELL_MODE_CTW = 0,
Added: trunk/src/mt-cursor-manager.c
==============================================================================
--- (empty file)
+++ trunk/src/mt-cursor-manager.c Sat Mar 29 20:33:23 2008
@@ -0,0 +1,315 @@
+/*
+ * Copyright  2008 Gerd Kohlberger <lowfi chello at>
+ *
+ * This file is part of Mousetweaks.
+ *
+ * Mousetweaks 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mousetweaks 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 <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <X11/Xcursor/Xcursor.h>
+#include <X11/extensions/Xfixes.h>
+
+#include "mt-cursor.h"
+#include "mt-cursor-manager.h"
+
+#define MT_CURSOR_MANAGER_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), MT_TYPE_CURSOR_MANAGER, MtCursorManagerPrivate))
+
+static int fixes_event = 0;
+static int fixes_error = 0;
+
+typedef struct _MtCursorManagerPrivate MtCursorManagerPrivate;
+struct _MtCursorManagerPrivate {
+ GHashTable *cache;
+ gboolean cursor_set;
+};
+
+enum {
+ CURSOR_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (MtCursorManager, mt_cursor_manager, G_TYPE_OBJECT)
+
+static void mt_cursor_manager_finalize (GObject *object);
+static void mt_cursor_manager_clear_cache (MtCursorManager *manager);
+static GdkFilterReturn xfixes_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data);
+
+static void
+mt_cursor_manager_class_init (MtCursorManagerClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = mt_cursor_manager_finalize;
+
+ signals[CURSOR_CHANGED] =
+ g_signal_new (g_intern_static_string ("cursor_changed"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ g_type_class_add_private (klass, sizeof (MtCursorManagerPrivate));
+}
+
+static void
+mt_cursor_manager_init (MtCursorManager *manager)
+{
+ MtCursorManagerPrivate *priv = MT_CURSOR_MANAGER_GET_PRIVATE (manager);
+
+ priv->cache = NULL;
+ priv->cursor_set = FALSE;
+}
+
+static void
+mt_cursor_manager_finalize (GObject *object)
+{
+ MtCursorManagerPrivate *priv = MT_CURSOR_MANAGER_GET_PRIVATE (object);
+
+ gdk_window_remove_filter (gdk_get_default_root_window (),
+ xfixes_filter, object);
+
+ if (priv->cache)
+ g_hash_table_destroy (priv->cache);
+
+ G_OBJECT_CLASS (mt_cursor_manager_parent_class)->finalize (object);
+}
+
+static gboolean
+mt_cursor_manager_set_xcursor (MtCursor *cursor)
+{
+ XcursorImage *ximage;
+ const guchar *image;
+ Cursor xcursor;
+ gushort width, height;
+ gushort xhot, yhot;
+
+ mt_cursor_get_hotspot (cursor, &xhot, &yhot);
+ mt_cursor_get_dimension (cursor, &width, &height);
+ image = mt_cursor_get_image (cursor);
+
+ ximage = XcursorImageCreate (width, height);
+ ximage->xhot = xhot;
+ ximage->yhot = yhot;
+ ximage->delay = 0;
+ ximage->pixels = (XcursorPixel *) image;
+
+ xcursor = XcursorImageLoadCursor (GDK_DISPLAY (), ximage);
+ if (xcursor) {
+ const gchar *name;
+
+ name = mt_cursor_get_name (cursor);
+ XFixesSetCursorName (GDK_DISPLAY (), xcursor, name);
+ XFixesChangeCursorByName (GDK_DISPLAY (), xcursor, name);
+ XFreeCursor (GDK_DISPLAY (), xcursor);
+ XcursorImageDestroy (ximage);
+
+ return TRUE;
+ }
+
+ XcursorImageDestroy (ximage);
+
+ return FALSE;
+}
+
+static void
+mt_cursor_manager_restore_cursor (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ MtCursorManagerPrivate *priv = MT_CURSOR_MANAGER_GET_PRIVATE (data);
+
+ priv->cursor_set = mt_cursor_manager_set_xcursor (MT_CURSOR (value));
+}
+
+static void
+mt_cursor_manager_add_cursor (MtCursorManager *manager,
+ XFixesCursorImage *image)
+{
+ MtCursor *cursor;
+ MtCursorManagerPrivate *priv;
+
+ cursor = mt_cursor_new (image->name, (guchar *) image->pixels,
+ image->width, image->height,
+ image->xhot, image->yhot);
+
+ if (cursor) {
+ priv = MT_CURSOR_MANAGER_GET_PRIVATE (manager);
+ g_hash_table_insert (priv->cache, g_strdup (image->name), cursor);
+ }
+}
+
+static GdkFilterReturn
+xfixes_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+ XEvent *xev = (XEvent *) xevent;
+
+ if (xev->type == fixes_event + XFixesCursorNotify) {
+ XFixesCursorNotifyEvent *cn = (XFixesCursorNotifyEvent *) xev;
+ MtCursorManager *manager = (MtCursorManager *) data;
+
+ if (cn->cursor_name != None) {
+ MtCursorManagerPrivate *priv = MT_CURSOR_MANAGER_GET_PRIVATE (manager);
+
+ if (!priv->cursor_set) {
+ XFixesCursorImage *image;
+
+ image = XFixesGetCursorImage (GDK_DISPLAY ());
+
+ if (mt_cursor_manager_lookup_cursor (manager, image->name) == NULL)
+ mt_cursor_manager_add_cursor (manager, image);
+
+ g_signal_emit (manager, signals[CURSOR_CHANGED], 0, image->name);
+
+ XFree (image);
+ }
+ else
+ priv->cursor_set = FALSE;
+ }
+ else
+ g_signal_emit (manager, signals[CURSOR_CHANGED], 0, "");
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+_clear_cursor_cache (GObject *settings,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ mt_cursor_manager_clear_cache (data);
+}
+
+static MtCursorManager *
+mt_cursor_manager_new (void)
+{
+ MtCursorManager *manager;
+ MtCursorManagerPrivate *priv;
+ GtkSettings *settings;
+
+ manager = g_object_new (MT_TYPE_CURSOR_MANAGER, NULL);
+ priv = MT_CURSOR_MANAGER_GET_PRIVATE (manager);
+ priv->cache = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_object_unref);
+
+ XFixesQueryExtension (GDK_DISPLAY (), &fixes_event, &fixes_error);
+ XFixesSelectCursorInput (GDK_DISPLAY (), GDK_ROOT_WINDOW (),
+ XFixesDisplayCursorNotifyMask);
+
+ gdk_window_add_filter (gdk_get_default_root_window (),
+ xfixes_filter, manager);
+
+ settings = gtk_settings_get_default ();
+ g_signal_connect (settings, "notify::gtk-cursor-theme-name",
+ G_CALLBACK (_clear_cursor_cache), manager);
+ g_signal_connect (settings, "notify::gtk-cursor-theme-size",
+ G_CALLBACK (_clear_cursor_cache), manager);
+
+ return manager;
+}
+
+MtCursorManager *
+mt_cursor_manager_get_default (void)
+{
+ static MtCursorManager *manager = NULL;
+
+ if (manager == NULL)
+ manager = mt_cursor_manager_new ();
+
+ return manager;
+}
+
+static void
+mt_cursor_manager_clear_cache (MtCursorManager *manager)
+{
+ MtCursorManagerPrivate *priv;
+
+ g_return_if_fail (MT_IS_CURSOR_MANAGER (manager));
+
+ priv = MT_CURSOR_MANAGER_GET_PRIVATE (manager);
+ g_hash_table_remove_all (priv->cache);
+}
+
+MtCursor *
+mt_cursor_manager_current_cursor (MtCursorManager *manager)
+{
+ MtCursorManagerPrivate *priv;
+ XFixesCursorImage *image;
+ MtCursor *cursor;
+
+ g_return_val_if_fail (MT_IS_CURSOR_MANAGER (manager), NULL);
+
+ image = XFixesGetCursorImage (GDK_DISPLAY ());
+ cursor = NULL;
+
+ if (image->name && image->name[0] != '\0') {
+ cursor = mt_cursor_manager_lookup_cursor (manager, image->name);
+
+ if (cursor == NULL) {
+ mt_cursor_manager_add_cursor (manager, image);
+ cursor = mt_cursor_manager_lookup_cursor (manager, image->name);
+ }
+ }
+
+ XFree (image);
+
+ return cursor;
+}
+
+MtCursor *
+mt_cursor_manager_lookup_cursor (MtCursorManager *manager,
+ const gchar *name)
+{
+ MtCursorManagerPrivate *priv;
+
+ g_return_val_if_fail (MT_IS_CURSOR_MANAGER (manager), NULL);
+
+ if (name == NULL || name[0] == '\0')
+ return NULL;
+
+ priv = MT_CURSOR_MANAGER_GET_PRIVATE (manager);
+
+ return g_hash_table_lookup (priv->cache, name);
+}
+
+void
+mt_cursor_manager_set_cursor (MtCursorManager *manager,
+ MtCursor *cursor)
+{
+ MtCursorManagerPrivate *priv;
+
+ g_return_if_fail (MT_IS_CURSOR_MANAGER (manager));
+ g_return_if_fail (MT_IS_CURSOR (cursor));
+
+ priv = MT_CURSOR_MANAGER_GET_PRIVATE (manager);
+ priv->cursor_set = mt_cursor_manager_set_xcursor (cursor);
+}
+
+void
+mt_cursor_manager_restore_all (MtCursorManager *manager)
+{
+ MtCursorManagerPrivate *priv;
+
+ g_return_if_fail (MT_IS_CURSOR_MANAGER (manager));
+
+ priv = MT_CURSOR_MANAGER_GET_PRIVATE (manager);
+ g_hash_table_foreach (priv->cache,
+ mt_cursor_manager_restore_cursor,
+ manager);
+}
Added: trunk/src/mt-cursor-manager.h
==============================================================================
--- (empty file)
+++ trunk/src/mt-cursor-manager.h Sat Mar 29 20:33:23 2008
@@ -0,0 +1,59 @@
+/*
+ * Copyright  2008 Gerd Kohlberger <lowfi chello at>
+ *
+ * This file is part of Mousetweaks.
+ *
+ * Mousetweaks 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mousetweaks 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 __MT_CURSOR_MANAGER_H__
+#define __MT_CURSOR_MANAGER_H__
+
+#include <glib-object.h>
+
+#include "mt-cursor.h"
+
+G_BEGIN_DECLS
+
+#define MT_TYPE_CURSOR_MANAGER (mt_cursor_manager_get_type ())
+#define MT_CURSOR_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MT_TYPE_CURSOR_MANAGER, MtCursor))
+#define MT_CURSOR_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MT_TYPE_CURSOR_MANAGER, MtCursorClass))
+#define MT_IS_CURSOR_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MT_TYPE_CURSOR_MANAGER))
+#define MT_IS_CURSOR_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MT_TYPE_CURSOR_MANAGER))
+#define MT_CURSOR_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MT_TYPE_CURSOR_MANAGER, MtCursorClass))
+
+typedef struct _MtCursorManager MtCursorManager;
+typedef struct _MtCursorManagerClass MtCursorManagerClass;
+
+struct _MtCursorManager {
+ GObject parent;
+};
+
+struct _MtCursorManagerClass {
+ GObjectClass parent;
+};
+
+GType mt_cursor_manager_get_type (void) G_GNUC_CONST;
+
+MtCursorManager * mt_cursor_manager_get_default (void);
+MtCursor * mt_cursor_manager_current_cursor (MtCursorManager *manager);
+MtCursor * mt_cursor_manager_lookup_cursor (MtCursorManager *manager,
+ const gchar *name);
+void mt_cursor_manager_set_cursor (MtCursorManager *manager,
+ MtCursor *cursor);
+void mt_cursor_manager_restore_all (MtCursorManager *manager);
+
+G_END_DECLS
+
+#endif /* __MT_CURSOR_MANAGER_H__ */
Added: trunk/src/mt-cursor.c
==============================================================================
--- (empty file)
+++ trunk/src/mt-cursor.c Sat Mar 29 20:33:23 2008
@@ -0,0 +1,192 @@
+/*
+ * Copyright  2008 Gerd Kohlberger <lowfi chello at>
+ *
+ * This file is part of Mousetweaks.
+ *
+ * Mousetweaks 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mousetweaks 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 <glib.h>
+#include <string.h>
+
+#include "mt-cursor.h"
+
+#define MT_CURSOR_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), MT_TYPE_CURSOR, MtCursorPrivate))
+
+typedef struct _MtCursorPrivate MtCursorPrivate;
+struct _MtCursorPrivate {
+ gchar *name;
+ guchar *image;
+ gushort width;
+ gushort height;
+ gushort xhot;
+ gushort yhot;
+};
+
+G_DEFINE_TYPE (MtCursor, mt_cursor, G_TYPE_OBJECT)
+
+static void mt_cursor_finalize (GObject *object);
+
+static void
+mt_cursor_class_init (MtCursorClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = mt_cursor_finalize;
+
+ g_type_class_add_private (klass, sizeof (MtCursorPrivate));
+}
+
+static void
+mt_cursor_init (MtCursor *cursor)
+{
+ MtCursorPrivate *priv = MT_CURSOR_GET_PRIVATE (cursor);
+
+ priv->name = NULL;
+ priv->image = NULL;
+ priv->width = 0;
+ priv->height = 0;
+ priv->xhot = 0;
+ priv->yhot = 0;
+}
+
+static void
+mt_cursor_finalize (GObject *object)
+{
+ MtCursorPrivate *priv = MT_CURSOR_GET_PRIVATE (object);
+
+ if (priv->name)
+ g_free (priv->name);
+
+ if (priv->image)
+ g_free (priv->image);
+
+ G_OBJECT_CLASS (mt_cursor_parent_class)->finalize (object);
+}
+
+static guchar *
+mt_cursor_copy_image (guchar *image,
+ gushort width,
+ gushort height)
+{
+ guchar *copy;
+ gulong n_bytes;
+
+ n_bytes = width * height * 4;
+ copy = (guchar *) g_try_malloc (n_bytes);
+
+ if (copy)
+ memcpy (copy, image, n_bytes);
+
+ return copy;
+}
+
+MtCursor *
+mt_cursor_new (const gchar *name,
+ guchar *image,
+ gushort width,
+ gushort height,
+ gushort xhot,
+ gushort yhot)
+{
+ MtCursor *cursor;
+ MtCursorPrivate *priv;
+ guchar *copy;
+
+ g_return_val_if_fail (name != NULL && name[0] != '\0', NULL);
+ g_return_val_if_fail (image != NULL, NULL);
+ g_return_val_if_fail (width > 0 && height > 0, NULL);
+ g_return_val_if_fail (xhot <= width && yhot <= height, NULL);
+
+ copy = mt_cursor_copy_image (image, width, height);
+
+ g_return_val_if_fail (copy != NULL, NULL);
+
+ cursor = g_object_new (MT_TYPE_CURSOR, NULL);
+ priv = MT_CURSOR_GET_PRIVATE (cursor);
+
+ priv->name = g_strdup (name);
+ priv->image = copy;
+ priv->width = width;
+ priv->height = height;
+ priv->xhot = xhot;
+ priv->yhot = yhot;
+
+ return cursor;
+}
+
+const gchar *
+mt_cursor_get_name (MtCursor *cursor)
+{
+ g_return_val_if_fail (MT_IS_CURSOR (cursor), NULL);
+
+ return MT_CURSOR_GET_PRIVATE (cursor)->name;
+}
+
+const guchar *
+mt_cursor_get_image (MtCursor *cursor)
+{
+ g_return_val_if_fail (MT_IS_CURSOR (cursor), NULL);
+
+ return MT_CURSOR_GET_PRIVATE (cursor)->image;
+}
+
+guchar *
+mt_cursor_get_image_copy (MtCursor *cursor)
+{
+ MtCursorPrivate *priv;
+ guchar *image;
+
+ g_return_val_if_fail (MT_IS_CURSOR (cursor), NULL);
+
+ priv = MT_CURSOR_GET_PRIVATE(cursor);
+ image = mt_cursor_copy_image (priv->image, priv->width, priv->height);
+
+ return image;
+}
+
+void
+mt_cursor_get_hotspot (MtCursor *cursor,
+ gushort *xhot,
+ gushort *yhot)
+{
+ MtCursorPrivate *priv;
+
+ g_return_if_fail (MT_IS_CURSOR (cursor));
+
+ priv = MT_CURSOR_GET_PRIVATE (cursor);
+
+ if (xhot != NULL)
+ *xhot = priv->xhot;
+
+ if (yhot != NULL)
+ *yhot = priv->yhot;
+}
+
+void
+mt_cursor_get_dimension (MtCursor *cursor,
+ gushort *width,
+ gushort *height)
+{
+ MtCursorPrivate *priv;
+
+ g_return_if_fail (MT_IS_CURSOR (cursor));
+
+ priv = MT_CURSOR_GET_PRIVATE (cursor);
+
+ if (width != NULL)
+ *width = priv->width;
+
+ if (height != NULL)
+ *height = priv->height;
+}
Added: trunk/src/mt-cursor.h
==============================================================================
--- (empty file)
+++ trunk/src/mt-cursor.h Sat Mar 29 20:33:23 2008
@@ -0,0 +1,65 @@
+/*
+ * Copyright  2008 Gerd Kohlberger <lowfi chello at>
+ *
+ * This file is part of Mousetweaks.
+ *
+ * Mousetweaks 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Mousetweaks 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 __MT_CURSOR_H__
+#define __MT_CURSOR_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MT_TYPE_CURSOR (mt_cursor_get_type ())
+#define MT_CURSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MT_TYPE_CURSOR, MtCursor))
+#define MT_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MT_TYPE_CURSOR, MtCursorClass))
+#define MT_IS_CURSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MT_TYPE_CURSOR))
+#define MT_IS_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MT_TYPE_CURSOR))
+#define MT_CURSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MT_TYPE_CURSOR, MtCursorClass))
+
+typedef struct _MtCursor MtCursor;
+typedef struct _MtCursorClass MtCursorClass;
+
+struct _MtCursor {
+ GObject parent;
+};
+
+struct _MtCursorClass {
+ GObjectClass parent;
+};
+
+GType mt_cursor_get_type (void) G_GNUC_CONST;
+
+MtCursor * mt_cursor_new (const gchar *name,
+ guchar *image,
+ gushort width,
+ gushort height,
+ gushort xhot,
+ gushort yhot);
+const gchar * mt_cursor_get_name (MtCursor *cursor);
+const guchar * mt_cursor_get_image (MtCursor *cursor);
+guchar * mt_cursor_get_image_copy (MtCursor *cursor);
+void mt_cursor_get_hotspot (MtCursor *cursor,
+ gushort *xhot,
+ gushort *yhot);
+void mt_cursor_get_dimension (MtCursor *cursor,
+ gushort *width,
+ gushort *height);
+
+G_END_DECLS
+
+#endif /* __MT_CURSOR_H__ */
Modified: trunk/src/mt-main.c
==============================================================================
--- trunk/src/mt-main.c (original)
+++ trunk/src/mt-main.c Sat Mar 29 20:33:23 2008
@@ -22,9 +22,9 @@
#include <string.h>
#include <math.h>
#include <unistd.h>
+
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
-#include <X11/extensions/Xfixes.h>
#include <cspi/spi.h>
#include "mt-common.h"
@@ -32,10 +32,10 @@
#include "mt-pidfile.h"
#include "mt-ctw.h"
#include "mt-timer.h"
+#include "mt-cursor-manager.h"
+#include "mt-cursor.h"
#include "mt-main.h"
-static int fixes_event_base = 0;
-
static void
mt_cursor_set (GdkCursorType type)
{
@@ -173,12 +173,13 @@
}
static void
-dwell_time_elapsed (MtTimer *timer, gpointer data)
+dwell_timer_finished (MtTimer *timer, gpointer data)
{
MTClosure *mt = (MTClosure *) data;
gint x, y;
gdk_display_get_pointer (gdk_display_get_default (), NULL, &x, &y, NULL);
+ mt_cursor_manager_restore_all (mt_cursor_manager_get_default ());
/* stop active drag */
if (mt->dwell_drag_started) {
@@ -210,10 +211,12 @@
}
static void
-delay_time_elapsed (MtTimer *timer, gpointer data)
+delay_timer_finished (MtTimer *timer, gpointer data)
{
MTClosure *mt = (MTClosure *) data;
+ mt_cursor_manager_restore_all (mt_cursor_manager_get_default ());
+
SPI_generateMouseEvent (0, 0, "b1r");
SPI_generateMouseEvent (mt->pointer_x, mt->pointer_y, "b3c");
}
@@ -224,17 +227,21 @@
{
MTClosure *mt = (MTClosure *) data;
- if (mt->dwell_enabled)
- if (!within_tolerance (mt, event->detail1, event->detail2))
- if (!mt->dwell_gesture_started) {
- mt->pointer_x = (gint) event->detail1;
- mt->pointer_y = (gint) event->detail2;
- mt_timer_start (mt->dwell_timer);
- }
+ if (mt->dwell_enabled) {
+ if (!within_tolerance (mt, event->detail1, event->detail2) &&
+ !mt->dwell_gesture_started) {
+ mt->pointer_x = (gint) event->detail1;
+ mt->pointer_y = (gint) event->detail2;
+ mt_timer_start (mt->dwell_timer);
+ }
+ }
- if (mt_timer_is_running (mt->delay_timer))
- if (!within_tolerance (mt, event->detail1, event->detail2))
+ if (mt_timer_is_running (mt->delay_timer)) {
+ if (!within_tolerance (mt, event->detail1, event->detail2)) {
mt_timer_stop (mt->delay_timer);
+ mt_cursor_manager_restore_all (mt_cursor_manager_get_default ());
+ }
+ }
}
static void
@@ -242,7 +249,7 @@
{
MTClosure *mt = (MTClosure *) data;
- if (g_str_equal (event->type, "mouse:button:b1p")) {
+ if (g_str_equal (event->type, "mouse:button:1p")) {
if (mt->delay_enabled) {
gdk_display_get_pointer (gdk_display_get_default (), NULL,
&mt->pointer_x, &mt->pointer_y, NULL);
@@ -252,29 +259,108 @@
if (mt->dwell_gesture_started)
dwell_stop_gesture (mt);
}
- else if (g_str_equal (event->type, "mouse:button:b1r"))
- if (mt_timer_is_running (mt->delay_timer))
+ else if (g_str_equal (event->type, "mouse:button:1r")) {
+ if (mt->delay_enabled) {
mt_timer_stop (mt->delay_timer);
+ mt_cursor_manager_restore_all (mt_cursor_manager_get_default ());
+ }
+ }
+}
+
+static gboolean
+cursor_overlay_time (guchar *image,
+ gint width,
+ gint height,
+ MtTimer *timer,
+ gdouble time)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ gdouble target;
+
+ target = mt_timer_get_target (timer);
+
+ surface = cairo_image_surface_create_for_data (image,
+ CAIRO_FORMAT_ARGB32,
+ width, height,
+ width * 4);
+ if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
+ return FALSE;
+
+ cr = cairo_create (surface);
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+ return FALSE;
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_ATOP);
+ cairo_rectangle (cr, 0, 0, width, height / (target / time));
+ cairo_set_source_rgba (cr, 0., 0., 0., 0.75);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ return TRUE;
}
-static GdkFilterReturn
-cursor_changed (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+void
+mt_update_cursor (MtCursor *cursor, MtTimer *timer, gdouble time)
{
- XEvent *xev = (XEvent *) xevent;
+ guchar *image;
+ gushort width, height;
- if (xev->type == fixes_event_base + XFixesCursorNotify) {
- MTClosure *mt = (MTClosure *) data;
- XFixesCursorImage *ci;
+ image = mt_cursor_get_image_copy (cursor);
+ if (image == NULL)
+ return;
- ci = XFixesGetCursorImage (GDK_DISPLAY());
+ mt_cursor_get_dimension (cursor, &width, &height);
- if (!mt->dwell_gesture_started)
- mt->override_cursor = !g_str_equal (ci->name, "left_ptr");
+ if (cursor_overlay_time (image, width, height, timer, time)) {
+ MtCursorManager *manager;
+ MtCursor *new_cursor;
+ const gchar *name;
+ gushort xhot, yhot;
- XFree (ci);
+ name = mt_cursor_get_name (cursor);
+ mt_cursor_get_hotspot (cursor, &xhot, &yhot);
+ new_cursor = mt_cursor_new (name, image, width, height, xhot, yhot);
+ manager = mt_cursor_manager_get_default ();
+ mt_cursor_manager_set_cursor (manager, new_cursor);
+ g_object_unref (new_cursor);
}
- return GDK_FILTER_CONTINUE;
+ g_free (image);
+}
+
+static void
+delay_timer_tick (MtTimer *timer, gdouble time, gpointer data)
+{
+ MTClosure *mt = (MTClosure *) data;
+
+ if (mt->animate_cursor && mt->cursor != NULL)
+ mt_update_cursor (mt->cursor, timer, time);
+}
+
+static void
+dwell_timer_tick (MtTimer *timer, gdouble time, gpointer data)
+{
+ MTClosure *mt = (MTClosure *) data;
+
+ if (mt->animate_cursor &&
+ mt->cursor != NULL &&
+ mt->dwell_mode == DWELL_MODE_CTW)
+ mt_update_cursor (mt->cursor, timer, time);
+}
+
+static void
+cursor_changed (MtCursorManager *manager,
+ const gchar *name,
+ gpointer data)
+{
+ MTClosure *mt = (MTClosure *) data;
+
+ if (!mt->dwell_gesture_started)
+ mt->override_cursor = !g_str_equal (name, "left_ptr");
+
+ mt->cursor = mt_cursor_manager_lookup_cursor (manager, name);
}
static void
@@ -324,6 +410,17 @@
mt->dwell_dirs[DWELL_CLICK_TYPE_DRAG] = gconf_value_get_int (value);
else if (g_str_equal (key, OPT_G_RIGHT) && value->type == GCONF_VALUE_INT)
mt->dwell_dirs[DWELL_CLICK_TYPE_RIGHT] = gconf_value_get_int (value);
+ else if (g_str_equal (key, OPT_ANIMATE) && value->type == GCONF_VALUE_BOOL) {
+ MtCursorManager *manager;
+
+ manager = mt_cursor_manager_get_default ();
+ mt->animate_cursor = gconf_value_get_bool (value);
+
+ if (mt->animate_cursor)
+ mt->cursor = mt_cursor_manager_current_cursor (manager);
+ else
+ mt_cursor_manager_restore_all (manager);
+ }
}
static void
@@ -337,6 +434,7 @@
mt->dwell_show_ctw = gconf_client_get_bool (mt->client, OPT_CTW, NULL);
mt->dwell_mode = gconf_client_get_int (mt->client, OPT_MODE, NULL);
mt->style = gconf_client_get_int (mt->client, OPT_STYLE, NULL);
+ mt->animate_cursor = gconf_client_get_bool (mt->client, OPT_ANIMATE, NULL);
val = gconf_client_get_float (mt->client, OPT_DELAY_T, NULL);
mt_timer_set_target (mt->delay_timer, val);
@@ -370,11 +468,15 @@
mt->delay_timer = mt_timer_new ();
g_signal_connect (mt->delay_timer, "finished",
- G_CALLBACK (delay_time_elapsed), mt);
+ G_CALLBACK (delay_timer_finished), mt);
+ g_signal_connect (mt->delay_timer, "tick",
+ G_CALLBACK (delay_timer_tick), mt);
mt->dwell_timer = mt_timer_new ();
g_signal_connect (mt->dwell_timer, "finished",
- G_CALLBACK (dwell_time_elapsed), mt);
+ G_CALLBACK (dwell_timer_finished), mt);
+ g_signal_connect (mt->dwell_timer, "tick",
+ G_CALLBACK (dwell_timer_tick), mt);
mt->service = mt_service_get_default ();
mt_service_set_clicktype (mt->service, DWELL_CLICK_TYPE_SINGLE, NULL);
@@ -397,8 +499,8 @@
main (int argc, char **argv)
{
MTClosure *mt;
+ MtCursorManager *manager;
AccessibleEventListener *bl, *ml;
- int fixes_error_base;
pid_t pid;
gboolean shutdown = FALSE, ctw = FALSE;
gchar *mode = NULL, *enable = NULL;
@@ -483,17 +585,6 @@
goto FINISH;
}
- /* listen for cursor changes */
- if (XFixesQueryExtension (GDK_DISPLAY(),
- &fixes_event_base,
- &fixes_error_base)) {
- XFixesSelectCursorInput (GDK_DISPLAY(),
- GDK_ROOT_WINDOW(),
- XFixesDisplayCursorNotifyMask);
- gdk_window_add_filter (gdk_get_default_root_window (),
- cursor_changed, mt);
- }
-
/* add at-spi listeners */
ml = SPI_createAccessibleEventListener (spi_motion_event, (void *) mt);
SPI_registerGlobalEventListener (ml, "mouse:abs");
@@ -530,7 +621,16 @@
if (!mt_ctw_init (mt, pos_x, pos_y))
goto CLEANUP;
+ manager = mt_cursor_manager_get_default ();
+ g_signal_connect (manager, "cursor_changed",
+ G_CALLBACK (cursor_changed), mt);
+
+ mt->cursor = mt_cursor_manager_current_cursor (manager);
+
SPI_event_main ();
+
+ mt_cursor_manager_restore_all (manager);
+ g_object_unref (manager);
}
CLEANUP:
Modified: trunk/src/mt-main.h
==============================================================================
--- trunk/src/mt-main.h (original)
+++ trunk/src/mt-main.h Sat Mar 29 20:33:23 2008
@@ -24,6 +24,7 @@
#include "mt-timer.h"
#include "mt-service.h"
+#include "mt-cursor.h"
G_BEGIN_DECLS
@@ -33,6 +34,7 @@
MtService *service;
MtTimer *delay_timer;
MtTimer *dwell_timer;
+ MtCursor *cursor;
gboolean dwell_drag_started;
gboolean dwell_gesture_started;
@@ -50,6 +52,7 @@
gboolean dwell_show_ctw;
gint dwell_mode;
gint dwell_dirs[4];
+ gboolean animate_cursor;
};
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]