~karl-qdh/ido/select-activate-set-date

« back to all changes in this revision

Viewing changes to src/idogesturemanager.c

  • Committer: Cody Russell
  • Date: 2011-01-18 17:12:19 UTC
  • Revision ID: crussell@canonical.com-20110118171219-0fj84pk70yh2zu6d
Remove IdoGestureManager

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
26
 
#include "idogesturemanager.h"
27
 
 
28
 
#include <gdk/gdkx.h>
29
 
#include <geis/geis.h>
30
 
 
31
 
typedef struct _IdoGestureRegistration IdoGestureRegistration;
32
 
typedef struct _IdoGestureBinding      IdoGestureBinding;
33
 
 
34
 
struct _IdoGestureManagerPrivate
35
 
{
36
 
  GHashTable *hash;
37
 
};
38
 
 
39
 
struct _IdoGestureBinding
40
 
{
41
 
  IdoGestureType     type;
42
 
  gint               touches;
43
 
  IdoGestureCallback start;
44
 
  IdoGestureCallback update;
45
 
  IdoGestureCallback end;
46
 
};
47
 
 
48
 
struct _IdoGestureRegistration
49
 
{
50
 
  GtkWindow         *window;
51
 
  GList             *bindings;
52
 
  GeisInstance       instance;
53
 
  GIOChannel        *iochannel;
54
 
};
55
 
 
56
 
static void gesture_added (void              *cookie,
57
 
                           GeisGestureType    gesture_type,
58
 
                           GeisGestureId      gesture_id,
59
 
                           GeisSize           attr_count,
60
 
                           GeisGestureAttr   *attrs);
61
 
 
62
 
static void gesture_removed (void              *cookie,
63
 
                             GeisGestureType    gesture_type,
64
 
                             GeisGestureId      gesture_id,
65
 
                             GeisSize           attr_count,
66
 
                             GeisGestureAttr   *attrs);
67
 
 
68
 
static void gesture_start (void              *cookie,
69
 
                           GeisGestureType    gesture_type,
70
 
                           GeisGestureId      gesture_id,
71
 
                           GeisSize           attr_count,
72
 
                           GeisGestureAttr   *attrs);
73
 
 
74
 
static void gesture_update (void              *cookie,
75
 
                            GeisGestureType    gesture_type,
76
 
                            GeisGestureId      gesture_id,
77
 
                            GeisSize           attr_count,
78
 
                            GeisGestureAttr   *attrs);
79
 
 
80
 
static void gesture_finish (void              *cookie,
81
 
                            GeisGestureType    gesture_type,
82
 
                            GeisGestureId      gesture_id,
83
 
                            GeisSize           attr_count,
84
 
                            GeisGestureAttr   *attrs);
85
 
 
86
 
static IdoGestureManager *manager_singleton = NULL;
87
 
static GeisGestureFuncs gesture_funcs = {
88
 
  gesture_added,
89
 
  gesture_removed,
90
 
  gesture_start,
91
 
  gesture_update,
92
 
  gesture_finish
93
 
};
94
 
 
95
 
G_DEFINE_TYPE (IdoGestureManager, ido_gesture_manager, G_TYPE_OBJECT)
96
 
 
97
 
#define IDO_GESTURE_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_GESTURE_MANAGER, IdoGestureManagerPrivate))
98
 
 
99
 
static void
100
 
ido_gesture_manager_dispose (GObject *object)
101
 
{
102
 
  IdoGestureManagerPrivate *priv = IDO_GESTURE_MANAGER (object)->priv;
103
 
 
104
 
  if (priv->hash != NULL)
105
 
    {
106
 
      g_hash_table_unref (priv->hash);
107
 
      priv->hash = NULL;
108
 
    }
109
 
}
110
 
 
111
 
static void
112
 
ido_gesture_manager_finalize (GObject *object)
113
 
{
114
 
}
115
 
 
116
 
static GObject *
117
 
ido_gesture_manager_constructor (GType                  type,
118
 
                                 guint                  n_params,
119
 
                                 GObjectConstructParam *params)
120
 
{
121
 
  GObject *object;
122
 
 
123
 
  if (manager_singleton != NULL)
124
 
    {
125
 
      object = g_object_ref (manager_singleton);
126
 
    }
127
 
  else
128
 
    {
129
 
      object = G_OBJECT_CLASS (ido_gesture_manager_parent_class)->constructor (type,
130
 
                                                                               n_params,
131
 
                                                                               params);
132
 
 
133
 
      manager_singleton = IDO_GESTURE_MANAGER (object);
134
 
      g_object_add_weak_pointer (object, (gpointer) &manager_singleton);
135
 
    }
136
 
 
137
 
  return object;
138
 
}
139
 
 
140
 
