~ubuntu-branches/ubuntu/oneiric/mousetweaks/oneiric

« back to all changes in this revision

Viewing changes to src/mt-cursor-manager.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich
  • Date: 2010-11-10 11:40:46 UTC
  • mfrom: (1.1.47 upstream)
  • Revision ID: james.westby@ubuntu.com-20101110114046-gd7qvdqsvnj3zcfb
Tags: 2.91.2-0ubuntu1
* New upstream release
  - Misc changes, improvements and fixes:
    + Add gsettings convert data
    + Add "geometry" option to set size and position of the click-type window
    + Add new "orientation" option to the click-type window
    + Remove "animate-cursor" option
    + Update git.mk
    + Sync with changes in gsettings-desktop-schemas
    + Fix mem leak and reduce nr. of cursor image copies
    + Don't emit cursor_changed signals if we have set the cursor
    + Bump gsettings-desktop-schemas dependency to 0.1.0
    + Remove mt-main header file
    + Disable panel applets by default for GNOME 3
    + Use gdk_display_get_default instead of GDK_DISPLAY (Javier Jardón)
    + Remove GdkGc based drawing code
    + Use a common X Display accessor
    + Remove mouse orientation checks
    + Only install man pages if the applets are built
    + Sync with GSettings changes in gnome-settings-daemon
    + Launch UA panel instead of the mouse capplet
  - Bug fixes:
    + #633844: L10N: Fix a typo
    + #633932: L10N: Add translation comments for button orientation
    + #631533: Adapt to GtkObject removal in GTK3 (Javier Jardón)
    + #620171: Migrate to GSettings
  - New and updated translations:
    + [ca] Carles Ferrando
    + [es] Jorge González
    + [gl] Fran Diéguez
    + [he] Yaron Shahrabani
    + [ja] Takayuki KUSANO
    + [sk] Pavol Šimo
    + [sl] Matej Urbančič
    + [el] Simos Xenitellis
    + [et] Ivar Smolin
    + [ko] Changwoo Ryu
    + [lt] Žygimantas Beručka
* debian/control:
  - Drop libatspi-dev from Build-Depends
  - Add gsettings-desktop-schemas-dev >= 0.1.0 to Build-Depends
  - Build depend on GTK 3.0 >= 2.91.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
18
 */
19
19
 
20
 
#include <gtk/gtk.h>
21
 
#include <gdk/gdkx.h>
22
20
#include <X11/Xcursor/Xcursor.h>
23
21
#include <X11/extensions/Xfixes.h>
24
22
 
 
23
#include "mt-cursor-manager.h"
25
24
#include "mt-cursor.h"
26
 
#include "mt-cursor-manager.h"
 
25
#include "mt-common.h"
27
26
 
28
27
static int xfixes_event = 0;
29
28
static int xfixes_error = 0;
31
30
struct _MtCursorManagerPrivate
32
31
{
33
32
    GHashTable *cache;
 
33
    MtCursor   *current;
34
34
};
35
35
 
36
36
enum
37
37
{
38
38
    CURSOR_CHANGED,
39
 
    CACHE_CLEARED,
40
39
    LAST_SIGNAL
41
40
};
42
41
 
43
42
static guint signals[LAST_SIGNAL] = { 0, };
44
43
 
45
 
static void            mt_cursor_manager_clear_cache  (GObject         *settings,
46
 
                                                       GParamSpec      *pspec,
47
 
                                                       MtCursorManager *manager);
48
 
static GdkFilterReturn mt_cursor_manager_event_filter (GdkXEvent       *gdk_xevent,
49
 
                                                       GdkEvent        *gdk_event,
50
 
                                                       gpointer         data);
 
44
static void            mt_cursor_manager_clear_cache        (GObject         *settings,
 
45
                                                             GParamSpec      *pspec,
 
46
                                                             MtCursorManager *manager);
 
47
static GdkFilterReturn mt_cursor_manager_event_filter       (GdkXEvent       *gdk_xevent,
 
48
                                                             GdkEvent        *gdk_event,
 
49
                                                             MtCursorManager *manager);
 
50
static void            mt_cursor_manager_add_current_cursor (MtCursorManager *manager,
 
51
                                                             Display         *display);
