~bratsche/libgrip/python-fixage-wip

1 by Cody Russell
Initial commit.
1
/*
2
 * Copyright 2010 Canonical, Ltd.
3
 *
4
 * This program is free software: you can redistribute it and/or modify it
5
 * under the terms of either or both of the following licenses:
6
 *
7
 * 1) the GNU Lesser General Public License version 3, as published by the
8
 * Free Software Foundation; and/or
9
 * 2) the GNU Lesser General Public License version 2.1, as published by
10
 * the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranties of
14
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
15
 * PURPOSE.  See the applicable version of the GNU Lesser General Public
16
 * License for more details.
17
 *
18
 * You should have received a copy of both the GNU Lesser General Public
19
 * License version 3 and version 2.1 along with this program.  If not, see
20
 * <http://www.gnu.org/licenses/>
21
 *
22
 * Authors:
23
 *    Cody Russell <crussell@canonical.com>
24
 */
25
10.1.1 by Cody Russell
Rename to libgrip
26
#include "gripgesturemanager.h"
1 by Cody Russell
Initial commit.
27
28
#include <gdk/gdkx.h>
29
#include <geis/geis.h>
30
10.1.1 by Cody Russell
Rename to libgrip
31
typedef struct _GripGestureRegistration GripGestureRegistration;
32
typedef struct _GripGestureBinding      GripGestureBinding;
15 by Cody Russell
Automatically defer registration to map-event.
33
typedef struct _GripRegistrationRequest GripRegistrationRequest;
1 by Cody Russell
Initial commit.
34
10.1.1 by Cody Russell
Rename to libgrip
35
struct _GripGestureManagerPrivate
1 by Cody Russell
Initial commit.
36
{
37
  GHashTable *hash;
15 by Cody Russell
Automatically defer registration to map-event.
38
  GList      *requests;
1 by Cody Russell
Initial commit.
39
};
40
10.1.1 by Cody Russell
Rename to libgrip
41
struct _GripGestureBinding
1 by Cody Russell
Initial commit.
42
{
10.1.1 by Cody Russell
Rename to libgrip
43
  GripGestureType      type;
16 by Cody Russell
Event routing by widget.
44
  GtkWidget           *widget;
10.1.1 by Cody Russell
Rename to libgrip
45
  gint                 touches;
46
  GripGestureCallback  callback;
47
  gpointer             data;
48
  GDestroyNotify       destroy;
1 by Cody Russell
Initial commit.
49
};
50
10.1.1 by Cody Russell
Rename to libgrip
51
struct _GripGestureRegistration
1 by Cody Russell
Initial commit.
52
{
53
  GtkWindow         *window;
54
  GList             *bindings;
18.1.1 by Cody Russell
Subscribe to individual geis events rather than using GEIS_ALL_GESTURES.
55
  GPtrArray         *gesture_list;
1 by Cody Russell
Initial commit.
56
  GeisInstance       instance;
57
  GIOChannel        *iochannel;
58
};
59
15 by Cody Russell
Automatically defer registration to map-event.
60
struct _GripRegistrationRequest
61
{
62
  GripGestureManager *manager;
16 by Cody Russell
Event routing by widget.
63
  GtkWidget          *widget;
15 by Cody Russell
Automatically defer registration to map-event.
64
  GripGestureType     gesture_type;
65
  gint                touch_points;
66
  GripGestureCallback callback;
67
  gpointer            user_data;
68
  GDestroyNotify      destroy;
69
};
70
18.1.1 by Cody Russell
Subscribe to individual geis events rather than using GEIS_ALL_GESTURES.
71
static const gchar *geis_gesture_types[] = {
72
  GEIS_GESTURE_TYPE_DRAG1,
73
  GEIS_GESTURE_TYPE_DRAG2,
74
  GEIS_GESTURE_TYPE_DRAG3,
75
  GEIS_GESTURE_TYPE_DRAG4,
76
  GEIS_GESTURE_TYPE_DRAG5,
77
  GEIS_GESTURE_TYPE_PINCH1,
78
  GEIS_GESTURE_TYPE_PINCH2,
79
  GEIS_GESTURE_TYPE_PINCH3,
80
  GEIS_GESTURE_TYPE_PINCH4,
81
  GEIS_GESTURE_TYPE_PINCH5,
82
  GEIS_GESTURE_TYPE_ROTATE1,
83
  GEIS_GESTURE_TYPE_ROTATE2,
84
  GEIS_GESTURE_TYPE_ROTATE3,
85
  GEIS_GESTURE_TYPE_ROTATE4,
86
  GEIS_GESTURE_TYPE_ROTATE5,
87
  GEIS_GESTURE_TYPE_TAP1,
88
  GEIS_GESTURE_TYPE_TAP2,
89
  GEIS_GESTURE_TYPE_TAP3,
90
  GEIS_GESTURE_TYPE_TAP4,
91
  GEIS_GESTURE_TYPE_TAP5,
92
};
93
1 by Cody Russell
Initial commit.
94
static void gesture_added (void              *cookie,
95
                           GeisGestureType    gesture_type,
96
                           GeisGestureId      gesture_id,
97
                           GeisSize           attr_count,
98
                           GeisGestureAttr   *attrs);
99
100
static void gesture_removed (void              *cookie,
101
                             GeisGestureType    gesture_type,
102
                             GeisGestureId      gesture_id,
103
                             GeisSize           attr_count,
104
                             GeisGestureAttr   *attrs);
105
106
static void gesture_start (void              *cookie,
107
                           GeisGestureType    gesture_type,
108
                           GeisGestureId      gesture_id,
109
                           GeisSize           attr_count,
110
                           GeisGestureAttr   *attrs);
111
112
static void gesture_update (void              *cookie,
113
                            GeisGestureType    gesture_type,
114
                            GeisGestureId      gesture_id,
115
                            GeisSize           attr_count,
116
                            GeisGestureAttr   *attrs);
117
118
static void gesture_finish (void              *cookie,
119
                            GeisGestureType    gesture_type,
120
                            GeisGestureId      gesture_id,
121
                            GeisSize           attr_count,
122
                            GeisGestureAttr   *attrs);
123
16 by Cody Russell
Event routing by widget.
124
static void window_mapped_cb (GtkWidget       *widget,
125
                              GdkEvent        *event,
126
                              gpointer         user_data);