static void
141
 
ido_gesture_manager_class_init (IdoGestureManagerClass *class)
142
 
{
143
 
  GObjectClass     *gobject_class;
144
 
 
145
 
  gobject_class = G_OBJECT_CLASS (class);
146
 
 
147
 
  ido_gesture_manager_parent_class = g_type_class_peek_parent (class);
148
 
 
149
 
  g_type_class_add_private (gobject_class, sizeof (IdoGestureManagerPrivate));
150
 
 
151
 
  gobject_class->constructor = ido_gesture_manager_constructor;
152
 
  gobject_class->dispose     = ido_gesture_manager_dispose;
153
 
  gobject_class->finalize    = ido_gesture_manager_finalize;
154
 
}
155
 
 
156
 
/*
157
 
static void
158
 
print_attr (GeisGestureAttr *attr)
159
 
{
160
 
  return;
161
 
 
162
 
  g_print ("\tattr '%s'=", attr->name);
163
 
  switch (attr->type)
164
 
    {
165
 
    case GEIS_ATTR_TYPE_BOOLEAN:
166
 
      g_print ("%s\n", attr->boolean_val ? "true" : "false");
167
 
      break;
168
 
    case GEIS_ATTR_TYPE_FLOAT:
169
 
      g_print ("%f\n", attr->float_val);
170
 
      break;
171
 
    case GEIS_ATTR_TYPE_INTEGER:
172
 
      g_print ("%d\n", (gint)attr->integer_val);
173
 
      break;
174
 
    case GEIS_ATTR_TYPE_STRING:
175
 
      g_print ("\"%s\"\n", attr->string_val);
176
 
      break;
177
 
    default:
178
 
      g_print ("<unknown>\n");
179
 
      break;
180
 
    }
181
 
}
182
 
*/
183
 
 
184
 
static gint
185
 
pinch_gesture_handle_properties (IdoEventGesturePinch *event,
186
 
                                 GeisSize              attr_count,
187
 
                                 GeisGestureAttr      *attrs)
188
 
{
189
 
  gint i = 0;
190
 
  gint touches = 0;
191
 
 
192
 
  for (i = 0; i < attr_count; ++i)
193
 
    {
194
 
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCHES) == 0 &&
195
 
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
196
 
        {
197
 
          touches = attrs[i].integer_val;
198
 
        }
199
 
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP) == 0 &&
200
 
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
201
 
        {
202
 
          event->timestamp = attrs[i].integer_val;
203
 
        }
204
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X) == 0 &&
205
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
206
 
        {
207
 
          event->focus_x = attrs[i].float_val;
208
 
        }
209
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y) == 0 &&
210
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
211
 
        {
212
 
          event->focus_y = attrs[i].float_val;
213
 
        }
214
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_RADIUS_DELTA) == 0 &&
215
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
216
 
        {
217
 
          event->radius_delta = attrs[i].float_val;
218
 
        }
219
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_RADIAL_VELOCITY) == 0 &&
220
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
221
 
        {
222
 
          event->radial_velocity = attrs[i].float_val;
223
 
        }
224
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_RADIUS) == 0 &&
225
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
226
 
        {
227
 
          event->radius = attrs[i].float_val;
228
 
        }
229
 
    }
230
 
 
231
 
  return touches;
232
 
}
233
 
 
234
 
static gint
235
 
drag_gesture_handle_properties (IdoEventGestureDrag *event,
236
 
                                GeisSize             attr_count,
237
 
                                GeisGestureAttr     *attrs)
238
 
{
239
 
  gint i;
240
 
  gint touches = 0;
241
 
 
242
 
  for (i = 0; i < attr_count; ++i)
243
 
    {
244
 
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCHES) == 0 &&
245
 
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
246
 
        {
247
 
          touches = attrs[i].integer_val;
248
 
        }
249
 
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP) == 0 &&
250
 
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
251
 
        {
252
 
          event->timestamp = attrs[i].integer_val;
253
 
        }
254
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X) == 0 &&
255
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
256
 
        {
257
 
          event->focus_x = attrs[i].float_val;
258
 
        }