51
52
 
52
53
G_DEFINE_TYPE (MtCursorManager, mt_cursor_manager, G_TYPE_OBJECT)
53
54
 
54
 
static Display *
55
 
mt_cursor_manager_display (void)
56
 
{
57
 
    return GDK_DISPLAY ();
58
 
}
59
 
 
60
55
static void
61
56
mt_cursor_manager_init (MtCursorManager *manager)
62
57
{
63
58
    GtkSettings *gs;
 
59
    Display *dpy;
64
60
 
65
61
    manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
66
62
                                                 MT_TYPE_CURSOR_MANAGER,
71
67
                                                  g_free,
72
68
                                                  g_object_unref);
73
69
 
 
70
    dpy = mt_common_get_xdisplay ();
 
71
 
74
72
    /* init XFixes extension */
75
 
    if (XFixesQueryExtension (mt_cursor_manager_display (),
76
 
                              &xfixes_event, &xfixes_error))
 
73
    if (XFixesQueryExtension (dpy, &xfixes_event, &xfixes_error))
77
74
    {
78
 
        XFixesSelectCursorInput (mt_cursor_manager_display (),
79
 
                                 GDK_ROOT_WINDOW (),
 
75
        XFixesSelectCursorInput (dpy, GDK_ROOT_WINDOW (),
80
76
                                 XFixesDisplayCursorNotifyMask);
81
77
    }
82
78
 
83
 
    gdk_window_add_filter (NULL, mt_cursor_manager_event_filter, manager);
 
79
    gdk_window_add_filter (NULL, (GdkFilterFunc) mt_cursor_manager_event_filter, manager);
84
80
 
85
81
    /* listen for cursor theme changes */
86
82
    gs = gtk_settings_get_default ();
88
84
                      G_CALLBACK (mt_cursor_manager_clear_cache), manager);
89
85
    g_signal_connect (gs, "notify::gtk-cursor-theme-size",
90
86
                      G_CALLBACK (mt_cursor_manager_clear_cache), manager);
 
87
 
 
88
    mt_cursor_manager_add_current_cursor (manager, dpy);
91
89
}
92
90
 
93
91
static void
95
93
{
96
94
    MtCursorManagerPrivate *priv = MT_CURSOR_MANAGER (object)->priv;
97
95
 
98
 
    gdk_window_remove_filter (NULL, mt_cursor_manager_event_filter, object);
 
96
    gdk_window_remove_filter (NULL, (GdkFilterFunc) mt_cursor_manager_event_filter, object);
99
97
    g_hash_table_destroy (priv->cache);
100
98
 
101
99
    G_OBJECT_CLASS (mt_cursor_manager_parent_class)->finalize (object);
116
114
                      g_cclosure_marshal_VOID__STRING,
117
115
                      G_TYPE_NONE, 1, G_TYPE_STRING);
118
116
 
119
 
    signals[CACHE_CLEARED] =
120
 
        g_signal_new (g_intern_static_string ("cache_cleared"),
121
 
                      G_OBJECT_CLASS_TYPE (klass),
122
 
                      G_SIGNAL_RUN_LAST,
123
 
                      0, NULL, NULL,
124
 
                      g_cclosure_marshal_VOID__VOID,
125
 
                      G_TYPE_NONE, 0);
126
 
 
127
117
    g_type_class_add_private (klass, sizeof (MtCursorManagerPrivate));
128
118
}
129
119
 
137
127
    gushort width, height;
138
128
    gushort xhot, yhot;
139
129
 
140
 
    dpy = mt_cursor_manager_display ();
 
130
    dpy = mt_common_get_xdisplay ();
141
131
    mt_cursor_get_dimension (cursor, &width, &height);
142
132
    ximage = XcursorImageCreate (width, height);
143
133
    xcursor = 0;
175
165
    mt_cursor_manager_set_xcursor (value);
176
166
}
177
167
 
178
 
static void
 
168
static MtCursor *
179
169
mt_cursor_manager_add_cursor (MtCursorManager   *manager,
180
170
                              XFixesCursorImage *image)
181
171
{
197
187
    }
198
188
    else