127
10.1.1 by Cody Russell
Rename to libgrip
128
static GripGestureManager *manager_singleton = NULL;
1 by Cody Russell
Initial commit.
129
static GeisGestureFuncs gesture_funcs = {
130
  gesture_added,
131
  gesture_removed,
132
  gesture_start,
133
  gesture_update,
134
  gesture_finish
135
};
136
10.1.1 by Cody Russell
Rename to libgrip
137
G_DEFINE_TYPE (GripGestureManager, grip_gesture_manager, G_TYPE_OBJECT)
1 by Cody Russell
Initial commit.
138
10.1.1 by Cody Russell
Rename to libgrip
139
#define GRIP_GESTURE_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GRIP_TYPE_GESTURE_MANAGER, GripGestureManagerPrivate))
1 by Cody Russell
Initial commit.
140
141
static void
10.1.1 by Cody Russell
Rename to libgrip
142
grip_gesture_manager_dispose (GObject *object)
1 by Cody Russell
Initial commit.
143
{
18.1.1 by Cody Russell
Subscribe to individual geis events rather than using GEIS_ALL_GESTURES.
144
}
145
146
static void
147
free_registration (gpointer key,
148
		   gpointer value,
149
		   gpointer user_data)
150
{
151
  GripGestureRegistration *reg = (GripGestureRegistration *)value;
152
  GList *tmp = NULL;
153
154
  geis_unsubscribe (reg->instance,
155
		    (GeisGestureType*)reg->gesture_list->pdata);
156
157
  /* We don't need to free the values in the GPtrArray. */
158
  g_ptr_array_free (reg->gesture_list, TRUE);
159
160
  for (tmp = reg->bindings; tmp != NULL; tmp = tmp->next)
161
    {
162
      g_free (tmp->data);
163
    }
164
165
  g_list_free (reg->bindings);
166
}
167
168
static void
169
grip_gesture_manager_finalize (GObject *object)
170
{
171
  GripGestureManagerPrivate *priv = GRIP_GESTURE_MANAGER_GET_PRIVATE (object);
1 by Cody Russell
Initial commit.
172
173
  if (priv->hash != NULL)
174
    {
18.1.1 by Cody Russell
Subscribe to individual geis events rather than using GEIS_ALL_GESTURES.
175
      g_hash_table_foreach (priv->hash,
176
			    free_registration,
177
			    NULL);
178
1 by Cody Russell
Initial commit.
179
      g_hash_table_unref (priv->hash);
180
      priv->hash = NULL;
181
    }
182
}
183
184
static GObject *
10.1.1 by Cody Russell
Rename to libgrip
185
grip_gesture_manager_constructor (GType                  type,
186
                                  guint                  n_params,
187
                                  GObjectConstructParam *params)
1 by Cody Russell
Initial commit.
188
{
189
  GObject *object;
190
191
  if (manager_singleton != NULL)
192
    {
193
      object = g_object_ref (manager_singleton);
194
    }
195
  else
196
    {
10.1.1 by Cody Russell
Rename to libgrip
197
      object = G_OBJECT_CLASS (grip_gesture_manager_parent_class)->constructor (type,
198
                                                                                n_params,
199
                                                                                params);
1 by Cody Russell
Initial commit.
200
10.1.1 by Cody Russell
Rename to libgrip
201
      manager_singleton = GRIP_GESTURE_MANAGER (object);
1 by Cody Russell
Initial commit.
202
      g_object_add_weak_pointer (object, (gpointer) &manager_singleton);
203
    }
204
205
  return object;
206
}
207
208
static void
10.1.1 by Cody Russell
Rename to libgrip
209
grip_gesture_manager_class_init (GripGestureManagerClass *class)
1 by Cody Russell
Initial commit.
210
{
211
  GObjectClass     *gobject_class;
212
213
  gobject_class = G_OBJECT_CLASS (class);
214
10.1.1 by Cody Russell
Rename to libgrip
215
  grip_gesture_manager_parent_class = g_type_class_peek_parent (class);
216
217
  g_type_class_add_private (gobject_class, sizeof (GripGestureManagerPrivate));
218
219
  gobject_class->constructor = grip_gesture_manager_constructor;
220
  gobject_class->dispose     = grip_gesture_manager_dispose;
221
  gobject_class->finalize    = grip_gesture_manager_finalize;
1 by Cody Russell
Initial commit.
222
}
223
224
static gint
10.1.1 by Cody Russell
Rename to libgrip
225
pinch_gesture_handle_properties (GripEventGesturePinch *event,
226
                                 GeisSize               attr_count,
227
                                 GeisGestureAttr       *attrs)
1 by Cody Russell
Initial commit.
228
{
229
  gint i = 0;
230
  gint touches = 0;
231
232
  for (i = 0; i < attr_count; ++i)
233
    {
234
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCHES) == 0 &&
235
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
236
        {
237
          touches = attrs[i].integer_val;
238
        }
239
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP) == 0 &&
240
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
241
        {
242
          event->timestamp = attrs[i].integer_val;
243
        }
244
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X) == 0 &&
245
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
246
        {
247
          event->focus_x = attrs[i].float_val;
248
        }
249
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y) == 0 &&
250
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
251
        {
252
          event->focus_y = attrs[i].float_val;
253
        }
254
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_RADIUS_DELTA) == 0 &&
255
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
256
        {
257
          event->radius_delta = attrs[i].float_val;
258
        }
259
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_RADIAL_VELOCITY) == 0 &&
260
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
261
        {
262
          event->radial_velocity = attrs[i].float_val;
263
        }
264
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_RADIUS) == 0 &&
265
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
266
        {
267
          event->radius = attrs[i].float_val;
268
        }
269
    }
270
271
  return touches;
272
}
273
274
static gint
10.1.1 by Cody Russell
Rename to libgrip
275
drag_gesture_handle_properties (GripEventGestureDrag *event,
276
                                GeisSize              attr_count,
277
                                GeisGestureAttr      *attrs)
1 by Cody Russell
Initial commit.
278
{
279
  gint i;
280
  gint touches = 0;
281
282
  for (i = 0; i < attr_count; ++i)
283
    {
284
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCHES) == 0 &&
285
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
286
        {
287
          touches = attrs[i].integer_val;
288
        }
289
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP) == 0 &&
290
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
291
        {
292
          event->timestamp = attrs[i].integer_val;
293
        }
294
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X) == 0 &&
295
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
296
        {
297
          event->focus_x = attrs[i].float_val;
298
        }
299
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y) == 0 &&
300
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
301
        {
302
          event->focus_y = attrs[i].float_val;
303
        }
304
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_DELTA_X) == 0 &&
305
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
306
        {
307
          event->delta_x = attrs[i].float_val;
308
        }
309
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_DELTA_Y) == 0 &&
310
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
311
        {
312
          event->delta_y = attrs[i].float_val;
313
        }
314
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_VELOCITY_X) == 0 &&
315
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
316
        {
317
          event->velocity_x = attrs[i].float_val;
318
        }
319
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_VELOCITY_Y) == 0 &&
320
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
321
        {
322
          event->velocity_y = attrs[i].float_val;
323
        }
324
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_POSITION_X) == 0 &&
325
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
326
        {
327
          event->position_x = attrs[i].float_val;
328
        }
