Ticket #4021: 0001-Cursor-tracker-only-display-the-cursor-in-mouse-trac.patch

File 0001-Cursor-tracker-only-display-the-cursor-in-mouse-trac.patch, 9.1 KB (added by erikos, 12 years ago)

Cursor tracker for the toolkit-gtk3

  • src/sugar3/Makefile.am

    From e7a839e48ac2821fa20f30ba3dabf0271932871d Mon Sep 17 00:00:00 2001
    From: Simon Schampijer <simon@laptop.org>
    Date: Thu, 11 Oct 2012 15:12:49 +0200
    Subject: [PATCH toolkit-gtk3] Cursor tracker: only display the cursor in
     mouse/trackpad mode
    
    Listen on RawEvents: listen for raw events on the root
    window and decide whether the cursor is shown or not. A
    touch begin event will hide the cursor a motion or button
    press event will show it.
    
    There is no API in XFixes to know whether a cursor is shown
    or not so we keep track of the current state. Furthermore
    we trap X errors if any bad access should happen.
    
    Signed-off-by: Simon Schampijer <simon@laptop.org>
    ---
     src/sugar3/Makefile.am            |   4 +
     src/sugar3/sugar-cursor-tracker.c | 177 ++++++++++++++++++++++++++++++++++++++
     src/sugar3/sugar-cursor-tracker.h |  54 ++++++++++++
     3 files changed, 235 insertions(+)
     create mode 100644 src/sugar3/sugar-cursor-tracker.c
     create mode 100644 src/sugar3/sugar-cursor-tracker.h
    
    diff --git a/src/sugar3/Makefile.am b/src/sugar3/Makefile.am
    index 1eda7d8..f25606b 100644
    a b libsugarext_la_SOURCES = \ 
    4747        gsm-xsmp.h                      \
    4848        sugar-grid.c                    \
    4949        sugar-grid.h                    \
     50        sugar-cursor-tracker.c          \
     51        sugar-cursor-tracker.h          \
    5052        sugar-gesture-grabber.c         \
    5153        sugar-gesture-grabber.h         \
    5254        sugar-key-grabber.c             \
    SugarExt_1_0_gir_FILES = \ 
    128130        gsm-session.h \
    129131        gsm-xsmp.c \
    130132        gsm-xsmp.h \
     133        sugar-cursor-tracker.c \
     134        sugar-cursor-tracker.h \
    131135        sugar-gesture-grabber.c \
    132136        sugar-gesture-grabber.h \
    133137        sugar-key-grabber.c \
  • new file src/sugar3/sugar-cursor-tracker.c

    diff --git a/src/sugar3/sugar-cursor-tracker.c b/src/sugar3/sugar-cursor-tracker.c
    new file mode 100644
    index 0000000..a881c50
    - +  
     1/*
     2 * Copyright (C) 2012 One laptop per child
     3 *
     4 * This library is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU Lesser General Public
     6 * License as published by the Free Software Foundation; either
     7 * version 2 of the License, or (at your option) any later version.
     8 *
     9 * This library is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 * Lesser General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU Lesser General Public
     15 * License along with this library; if not, write to the
     16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     17 * Boston, MA 02111-1307, USA.
     18 *
     19 * Author: Simon Schampijer  <simon@laptop.org>
     20 */
     21
     22#include <gdk/gdkx.h>
     23#include <X11/extensions/XInput2.h>
     24#include "sugar-cursor-tracker.h"
     25
     26typedef struct _SugarCursorTrackerPriv SugarCursorTrackerPriv;
     27
     28struct _SugarCursorTrackerPriv
     29{
     30        GdkWindow *root_window;
     31        gboolean cursor_shown;
     32};
     33
     34G_DEFINE_TYPE (SugarCursorTracker, sugar_cursor_tracker, G_TYPE_OBJECT)
     35
     36
     37static void
     38sugar_cursor_tracker_finalize (GObject *object)
     39{
     40        SugarCursorTrackerPriv *priv = SUGAR_CURSOR_TRACKER (object)->_priv;
     41
     42        G_OBJECT_CLASS (sugar_cursor_tracker_parent_class)->finalize (object);
     43}
     44
     45static void
     46sugar_cursor_tracker_class_init (SugarCursorTrackerClass *klass)
     47{
     48        GObjectClass *object_class = G_OBJECT_CLASS (klass);
     49
     50        object_class->finalize = sugar_cursor_tracker_finalize;
     51
     52        g_type_class_add_private (klass, sizeof (SugarCursorTrackerPriv));
     53}
     54
     55static GdkWindow *
     56_get_default_root_window (void)
     57{
     58        GdkDisplay *display;
     59        GdkScreen *screen;
     60
     61        display = gdk_display_get_default ();
     62        screen = gdk_display_get_default_screen (display);
     63
     64        return gdk_screen_get_root_window (screen);
     65}
     66
     67static void
     68_track_raw_events (GdkWindow *window)
     69{
     70        XIEventMask mask;
     71        guchar *evmask;
     72        GdkDisplay *display;
     73
     74        evmask = g_new0 (guchar, XIMaskLen (XI_LASTEVENT));
     75        XISetMask (evmask, XI_RawTouchBegin);
     76        XISetMask (evmask, XI_RawTouchEnd);
     77        XISetMask (evmask, XI_RawTouchUpdate);
     78        XISetMask (evmask, XI_RawMotion);
     79        XISetMask (evmask, XI_RawButtonPress);
     80
     81        mask.deviceid = XIAllMasterDevices;
     82        mask.mask_len = sizeof (evmask);
     83        mask.mask = evmask;
     84
     85        display = gdk_window_get_display (window);
     86        XISelectEvents (gdk_x11_display_get_xdisplay (display),
     87                        gdk_x11_window_get_xid (window),
     88                        &mask, 1);
     89}
     90
     91static void
     92_set_cursor_visibility (SugarCursorTracker *tracker,
     93                        gboolean visible)
     94{
     95        GdkDisplay *display;
     96        Display *xdisplay;
     97        SugarCursorTrackerPriv *priv;
     98
     99        priv = tracker->_priv;
     100        display = gdk_display_get_default ();
     101        xdisplay = GDK_DISPLAY_XDISPLAY (display);
     102
     103        gdk_error_trap_push ();
     104
     105        if (visible == TRUE) {
     106            if (priv->cursor_shown == FALSE) {
     107                XFixesShowCursor (xdisplay, GDK_WINDOW_XID (_get_default_root_window ()));
     108                priv->cursor_shown = TRUE;
     109            }
     110        }
     111        else {
     112            if (priv->cursor_shown == TRUE) {
     113                XFixesHideCursor (xdisplay, GDK_WINDOW_XID (_get_default_root_window ()));
     114                priv->cursor_shown = False;
     115            }
     116        }
     117
     118        if (gdk_error_trap_pop ()) {
     119            g_warning ("An error occurred trying to %s the cursor",
     120                       FALSE ? "show" : "hide");
     121        }
     122}
     123
     124static GdkFilterReturn
     125filter_function (GdkXEvent *xevent,
     126                 GdkEvent  *gdkevent,
     127                 gpointer   user_data)
     128{
     129        XEvent *ev = xevent;
     130        XIEvent *xiev;
     131        SugarCursorTracker *tracker;
     132
     133        if (ev->type != GenericEvent)
     134                return GDK_FILTER_CONTINUE;
     135
     136        tracker = user_data;
     137
     138        xiev = ev->xcookie.data;
     139
     140        switch (xiev->evtype) {
     141        case XI_RawTouchBegin:
     142                _set_cursor_visibility (tracker, FALSE);
     143                return GDK_FILTER_REMOVE;
     144        case XI_RawMotion:
     145                _set_cursor_visibility (tracker, TRUE);
     146                return GDK_FILTER_REMOVE;
     147        case XI_RawButtonPress:
     148                _set_cursor_visibility (tracker, TRUE);
     149                return GDK_FILTER_REMOVE;
     150        default:
     151                return GDK_FILTER_CONTINUE;
     152        }
     153}
     154
     155static void
     156sugar_cursor_tracker_init (SugarCursorTracker *tracker)
     157{
     158        SugarCursorTrackerPriv *priv;
     159        tracker->_priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (tracker,
     160                                                             SUGAR_TYPE_CURSOR_TRACKER,
     161                                                             SugarCursorTrackerPriv);
     162        priv->root_window = _get_default_root_window ();
     163        priv->cursor_shown = True;
     164
     165        tracker->_priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (tracker,
     166                                                             SUGAR_TYPE_CURSOR_TRACKER,
     167                                                             SugarCursorTrackerPriv);
     168        priv->root_window = _get_default_root_window ();
     169        _track_raw_events (priv->root_window);
     170        gdk_window_add_filter (NULL, filter_function, tracker);
     171}
     172
     173SugarCursorTracker *
     174sugar_cursor_tracker_new (void)
     175{
     176        return g_object_new (SUGAR_TYPE_CURSOR_TRACKER, NULL);
     177}
  • new file src/sugar3/sugar-cursor-tracker.h

    diff --git a/src/sugar3/sugar-cursor-tracker.h b/src/sugar3/sugar-cursor-tracker.h
    new file mode 100644
    index 0000000..2ca60d1
    - +  
     1/*
     2 * Copyright (C) 2012 One laptop per child
     3 *
     4 * This library is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU Lesser General Public
     6 * License as published by the Free Software Foundation; either
     7 * version 2 of the License, or (at your option) any later version.
     8 *
     9 * This library is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 * Lesser General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU Lesser General Public
     15 * License along with this library; if not, write to the
     16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     17 * Boston, MA 02111-1307, USA.
     18 *
     19 * Author: Simon Schampijer  <simon@laptop.org>
     20 */
     21
     22#ifndef __SUGAR_CURSOR_TRACKER_H__
     23#define __SUGAR_CURSOR_TRACKER_H__
     24
     25#include <gtk/gtk.h>
     26#include "event-controller/sugar-event-controllers.h"
     27
     28G_BEGIN_DECLS
     29
     30typedef struct _SugarCursorTracker SugarCursorTracker;
     31typedef struct _SugarCursorTrackerClass SugarCursorTrackerClass;
     32
     33#define SUGAR_TYPE_CURSOR_TRACKER              (sugar_cursor_tracker_get_type())
     34#define SUGAR_CURSOR_TRACKER(object)           (G_TYPE_CHECK_INSTANCE_CAST((object), SUGAR_TYPE_CURSOR_TRACKER, SugarCursorTracker))
     35#define SUGAR_CURSOR_TRACKER_CLASS(klass)      (G_TYPE_CHACK_CLASS_CAST((klass), SUGAR_TYPE_CURSOR_TRACKER, SugarCursorTrackerClass))
     36#define SUGAR_IS_CURSOR_TRACKER(object)        (G_TYPE_CHECK_INSTANCE_TYPE((object), SUGAR_TYPE_CURSOR_TRACKER))
     37#define SUGAR_IS_CURSOR_TRACKER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), SUGAR_TYPE_CURSOR_TRACKER))
     38#define SUGAR_CURSOR_TRACKER_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), SUGAR_TYPE_CURSOR_TRACKER, SugarCursorTrackerClass))
     39
     40struct _SugarCursorTracker {
     41        GObject parent_instance;
     42        gpointer _priv;
     43};
     44
     45struct _SugarCursorTrackerClass {
     46        GObjectClass parent_class;
     47};
     48
     49GType                sugar_cursor_tracker_get_type (void);
     50SugarCursorTracker * sugar_cursor_tracker_new      (void);
     51
     52G_END_DECLS
     53
     54#endif /* __SUGAR_CURSOR_TRACKER_H__ */