259
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y) == 0 &&
260
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
261
 
        {
262
 
          event->focus_y = attrs[i].float_val;
263
 
        }
264
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_DELTA_X) == 0 &&
265
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
266
 
        {
267
 
          event->delta_x = attrs[i].float_val;
268
 
        }
269
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_DELTA_Y) == 0 &&
270
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
271
 
        {
272
 
          event->delta_y = attrs[i].float_val;
273
 
        }
274
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_VELOCITY_X) == 0 &&
275
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
276
 
        {
277
 
          event->velocity_x = attrs[i].float_val;
278
 
        }
279
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_VELOCITY_Y) == 0 &&
280
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
281
 
        {
282
 
          event->velocity_y = attrs[i].float_val;
283
 
        }
284
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_POSITION_X) == 0 &&
285
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
286
 
        {
287
 
          event->position_x = attrs[i].float_val;
288
 
        }
289
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_POSITION_Y) == 0 &&
290
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
291
 
        {
292
 
          event->position_y = attrs[i].float_val;
293
 
        }
294
 
    }
295
 
 
296
 
  return touches;
297
 
}
298
 
 
299
 
static gint
300
 
rotate_gesture_handle_properties (IdoEventGestureRotate *event,
301
 
                                  GeisSize               attr_count,
302
 
                                  GeisGestureAttr       *attrs)
303
 
{
304
 
  gint i;
305
 
  gint touches = 0;
306
 
 
307
 
  for (i = 0; i < attr_count; ++i)
308
 
    {
309
 
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TOUCHES) == 0 &&
310
 
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
311
 
        {
312
 
          touches = attrs[i].integer_val;
313
 
        }
314
 
      if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP) == 0 &&
315
 
          attrs[i].type == GEIS_ATTR_TYPE_INTEGER)
316
 
        {
317
 
          event->timestamp = attrs[i].integer_val;
318
 
        }
319
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X) == 0 &&
320
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
321
 
        {
322
 
          event->focus_x = attrs[i].float_val;
323
 
        }
324
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y) == 0 &&
325
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
326
 
        {
327
 
          event->focus_y = attrs[i].float_val;
328
 
        }
329
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_ANGLE_DELTA) == 0 &&
330
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
331
 
        {
332
 
          event->angle_delta = attrs[i].float_val;
333
 
        }
334
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_ANGULAR_VELOCITY) == 0 &&
335
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
336
 
        {
337
 
          event->angular_velocity = attrs[i].float_val;
338
 
        }
339
 
      else if (g_strcmp0 (attrs[i].name, GEIS_GESTURE_ATTRIBUTE_ANGLE) == 0 &&
340
 
               attrs[i].type == GEIS_ATTR_TYPE_FLOAT)
341
 
        {
342
 
          event->angle = attrs[i].float_val;
343
 
        }
344
 
    }
345
 
 
346
 
  return touches;
347
 
}
348
 
 
349
 
 
350
 
static void
351
 
gesture_added (void              *cookie,
352
 
               GeisGestureType    gesture_type,
353
 
               GeisGestureId      gesture_id,
354
 
               GeisSize           attr_count,
355
 
               GeisGestureAttr   *attrs)
356
 
{
357
 
}
358
 
 
359
 
static void
360
 
gesture_removed (void              *cookie,
361
 
                 GeisGestureType    gesture_type,
362
 
                 GeisGestureId      gesture_id,
363
 
                 GeisSize           attr_count,
364
 
                 GeisGestureAttr   *attrs)
365
 
{
366
 
}
367
 
 
368
 
static void
369
 
gesture_start (void              *cookie,
370
 
               GeisGestureType    type,
371
 
               GeisGestureId      id,
372
 
               GeisSize           attr_count,
373
 
               GeisGestureAttr   *attrs)
374
 