329
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_POSITION_Y) == 0 &&
330
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
331
        {
332
          event->position_y = attrs[i].float_val;
333
        }
334
    }
335
336
  return touches;
337
}
338
339
static gint
10.1.1 by Cody Russell
Rename to libgrip
340
rotate_gesture_handle_properties (GripEventGestureRotate *event,
341
                                  GeisSize                attr_count,
342
                                  GeisGestureAttr        *attrs)
1 by Cody Russell
Initial commit.
343
{
344
  gint i;
345
  gint touches = 0;
346
347
  for (i = 0; i < attr_count; ++i)
348
    {
349
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCHES) == 0 &&
350
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
351
        {
352
          touches = attrs[i].integer_val;
353
        }
354
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP) == 0 &&
355
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
356
        {
357
          event->timestamp = attrs[i].integer_val;
358
        }
359
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X) == 0 &&
360
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
361
        {
362
          event->focus_x = attrs[i].float_val;
363
        }
364
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y) == 0 &&
365
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
366
        {
367
          event->focus_y = attrs[i].float_val;
368
        }
369
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_ANGLE_DELTA) == 0 &&
370
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
371
        {
372
          event->angle_delta = attrs[i].float_val;
373
        }
374
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_ANGULAR_VELOCITY) == 0 &&
375
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
376
        {
377
          event->angular_velocity = attrs[i].float_val;
378
        }
379
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_ANGLE) == 0 &&
380
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
381
        {
382
          event->angle = attrs[i].float_val;
383
        }
384
    }
385
386
  return touches;
387
}
388
9 by Cody Russell
Add support for tap gestures
389
static gint
10.1.1 by Cody Russell
Rename to libgrip
390
tap_gesture_handle_properties (GripEventGestureTap *event,
391
			       GeisSize             attr_count,
392
			       GeisGestureAttr     *attrs)
9 by Cody Russell
Add support for tap gestures
393
{
394
  gint i;
395
  gint touches = 0;
396
397
  for (i = 0; i < attr_count; ++i)
398
    {
399
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCHES) == 0 &&
400
	  attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
401
	{
402
	  touches = attrs[i].integer_val;
403
	}
404
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP) == 0 &&
405
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
406
        {
407
          event->timestamp = attrs[i].integer_val;
408
        }
16 by Cody Russell
Event routing by widget.
409
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X) == 0 &&
410
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
411
        {
412
          event->focus_x = attrs[i].float_val;
413
        }
414
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y) == 0 &&
415
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
416
        {
417
          event->focus_y = attrs[i].float_val;
418
        }
9 by Cody Russell
Add support for tap gestures
419
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_POSITION_X) == 0 &&
420
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
421
        {
422
          event->position_x = attrs[i].float_val;
423
        }
424
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_POSITION_Y) == 0 &&
425
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
426
        {
427
          event->position_y = attrs[i].float_val;
428
        }
429
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TAP_TIME) == 0 &&
430
               attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
431
        {
432
          event->tap_time = attrs[i].float_val;
433
        }
434
    }
435
436
  return touches;
437
}
1 by Cody Russell
Initial commit.
438
439
static void
440
gesture_added (void              *cookie,
441
               GeisGestureType    gesture_type,
442
               GeisGestureId      gesture_id,
443
               GeisSize           attr_count,
444
               GeisGestureAttr   *attrs)
445
{
446
}
447
448
static void
449
gesture_removed (void              *cookie,
450
                 GeisGestureType    gesture_type,
451
                 GeisGestureId      gesture_id,
452
                 GeisSize           attr_count,
453
                 GeisGestureAttr   *attrs)
454
{
455
}
456
16 by Cody Russell
Event routing by widget.
457
static gboolean
458
matches_widget (GtkWidget *widget,
459
                GdkWindow *window,
460
                gint       x,
461
                gint       y)
462
{
463
  GtkAllocation alloc;
464
  gint ax, ay;
465
466
  gtk_widget_get_allocation (widget, &alloc);
467
  gdk_window_get_root_coords (window, alloc.x, alloc.y, &ax, &ay);
468
469
  return (x >= ax && x < ax + alloc.width && y >= ay && y < ay + alloc.height);
470
}
471
1 by Cody Russell
Initial commit.
472
static void
473
gesture_start (void              *cookie,
474
               GeisGestureType    type,
475
               GeisGestureId      id,
476
               GeisSize           attr_count,
477
               GeisGestureAttr   *attrs)
