~ubuntu-branches/ubuntu/trusty/geis/trusty

« back to all changes in this revision

Viewing changes to testsuite/geistest/geistest.c

  • Committer: Package Import Robot
  • Author(s): Chase Douglas
  • Date: 2012-07-30 08:51:42 UTC
  • Revision ID: package-import@ubuntu.com-20120730085142-jrc33ygjvt0ob1wl
Tags: upstream-2.2.11
ImportĀ upstreamĀ versionĀ 2.2.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * geistest.c Demo code for programming against the geis interface.
 
3
 *
 
4
 * Copyright 2010 Canonical Ltd.
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or modify it under
 
7
 * the terms of the GNU General Public License as published by the Free Software
 
8
 * Foundation; either version 3 of the License, or (at your option) any later
 
9
 * version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful, but WITHOUT
 
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 
14
 * details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License along with
 
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
 
18
 * Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
19
 */
 
20
#include "geis_config.h"
 
21
 
 
22
#include <errno.h>
 
23
#include <geis/geis.h>
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
#include <string.h>
 
27
#include <sys/select.h>
 
28
#include <unistd.h>
 
29
#include <xcb/xcb.h>
 
30
 
 
31
GeisSize g_smw = 0;
 
32
 
 
33
const char* s_gestures[] = {
 
34
  GEIS_GESTURE_TYPE_DRAG2, GEIS_GESTURE_TYPE_DRAG3,
 
35
  GEIS_GESTURE_TYPE_PINCH2, GEIS_GESTURE_TYPE_PINCH3,
 
36
  GEIS_GESTURE_TYPE_ROTATE2, GEIS_GESTURE_TYPE_ROTATE3,
 
37
  GEIS_GESTURE_TYPE_TAP2, GEIS_GESTURE_TYPE_TAP3, GEIS_GESTURE_TYPE_TAP4,
 
38
  GEIS_GESTURE_TYPE_TOUCH3, GEIS_GESTURE_TYPE_TOUCH4,
 
39
  GEIS_GESTURE_TYPE_FLICK2, GEIS_GESTURE_TYPE_FLICK3, GEIS_GESTURE_TYPE_FLICK4,
 
40
  NULL
 
41
};
 
42
 
 
43
GeisSize           g_device_count = 0;
 
44
GeisInputDeviceId *g_devices = GEIS_ALL_INPUT_DEVICES;
 
45
 
 
46
 
 
47
static void
 
48
print_attr(GeisGestureAttr *attr)
 
49
{
 
50
  fprintf(stdout, "\tattr \"%s\" = ", attr->name);
 
51
  switch (attr->type)
 
52
  {
 
53
    case GEIS_ATTR_TYPE_BOOLEAN:
 
54
      fprintf(stdout, "%s\n", attr->boolean_val ? "true" : "false");
 
55
      break;
 
56
    case GEIS_ATTR_TYPE_FLOAT:
 
57
      fprintf(stdout, "%f\n", attr->float_val);
 
58
      break;
 
59
    case GEIS_ATTR_TYPE_INTEGER:
 
60
      fprintf(stdout, "%d\n", attr->integer_val);
 
61
      break;
 
62
    case GEIS_ATTR_TYPE_STRING:
 
63
      fprintf(stdout, "\"%s\"\n", attr->string_val);
 
64
      break;
 
65
    default:
 
66
      fprintf(stdout, "<unknown>\n");
 
67
      break;
 
68
  }
 
69
}
 
70
 
 
71
 
 
72
static void
 
73
input_device_added(void              *cookie GEIS_UNUSED,
 
74
                   GeisInputDeviceId  device_id,
 
75
                   void              *attrs)
 
76
{
 
77
  GeisGestureAttr *a;
 
78
  fprintf(stdout, "Device %d added\n", device_id);
 
79
  for (a = attrs; a->name; ++a)
 
80
  {
 
81
    print_attr(a);
 
82
  }
 
83
}
 
84
 
 
85
 
 
86
static void
 
87
input_device_changed(void              *cookie GEIS_UNUSED,
 
88
                     GeisInputDeviceId  device_id GEIS_UNUSED,
 
89
                     void              *attrs GEIS_UNUSED)
 