{
375
 
  IdoGestureRegistration *reg = (IdoGestureRegistration *)cookie;
376
 
  GList *l = NULL;
377
 
 
378
 
  for (l = reg->bindings; l != NULL; l = l->next)
379
 
    {
380
 
      IdoGestureBinding *binding = (IdoGestureBinding *)l->data;
381
 
 
382
 
      if (binding->type == type)
383
 
        {
384
 
          if (type == IDO_GESTURE_DRAG)
385
 
            {
386
 
              IdoEventGestureDrag drag;
387
 
 
388
 
              drag.type    = type;
389
 
              drag.id      = id;
390
 
              drag.fingers = drag_gesture_handle_properties (&drag,
391
 
                                                             attr_count,
392
 
                                                             attrs);
393
 
 
394
 
              if (drag.fingers == binding->touches)
395
 
                {
396
 
                  binding->start (reg->window,
397
 
                                  ((IdoGestureEvent*)&drag));
398
 
                }
399
 
            }
400
 
          else if (type == IDO_GESTURE_PINCH)
401
 
            {
402
 
              IdoEventGesturePinch pinch;
403
 
 
404
 
              pinch.type    = type;
405
 
              pinch.id      = id;
406
 
              pinch.fingers = pinch_gesture_handle_properties (&pinch,
407
 
                                                               attr_count,
408
 
                                                               attrs);
409
 
 
410
 
              if (pinch.fingers == binding->touches)
411
 
                {
412
 
                  binding->start (reg->window,
413
 
                                  ((IdoGestureEvent*)&pinch));
414
 
                }
415
 
            }
416
 
          else if (type == IDO_GESTURE_ROTATE)
417
 
            {
418
 
              IdoEventGestureRotate rotate;
419
 
 
420
 
              rotate.type    = type;
421
 
              rotate.id      = id;
422
 
              rotate.fingers = rotate_gesture_handle_properties (&rotate,
423
 
                                                                 attr_count,
424
 
                                                                 attrs);
425
 
 
426
 
              if (rotate.fingers == binding->touches)
427
 
                {
428
 
                  binding->start (reg->window,
429
 
                                  ((IdoGestureEvent*)&rotate));
430
 
                }
431
 
            }
432
 
 
433
 
          return;
434
 
        }
435
 
    }
436
 
}
437
 
 
438
 
static void
439
 
gesture_update (void              *cookie,
440
 
                GeisGestureType    type,
441
 
                GeisGestureId      id,
442
 
                GeisSize           attr_count,
443
 
                GeisGestureAttr   *attrs)
444
 
{
445
 
  IdoGestureRegistration *reg = (IdoGestureRegistration *)cookie;
446
 
  GList *l = NULL;
447
 
 
448
 
  for (l = reg->bindings; l != NULL; l = l->next)
449
 
    {
450
 
      IdoGestureBinding *binding = (IdoGestureBinding *)l->data;
451
 
 
452
 
      if (binding->type == type)
453
 
        {
454
 
          if (type == IDO_GESTURE_DRAG)
455
 
            {
456
 
              IdoEventGestureDrag drag;
457
 
 
458
 
              drag.type    = type;
459
 
              drag.id      = id;
460
 
              drag.fingers = drag_gesture_handle_properties (&drag,
461
 
                                                             attr_count,
462
 
                                                             attrs);
463
 
 
464
 
              if (drag.fingers == binding->touches)
465
 
                {
466
 
                  binding->update (reg->window,
467
 
                                   ((IdoGestureEvent*)&drag));
468
 
                }
469
 
            }
470
 
          else if (type == IDO_GESTURE_PINCH)
471
 
            {
472
 
              IdoEventGesturePinch pinch;
473
 
 
474
 
              pinch.type    = type;
475
 
              pinch.id      = id;
476
 
              pinch.fingers = pinch_gesture_handle_properties (&pinch,
477
 
                                                               attr_count,
478
 
                                                               attrs);
479
 
 
480
 
              if (pinch.fingers == binding->touches)
481
 
                {
482
 
                  binding->update (reg->window,
483
 
                                   ((IdoGestureEvent*)&pinch));
484
 
                }
485
 
            }
486
 
          else if (type == IDO_GESTURE_ROTATE)
487
 
            {
488
 
              IdoEventGestureRotate rotate;
489
 
 
490
 
              rotate.type    = type;
491
 
              rotate.id      = id;
492
 
              rotate.fingers = rotate_gesture_handle_properties (&rotate,
493
 
                                                                 attr_count,
494
 
                                                                 attrs);
495
 
 
496
 
              if (rotate.fingers == binding->touches)
497
 
                {
498
 
                  binding->update (reg->window,
499
 
                                   ((IdoGestureEvent*)&rotate));
500
 
                }
501
 
            }
502
 
        }
503
 
    }
504
 
}
505
 
 
506
 
static void
507
 
gesture_finish (void              *cookie,
508
 
                GeisGestureType    type,
509
 
                GeisGestureId      id,
510
 
                GeisSize           attr_count,
511
 
                GeisGestureAttr   *attrs)
512
 