478
{
10.1.1 by Cody Russell
Rename to libgrip
479
  GripGestureRegistration *reg = (GripGestureRegistration *)cookie;
1 by Cody Russell
Initial commit.
480
  GList *l = NULL;
481
482
  for (l = reg->bindings; l != NULL; l = l->next)
483
    {
10.1.1 by Cody Russell
Rename to libgrip
484
      GripGestureBinding *binding = (GripGestureBinding *)l->data;
1 by Cody Russell
Initial commit.
485
486
      if (binding->type == type)
487
        {
23 by Cody Russell
Work-in-progress fixage for Python-fu
488
	  GripGestureEvent *event = grip_gesture_event_new (type);
489
10.1.1 by Cody Russell
Rename to libgrip
490
          if (type == GRIP_GESTURE_DRAG)
1 by Cody Russell
Initial commit.
491
            {
23 by Cody Russell
Work-in-progress fixage for Python-fu
492
              GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
493
494
              drag->type    = type;
495
              drag->id      = id;
496
              drag->fingers = drag_gesture_handle_properties (drag,
497
							      attr_count,
498
							      attrs);
499
500
              if (drag->fingers == binding->touches)
1 by Cody Russell
Initial commit.
501
                {
16 by Cody Russell
Event routing by widget.
502
                  if (matches_widget (binding->widget,
503
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
504
                                      (gint)drag->focus_x,
505
                                      (gint)drag->focus_y))
16 by Cody Russell
Event routing by widget.
506
                    {
507
                      binding->callback (binding->widget,
508
                                         GRIP_TIME_START,
23 by Cody Russell
Work-in-progress fixage for Python-fu
509
                                         event,
16 by Cody Russell
Event routing by widget.
510
                                         binding->data);
511
                    }
1 by Cody Russell
Initial commit.
512
                }
513
            }
10.1.1 by Cody Russell
Rename to libgrip
514
          else if (type == GRIP_GESTURE_PINCH)
1 by Cody Russell
Initial commit.
515
            {
23 by Cody Russell
Work-in-progress fixage for Python-fu
516
              GripEventGesturePinch *pinch = (GripEventGesturePinch *)event;
517
518
              pinch->type    = type;
519
              pinch->id      = id;
520
              pinch->fingers = pinch_gesture_handle_properties (pinch,
521
								attr_count,
522
								attrs);
523
524
              if (pinch->fingers == binding->touches)
1 by Cody Russell
Initial commit.
525
                {
16 by Cody Russell
Event routing by widget.
526
                  if (matches_widget (binding->widget,
527
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
528
                                      (gint)pinch->focus_x,
529
                                      (gint)pinch->focus_y))
16 by Cody Russell
Event routing by widget.
530
                    {
531
                      binding->callback (binding->widget,
532
                                         GRIP_TIME_START,
23 by Cody Russell
Work-in-progress fixage for Python-fu
533
                                         event,
16 by Cody Russell
Event routing by widget.
534
                                         binding->data);
535
                    }
1 by Cody Russell
Initial commit.
536
                }
537
            }
10.1.1 by Cody Russell
Rename to libgrip
538
          else if (type == GRIP_GESTURE_ROTATE)
1 by Cody Russell
Initial commit.
539
            {
23 by Cody Russell
Work-in-progress fixage for Python-fu
540
              GripEventGestureRotate *rotate = (GripEventGestureRotate *)event;
541
542
              rotate->type    = type;
543
              rotate->id      = id;
544
              rotate->fingers = rotate_gesture_handle_properties (rotate,
545
								  attr_count,
546
								  attrs);
547
548
              if (rotate->fingers == binding->touches)
1 by Cody Russell
Initial commit.
549
                {
16 by Cody Russell
Event routing by widget.
550
                  if (matches_widget (binding->widget,
551
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
552
                                      (gint)rotate->focus_x,
553
                                      (gint)rotate->focus_y))
16 by Cody Russell
Event routing by widget.
554
                    {
555
                      binding->callback (binding->widget,
556
                                         GRIP_TIME_START,
23 by Cody Russell
Work-in-progress fixage for Python-fu
557
                                         event,
16 by Cody Russell
Event routing by widget.
558
                                         binding->data);
559
                    }
1 by Cody Russell
Initial commit.
560
                }
561
            }
10.1.1 by Cody Russell
Rename to libgrip
562
	  else if (type == GRIP_GESTURE_TAP)
9 by Cody Russell
Add support for tap gestures
563
	    {
23 by Cody Russell
Work-in-progress fixage for Python-fu
564
	      GripEventGestureTap *tap = (GripEventGestureTap *)event;
565
566
	      tap->type    = type;
567
	      tap->id      = id;
568
	      tap->fingers = tap_gesture_handle_properties (tap,
569
							    attr_count,
570
							    attrs);
571
572
	      if (tap->fingers == binding->touches)
9 by Cody Russell
Add support for tap gestures
573
		{
16 by Cody Russell
Event routing by widget.
574
                  if (matches_widget (binding->widget,
575
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
576
                                      (gint)tap->focus_x,
577
                                      (gint)tap->focus_y))
16 by Cody Russell
Event routing by widget.
578
                    {
579
                      binding->callback (binding->widget,
580
                                         GRIP_TIME_START,
23 by Cody Russell
Work-in-progress fixage for Python-fu
581
                                         event,
16 by Cody Russell
Event routing by widget.
582
                                         binding->data);
583
                    }
584
                }
9 by Cody Russell
Add support for tap gestures
585
	    }
23 by Cody Russell
Work-in-progress fixage for Python-fu
586
587
	  grip_gesture_event_free (event);
1 by Cody Russell
Initial commit.
588
        }
589
    }
590
}
591
592
static void
593
gesture_update (void              *cookie,
594
                GeisGestureType    type,
595
                GeisGestureId      id,
596
                GeisSize           attr_count,
597
                GeisGestureAttr   *attrs)
598
{
10.1.1 by Cody Russell
Rename to libgrip
599
  GripGestureRegistration *reg = (GripGestureRegistration *)cookie;
1 by Cody Russell
Initial commit.
600
  GList *l = NULL;
601
602
  for (l = reg->bindings; l != NULL; l = l->next)
603
    {
10.1.1 by Cody Russell
Rename to libgrip
604
      GripGestureBinding *binding = (GripGestureBinding *)l->data;
1 by Cody Russell
Initial commit.
605
606
      if (binding->type == type)
607
        {
23 by Cody Russell
Work-in-progress fixage for Python-fu
608
	  GripGestureEvent *event = grip_gesture_event_new (type);
609
10.1.1 by Cody Russell
Rename to libgrip
610
          if (type == GRIP_GESTURE_DRAG)
1 by Cody Russell
Initial commit.
611
            {
23 by Cody Russell
Work-in-progress fixage for Python-fu
612
              GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
613
614
              drag->type    = type;
615
              drag->id      = id;
616
              drag->fingers = drag_gesture_handle_properties (drag,
617
							      attr_count,
618
							      attrs);
619
620
              if (drag->fingers == binding->touches)
1 by Cody Russell
Initial commit.
621
                {
16 by Cody Russell
Event routing by widget.
622
                  if (matches_widget (binding->widget,
623
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
624
                                      (gint)drag->focus_x,
625
                                      (gint)drag->focus_y))
16 by Cody Russell
Event routing by widget.
626
                    {
627
                      binding->callback (binding->widget,
628
                                         GRIP_TIME_UPDATE,
23 by Cody Russell
Work-in-progress fixage for Python-fu
629
                                         event,
16 by Cody Russell
Event routing by widget.
630
                                         binding->data);
631
                    }
1 by Cody Russell
Initial commit.
632
                }
633
            }
10.1.1 by Cody Russell
Rename to libgrip
634
          else if (type == GRIP_GESTURE_PINCH)
1 by Cody Russell
Initial commit.
635
            {
23 by Cody Russell
Work-in-progress fixage for Python-fu
636
              GripEventGesturePinch *pinch = (GripEventGesturePinch *)event;
637
638
              pinch->type    = type;
639
              pinch->id      = id;
640
              pinch->fingers = pinch_gesture_handle_properties (pinch,
641
								attr_count,
642
								attrs);
643
644
              if (pinch->fingers == binding->touches)
1 by Cody Russell
Initial commit.
645
                {
16 by Cody Russell
Event routing by widget.
646
                  if (matches_widget (binding->widget,
647
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
648
                                      (gint)pinch->focus_x,
649
                                      (gint)pinch->focus_y))
16 by Cody Russell
Event routing by widget.
650
                    {
651
                      binding->callback (binding->widget,
652
                                         GRIP_TIME_UPDATE,
23 by Cody Russell
Work-in-progress fixage for Python-fu
653
                                         event,
16 by Cody Russell
Event routing by widget.
654
                                         binding->data);
655
                    }
1 by Cody Russell
Initial commit.
656
                }
657
            }
10.1.1 by Cody Russell
Rename to libgrip
658
          else if (type == GRIP_GESTURE_ROTATE)
1 by Cody Russell
Initial commit.
659
            {
23 by Cody Russell
Work-in-progress fixage for Python-fu
660
              GripEventGestureRotate *rotate = (GripEventGestureRotate *)event;
661
662
              rotate->type    = type;
663
              rotate->id      = id;
664
              rotate->fingers = rotate_gesture_handle_properties (rotate,
665
								  attr_count,
666
								  attrs);
667
668
              if (rotate->fingers == binding->touches)
1 by Cody Russell
Initial commit.
669
                {
16 by Cody Russell
Event routing by widget.
670
                  if (matches_widget (binding->widget,
671
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
672
                                      (gint)rotate->focus_x,
673
                                      (gint)rotate->focus_y))
16 by Cody Russell
Event routing by widget.
674
                    {
675
                      binding->callback (binding->widget,
676
                                         GRIP_TIME_UPDATE,
23 by Cody Russell
Work-in-progress fixage for Python-fu
677
                                         event,
16 by Cody Russell
Event routing by widget.
678
                                         binding->data);
679
                    }
1 by Cody Russell
Initial commit.
680
                }
681
            }
10.1.1 by Cody Russell
Rename to libgrip
682
	  else if (type == GRIP_GESTURE_TAP)
9 by Cody Russell
Add support for tap gestures
683
	    {
23 by Cody Russell
Work-in-progress fixage for Python-fu
684
	      GripEventGestureTap *tap = (GripEventGestureTap *)event;
685
686
	      tap->type    = type;
687
	      tap->id      = id;
688
	      tap->fingers = tap_gesture_handle_properties (tap,
689
							    attr_count,
690
							    attrs);
691
692
	      if (tap->fingers == binding->touches)
9 by Cody Russell
Add support for tap gestures
693
		{
16 by Cody Russell
Event routing by widget.
694
                  if (matches_widget (binding->widget,
695
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
696
                                      (gint)tap->focus_x,
697
                                      (gint)tap->focus_y))
16 by Cody Russell
Event routing by widget.
698
                    {
699
                      binding->callback (binding->widget,
700
                                         GRIP_TIME_UPDATE,
23 by Cody Russell
Work-in-progress fixage for Python-fu
701
                                         event,
16 by Cody Russell
Event routing by widget.
702
                                         binding->data);
703
                    }
704
                }
9 by Cody Russell
Add support for tap gestures
705
	    }
23 by Cody Russell
Work-in-progress fixage for Python-fu
706
707
	  grip_gesture_event_free (event);
1 by Cody Russell
Initial commit.
708
        }
709
    }
710
}
711
712
static void
713
gesture_finish (void              *cookie,
714
                GeisGestureType    type,
715
                GeisGestureId      id,
716
                GeisSize           attr_count,
717
                GeisGestureAttr   *attrs)