90
{
 
91
}
 
92
 
 
93
 
 
94
static void
 
95
input_device_removed(void              *cookie GEIS_UNUSED,
 
96
                     GeisInputDeviceId  device_id,
 
97
                     void              *attrs)
 
98
{
 
99
  GeisGestureAttr *a;
 
100
  fprintf(stdout, "Device %d removed\n", device_id);
 
101
  for (a = attrs; a->name; ++a)
 
102
  {
 
103
    print_attr(a);
 
104
  }
 
105
}
 
106
 
 
107
 
 
108
static void
 
109
gesture_added(void            *cookie GEIS_UNUSED,
 
110
              GeisGestureType  gesture_type,
 
111
              GeisGestureId    gesture_id GEIS_UNUSED,
 
112
              GeisSize         attr_count,
 
113
              GeisGestureAttr *attrs)
 
114
{
 
115
  GeisSize i = 0;
 
116
  fprintf(stdout, "Gesture type %d added\n", gesture_type);
 
117
  for (i = 0; i < attr_count; ++i)
 
118
    print_attr(&attrs[i]);
 
119
}
 
120
 
 
121
static void
 
122
gesture_removed(void              *cookie GEIS_UNUSED,
 
123
                GeisGestureType    gesture_type,
 
124
                GeisGestureId      gesture_id GEIS_UNUSED,
 
125
                GeisSize           attr_count,
 
126
                GeisGestureAttr   *attrs)
 
127
{
 
128
  GeisSize i = 0;
 
129
  fprintf(stdout, "Gesture type %d removed\n", gesture_type);
 
130
  for (i = 0; i < attr_count; ++i)
 
131
    print_attr(&attrs[i]);
 
132
}
 
133
 
 
134
static void
 
135
gesture_start(void              *cookie GEIS_UNUSED,
 
136
              GeisGestureType    gesture_type,
 
137
              GeisGestureId      gesture_id,
 
138
              GeisSize           attr_count,
 
139
              GeisGestureAttr   *attrs)
 
140
{
 
141
  GeisSize i = 0;
 
142
  fprintf(stdout, "Gesture id %d type %d started\n", gesture_id, gesture_type);
 
143
  for (i = 0; i < attr_count; ++i)
 
144
    print_attr(&attrs[i]);
 
145
}
 
146
 
 
147
static void
 
148
gesture_update(void              *cookie GEIS_UNUSED,
 
149
               GeisGestureType    gesture_type,
 
150
               GeisGestureId      gesture_id,
 
151
               GeisSize           attr_count,
 
152
               GeisGestureAttr   *attrs)
 
153
{
 
154
  GeisSize i = 0;
 
155
  fprintf(stdout, "Gesture id %d type %d updated\n", gesture_id, gesture_type);
 
156
  for (i = 0; i < attr_count; ++i)
 
157
    print_attr(&attrs[i]);
 
158
}
 
159
 
 
160
static void
 
161
gesture_finish(void              *cookie GEIS_UNUSED,
 
162
               GeisGestureType    gesture_type,
 
163
               GeisGestureId      gesture_id,
 
164
               GeisSize           attr_count,
 
165
               GeisGestureAttr   *attrs)
 
166
{
 
167
  GeisSize i = 0;
 
168
  fprintf(stdout, "Gesture id %d type %d finished\n", gesture_id, gesture_type);
 
169
  for (i = 0; i < attr_count; ++i)
 
170
    print_attr(&attrs[i]);
 
171
}
 
172
 
 
173
 
 
174
GeisInputFuncs input_funcs = {
 
175
  input_device_added,
 
176
  input_device_changed,
 
177
  input_device_removed
 
178
};
 
179
 
 
180
GeisGestureFuncs gesture_funcs = {
 
181
  gesture_added,
 
182
  gesture_removed,
 
183
  gesture_start,
 
184
  gesture_update,
 
185
  gesture_finish
 
186
};
 
187
 
 
188
 
 
189
static void
 
190
_add_device_id(GeisInteger id)
 