199
189
    {
200
 
        pixels = (guchar *) image->pixels;
 
190
        pixels = g_memdup (image->pixels, image->width * image->height * 4);
201
191
    }
202
192
 
203
193
    cursor = mt_cursor_new (image->name, pixels,
209
199
                             g_strdup (image->name),
210
200
                             cursor);
211
201
    }
 
202
 
 
203
    return cursor;
 
204
}
 
205
 
 
206
static void
 
207
mt_cursor_manager_add_current_cursor (MtCursorManager *manager,
 
208
                                      Display         *display)
 
209
{
 
210
    XFixesCursorImage *image;
 
211
 
 
212
    image = XFixesGetCursorImage (display);
 
213
    if (image)
 
214
    {
 
215
        manager->priv->current = mt_cursor_manager_add_cursor (manager, image);
 
216
        XFree (image);
 
217
    }
212
218
}
213
219
 
214
220
static GdkFilterReturn
215
 
mt_cursor_manager_event_filter (GdkXEvent *gdk_xevent,
216
 
                                GdkEvent  *gdk_event,
217
 
                                gpointer   data)
 
221
mt_cursor_manager_event_filter (GdkXEvent       *gdk_xevent,
 
222
                                GdkEvent        *gdk_event,
 
223
                                MtCursorManager *manager)
218
224
{
219
225
    XEvent *xev = gdk_xevent;
220
226
 
224
230
 
225
231
        if (cn->cursor_name != None)
226
232
        {
227
 
            MtCursorManager *manager = data;
228
 
            XFixesCursorImage *image;
229
 
 
230
 
            image = XFixesGetCursorImage (cn->display);
231
 
            if (!mt_cursor_manager_lookup_cursor (manager, image->name))
232
 
                mt_cursor_manager_add_cursor (manager, image);
233
 
 
234
 
            g_signal_emit (manager, signals[CURSOR_CHANGED], 0, image->name);
235
 
            XFree (image);
 
233
            MtCursorManagerPrivate *priv = manager->priv;
 
234
            char *name;
 
235
 
 
236
            name = XGetAtomName (cn->display, cn->cursor_name);
 
237
 
 
238
            if (!priv->current || !g_str_equal (name, mt_cursor_get_name (priv->current)))
 
239
            {
 
240
                priv->current = mt_cursor_manager_lookup_cursor (manager, name);
 
241
 
 
242
                if (!priv->current)
 
243
                {
 
244
                    mt_cursor_manager_add_current_cursor (manager, cn->display);
 
245
                }
 
246
 
 
247
                g_signal_emit (manager, signals[CURSOR_CHANGED], 0, name);
 
248
            }
 
249
            XFree (name);
236
250
        }
237
251
    }
238
252
    return GDK_FILTER_CONTINUE;
244
258
                               MtCursorManager *manager)
245
259
{
246
260
    g_hash_table_remove_all (manager->priv->cache);
247
 
    g_signal_emit (manager, signals[CACHE_CLEARED], 0);
 
261
    manager->priv->current = NULL;
248
262
}
249
263
 
250
264
MtCursorManager *
261
275
}
262
276
 
263
277
MtCursor *
264
 
mt_cursor_manager_current_cursor (MtCursorManager *manager)
 
278
mt_cursor_manager_get_current_cursor (MtCursorManager *manager)
265
279
{
266
 
    XFixesCursorImage *image;
267
 
    MtCursor *cursor;
268
 
 
269
280
    g_return_val_if_fail (MT_IS_CURSOR_MANAGER (manager), NULL);
270
281
 
271
 
    image = XFixesGetCursorImage (mt_cursor_manager_display ());
272
 
    cursor = NULL;
273
 
 
274
 
    if (image->name && image->name[0] != '\0')
275
 
    {
276
 
        cursor = mt_cursor_manager_lookup_cursor (manager, image->name);
277
 
        if (!cursor)
278
 
        {
279
 
            mt_cursor_manager_add_cursor (manager, image);
280
 
            cursor = mt_cursor_manager_lookup_cursor (manager, image->name);
281
 
        }
282
 
    }
283
 
    XFree (image);
284
 
 
285
 
    return cursor;
 
282
    return g_object_ref (manager->priv->current);
286
283
}
287
284
 
288
285
MtCursor *