718
{
10.1.1 by Cody Russell
Rename to libgrip
719
  GripGestureRegistration *reg = (GripGestureRegistration *)cookie;
1 by Cody Russell
Initial commit.
720
  GList *l = NULL;
721
722
  for (l = reg->bindings; l != NULL; l = l->next)
723
    {
10.1.1 by Cody Russell
Rename to libgrip
724
      GripGestureBinding *binding = (GripGestureBinding *)l->data;
1 by Cody Russell
Initial commit.
725
726
      if (binding->type == type)
727
        {
23 by Cody Russell
Work-in-progress fixage for Python-fu
728
	  GripGestureEvent *event = grip_gesture_event_new (type);
729
10.1.1 by Cody Russell
Rename to libgrip
730
          if (type == GRIP_GESTURE_DRAG)
1 by Cody Russell
Initial commit.
731
            {
23 by Cody Russell
Work-in-progress fixage for Python-fu
732
              GripEventGestureDrag *drag = (GripEventGestureDrag *)event;
733
734
              drag->type    = type;
735
              drag->id      = id;
736
              drag->fingers = drag_gesture_handle_properties (drag,
737
							      attr_count,
738
							      attrs);
739
740
              if (drag->fingers == binding->touches)
1 by Cody Russell
Initial commit.
741
                {
16 by Cody Russell
Event routing by widget.
742
                  if (matches_widget (binding->widget,
743
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
744
                                      (gint)drag->focus_x,
745
                                      (gint)drag->focus_y))
16 by Cody Russell
Event routing by widget.
746
                    {
747
                      binding->callback (binding->widget,
748
                                         GRIP_TIME_END,
23 by Cody Russell
Work-in-progress fixage for Python-fu
749
                                         event,
16 by Cody Russell
Event routing by widget.
750
                                         binding->data);
751
                    }
1 by Cody Russell
Initial commit.
752
                }
753
            }
10.1.1 by Cody Russell
Rename to libgrip
754
          else if (type == GRIP_GESTURE_PINCH)
1 by Cody Russell
Initial commit.
755
            {
23 by Cody Russell
Work-in-progress fixage for Python-fu
756
              GripEventGesturePinch *pinch = (GripEventGesturePinch *)event;
757
758
              pinch->type    = type;
759
              pinch->id      = id;
760
              pinch->fingers = pinch_gesture_handle_properties (pinch,
761
								attr_count,
762
								attrs);
763
764
              if (pinch->fingers == binding->touches)
1 by Cody Russell
Initial commit.
765
                {
16 by Cody Russell
Event routing by widget.
766
                  if (matches_widget (binding->widget,
767
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
768
                                      (gint)pinch->focus_x,
769
                                      (gint)pinch->focus_y))
16 by Cody Russell
Event routing by widget.
770
                    {
771
                      binding->callback (binding->widget,
772
                                         GRIP_TIME_END,
23 by Cody Russell
Work-in-progress fixage for Python-fu
773
                                         event,
16 by Cody Russell
Event routing by widget.
774
                                         binding->data);
775
                    }
1 by Cody Russell
Initial commit.
776
                }
777
            }
10.1.1 by Cody Russell
Rename to libgrip
778
          else if (type == GRIP_GESTURE_ROTATE)
1 by Cody Russell
Initial commit.
779
            {
23 by Cody Russell
Work-in-progress fixage for Python-fu
780
              GripEventGestureRotate *rotate = (GripEventGestureRotate *)event;
781
782
              rotate->type    = type;
783
              rotate->id      = id;
784
              rotate->fingers = rotate_gesture_handle_properties (rotate,
785
								  attr_count,
786
								  attrs);
787
788
              if (rotate->fingers == binding->touches)
1 by Cody Russell
Initial commit.
789
                {
16 by Cody Russell
Event routing by widget.
790
                  if (matches_widget (binding->widget,
791
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
792
                                      (gint)rotate->focus_x,
793
                                      (gint)rotate->focus_y))
16 by Cody Russell
Event routing by widget.
794
                    {
795
                      binding->callback (binding->widget,
796
                                         GRIP_TIME_END,
23 by Cody Russell
Work-in-progress fixage for Python-fu
797
                                         event,
16 by Cody Russell
Event routing by widget.
798
                                         binding->data);
799
                    }
1 by Cody Russell
Initial commit.
800
                }
801
            }
10.1.1 by Cody Russell
Rename to libgrip
802
	  else if (type == GRIP_GESTURE_TAP)
9 by Cody Russell
Add support for tap gestures
803
	    {
23 by Cody Russell
Work-in-progress fixage for Python-fu
804
	      GripEventGestureTap *tap = (GripEventGestureTap *)event;
805
806
	      tap->type    = type;
807
	      tap->id      = id;
808
	      tap->fingers = tap_gesture_handle_properties (tap,
809
							    attr_count,
810
							    attrs);
811
812
	      if (tap->fingers == binding->touches)
9 by Cody Russell
Add support for tap gestures
813
		{
16 by Cody Russell
Event routing by widget.
814
                  if (matches_widget (binding->widget,
815
                                      GTK_WIDGET (reg->window)->window,
23 by Cody Russell
Work-in-progress fixage for Python-fu
816
                                      (gint)tap->focus_x,
817
                                      (gint)tap->focus_y))
16 by Cody Russell
Event routing by widget.
818
                    {
819
                      binding->callback (binding->widget,
820
                                         GRIP_TIME_END,
23 by Cody Russell
Work-in-progress fixage for Python-fu
821
                                         event,
16 by Cody Russell
Event routing by widget.
822
                                         binding->data);
823
                    }
824
                }
9 by Cody Russell
Add support for tap gestures
825
	    }
23 by Cody Russell
Work-in-progress fixage for Python-fu
826
827
	  grip_gesture_event_free (event);
1 by Cody Russell
Initial commit.
828
        }
829
    }
830
}
831
832
static void
10.1.1 by Cody Russell
Rename to libgrip
833
grip_gesture_manager_init (GripGestureManager *item)
1 by Cody Russell
Initial commit.
834
{
10.1.1 by Cody Russell
Rename to libgrip
835
  GripGestureManagerPrivate *priv;
1 by Cody Russell
Initial commit.
836
10.1.1 by Cody Russell
Rename to libgrip
837
  priv = item->priv = GRIP_GESTURE_MANAGER_GET_PRIVATE (item);
1 by Cody Russell
Initial commit.
838
839
  priv->hash = g_hash_table_new (g_direct_hash, g_direct_equal);
840
}
841
842
static gboolean
843
io_callback (GIOChannel   *source,
844
             GIOCondition  condition,
845
             gpointer      data)