191
{
 
192
  GeisInputDeviceId *d = realloc(g_devices, g_device_count + 2);
 
193
  if (!d)
 
194
  {
 
195
    fprintf(stderr, "error allocating device list.\n");
 
196
    exit(1);
 
197
  }
 
198
  g_devices = d;
 
199
  g_devices[g_device_count] = id;
 
200
  g_devices[g_device_count+1]   = 0;
 
201
  ++g_device_count;
 
202
}
 
203
 
 
204
 
 
205
int
 
206
parse_opts(int argc, char* argv[], uint32_t *window_id)
 
207
{
 
208
  int opt;
 
209
 
 
210
  while ((opt = getopt(argc, argv, "w:d:")) != -1)
 
211
  {
 
212
    switch (opt)
 
213
    {
 
214
      case 'w':
 
215
        *window_id = strtol(optarg, NULL, 0);
 
216
        break;
 
217
 
 
218
      case 'd':
 
219
        {
 
220
          GeisInteger id = strtol(optarg, NULL, 0);
 
221
          if (0 == id)
 
222
          {
 
223
            fprintf(stderr, "invalid device id '%s'\n'", optarg);
 
224
            return 0;
 
225
          }
 
226
          _add_device_id(id);
 
227
        }
 
228
        break;
 
229
 
 
230
      default:
 
231
        return 0;
 
232
    }
 
233
  }
 
234
 
 
235
  return 1;
 
236
}
 
237
 
 
238
 
 
239
static GeisInstance
 
240
subscribe_window(uint32_t window_id)
 
241
{
 
242
  GeisStatus status = GEIS_UNKNOWN_ERROR;
 
243
  GeisXcbWinInfo xcb_win_info = {
 
244
    .display_name  = NULL,
 
245
    .screenp       = NULL,
 
246
    .window_id     = window_id
 
247
  };
 
248
  GeisWinInfo win_info = {
 
249
    GEIS_XCB_FULL_WINDOW,
 
250
    &xcb_win_info
 
251
  };
 
252
  GeisInstance instance;
 
253
 
 
254
  status = geis_init(&win_info, &instance);
 
255
  if (status != GEIS_STATUS_SUCCESS)
 
256
  {
 
257
    fprintf(stderr, "error in geis_init\n");
 
258
    return NULL;
 
259
  }
 
260
 
 
261
  status = geis_input_devices(instance, &input_funcs, NULL);
 
262
  if (status != GEIS_STATUS_SUCCESS)
 
263
  {
 
264
    fprintf(stderr, "error subscribing to input devices\n");
 
265
    return NULL;
 
266
  }
 
267
 
 
268
  status = geis_subscribe(instance,
 
269
                          g_devices,
 
270
                          s_gestures,
 
271
                          &gesture_funcs,
 
272
                          NULL);
 
273
  if (status != GEIS_STATUS_SUCCESS)
 
274
  {
 
275
    fprintf(stderr, "error subscribing to gestures\n");
 
276
    return NULL;
 
277
  }
 
278
 
 
279
  return instance;
 
280
}
 
281
 
 
282
 
 
283
static void
 
284
subscribe_all_windows(GeisInstance **instance_table)
 
285
{
 
286
  int instance_table_size = 0;
 
287
 
 
288
  xcb_connection_t *xcb = xcb_connect(NULL, NULL);
 
289
  if (!xcb) {
 
290
    fprintf(stderr, "error connecting to X server\n");
 
291
    exit(1);
 
292
  }
 
293
 
 
294
  const xcb_setup_t *setup = xcb_get_setup(xcb);
 
295
  if (!setup)
 
296
  {
 
297
    fprintf(stderr, "error getting xcb setup\n");
 
298
    exit(1);
 
299
  }
 
300
 
 
301
  xcb_screen_iterator_t screen = xcb_setup_roots_iterator(setup);
 
302
  while (screen.rem)
 
303
  {
 
304
    ++instance_table_size;
 
305
    xcb_screen_next(&screen);
 
306
  }
 
307
 
 
308
  *instance_table = calloc(instance_table_size, sizeof(GeisInstance));
 
309
 
 
310
  screen = xcb_setup_roots_iterator(setup);
 
311
  for (int i = 0; screen.rem; ++i, xcb_screen_next(&screen))
 
312
  {
 
313
    GeisInstance instance = subscribe_window(screen.data->root);
 
314
    if (!instance)
 
315
    {
 
316
      fprintf(stderr, "error subscribing window 0x%08x\n",
 
317
              (unsigned)screen.data->root);
 
318
      exit(1);
 
319
    }
 
320
    *instance_table[i] = instance;
 
321
  }
 
322
 
 
323
  xcb_disconnect(xcb);
 
324
}
 