{
513
 
  IdoGestureRegistration *reg = (IdoGestureRegistration *)cookie;
514
 
  GList *l = NULL;
515
 
 
516
 
  for (l = reg->bindings; l != NULL; l = l->next)
517
 
    {
518
 
      IdoGestureBinding *binding = (IdoGestureBinding *)l->data;
519
 
 
520
 
      if (binding->type == type)
521
 
        {
522
 
          if (type == IDO_GESTURE_DRAG)
523
 
            {
524
 
              IdoEventGestureDrag drag;
525
 
 
526
 
              drag.type    = type;
527
 
              drag.id      = id;
528
 
              drag.fingers = drag_gesture_handle_properties (&drag,
529
 
                                                             attr_count,
530
 
                                                             attrs);
531
 
 
532
 
              if (drag.fingers == binding->touches)
533
 
                {
534
 
                  binding->end (reg->window,
535
 
                                ((IdoGestureEvent*)&drag));
536
 
                }
537
 
            }
538
 
          else if (type == IDO_GESTURE_PINCH)
539
 
            {
540
 
              IdoEventGesturePinch pinch;
541
 
 
542
 
              pinch.type    = type;
543
 
              pinch.id      = id;
544
 
              pinch.fingers = pinch_gesture_handle_properties (&pinch,
545
 
                                                               attr_count,
546
 
                                                               attrs);
547
 
 
548
 
              if (pinch.fingers == binding->touches)
549
 
                {
550
 
                  binding->end (reg->window,
551
 
                                ((IdoGestureEvent*)&pinch));
552
 
                }
553
 
            }
554
 
          else if (type == IDO_GESTURE_ROTATE)
555
 
            {
556
 
              IdoEventGestureRotate rotate;
557
 
 
558
 
              rotate.type    = type;
559
 
              rotate.id      = id;
560
 
              rotate.fingers = rotate_gesture_handle_properties (&rotate,
561
 
                                                                 attr_count,
562
 
                                                                 attrs);
563
 
 
564
 
              if (rotate.fingers == binding->touches)
565
 
                {
566
 
                  binding->end (reg->window,
567
 
                                ((IdoGestureEvent*)&rotate));
568
 
                }
569
 
            }
570
 
        }
571
 
    }
572
 
}
573
 
 
574
 
static void
575
 
ido_gesture_manager_init (IdoGestureManager *item)
576
 
{
577
 
  IdoGestureManagerPrivate *priv;
578
 
 
579
 
  priv = item->priv = IDO_GESTURE_MANAGER_GET_PRIVATE (item);
580
 
 
581
 
  priv->hash = g_hash_table_new (g_direct_hash, g_direct_equal);
582
 
}
583
 
 
584
 
static gboolean
585
 
io_callback (GIOChannel *source,
586
 
             GIOCondition condition,
587
 
             gpointer     data)
588
 
{
589
 
  IdoGestureRegistration *reg = (IdoGestureRegistration *)data;
590
 
 
591
 
  geis_event_dispatch (reg->instance);
592
 
 
593
 
  return TRUE;
594
 
}
595
 
 
596
 
static void
597
 
window_destroyed_cb (GtkObject *object,
598
 
                     gpointer   user_data)
599
 
{
600
 
  IdoGestureManager *manager = (IdoGestureManager *)user_data;
601
 
  IdoGestureManagerPrivate *priv = manager->priv;
602
 
  IdoGestureRegistration *reg = g_hash_table_lookup (priv->hash, object);
603
 
  GList *list;
604
 
 
605
 
  for (list = reg->bindings; list != NULL; list = list->next)
606
 
    {
607
 
      IdoGestureBinding *binding = (IdoGestureBinding *)list->data;
608
 
 
609
 
      g_free (binding);
610
 
    }
611
 
 
612
 
  g_list_free (reg->bindings);
613
 
 
614
 
  g_io_channel_shutdown (reg->iochannel, TRUE, NULL);
615
 
 
616
 
  geis_finish (reg->instance);
617
 
 
618
 
  g_hash_table_remove (priv->hash, object);
619
 
  g_free (reg);
620
 
}
621
 
 
622
 
 
623
 
/* Public API */
624
 
IdoGestureManager *
625
 
ido_gesture_manager_get (void)
626
 
{
627
 
  return g_object_new (IDO_TYPE_GESTURE_MANAGER, NULL);
628
 
}
629
 
 
630
 