846
{
10.1.1 by Cody Russell
Rename to libgrip
847
  GripGestureRegistration *reg = (GripGestureRegistration *)data;
1 by Cody Russell
Initial commit.
848
849
  geis_event_dispatch (reg->instance);
850
851
  return TRUE;
852
}
853
854
static void
855
window_destroyed_cb (GtkObject *object,
856
                     gpointer   user_data)
857
{
10.1.1 by Cody Russell
Rename to libgrip
858
  GripGestureManager *manager = (GripGestureManager *)user_data;
859
  GripGestureManagerPrivate *priv = manager->priv;
860
  GripGestureRegistration *reg = g_hash_table_lookup (priv->hash, object);
1 by Cody Russell
Initial commit.
861
  GList *list;
862
863
  for (list = reg->bindings; list != NULL; list = list->next)
864
    {
10.1.1 by Cody Russell
Rename to libgrip
865
      GripGestureBinding *binding = (GripGestureBinding *)list->data;
1 by Cody Russell
Initial commit.
866
3 by Cody Russell
Add data to binding.
867
      if (binding->destroy)
868
        {
869
          GDestroyNotify d = binding->destroy;
870
871
          d (binding->data);
872
        }
873
1 by Cody Russell
Initial commit.
874
      g_free (binding);
875
    }
876
877
  g_list_free (reg->bindings);
878
879
  g_io_channel_shutdown (reg->iochannel, TRUE, NULL);
880
881
  geis_finish (reg->instance);
882
883
  g_hash_table_remove (priv->hash, object);
884
  g_free (reg);
885
}
886
18.1.1 by Cody Russell
Subscribe to individual geis events rather than using GEIS_ALL_GESTURES.
887
static const gchar *
888
grip_type_to_geis_type (GripGestureType gesture_type,
889
			gint            touch_points)
890
{
18.1.2 by Cody Russell
Add some comments.
891
  /* grail taps begin at 15, so let's convert that into something we
892
   * can index in geis_gesture_types. */
18.1.1 by Cody Russell
Subscribe to individual geis events rather than using GEIS_ALL_GESTURES.
893
  int t = gesture_type == 15 ? 3 : gesture_type;
894
895
  return geis_gesture_types[(t * 5 + touch_points) - 1];
896
}
897
1 by Cody Russell
Initial commit.
898
899
/* Public API */
10.1.1 by Cody Russell
Rename to libgrip
900
GripGestureManager *
901
grip_gesture_manager_get (void)
1 by Cody Russell
Initial commit.
902
{
10.1.1 by Cody Russell
Rename to libgrip
903
  return g_object_new (GRIP_TYPE_GESTURE_MANAGER, NULL);
1 by Cody Russell
Initial commit.
904
}
905
15 by Cody Russell
Automatically defer registration to map-event.
906
static void
907
register_internal (GripGestureManager *manager,
16 by Cody Russell
Event routing by widget.
908
                   GtkWidget          *widget,
15 by Cody Russell
Automatically defer registration to map-event.
909
                   GripGestureType     gesture_type,
910
                   gint                touch_points,
911
                   GripGestureCallback callback,
912
                   gpointer            user_data,
913
                   GDestroyNotify      destroy)