325
 
 
326
int
 
327
main(int argc, char* argv[])
 
328
{
 
329
  int result = -1;
 
330
  uint32_t      window_id = 0;
 
331
  int           fd = -1;
 
332
  GeisStatus    status = GEIS_UNKNOWN_ERROR;
 
333
  GeisInstance *instance_table = NULL;
 
334
  size_t        instance_table_size = 0;
 
335
 
 
336
  if (!parse_opts(argc, argv, &window_id))
 
337
  {
 
338
    fprintf(stderr, "usage: %s windowid\n", argv[0]);
 
339
    return -1;
 
340
  }
 
341
 
 
342
  if (window_id != 0)
 
343
  {
 
344
    instance_table_size = 1;
 
345
    instance_table = calloc(instance_table_size, sizeof(GeisInstance));
 
346
    instance_table[0] = subscribe_window(window_id);
 
347
    if (!instance_table[0])
 
348
    {
 
349
      fprintf(stderr, "can not continue, exiting....\n");
 
350
      goto error_exit;
 
351
    }
 
352
  }
 
353
  else
 
354
  {
 
355
    subscribe_all_windows(&instance_table);
 
356
  }
 
357
 
 
358
  status = geis_configuration_supported(instance_table[0], GEIS_CONFIG_UNIX_FD);
 
359
  if (status != GEIS_STATUS_SUCCESS)
 
360
  {
 
361
    fprintf(stderr, "GEIS does not support Unix fd\n");
 
362
    goto fail_exit;
 
363
  }
 
364
 
 
365
  status = geis_configuration_get_value(instance_table[0], GEIS_CONFIG_UNIX_FD, &fd);
 
366
  if (status != GEIS_STATUS_SUCCESS)
 
367
  {
 
368
    fprintf(stderr, "error retrieving GEIS fd\n");
 
369
    goto fail_exit;
 
370
  }
 
371
 
 
372
  while (1)
 
373
  {
 
374
    size_t i;
 
375
    int fd;
 
376
    int max_fd = 0;
 
377
    fd_set read_fds;
 
378
    FD_ZERO(&read_fds);
 
379
    FD_SET(0, &read_fds);
 
380
    for (i = 0; i < instance_table_size; ++i)
 
381
    {
 
382
      status = geis_configuration_get_value(instance_table[i],
 
383
                                            GEIS_CONFIG_UNIX_FD, &fd);
 
384
      max_fd = (fd > max_fd ? fd : max_fd);
 
385
      FD_SET(fd, &read_fds);
 
386
    }
 
387
    int sstat = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
 
388
    if (sstat < 0)
 
389
    {
 
390
      fprintf(stderr, "error %d in select(): %s\n", errno, strerror(errno));
 
391
      break;
 
392
    }
 
393
 
 
394
    for (i = 0; i < instance_table_size; ++i)
 
395
    {
 
396
      status = geis_configuration_get_value(instance_table[i],
 
397
                                            GEIS_CONFIG_UNIX_FD, &fd);
 
398
      if (FD_ISSET(fd, &read_fds))
 
399
      {
 
400
        geis_event_dispatch(instance_table[i]);
 
401
      }
 
402
    }
 
403
 
 
404
    if (FD_ISSET(0, &read_fds))
 
405
    {
 
406
      break;
 
407
    }
 
408
  }
 
409
 
 
410
fail_exit:
 
411
  {
 
412
    size_t i;
 
413
    for (i = 0; i < instance_table_size; ++i)
 
414
    {
 
415
      geis_finish(instance_table[i]);
 
416
    }
 
417
  }
 
418
 
 
419
error_exit:
 
420
  if (instance_table_size > 0)
 
421
  {
 
422
    free(instance_table);
 
423
  }
 
424
  return result;
 
425
}
 
426