/**
631
 
 * ido_gesture_manager_register_window:
632
 
 * @window: A #GtkWindow to register the gesture event for.
633
 
 * @gesture_type: The type of gesture event to register.
634
 
 * @touch_points: Number of touch points for this gesture.
635
 
 * @start: Called when a user initiates a gesture.
636
 
 * @update: Called each time the user updates the gesture.
637
 
 * @end: Called when the user ends the gesture.
638
 
 *
639
 
 * Registers a toplevel window to receive gesture events.
640
 
 * The callback parameters provided will be called by the
641
 
 * #IdoGestureManager whenever the user initiates a gesture
642
 
 * on the specified window.
643
 
 */
644
 
void
645
 
ido_gesture_manager_register_window (IdoGestureManager *manager,
646
 
                                     GtkWindow         *window,
647
 
                                     IdoGestureType     gesture_type,
648
 
                                     gint               touch_points,
649
 
                                     IdoGestureCallback start,
650
 
                                     IdoGestureCallback update,
651
 
                                     IdoGestureCallback end)
652
 
{
653
 
  IdoGestureManagerPrivate *priv;
654
 
  IdoGestureRegistration *reg;
655
 
  IdoGestureBinding *binding;
656
 
 
657
 
  g_return_if_fail (IDO_IS_GESTURE_MANAGER (manager));
658
 
  g_return_if_fail (GTK_IS_WINDOW (window));
659
 
  g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (window)));
660
 
 
661
 
  priv = manager->priv;
662
 
 
663
 
  if (!(reg = g_hash_table_lookup (priv->hash, window)))
664
 
    {
665
 
      GeisInstance instance;
666
 
      GIOChannel *iochannel;
667
 
      gint fd = -1;
668
 
      GeisXcbWinInfo xcb_win_info = {
669
 
        .display_name = NULL,
670
 
        .screenp      = NULL,
671
 
        .window_id    = GDK_DRAWABLE_XID (GTK_WIDGET (window)->window)
672
 
      };
673
 
      GeisWinInfo win_info = {
674
 
        GEIS_XCB_FULL_WINDOW,
675
 
        &xcb_win_info
676
 
      };
677
 
 
678
 
      if (geis_init (&win_info, &instance) != GEIS_STATUS_SUCCESS)
679
 
        {
680
 
          g_warning ("Failed to initialize gesture manager.");
681
 
          return;
682
 
        }
683
 
 
684
 
      if (geis_configuration_supported (instance,
685
 
                                        GEIS_CONFIG_UNIX_FD) != GEIS_STATUS_SUCCESS)
686
 
        {
687
 
          g_warning ("Gesture manager does not support UNIX fd.");
688
 
          return;
689
 
        }
690
 
 
691
 
      if (geis_configuration_get_value (instance,
692
 
                                        GEIS_CONFIG_UNIX_FD,
693
 
                                        &fd) != GEIS_STATUS_SUCCESS)
694
 
        {
695
 
          g_error ("Gesture manager failed to obtain UNIX fd.");
696
 
          return;
697
 
        }
698
 
 
699
 
      reg = g_new0 (IdoGestureRegistration, 1);
700
 
 
701
 
      reg->window   = window;
702
 
      reg->instance = instance;
703
 
 
704
 
      g_signal_connect (window,
705
 
                        "destroy",
706
 
                        G_CALLBACK (window_destroyed_cb),
707
 
                        manager);
708
 
 
709
 
      geis_subscribe (reg->instance,
710
 
                      GEIS_ALL_INPUT_DEVICES,
711
 
                      GEIS_ALL_GESTURES,
712
 
                      &gesture_funcs,
713
 
                      reg);
714
 
 
715
 
      iochannel = g_io_channel_unix_new (fd);
716
 
      g_io_add_watch (iochannel,
717
 
                      G_IO_IN,
718
 
                      io_callback,
719
 
                      reg);
720
 
 
721
 
      reg->iochannel = iochannel;
722
 
    }
723
 
 
724
 
  /* XXX - check for duplicates in reg->bindings first */
725
 
  binding = g_new0 (IdoGestureBinding, 1);
726
 
 
727
 
  binding->type    = gesture_type;
728
 
  binding->touches = touch_points;
729
 
  binding->start   = start;
730
 
  binding->update  = update;
731
 
  binding->end     = end;
732
 
 
733
 
  reg->bindings = g_list_append (reg->bindings, binding);
734
 
 
735
 
  g_hash_table_insert (priv->hash,
736
 
                       window,
737
 
                       reg);
738
 
}