1 by Cody Russell
Initial commit.
914
{
10.1.1 by Cody Russell
Rename to libgrip
915
  GripGestureManagerPrivate *priv;
916
  GripGestureRegistration *reg;
917
  GripGestureBinding *binding;
16 by Cody Russell
Event routing by widget.
918
  GtkWidget *toplevel;
1 by Cody Russell
Initial commit.
919
10.1.1 by Cody Russell
Rename to libgrip
920
  g_return_if_fail (GRIP_IS_GESTURE_MANAGER (manager));
16 by Cody Russell
Event routing by widget.
921
  g_return_if_fail (GTK_IS_WIDGET (widget));
922
923
  toplevel = gtk_widget_get_toplevel (widget);
924
925
  g_return_if_fail (GTK_IS_WINDOW (toplevel));
1 by Cody Russell
Initial commit.
926
927
  priv = manager->priv;
928
16 by Cody Russell
Event routing by widget.
929
  if (!(reg = g_hash_table_lookup (priv->hash, toplevel)))
1 by Cody Russell
Initial commit.
930
    {
15 by Cody Russell
Automatically defer registration to map-event.
931
      GeisInstance  instance;
932
      GIOChannel   *iochannel;
1 by Cody Russell
Initial commit.
933
      gint fd = -1;
934
      GeisXcbWinInfo xcb_win_info = {
935
        .display_name = NULL,
936
        .screenp      = NULL,
16 by Cody Russell
Event routing by widget.
937
        .window_id    = GDK_DRAWABLE_XID (toplevel->window)
1 by Cody Russell
Initial commit.
938
      };
939
      GeisWinInfo win_info = {
940
        GEIS_XCB_FULL_WINDOW,
941
        &xcb_win_info
942
      };
943
944
      if (geis_init (&win_info, &instance) != GEIS_STATUS_SUCCESS)
945
        {
946
          g_warning ("Failed to initialize gesture manager.");
947
          return;
948
        }
949
950
      if (geis_configuration_supported (instance,
951
                                        GEIS_CONFIG_UNIX_FD) != GEIS_STATUS_SUCCESS)
952
        {
953
          g_warning ("Gesture manager does not support UNIX fd.");
954
          return;
955
        }
956
957
      if (geis_configuration_get_value (instance,
958
                                        GEIS_CONFIG_UNIX_FD,
959
                                        &fd) != GEIS_STATUS_SUCCESS)
960
        {
961
          g_error ("Gesture manager failed to obtain UNIX fd.");
962
          return;
963
        }
964
10.1.1 by Cody Russell
Rename to libgrip
965
      reg = g_new0 (GripGestureRegistration, 1);
1 by Cody Russell
Initial commit.
966
16 by Cody Russell
Event routing by widget.
967
      reg->window   = GTK_WINDOW (toplevel);
1 by Cody Russell
Initial commit.
968
      reg->instance = instance;
969
16 by Cody Russell
Event routing by widget.
970
      g_signal_connect (toplevel,
1 by Cody Russell
Initial commit.
971
                        "destroy",
972
                        G_CALLBACK (window_destroyed_cb),
973
                        manager);
974
975
      iochannel = g_io_channel_unix_new (fd);
976
      g_io_add_watch (iochannel,
977
                      G_IO_IN,
978
                      io_callback,
979
                      reg);
980
981
      reg->iochannel = iochannel;
18.1.1 by Cody Russell
Subscribe to individual geis events rather than using GEIS_ALL_GESTURES.
982
983
      reg->gesture_list = g_ptr_array_new ();
984
    }
985
  else
986
    {
987
      geis_unsubscribe (reg->instance,
988
			(GeisGestureType*)reg->gesture_list->pdata);
989
    }
990
991
  if (reg->gesture_list->len)
992
    g_ptr_array_remove_index (reg->gesture_list,
993
			      reg->gesture_list->len - 1);
994
995
  g_ptr_array_add (reg->gesture_list,
996
		   (gchar *)grip_type_to_geis_type (gesture_type, touch_points));
997
  g_ptr_array_add (reg->gesture_list,
998
		   NULL);
999
1000
  geis_subscribe (reg->instance,
1001
		  GEIS_ALL_INPUT_DEVICES,
1002
		  (const char**)reg->gesture_list->pdata,
1003
		  &gesture_funcs,
1004
		  reg);
1 by Cody Russell
Initial commit.
1005
1006
  /* XXX - check for duplicates in reg->bindings first */
10.1.1 by Cody Russell
Rename to libgrip
1007
  binding = g_new0 (GripGestureBinding, 1);
1 by Cody Russell
Initial commit.
1008
6.1.1 by Cody Russell
Single callback
1009
  binding->type     = gesture_type;
16 by Cody Russell
Event routing by widget.
1010
  binding->widget   = widget;
6.1.1 by Cody Russell
Single callback
1011
  binding->touches  = touch_points;
1012
  binding->callback = callback;
1013
  binding->data     = user_data;
1014
  binding->destroy  = destroy;
1 by Cody Russell
Initial commit.
1015
1016
  reg->bindings = g_list_append (reg->bindings, binding);
1017
1018
  g_hash_table_insert (priv->hash,
16 by Cody Russell
Event routing by widget.
1019
                       toplevel,
1 by Cody Russell
Initial commit.
1020
                       reg);
1021
}
15 by Cody Russell
Automatically defer registration to map-event.
1022
1023
static void
16 by Cody Russell
Event routing by widget.
1024
toplevel_notify_cb (GtkWidget    *widget,
1025
                    GParamSpec   *pspec,
1026
                    gpointer      user_data)
1027
{
1028
  if (pspec->name == g_intern_static_string ("parent"))
1029
    {
1030
      GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
1031
      GripRegistrationRequest *req = (GripRegistrationRequest *)user_data;
1032
1033
      if (GTK_IS_WINDOW (toplevel))
1034
        {
1035
          g_signal_handlers_disconnect_by_func (widget,
1036
                                                G_CALLBACK (toplevel_notify_cb),
1037
                                                user_data);
1038
1039
          if (gtk_widget_get_mapped (GTK_WIDGET (toplevel)))
1040
            {
1041
              register_internal (req->manager,
1042
                                 req->widget,
1043
                                 req->gesture_type,
1044
                                 req->touch_points,
1045
                                 req->callback,
1046
                                 req->user_data,
1047
                                 req->destroy);
1048
1049
              g_free (req);
1050
            }
1051
          else
1052
            {
1053
              GripGestureManagerPrivate *priv = req->manager->priv;
1054
1055
              priv->requests = g_list_append (priv->requests, req);
1056
1057
              g_signal_connect (toplevel,
1058
                                "map-event",
1059
                                G_CALLBACK (window_mapped_cb),
1060
                                req->manager);
1061
            }
1062
        }
1063
      else
1064
        {
1065
          g_signal_connect (G_OBJECT (toplevel),
1066
                            "notify",
1067
                            G_CALLBACK (toplevel_notify_cb),
1068
                            user_data);
1069
        }
1070
    }
1071
}
1072
1073
static void
1074
register_widget (GripGestureManager *manager,
1075
                 GtkWidget          *widget,
1076
                 GripGestureType     gesture_type,
1077
                 gint                touch_points,
1078
                 GripGestureCallback callback,
1079
                 gpointer            user_data,
1080
                 GDestroyNotify      destroy)
1081
{
1082
  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
1083
1084
  if (GTK_IS_WINDOW (toplevel))
1085
    {
1086
      register_internal (manager,
1087
                         widget,
1088
                         gesture_type,
1089
                         touch_points,
1090
                         callback,
1091
                         user_data,
1092
                         destroy);
1093
    }
1094
  else
1095
    {
1096
      GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1);
1097
1098
      req->manager      = manager;
1099
      req->widget       = widget;
1100
      req->gesture_type = gesture_type;
1101
      req->touch_points = touch_points;
1102
      req->callback     = callback;
1103
      req->user_data    = user_data;
1104
      req->destroy      = destroy;
1105
1106
      g_signal_connect (toplevel,
1107
                        "notify",
1108
                        G_CALLBACK (toplevel_notify_cb),
1109
                        req);
1110
    }
1111
}
1112
1113
static void
15 by Cody Russell
Automatically defer registration to map-event.
1114
window_mapped_cb (GtkWidget   *widget,
1115
                  GdkEvent    *event,
1116
                  gpointer     user_data)
1117
{
1118
  GripGestureManager *manager = (GripGestureManager *)user_data;
1119
  GripGestureManagerPrivate *priv = manager->priv;
1120
  GList *tmp;
1121
1122
  for (tmp = priv->requests; tmp != NULL; tmp = tmp->next)
1123
    {
1124
      GripRegistrationRequest *req = tmp->data;
1125
16 by Cody Russell
Event routing by widget.
1126
      register_widget (req->manager,
1127
                       req->widget,
1128
                       req->gesture_type,
1129
                       req->touch_points,
1130
                       req->callback,
1131
                       req->user_data,
1132
                       req->destroy);
15 by Cody Russell
Automatically defer registration to map-event.
1133
1134
      g_free (req);
1135
    }
1136
1137
  g_list_free (priv->requests);
1138
  priv->requests = NULL;
1139
1140
  g_signal_handlers_disconnect_by_func (widget,
1141
                                        window_mapped_cb,
1142
                                        user_data);
1143
}
1144
1145
/**
1146
 * grip_gesture_manager_register_window:
1147
 * @manager: A #GripGestureManager instance.
1148
 * @window: A #GtkWindow to register the gesture event for.
1149
 * @gesture_type: The type of gesture event to register.
1150
 * @touch_points: Number of touch points for this gesture.
1151
 * @callback: Called when a gesture starts, updates, or ends.
1152
 * @user_data: User data
1153
 * @destroy: Destroy callback for user data.
1154
 *
1155
 * Registers a toplevel window to receive gesture events.
1156
 * The callback parameters provided will be called by the
1157
 * #GripGestureManager whenever the user initiates a gesture
1158
 * on the specified window.
1159
 */
1160
void
1161
grip_gesture_manager_register_window (GripGestureManager  *manager,
16 by Cody Russell
Event routing by widget.
1162
                                      GtkWidget           *widget,
15 by Cody Russell
Automatically defer registration to map-event.
1163
                                      GripGestureType      gesture_type,
1164
                                      gint                 touch_points,
1165
                                      GripGestureCallback  callback,
1166
                                      gpointer             user_data,
1167
                                      GDestroyNotify       destroy)
1168
{
16 by Cody Russell
Event routing by widget.
1169
  GtkWidget *toplevel;
1170
15 by Cody Russell
Automatically defer registration to map-event.
1171
  g_return_if_fail (GRIP_IS_GESTURE_MANAGER (manager));
16 by Cody Russell
Event routing by widget.
1172
  g_return_if_fail (GTK_IS_WIDGET (widget));
1173
1174
  toplevel = gtk_widget_get_toplevel (widget);
1175
1176
  if (GTK_IS_WINDOW (toplevel))
15 by Cody Russell
Automatically defer registration to map-event.
1177
    {
16 by Cody Russell
Event routing by widget.
1178
      if (gtk_widget_get_mapped (GTK_WIDGET (toplevel)))
1179
        {
1180
          register_internal (manager,
1181
                             widget,
1182
                             gesture_type,
1183
                             touch_points,
1184
                             callback,
1185
                             user_data,
1186
                             destroy);
1187
        }
1188
      else
1189
        {
1190
          GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1);
1191
          GripGestureManagerPrivate *priv = manager->priv;
1192
1193
          req->manager      = manager;
1194
          req->widget       = widget;
1195
          req->gesture_type = gesture_type;
1196
          req->touch_points = touch_points;
1197
          req->callback     = callback;
1198
          req->user_data    = user_data;
1199
          req->destroy      = destroy;
1200
1201
          priv->requests = g_list_append (priv->requests, req);
1202
1203
          g_signal_connect (toplevel,
1204
                            "map-event",
1205
                            G_CALLBACK (window_mapped_cb),
1206
                            manager);
1207
        }
15 by Cody Russell
Automatically defer registration to map-event.
1208
    }
1209
  else
1210
    {
1211
      GripRegistrationRequest *req = g_new0 (GripRegistrationRequest, 1);
1212
1213
      req->manager      = manager;
16 by Cody Russell
Event routing by widget.
1214
      req->widget       = widget;
15 by Cody Russell
Automatically defer registration to map-event.
1215
      req->gesture_type = gesture_type;
1216
      req->touch_points = touch_points;
1217
      req->callback     = callback;
1218
      req->user_data    = user_data;
1219
      req->destroy      = destroy;
1220
16 by Cody Russell
Event routing by widget.
1221
      g_signal_connect (toplevel,
1222
                        "notify",
1223
                        G_CALLBACK (toplevel_notify_cb),
1224
                        req);
15 by Cody Russell
Automatically defer registration to map-event.
1225
    }
1226
}
23 by Cody Russell
Work-in-progress fixage for Python-fu
1227
1228
GType
1229
grip_gesture_event_get_type (void)
1230
{
1231
  static GType type = 0;
1232
1233
  if (type == 0)
1234
    {
1235
      type = g_boxed_type_register_static (g_intern_static_string ("GripGestureEvent"),
1236
					   (GBoxedCopyFunc)grip_gesture_event_copy,
1237
					   (GBoxedFreeFunc)grip_gesture_event_free);
1238
    }
1239
1240
  return type;
1241
}
1242
1243
GripGestureEvent *
1244
grip_gesture_event_new (GripGestureType type)
1245
{
1246
  GripGestureEvent *event = g_slice_new0 (GripGestureEvent);
1247
1248
  event->any.type = type;
1249
1250
  return event;
1251
}
1252
1253
GripGestureEvent *
1254
grip_gesture_event_copy (const GripGestureEvent *event)
1255
{
1256
  GripGestureEvent *new_event;
1257
1258
  g_return_val_if_fail (event != NULL, NULL);
1259
1260
  new_event = grip_gesture_event_new (event->type);
1261
  *new_event = *event;
1262
1263
  return new_event;
1264
}
1265
1266
void
1267
grip_gesture_event_free (GripGestureEvent *event)
1268
{
1269
  g_return_if_fail (event != NULL);
1270
1271
  g_slice_free (GripGestureEvent, event);
1272
}