Merge lp:~bregma/geis/lp-617301 into lp:geis

Proposed by Stephen M. Webb
Status: Merged
Merged at revision: 142
Proposed branch: lp:~bregma/geis/lp-617301
Merge into: lp:geis
Diff against target: 2876 lines (+2731/-3)
21 files modified
.bzrignore (+1/-0)
ChangeLog (+12/-0)
Makefile.am (+1/-1)
configure.ac (+6/-2)
python/Makefile.am (+44/-0)
python/_geis_bindings/_geis_bindings.c (+165/-0)
python/geis/__init__.py (+234/-0)
python/geis/geis_v2.py (+640/-0)
python/pygeis (+136/-0)
python/run_pygeis (+11/-0)
tools/Makefile.am (+23/-0)
tools/geisview/Makefile.am (+46/-0)
tools/geisview/__init__.py (+24/-0)
tools/geisview/defaults.py.in (+62/-0)
tools/geisview/deviceview.py (+46/-0)
tools/geisview/filter_definition.py (+135/-0)
tools/geisview/filter_definition.ui (+329/-0)
tools/geisview/filter_list.py (+59/-0)
tools/geisview/filter_list.ui (+174/-0)
tools/geisview/geisview (+250/-0)
tools/geisview/geisview.ui (+333/-0)
To merge this branch: bzr merge lp:~bregma/geis/lp-617301
Reviewer Review Type Date Requested Status
Jussi Pakkanen (community) Needs Fixing
Review via email: mp+61883@code.launchpad.net

Description of the change

Added Python bindings and the start of a Python-based "geisview" tool to visualize gesture events.

To post a comment you must log in.
Revision history for this message
Jussi Pakkanen (jpakkane) wrote :

Looks fine, builds, installs and works. Some minor things:

Some Python files are still GPL 2+ (e.g. tools/geisview/defaults.py.in).

The documentation for Group says this:

class Group(object):
 """Represents a particular group."""

Since group is a very common word, maybe some clarification would be in order. What is this a group of, exactly?

review: Needs Fixing
lp:~bregma/geis/lp-617301 updated
153. By Stephen M. Webb

Fixed tools/geisview/defaults.py.in licensing and descriptive comment for geis.Group class.

154. By Stephen M. Webb

Fixed some pyflakes warnings.

155. By Stephen M. Webb

Silenced some pylint whinings.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2011-03-17 04:06:04 +0000
+++ .bzrignore 2011-05-27 15:36:38 +0000
@@ -21,6 +21,7 @@
21debian/libutouch-geis121debian/libutouch-geis1
22debian/libutouch-geis1-dbg22debian/libutouch-geis1-dbg
23debian/tmp23debian/tmp
24defaults.py
24doc/api25doc/api
25doc/docbook-xsl.css26doc/docbook-xsl.css
26doc/geisspec-1.0.html27doc/geisspec-1.0.html
2728
=== modified file 'ChangeLog'
--- ChangeLog 2011-05-03 16:29:45 +0000
+++ ChangeLog 2011-05-27 15:36:38 +0000
@@ -1,3 +1,15 @@
12011-03-31 Stephen M. Webb <stephen.webb@canonical.com>
2
3 Add initial python bindings.
4
5 * python/Makefile.am: new file
6 * python/_geis_bindings/_geis_bindings.c: new file
7 * python/geis/__init__.py: new file
8 * python/geis/geis_v2.py: new file
9 * python/pygeis: new script
10 * Makefile.am (SUBDIRS): added python
11 * configure.ac (AC_CONFIG_FILES): added new generated files
12
12011-04-10 Stephen M. Webb <stephen.webb@canonical.com>132011-04-10 Stephen M. Webb <stephen.webb@canonical.com>
214
3 Repaired a callback persistence problem (LP: #754135).15 Repaired a callback persistence problem (LP: #754135).
416
=== modified file 'Makefile.am'
--- Makefile.am 2011-03-17 04:06:04 +0000
+++ Makefile.am 2011-05-27 15:36:38 +0000
@@ -21,7 +21,7 @@
2121
22ACLOCAL_MFLAGS = -I m422ACLOCAL_MFLAGS = -I m4
2323
24SUBDIRS = include libs libutouch-geis testsuite examples doc24SUBDIRS = include libs libutouch-geis testsuite python tools examples doc
2525
26doc-%:26doc-%:
27 $(MAKE) -C doc $@27 $(MAKE) -C doc $@
2828
=== modified file 'configure.ac'
--- configure.ac 2011-05-05 08:20:51 +0000
+++ configure.ac 2011-05-27 15:36:38 +0000
@@ -31,7 +31,7 @@
3131
32# Checks for programs.32# Checks for programs.
33AM_PROG_CC_C_O33AM_PROG_CC_C_O
34AM_PATH_PYTHON([2.5])34AM_PATH_PYTHON([2.7])
3535
36LT_PREREQ([2.2.6b])36LT_PREREQ([2.2.6b])
37LT_INIT37LT_INIT
@@ -47,6 +47,7 @@
47 AC_MSG_ERROR([X11-XCB development libraries not found]))47 AC_MSG_ERROR([X11-XCB development libraries not found]))
48PKG_CHECK_MODULES([XI2], [xi >= 1.3], ,48PKG_CHECK_MODULES([XI2], [xi >= 1.3], ,
49 AC_MSG_ERROR([XI2 development libraries not found]))49 AC_MSG_ERROR([XI2 development libraries not found]))
50PKG_CHECK_MODULES([PYTHON], [python >= 2.7])
5051
51AX_ENABLE_XI252AX_ENABLE_XI2
5253
@@ -101,5 +102,8 @@
101 testsuite/geis2/Makefile102 testsuite/geis2/Makefile
102 testsuite/geis1/Makefile103 testsuite/geis1/Makefile
103 testsuite/geistest/Makefile104 testsuite/geistest/Makefile
104 examples/Makefile])105 examples/Makefile
106 python/Makefile
107 tools/Makefile
108 tools/geisview/Makefile])
105AC_OUTPUT109AC_OUTPUT
106110
=== added directory 'python'
=== added file 'python/Makefile.am'
--- python/Makefile.am 1970-01-01 00:00:00 +0000
+++ python/Makefile.am 2011-05-27 15:36:38 +0000
@@ -0,0 +1,44 @@
1#
2# @file python/Makefile.am
3# @brief automake recipe for the libgeis python bindings
4#
5# Copyright 2011 Canonical, Ltd.
6#
7# This file is part of the utouch-geis library. This library is free software;
8# you can redistribute it and/or modify it under the terms of the GNU Lesser
9# General Public License as published by the Free Software Foundation; either
10# version 3 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful, but WITHOUT
13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15# details.
16#
17# You should have received a copy of the GNU Lesser General Public License
18# along with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
21dist_bin_SCRIPTS = pygeis
22
23dist_noinst_SCRIPTS = run_pygeis
24
25nobase_python_PYTHON = \
26 geis/__init__.py \
27 geis/geis_v2.py
28
29pyexec_LTLIBRARIES = _geis_bindings.la
30
31_geis_bindings_la_SOURCES = \
32 _geis_bindings/_geis_bindings.c
33
34_geis_bindings_la_CFLAGS = \
35 -I$(top_srcdir)/include \
36 -I$(top_srcdir)/libutouch-geis \
37 $(PYTHON_CFLAGS)
38
39_geis_bindings_la_LDFLAGS = \
40 -module -avoid-version \
41 -export-symbols-regex init_geis_bindings \
42 $(top_builddir)/libutouch-geis/libutouch-geis.la \
43 $(PYTHON_LDFLAGS)
44
045
=== added directory 'python/_geis_bindings'
=== added file 'python/_geis_bindings/_geis_bindings.c'
--- python/_geis_bindings/_geis_bindings.c 1970-01-01 00:00:00 +0000
+++ python/_geis_bindings/_geis_bindings.c 2011-05-27 15:36:38 +0000
@@ -0,0 +1,165 @@
1#include <Python.h>
2
3#include <geis/geis.h>
4
5
6PyDoc_STRVAR(module_doc,
7 "Low-level python bindings for libutouch-geis.\n"
8 "Do not use this module directly "
9 "-- the public API is provided by the 'geis' module."
10);
11
12
13static PyMethodDef exported_functions[] = {
14 { NULL, NULL, 0, NULL }
15};
16
17PyMODINIT_FUNC
18init_geis_bindings(void)
19{
20 PyObject *this_module;
21
22 this_module = Py_InitModule3("_geis_bindings", exported_functions, module_doc);
23 if (!this_module)
24 return;
25
26 /* Global status values. */
27 PyModule_AddIntConstant(this_module, "GEIS_STATUS_SUCCESS",
28 GEIS_STATUS_SUCCESS);
29 PyModule_AddIntConstant(this_module, "GEIS_STATUS_CONTINUE",
30 GEIS_STATUS_CONTINUE);
31 PyModule_AddIntConstant(this_module, "GEIS_STATUS_EMPTY",
32 GEIS_STATUS_EMPTY);
33 PyModule_AddIntConstant(this_module, "GEIS_STATUS_NOT_SUPPORTED",
34 GEIS_STATUS_NOT_SUPPORTED);
35 PyModule_AddIntConstant(this_module, "GEIS_STATUS_BAD_ARGUMENT",
36 GEIS_STATUS_BAD_ARGUMENT);
37 PyModule_AddIntConstant(this_module, "GEIS_STATUS_UNKNOWN_ERROR",
38 GEIS_STATUS_UNKNOWN_ERROR);
39
40 /* Attribute types */
41 PyModule_AddIntConstant(this_module, "GEIS_ATTR_TYPE_BOOLEAN",
42 GEIS_ATTR_TYPE_BOOLEAN);
43 PyModule_AddIntConstant(this_module, "GEIS_ATTR_TYPE_FLOAT",
44 GEIS_ATTR_TYPE_FLOAT);
45 PyModule_AddIntConstant(this_module, "GEIS_ATTR_TYPE_INTEGER",
46 GEIS_ATTR_TYPE_INTEGER);
47 PyModule_AddIntConstant(this_module, "GEIS_ATTR_TYPE_POINTER",
48 GEIS_ATTR_TYPE_POINTER);
49 PyModule_AddIntConstant(this_module, "GEIS_ATTR_TYPE_STRING",
50 GEIS_ATTR_TYPE_STRING);
51
52 /* Initialization Options */
53 PyModule_AddStringMacro(this_module, GEIS_INIT_SERVICE_PROVIDER);
54 PyModule_AddStringMacro(this_module, GEIS_INIT_TRACK_DEVICES);
55 PyModule_AddStringMacro(this_module, GEIS_INIT_TRACK_GESTURE_CLASSES);
56 PyModule_AddStringMacro(this_module, GEIS_INIT_UTOUCH_MOCK_ENGINE);
57 PyModule_AddStringMacro(this_module, GEIS_INIT_UTOUCH_XCB);
58
59 /* Configuration Items */
60 PyModule_AddStringMacro(this_module, GEIS_CONFIGURATION_FD);
61 PyModule_AddStringMacro(this_module, GEIS_CONFIG_UTOUCH_MAX_EVENTS);
62
63 /* Device Constants */
64 PyModule_AddStringMacro(this_module, GEIS_EVENT_ATTRIBUTE_DEVICE);
65 PyModule_AddStringMacro(this_module, GEIS_DEVICE_ATTRIBUTE_NAME);
66 PyModule_AddStringMacro(this_module, GEIS_DEVICE_ATTRIBUTE_ID);
67 PyModule_AddStringMacro(this_module, GEIS_DEVICE_ATTRIBUTE_TOUCHES);
68 PyModule_AddStringMacro(this_module, GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH);
69 PyModule_AddStringMacro(this_module, GEIS_DEVICE_ATTRIBUTE_INDEPENDENT_TOUCH);
70
71 /* Gesture Class Constants */
72 PyModule_AddStringMacro(this_module, GEIS_EVENT_ATTRIBUTE_CLASS);
73 PyModule_AddStringMacro(this_module, GEIS_CLASS_ATTRIBUTE_NAME);
74 PyModule_AddStringMacro(this_module, GEIS_CLASS_ATTRIBUTE_ID);
75
76 /* Region Constants */
77 PyModule_AddStringMacro(this_module, GEIS_REGION_ATTRIBUTE_WINDOWID);
78 PyModule_AddStringMacro(this_module, GEIS_REGION_X11_ROOT);
79 PyModule_AddStringMacro(this_module, GEIS_REGION_X11_WINDOWID);
80
81 /* Gesture Constants */
82 PyModule_AddStringMacro(this_module, GEIS_EVENT_ATTRIBUTE_GROUPSET);
83 PyModule_AddStringMacro(this_module, GEIS_EVENT_ATTRIBUTE_TOUCHSET);
84 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_ANGLE);
85 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_ANGLE_DELTA);
86 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_ANGULAR_VELOCITY);
87 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X1);
88 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X2);
89 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y1);
90 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y2);
91 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_CHILD_WINDOW_ID);
92 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_DELTA_X);
93 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_DELTA_Y);
94 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_DEVICE_ID);
95 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_EVENT_WINDOW_ID);
96 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_FOCUS_X);
97 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y);
98 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_GESTURE_NAME);
99 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_POSITION_X);
100 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_POSITION_Y);
101 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_RADIAL_VELOCITY);
102 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_RADIUS);
103 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_RADIUS_DELTA);
104 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_ROOT_WINDOW_ID);
105 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TAP_TIME);
106 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP);
107 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_0_ID);
108 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_0_X);
109 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_0_Y);
110 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_1_ID);
111 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_1_X);
112 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_1_Y);
113 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_2_ID);
114 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_2_X);
115 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_2_Y);
116 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_3_ID);
117 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_3_X);
118 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_3_Y);
119 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_4_ID);
120 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_4_X);
121 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCH_4_Y);
122 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_TOUCHES);
123 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_VELOCITY_X);
124 PyModule_AddStringMacro(this_module, GEIS_GESTURE_ATTRIBUTE_VELOCITY_Y);
125 PyModule_AddStringMacro(this_module, GEIS_TOUCH_ATTRIBUTE_ID);
126 PyModule_AddStringMacro(this_module, GEIS_TOUCH_ATTRIBUTE_X);
127 PyModule_AddStringMacro(this_module, GEIS_TOUCH_ATTRIBUTE_Y);
128
129 /* Event Types */
130 PyModule_AddIntConstant(this_module, "GEIS_EVENT_DEVICE_AVAILABLE",
131 GEIS_EVENT_DEVICE_AVAILABLE);
132 PyModule_AddIntConstant(this_module, "GEIS_EVENT_DEVICE_UNAVAILABLE",
133 GEIS_EVENT_DEVICE_UNAVAILABLE);
134 PyModule_AddIntConstant(this_module, "GEIS_EVENT_CLASS_AVAILABLE",
135 GEIS_EVENT_CLASS_AVAILABLE);
136 PyModule_AddIntConstant(this_module, "GEIS_EVENT_CLASS_CHANGED",
137 GEIS_EVENT_CLASS_CHANGED);
138 PyModule_AddIntConstant(this_module, "GEIS_EVENT_CLASS_UNAVAILABLE",
139 GEIS_EVENT_CLASS_UNAVAILABLE);
140 PyModule_AddIntConstant(this_module, "GEIS_EVENT_GESTURE_BEGIN",
141 GEIS_EVENT_GESTURE_BEGIN);
142 PyModule_AddIntConstant(this_module, "GEIS_EVENT_GESTURE_UPDATE",
143 GEIS_EVENT_GESTURE_UPDATE);
144 PyModule_AddIntConstant(this_module, "GEIS_EVENT_GESTURE_END",
145 GEIS_EVENT_GESTURE_END);
146 PyModule_AddIntConstant(this_module, "GEIS_EVENT_INIT_COMPLETE",
147 GEIS_EVENT_INIT_COMPLETE);
148 PyModule_AddIntConstant(this_module, "GEIS_EVENT_USER_DEFINED",
149 GEIS_EVENT_USER_DEFINED);
150 PyModule_AddIntConstant(this_module, "GEIS_EVENT_ERROR",
151 GEIS_EVENT_ERROR);
152
153 /* Filtery Bits */
154 PyModule_AddIntConstant(this_module, "GEIS_FILTER_DEVICE", GEIS_FILTER_DEVICE);
155 PyModule_AddIntConstant(this_module, "GEIS_FILTER_CLASS", GEIS_FILTER_CLASS);
156 PyModule_AddIntConstant(this_module, "GEIS_FILTER_REGION", GEIS_FILTER_REGION);
157
158 PyModule_AddIntConstant(this_module, "GEIS_FILTER_OP_EQ", GEIS_FILTER_OP_EQ);
159 PyModule_AddIntConstant(this_module, "GEIS_FILTER_OP_NE", GEIS_FILTER_OP_NE);
160 PyModule_AddIntConstant(this_module, "GEIS_FILTER_OP_GT", GEIS_FILTER_OP_GT);
161 PyModule_AddIntConstant(this_module, "GEIS_FILTER_OP_GE", GEIS_FILTER_OP_GE);
162 PyModule_AddIntConstant(this_module, "GEIS_FILTER_OP_LT", GEIS_FILTER_OP_LT);
163 PyModule_AddIntConstant(this_module, "GEIS_FILTER_OP_LE", GEIS_FILTER_OP_LE);
164}
165
0166
=== added directory 'python/geis'
=== added file 'python/geis/__init__.py'
--- python/geis/__init__.py 1970-01-01 00:00:00 +0000
+++ python/geis/__init__.py 2011-05-27 15:36:38 +0000
@@ -0,0 +1,234 @@
1# Copyright (C) 2011 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Python bindings for the GEIS gesture recognition interface.
18"""
19
20__all__ = (
21 'Geis', 'Event', 'Filter', 'Subscription',
22 'NoMoreEvents',
23 'GEIS_STATUS_SUCCESS',
24 'GEIS_STATUS_CONTINUE',
25 'GEIS_STATUS_EMPTY',
26 'GEIS_STATUS_NOT_SUPPORTED',
27 'GEIS_STATUS_BAD_ARGUMENT',
28 'GEIS_STATUS_UNKNOWN_ERROR',
29 'GEIS_ATTR_TYPE_BOOLEAN',
30 'GEIS_ATTR_TYPE_FLOAT',
31 'GEIS_ATTR_TYPE_INTEGER',
32 'GEIS_ATTR_TYPE_POINTER',
33 'GEIS_ATTR_TYPE_STRING',
34 'GEIS_INIT_SERVICE_PROVIDER',
35 'GEIS_INIT_TRACK_DEVICES',
36 'GEIS_INIT_TRACK_GESTURE_CLASSES',
37 'GEIS_INIT_UTOUCH_MOCK_ENGINE',
38 'GEIS_INIT_UTOUCH_XCB',
39 'GEIS_CLASS_ATTRIBUTE_ID',
40 'GEIS_CLASS_ATTRIBUTE_NAME',
41 'GEIS_CONFIGURATION_FD',
42 'GEIS_CONFIG_UTOUCH_MAX_EVENTS',
43 'GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH',
44 'GEIS_DEVICE_ATTRIBUTE_ID',
45 'GEIS_DEVICE_ATTRIBUTE_INDEPENDENT_TOUCH',
46 'GEIS_DEVICE_ATTRIBUTE_NAME',
47 'GEIS_DEVICE_ATTRIBUTE_TOUCHES',
48 'GEIS_EVENT_ATTRIBUTE_CLASS',
49 'GEIS_EVENT_ATTRIBUTE_DEVICE',
50 'GEIS_EVENT_ATTRIBUTE_GROUPSET',
51 'GEIS_EVENT_ATTRIBUTE_GROUPSET',
52 'GEIS_EVENT_ATTRIBUTE_TOUCHSET',
53 'GEIS_EVENT_ATTRIBUTE_TOUCHSET',
54 'GEIS_EVENT_CLASS_AVAILABLE',
55 'GEIS_EVENT_CLASS_CHANGED',
56 'GEIS_EVENT_CLASS_UNAVAILABLE',
57 'GEIS_EVENT_DEVICE_AVAILABLE',
58 'GEIS_EVENT_DEVICE_UNAVAILABLE',
59 'GEIS_EVENT_ERROR',
60 'GEIS_EVENT_GESTURE_BEGIN',
61 'GEIS_EVENT_GESTURE_END',
62 'GEIS_EVENT_GESTURE_UPDATE',
63 'GEIS_EVENT_INIT_COMPLETE',
64 'GEIS_EVENT_USER_DEFINED',
65 'GEIS_GESTURE_ATTRIBUTE_ANGLE',
66 'GEIS_GESTURE_ATTRIBUTE_ANGLE_DELTA',
67 'GEIS_GESTURE_ATTRIBUTE_ANGULAR_VELOCITY',
68 'GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X1',
69 'GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X2',
70 'GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y1',
71 'GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y2',
72 'GEIS_GESTURE_ATTRIBUTE_CHILD_WINDOW_ID',
73 'GEIS_GESTURE_ATTRIBUTE_DELTA_X',
74 'GEIS_GESTURE_ATTRIBUTE_DELTA_Y',
75 'GEIS_GESTURE_ATTRIBUTE_DEVICE_ID',
76 'GEIS_GESTURE_ATTRIBUTE_EVENT_WINDOW_ID',
77 'GEIS_GESTURE_ATTRIBUTE_FOCUS_X',
78 'GEIS_GESTURE_ATTRIBUTE_FOCUS_Y',
79 'GEIS_GESTURE_ATTRIBUTE_GESTURE_NAME',
80 'GEIS_GESTURE_ATTRIBUTE_POSITION_X',
81 'GEIS_GESTURE_ATTRIBUTE_POSITION_Y',
82 'GEIS_GESTURE_ATTRIBUTE_RADIAL_VELOCITY',
83 'GEIS_GESTURE_ATTRIBUTE_RADIUS',
84 'GEIS_GESTURE_ATTRIBUTE_RADIUS_DELTA',
85 'GEIS_GESTURE_ATTRIBUTE_ROOT_WINDOW_ID',
86 'GEIS_GESTURE_ATTRIBUTE_TAP_TIME',
87 'GEIS_GESTURE_ATTRIBUTE_TIMESTAMP',
88 'GEIS_GESTURE_ATTRIBUTE_TOUCH_0_ID',
89 'GEIS_GESTURE_ATTRIBUTE_TOUCH_0_X',
90 'GEIS_GESTURE_ATTRIBUTE_TOUCH_0_Y',
91 'GEIS_GESTURE_ATTRIBUTE_TOUCH_1_ID',
92 'GEIS_GESTURE_ATTRIBUTE_TOUCH_1_X',
93 'GEIS_GESTURE_ATTRIBUTE_TOUCH_1_Y',
94 'GEIS_GESTURE_ATTRIBUTE_TOUCH_2_ID',
95 'GEIS_GESTURE_ATTRIBUTE_TOUCH_2_X',
96 'GEIS_GESTURE_ATTRIBUTE_TOUCH_2_Y',
97 'GEIS_GESTURE_ATTRIBUTE_TOUCH_3_ID',
98 'GEIS_GESTURE_ATTRIBUTE_TOUCH_3_X',
99 'GEIS_GESTURE_ATTRIBUTE_TOUCH_3_Y',
100 'GEIS_GESTURE_ATTRIBUTE_TOUCH_4_ID',
101 'GEIS_GESTURE_ATTRIBUTE_TOUCH_4_X',
102 'GEIS_GESTURE_ATTRIBUTE_TOUCH_4_Y',
103 'GEIS_GESTURE_ATTRIBUTE_TOUCHES',
104 'GEIS_GESTURE_ATTRIBUTE_VELOCITY_X',
105 'GEIS_GESTURE_ATTRIBUTE_VELOCITY_Y',
106 'GEIS_REGION_ATTRIBUTE_WINDOWID',
107 'GEIS_REGION_X11_ROOT',
108 'GEIS_REGION_X11_WINDOWID',
109 'GEIS_TOUCH_ATTRIBUTE_ID',
110 'GEIS_TOUCH_ATTRIBUTE_ID',
111 'GEIS_TOUCH_ATTRIBUTE_X',
112 'GEIS_TOUCH_ATTRIBUTE_X',
113 'GEIS_TOUCH_ATTRIBUTE_Y',
114 'GEIS_TOUCH_ATTRIBUTE_Y',
115 'GEIS_FILTER_DEVICE',
116 'GEIS_FILTER_CLASS',
117 'GEIS_FILTER_REGION',
118 'GEIS_FILTER_OP_EQ',
119 'GEIS_FILTER_OP_NE',
120 'GEIS_FILTER_OP_GT',
121 'GEIS_FILTER_OP_GE',
122 'GEIS_FILTER_OP_LT',
123 'GEIS_FILTER_OP_LE',
124 )
125
126from _geis_bindings import GEIS_STATUS_SUCCESS, \
127 GEIS_STATUS_CONTINUE, \
128 GEIS_STATUS_EMPTY, \
129 GEIS_STATUS_NOT_SUPPORTED, \
130 GEIS_STATUS_BAD_ARGUMENT, \
131 GEIS_STATUS_UNKNOWN_ERROR
132
133from _geis_bindings import GEIS_ATTR_TYPE_BOOLEAN, \
134 GEIS_ATTR_TYPE_FLOAT, \
135 GEIS_ATTR_TYPE_INTEGER, \
136 GEIS_ATTR_TYPE_POINTER, \
137 GEIS_ATTR_TYPE_STRING
138
139from _geis_bindings import GEIS_INIT_SERVICE_PROVIDER, \
140 GEIS_INIT_TRACK_DEVICES, \
141 GEIS_INIT_TRACK_GESTURE_CLASSES, \
142 GEIS_INIT_UTOUCH_MOCK_ENGINE, \
143 GEIS_INIT_UTOUCH_XCB
144
145from _geis_bindings import GEIS_CONFIGURATION_FD, \
146 GEIS_CONFIG_UTOUCH_MAX_EVENTS
147
148from _geis_bindings import GEIS_EVENT_ATTRIBUTE_DEVICE, \
149 GEIS_DEVICE_ATTRIBUTE_NAME, \
150 GEIS_DEVICE_ATTRIBUTE_ID, \
151 GEIS_DEVICE_ATTRIBUTE_TOUCHES, \
152 GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH, \
153 GEIS_DEVICE_ATTRIBUTE_INDEPENDENT_TOUCH
154
155from _geis_bindings import GEIS_EVENT_ATTRIBUTE_CLASS, \
156 GEIS_CLASS_ATTRIBUTE_NAME, \
157 GEIS_CLASS_ATTRIBUTE_ID
158
159from _geis_bindings import GEIS_REGION_ATTRIBUTE_WINDOWID, \
160 GEIS_REGION_X11_ROOT, \
161 GEIS_REGION_X11_WINDOWID
162
163from _geis_bindings import GEIS_EVENT_ATTRIBUTE_GROUPSET, \
164 GEIS_EVENT_ATTRIBUTE_TOUCHSET, \
165 GEIS_TOUCH_ATTRIBUTE_ID, \
166 GEIS_TOUCH_ATTRIBUTE_X, \
167 GEIS_TOUCH_ATTRIBUTE_Y
168
169from _geis_bindings import GEIS_EVENT_DEVICE_AVAILABLE, \
170 GEIS_EVENT_DEVICE_UNAVAILABLE, \
171 GEIS_EVENT_CLASS_AVAILABLE, \
172 GEIS_EVENT_CLASS_CHANGED, \
173 GEIS_EVENT_CLASS_UNAVAILABLE, \
174 GEIS_EVENT_GESTURE_BEGIN, \
175 GEIS_EVENT_GESTURE_UPDATE, \
176 GEIS_EVENT_GESTURE_END, \
177 GEIS_EVENT_INIT_COMPLETE, \
178 GEIS_EVENT_USER_DEFINED, \
179 GEIS_EVENT_ERROR
180
181from _geis_bindings import GEIS_GESTURE_ATTRIBUTE_ANGLE, \
182 GEIS_GESTURE_ATTRIBUTE_ANGLE_DELTA, \
183 GEIS_GESTURE_ATTRIBUTE_ANGULAR_VELOCITY, \
184 GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X1, \
185 GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X2, \
186 GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y1, \
187 GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y2, \
188 GEIS_GESTURE_ATTRIBUTE_CHILD_WINDOW_ID, \
189 GEIS_GESTURE_ATTRIBUTE_DELTA_X, \
190 GEIS_GESTURE_ATTRIBUTE_DELTA_Y, \
191 GEIS_GESTURE_ATTRIBUTE_DEVICE_ID, \
192 GEIS_GESTURE_ATTRIBUTE_EVENT_WINDOW_ID, \
193 GEIS_GESTURE_ATTRIBUTE_FOCUS_X, \
194 GEIS_GESTURE_ATTRIBUTE_FOCUS_Y, \
195 GEIS_GESTURE_ATTRIBUTE_GESTURE_NAME, \
196 GEIS_GESTURE_ATTRIBUTE_POSITION_X, \
197 GEIS_GESTURE_ATTRIBUTE_POSITION_Y, \
198 GEIS_GESTURE_ATTRIBUTE_RADIAL_VELOCITY, \
199 GEIS_GESTURE_ATTRIBUTE_RADIUS, \
200 GEIS_GESTURE_ATTRIBUTE_RADIUS_DELTA, \
201 GEIS_GESTURE_ATTRIBUTE_ROOT_WINDOW_ID, \
202 GEIS_GESTURE_ATTRIBUTE_TAP_TIME, \
203 GEIS_GESTURE_ATTRIBUTE_TIMESTAMP, \
204 GEIS_GESTURE_ATTRIBUTE_TOUCH_0_ID, \
205 GEIS_GESTURE_ATTRIBUTE_TOUCH_0_X, \
206 GEIS_GESTURE_ATTRIBUTE_TOUCH_0_Y, \
207 GEIS_GESTURE_ATTRIBUTE_TOUCH_1_ID, \
208 GEIS_GESTURE_ATTRIBUTE_TOUCH_1_X, \
209 GEIS_GESTURE_ATTRIBUTE_TOUCH_1_Y, \
210 GEIS_GESTURE_ATTRIBUTE_TOUCH_2_ID, \
211 GEIS_GESTURE_ATTRIBUTE_TOUCH_2_X, \
212 GEIS_GESTURE_ATTRIBUTE_TOUCH_2_Y, \
213 GEIS_GESTURE_ATTRIBUTE_TOUCH_3_ID, \
214 GEIS_GESTURE_ATTRIBUTE_TOUCH_3_X, \
215 GEIS_GESTURE_ATTRIBUTE_TOUCH_3_Y, \
216 GEIS_GESTURE_ATTRIBUTE_TOUCH_4_ID, \
217 GEIS_GESTURE_ATTRIBUTE_TOUCH_4_X, \
218 GEIS_GESTURE_ATTRIBUTE_TOUCH_4_Y, \
219 GEIS_GESTURE_ATTRIBUTE_TOUCHES, \
220 GEIS_GESTURE_ATTRIBUTE_VELOCITY_X, \
221 GEIS_GESTURE_ATTRIBUTE_VELOCITY_Y
222
223from _geis_bindings import GEIS_FILTER_DEVICE, \
224 GEIS_FILTER_CLASS, \
225 GEIS_FILTER_REGION, \
226 GEIS_FILTER_OP_EQ, \
227 GEIS_FILTER_OP_NE, \
228 GEIS_FILTER_OP_GT, \
229 GEIS_FILTER_OP_GE, \
230 GEIS_FILTER_OP_LT, \
231 GEIS_FILTER_OP_LE
232
233from geis.geis_v2 import Geis, Event, Filter, Subscription, NoMoreEvents
234
0235
=== added file 'python/geis/geis_v2.py'
--- python/geis/geis_v2.py 1970-01-01 00:00:00 +0000
+++ python/geis/geis_v2.py 2011-05-27 15:36:38 +0000
@@ -0,0 +1,640 @@
1# Copyright (C) 2011 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Python bindings for the GEIS v2 gesture recognition interface.
18
19Do not use this module directly -- the public API is provided by the 'geis'
20module.
21"""
22
23import ctypes
24import ctypes.util
25import _geis_bindings
26import re
27import sys
28
29
30class GeisError(Exception):
31 """ A general error has occurred internally in GEIS.
32 """
33 def __init__(self, reason):
34 Exception.__init__(self, reason)
35
36
37class NoMoreEvents(Exception):
38 """ Raised by the event dispatch mechanism to indicate there are no
39 pending events in the queue.
40 """
41
42 def __init__(self):
43 Exception.__init__(self, 'geis event queue is empty')
44
45
46
47def _check_null(ret, func, args):
48 """ Converts a NULL pointer return value into an Exception.
49 """
50 if ret == 0:
51 raise GeisError("%s failed" % func.__name__)
52 return ret
53
54_EventCallback = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p,
55 ctypes.py_object)
56
57_geis_lib = ctypes.CDLL(ctypes.util.find_library("utouch-geis"))
58try:
59 _geis_new = _geis_lib.geis_new
60 _geis_new.restype = ctypes.c_void_p
61 _geis_new.errcheck = _check_null
62 _geis_delete = _geis_lib.geis_delete
63 _geis_get_configuration = _geis_lib.geis_get_configuration
64 _geis_dispatch_events = _geis_lib.geis_dispatch_events
65 _geis_register_class_callback = _geis_lib.geis_register_class_callback
66 _geis_register_device_callback = _geis_lib.geis_register_device_callback
67 _geis_register_event_callback = _geis_lib.geis_register_event_callback
68 _geis_next_event = _geis_lib.geis_next_event
69
70 _geis_subscription_new = _geis_lib.geis_subscription_new
71 _geis_subscription_new.restype = ctypes.c_void_p
72 _geis_subscription_new.errcheck = _check_null
73 _geis_subscription_delete = _geis_lib.geis_subscription_delete
74 _geis_subscription_activate = _geis_lib.geis_subscription_activate
75 _geis_subscription_deactivate = _geis_lib.geis_subscription_deactivate
76 _geis_subscription_name = _geis_lib.geis_subscription_name
77
78 _geis_attr_name = _geis_lib.geis_attr_name
79 _geis_attr_name.restype = ctypes.c_char_p
80 _geis_attr_type = _geis_lib.geis_attr_type
81 _geis_attr_value_to_pointer = _geis_lib.geis_attr_value_to_pointer
82
83 _geis_event_type = _geis_lib.geis_event_type
84 _geis_event_attr_count = _geis_lib.geis_event_attr_count
85 _geis_event_attr = _geis_lib.geis_event_attr
86 _geis_event_attr.restype = ctypes.c_void_p
87
88 _geis_gesture_class_unref = _geis_lib.geis_gesture_class_unref
89 _geis_gesture_class_name = _geis_lib.geis_gesture_class_name
90 _geis_gesture_class_name.restype = ctypes.c_char_p
91 _geis_gesture_class_id = _geis_lib.geis_gesture_class_id
92 _geis_gesture_class_attr_count = _geis_lib.geis_gesture_class_attr_count
93 _geis_gesture_class_attr = _geis_lib.geis_gesture_class_attr
94 _geis_gesture_class_attr.restype = ctypes.c_void_p
95
96 _geis_device_ref = _geis_lib.geis_device_ref
97 _geis_device_unref = _geis_lib.geis_device_unref
98 _geis_device_name = _geis_lib.geis_device_name
99 _geis_device_name.restype = ctypes.c_char_p
100 _geis_device_id = _geis_lib.geis_device_id
101 _geis_device_attr_count = _geis_lib.geis_device_attr_count
102 _geis_device_attr = _geis_lib.geis_device_attr
103 _geis_device_attr.restype = ctypes.c_void_p
104
105 _geis_touchset_touch_count = _geis_lib.geis_touchset_touch_count
106 _geis_touchset_touch = _geis_lib.geis_touchset_touch
107 _geis_touchset_touch.restype = ctypes.c_void_p
108
109 _geis_touch_attr_count = _geis_lib.geis_touch_attr_count
110 _geis_touch_attr = _geis_lib.geis_touch_attr
111 _geis_touch_attr.restype = ctypes.c_void_p
112
113 _geis_groupset_group_count = _geis_lib.geis_groupset_group_count
114 _geis_groupset_group = _geis_lib.geis_groupset_group
115 _geis_groupset_group.restype = ctypes.c_void_p
116
117 _geis_group_frame_count = _geis_lib.geis_group_frame_count
118 _geis_group_frame = _geis_lib.geis_group_frame
119 _geis_group_frame.restype = ctypes.c_void_p
120
121 _geis_frame_attr_count = _geis_lib.geis_frame_attr_count
122 _geis_frame_attr = _geis_lib.geis_frame_attr
123 _geis_frame_attr.restype = ctypes.c_void_p
124 _geis_frame_touchid_count = _geis_lib.geis_frame_touchid_count
125 _geis_frame_touchid = _geis_lib.geis_frame_touchid
126
127except AttributeError as ex:
128 print ex
129 sys.exit(1)
130
131
132class GestureClass(object):
133 """Describes a class of gestures.
134 """
135
136 def __init__(self, attr):
137 self._class = _geis_attr_value_to_pointer(attr)
138 self._id = _geis_gesture_class_id(self._class)
139 self._name = _geis_gesture_class_name(self._class)
140 self._attr_count = _geis_gesture_class_attr_count(self._class)
141 self._attrs = {}
142 for i in range(self._attr_count):
143 attr = _geis_gesture_class_attr(self._class, i)
144 attr_name = _geis_attr_name(attr)
145 self._attrs[attr_name] = _attr_types.get(_geis_attr_type(attr),
146 _attr_type_unknown)(attr)
147
148 def id(self):
149 """ Gets the gesture class's system identifier (an integer).
150 """
151 return self._id
152
153 def name(self):
154 """ Gets the gesture class's self-identified name.
155 """
156 return self._name
157
158 def attrs(self):
159 """ Gets the named attributes associated with the gesture class.
160 """
161 return self._attrs
162
163
164class Device(object):
165 """Describes a touchable device.
166 """
167
168 def __init__(self, attr):
169 self._device = _geis_attr_value_to_pointer(attr)
170 self._id = _geis_device_id(self._device)
171 self._name = _geis_device_name(self._device)
172 self._min_x = 0.0
173 self._min_y = 0.0
174 self._max_x = 0.0
175 self._max_y = 0.0
176 self._attr_count = _geis_device_attr_count(self._device)
177 self._attrs = {}
178 for i in range(self._attr_count):
179 attr = _geis_device_attr(self._device, i)
180 attr_name = _geis_attr_name(attr)
181 self._attrs[attr_name] = _attr_types.get(_geis_attr_type(attr),
182 _attr_type_unknown)(attr)
183 if re.search("Abs MT Position X \d+ min", attr_name):
184 self._min_x = self._attrs[attr_name]
185 if re.search("Abs MT Position X \d+ max", attr_name):
186 self._max_x = self._attrs[attr_name]
187 if re.search("Abs MT Position Y \d+ min", attr_name):
188 self._min_y = self._attrs[attr_name]
189 if re.search("Abs MT Position Y \d+ max", attr_name):
190 self._max_y = self._attrs[attr_name]
191
192 def id(self):
193 """ Gets the device's system identifier (an integer).
194 """
195 return self._id
196
197 def name(self):
198 """ Gets the device's self-identified name.
199 """
200 return self._name
201
202 def extents(self):
203 """ Gets the device's defined extents (bounding box).
204
205 Returns: A tuple of (min X, min Y, max X, max Y).
206 """
207 return (self._min_x, self._min_y, self._max_x, self._max_y)
208
209 def attrs(self):
210 """ Gets the named attributes associated with the device.
211 """
212 return self._attrs
213
214
215class Touch(object):
216 """Represents a particular touch."""
217
218 def __init__(self, touch):
219 self._touch = touch
220 self._attr_count = _geis_touch_attr_count(self._touch)
221
222 def id(self):
223 """ Gets the persistent identifier of the touch.
224 """
225 return _geis_lib.geis_touch_id(self._touch)
226
227 def attrs(self):
228 """ Gets the attributes of the touch.
229 """
230 attr_list = {}
231 for i in range(self._attr_count):
232 attr = _geis_touch_attr(self._touch, i)
233 attr_name = _geis_attr_name(attr)
234 attr_list[attr_name] = _attr_types.get(_geis_attr_type(attr),
235 _attr_type_unknown)(attr)
236 return attr_list
237
238
239class Touchset(object):
240 """A collection of Touch objects."""
241
242 def __init__(self, attr):
243 self._touchset = _geis_attr_value_to_pointer(attr)
244 self._count = _geis_touchset_touch_count(self._touchset)
245 self._index = 0
246
247 def __len__(self):
248 return self._count
249
250 def __iter__(self):
251 return self
252
253 def next(self):
254 """ Gets the next touch in the touchset as an iterable.
255 """
256 if self._index == self._count:
257 raise StopIteration
258 touch = Touch(_geis_touchset_touch(self._touchset, self._index))
259 self._index = self._index + 1
260 return touch
261
262
263class Groupset(object):
264 """A collection of Group objects."""
265
266 def __init__(self, attr):
267 self._groupset = _geis_attr_value_to_pointer(attr)
268 self._count = _geis_groupset_group_count(self._groupset)
269 self._index = 0
270
271 def __len__(self):
272 return self._count
273
274 def __iter__(self):
275 return self
276
277 def next(self):
278 """ Gets the next group in the groupset as an iterable.
279 """
280 if self._index == self._count:
281 raise StopIteration
282 touch = Group(_geis_groupset_group(self._groupset, self._index))
283 self._index = self._index + 1
284 return touch
285
286
287class Group(object):
288 """A set of Frame objects made up of a combination of touches."""
289
290 def __init__(self, group):
291 self._group = group
292 self._count = _geis_group_frame_count(self._group)
293 self._index = 0
294
295 def __len__(self):
296 return self._count
297
298 def __iter__(self):
299 return self
300
301 def id(self):
302 return _geis_lib.geis_group_id(self._group)
303
304 def next(self):
305 """ Gets the next frame in the group as an iterable.
306 """
307 if self._index == self._count:
308 raise StopIteration
309 frame = Frame(_geis_group_frame(self._group, self._index))
310 self._index = self._index + 1
311 return frame
312
313
314class Frame(object):
315 """A gesture frame."""
316
317 def __init__(self, frame):
318 self._frame = frame
319
320 def id(self):
321 return _geis_lib.geis_frame_id(self._frame)
322
323 def attrs(self):
324 attr_list = {}
325 for i in range(_geis_frame_attr_count(self._frame)):
326 attr = _geis_frame_attr(self._frame, i)
327 attr_name = _geis_attr_name(attr)
328 attr_list[attr_name] = _attr_types.get(_geis_attr_type(attr),
329 _attr_type_unknown)(attr)
330 return attr_list
331
332 def touches(self):
333 touch_list = []
334 for i in range(_geis_frame_touchid_count(self._frame)):
335 touch_list.append(_geis_frame_touchid(self._frame, i))
336 return touch_list
337
338
339def _pointer_type_class(attr):
340 """ Converts a generic attr into a GestureClass object.
341 """
342 return GestureClass(attr)
343
344
345def _pointer_type_device(attr):
346 """ Converts a generic attr into a Device object.
347 """
348 return Device(attr)
349
350
351def _pointer_type_groupset(attr):
352 """ Converts a generic attr into a Groupset object.
353 """
354 return Groupset(attr)
355
356
357def _pointer_type_touchset(attr):
358 """ Converts a generic attr into a Touchset object.
359 """
360 return Touchset(attr)
361
362
363def _pointer_type_unknown(attr):
364 print "unknown pointer type", _geis_attr_name(attr)
365 return None
366
367
368_attr_pointer_type = {
369 _geis_bindings.GEIS_EVENT_ATTRIBUTE_CLASS: _pointer_type_class,
370 _geis_bindings.GEIS_EVENT_ATTRIBUTE_DEVICE: _pointer_type_device,
371 _geis_bindings.GEIS_EVENT_ATTRIBUTE_GROUPSET: _pointer_type_groupset,
372 _geis_bindings.GEIS_EVENT_ATTRIBUTE_TOUCHSET: _pointer_type_touchset
373}
374
375
376def _attr_type_boolean(attr):
377 """ Extracts an attribute value as a boolean.
378 """
379 return _geis_lib.geis_attr_value_to_boolean(attr)
380
381
382def _attr_type_float(attr):
383 """ Extracts an attribute value as a float.
384 """
385 geis_attr_value_to_float = _geis_lib.geis_attr_value_to_float
386 geis_attr_value_to_float.restype = ctypes.c_float
387 return geis_attr_value_to_float(attr)
388
389
390def _attr_type_integer(attr):
391 """ Extracts an attribute value as a integer.
392 """
393 return _geis_lib.geis_attr_value_to_integer(attr)
394
395
396def _attr_type_pointer(attr):
397 """ Extracts an attribute value as an object.
398 """
399 return _attr_pointer_type.get(_geis_attr_name(attr), _pointer_type_unknown)(attr)
400
401
402def _attr_type_string(attr):
403 """ Extracts an attribute value as a string.
404 """
405 geis_attr_value_to_string = _geis_lib.geis_attr_value_to_string
406 geis_attr_value_to_string.restype = ctypes.c_char_p
407 return geis_attr_value_to_string(attr)
408
409
410def _attr_type_unknown(attr):
411 print "unknown attr type", _geis_attr_name(attr)
412 return None
413
414
415_attr_types = {
416 _geis_bindings.GEIS_ATTR_TYPE_BOOLEAN: _attr_type_boolean,
417 _geis_bindings.GEIS_ATTR_TYPE_FLOAT: _attr_type_float,
418 _geis_bindings.GEIS_ATTR_TYPE_INTEGER: _attr_type_integer,
419 _geis_bindings.GEIS_ATTR_TYPE_POINTER: _attr_type_pointer,
420 _geis_bindings.GEIS_ATTR_TYPE_STRING: _attr_type_string
421}
422
423
424def _cb_wrapper(ignored, eptr, context):
425 """ A currying wrapper for event callbacks.
426
427 This is a currying function to wrap a Python callback with arbitrary
428 arguments so it can be invoked from a C callback.
429
430 :param ignored: This argumenet is ignored.
431 :param eptr: A C pointer to the internal GEIS event.
432 :param context: A tuple containing the Geis class instance,
433 the Python callable, and the argument list.
434 """
435 (geis_instance, cb, args) = context
436 cb(geis_instance, Event(eptr), args[0])
437
438
439class Geis(object):
440 """A GEIS API instance.
441 """
442
443 def __init__(self, *args):
444 """Create a GEIS instance.
445
446 This constructor takes a variable number of arguments (zero or more)
447 all of he geis.GEIS_INIT_... form.
448
449 On failure, an Exception is raised.
450 """
451 terminator = 0,
452 va_args = args + terminator
453 self._instance = _geis_new(*va_args)
454 self._cb_wrapper = _EventCallback(_cb_wrapper)
455 self._class_curry = None
456 self._device_curry = None
457 self._event_curry = None
458
459 def __del__(self):
460 _geis_delete(self._instance)
461
462 @property
463 def _as_parameter_(self):
464 return self._instance
465
466 def get_configuration(self, item_name):
467 """ Gets a named configuration value. """
468 if (item_name == _geis_bindings.GEIS_CONFIGURATION_FD):
469 fd = ctypes.c_long()
470 status = _geis_get_configuration(self._instance,
471 item_name,
472 ctypes.byref(fd))
473 if status != _geis_bindings.GEIS_STATUS_SUCCESS:
474 raise GeisError('error retrieving GEIS fd')
475 return fd.value
476 raise ValueError('unsupported config item name')
477
478 def set_configuration(self, name, value):
479 """ Sets a named configuration value. """
480 raise ValueError('unsupported config item name')
481
482 def register_class_callback(self, callback, *args):
483 """ Registers a python callback to receive GEIS gesture class events.
484 """
485 context = self, callback, args
486 self._class_curry = ctypes.py_object(context)
487 _geis_register_class_callback(self._instance,
488 self._cb_wrapper,
489 self._class_curry)
490
491 def register_device_callback(self, callback, *args):
492 """ Registers a python callback to receive GEIS gesture device events.
493 """
494 context = self, callback, args
495 self._device_curry = ctypes.py_object(context)
496 _geis_register_device_callback(self._instance,
497 self._cb_wrapper,
498 self._device_curry)
499
500 def register_event_callback(self, callback, *args):
501 """ Registers a python callback to receive general GEIS events.
502 """
503 self._event_curry = ctypes.py_object((self, callback, args))
504 _geis_register_event_callback(self._instance,
505 self._cb_wrapper,
506 self._event_curry)
507
508 def dispatch_events(self):
509 """ Pumps the geis event loop. """
510 return _geis_dispatch_events(self._instance)
511
512 def next_event(self):
513 """ Pulls the next event, if any, off the geis event queue.
514
515 :return: a geis.Event object
516 :raise: geis.NoMoreEvents
517 """
518 event = Event()
519 status = _geis_next_event(self._instance, event)
520 if status not in [_geis_bindings.GEIS_STATUS_CONTINUE,
521 _geis_bindings.GEIS_STATUS_SUCCESS]:
522 raise NoMoreEvents()
523 return event
524
525
526class Event(object):
527 """ An event returned from the GEIS API.
528 """
529
530 def __init__(self, internal=ctypes.c_void_p()):
531 self._event = internal
532
533 @property
534 def _as_parameter_(self):
535 return ctypes.byref(self._event)
536
537 def type(self):
538 """ Gets the type of the event.
539 """
540 return _geis_event_type(self._event)
541
542 def attrs(self):
543 """ Gets the attributes associated with the event.
544 """
545 attr_list = {}
546 for i in range(_geis_event_attr_count(self._event)):
547 attr = _geis_event_attr(self._event, i)
548 attr_name = _geis_attr_name(attr)
549 attr_list[attr_name] = _attr_types.get(_geis_attr_type(attr),
550 _attr_type_unknown)(attr)
551 return attr_list
552
553
554class Filter(object):
555 """ A Geis Filter object.
556 """
557
558 def __init__(self, geis, name):
559 self._filter = _geis_lib.geis_filter_new(geis, name)
560
561 def __del__(self):
562 _geis_lib.geis_filter_delete(self._filter)
563
564 @property
565 def _as_parameter_(self):
566 return self._filter
567
568 def name(self):
569 """ Gets the name of the filter.
570 """
571 return _geis_lib.geis_filter_name(self._filter)
572
573 def add_term(self, facility, *terms):
574 """ Adds a new term to the filter.
575
576 :param facility: the filter facility to which the terms belong
577 :param terms: a collection of (name, operation, value) tuples
578 """
579 for term in terms:
580 if len(term) != 3:
581 raise ValueError('invalid filter term')
582 name, op, value = term
583 _geis_lib.geis_filter_add_term(self._filter, facility,
584 name, op, value,
585 0)
586
587
588class Subscription(object):
589 """ A Geis subscription object.
590 """
591
592 def __init__(self, geis):
593 """Constructs a GEIS subscription object.
594
595 A subscription is a request to the gesture recognizer to receive gesture
596 events.
597
598 The default subscription is to receive all events from all devices for
599 all regions. The domain of the events received can be restructed
600 through the use of filters.
601
602 :param geis: The GEIS v2 instance.
603 :raise: Exception
604 """
605 object.__init__(self)
606 self._sub = _geis_subscription_new(geis, "py", 0)
607
608 def __del__(self):
609 _geis_subscription_delete(self._sub)
610
611 def activate(self):
612 """ Activates the subscription.
613 """
614 _geis_subscription_activate(self._sub)
615
616 def deactivate(self):
617 """ Deactivates the subscription.
618 """
619 _geis_subscription_deactivate(self._sub)
620
621 def name(self):
622 """ Gets the name of the subscription.
623 """
624 return _geis_subscription_name(self._sub)
625
626 def add_filter(self, filt):
627 """Adds a filter to the subscription.
628
629 :param filter: the filter to add
630 """
631 _geis_lib.geis_subscription_add_filter(self._sub, filt)
632
633 def remove_filter(self, filt):
634 """ Removes a filter from the subscription.
635
636 :param filter: the filter to remove
637 """
638 _geis_lib.geis_subscription_remove_filter(self._sub, filt)
639
640
0641
=== added file 'python/pygeis'
--- python/pygeis 1970-01-01 00:00:00 +0000
+++ python/pygeis 2011-05-27 15:36:38 +0000
@@ -0,0 +1,136 @@
1#!/usr/bin/python
2#
3# @file pygies
4# @brief a demo/test program for the GEIS python bindings
5#
6# Copyright (C) 2011 Canonical Ltd
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21
22import argparse
23import geis
24import glib
25import sys
26
27
28def _print_gesture(attrs):
29 touchset = attrs[geis.GEIS_EVENT_ATTRIBUTE_TOUCHSET]
30 groupset = attrs[geis.GEIS_EVENT_ATTRIBUTE_GROUPSET]
31 print " touches (" + str(len(touchset)) + "):"
32 for touch in touchset:
33 print " ", touch.id(), touch.attrs()
34 print " groups:"
35 for group in groupset:
36 print " ", group.id(), ":"
37 for frame in group:
38 print " frame ", frame.id(), ":"
39 for (k, v) in frame.attrs().iteritems():
40 print " " + k + ":", v
41 print " touches: ", frame.touches()
42
43def _do_init_complete(event, sub):
44 print "init complete"
45 sub.activate()
46
47def _do_device_available(event, sub):
48 print "device available"
49
50def _do_gesture_begin(event, sub):
51 print "gesture begin"
52 _print_gesture(event.attrs())
53
54def _do_gesture_update(event, sub):
55 print "gesture update"
56 _print_gesture(event.attrs())
57
58def _do_gesture_end(event, sub):
59 print "gesture end"
60 _print_gesture(event.attrs())
61
62def _do_other_event(event, sub):
63 print "unknown geis event received"
64
65_geis_event_action = {
66 geis.GEIS_EVENT_INIT_COMPLETE: _do_init_complete,
67 geis.GEIS_EVENT_DEVICE_AVAILABLE: _do_device_available,
68 geis.GEIS_EVENT_GESTURE_BEGIN: _do_gesture_begin,
69 geis.GEIS_EVENT_GESTURE_UPDATE: _do_gesture_update,
70 geis.GEIS_EVENT_GESTURE_END: _do_gesture_end
71}
72
73
74def _dispatch_geis_events(fd, condition, g):
75 """ Performs GEIS event loop processing. """
76 status = g.dispatch_events()
77 while status == geis.GEIS_STATUS_CONTINUE:
78 status = g.dispatch_events()
79
80 try:
81 while True:
82 event = g.next_event()
83 _geis_event_action.get(event.type(), _do_other_event)(event, None)
84 except geis.NoMoreEvents:
85 pass
86 return True
87
88
89def _class_callback(g, event, sub):
90 if event.type() == geis.GEIS_EVENT_CLASS_AVAILABLE:
91 gclass = event.attrs()[geis.GEIS_EVENT_ATTRIBUTE_CLASS]
92 name = gclass.name()
93 print ".. adding class %s" % name
94 filt = geis.Filter(g, name)
95 filt.add_term(geis.GEIS_FILTER_CLASS,
96 (geis.GEIS_CLASS_ATTRIBUTE_NAME, geis.GEIS_FILTER_OP_EQ, name),
97 (geis.GEIS_GESTURE_ATTRIBUTE_TOUCHES, geis.GEIS_FILTER_OP_GT, 2))
98 sub.add_filter(filt)
99
100
101def _event_callback(geis, event, sub):
102 _geis_event_action.get(event.type(), _do_other_event)(event, sub)
103
104
105class Options(argparse.ArgumentParser):
106
107 def __init__(self):
108 argparse.ArgumentParser.__init__(self,
109 description="monitor uTouch gestures")
110 self.add_argument('-V', '--version', action='version', version='1.0')
111
112
113if __name__ == '__main__':
114 options = Options()
115 try:
116 options.parse_args()
117 except argparse.ArgumentError, ex:
118 print ex
119 sys.exit(1)
120
121 g = geis.Geis(geis.GEIS_INIT_TRACK_DEVICES,
122 geis.GEIS_INIT_TRACK_GESTURE_CLASSES)
123 geis_fd = g.get_configuration(geis.GEIS_CONFIGURATION_FD)
124 sub = geis.Subscription(g)
125 g.register_class_callback(_class_callback, sub)
126 g.register_event_callback(_event_callback, sub)
127
128 try:
129 ml = glib.MainLoop()
130 glib.io_add_watch(geis_fd, glib.IO_IN, _dispatch_geis_events, g)
131 ml.run()
132
133 except KeyboardInterrupt:
134 pass
135
136
0137
=== added file 'python/run_pygeis'
--- python/run_pygeis 1970-01-01 00:00:00 +0000
+++ python/run_pygeis 2011-05-27 15:36:38 +0000
@@ -0,0 +1,11 @@
1#!/bin/sh
2#
3# Runs the pygeis program from inside the build tree.
4#
5tool_path=$(dirname $0)
6
7LD_LIBRARY_PATH=$tool_path/../libutouch-geis/.libs
8PYTHONPATH=$tool_path/.libs
9
10export LD_LIBRARY_PATH PYTHONPATH
11$tool_path/pygeis "$@"
012
=== added directory 'tools'
=== added file 'tools/Makefile.am'
--- tools/Makefile.am 1970-01-01 00:00:00 +0000
+++ tools/Makefile.am 2011-05-27 15:36:38 +0000
@@ -0,0 +1,23 @@
1#
2# @file tools/Makefile.am
3# @brief automake recipe for the GEIS tools
4#
5#
6# Copyright 2011 Canonical, Ltd.
7#
8# This file is part of the utouch-geis library. This library is free software;
9# you can redistribute it and/or modify it under the terms of the GNU Lesser
10# General Public License as published by the Free Software Foundation; either
11# version 3 of the License, or (at your option) any later version.
12#
13# This library is distributed in the hope that it will be useful, but WITHOUT
14# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
16# details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21
22SUBDIRS = geisview
23
024
=== added directory 'tools/geisview'
=== added file 'tools/geisview/Makefile.am'
--- tools/geisview/Makefile.am 1970-01-01 00:00:00 +0000
+++ tools/geisview/Makefile.am 2011-05-27 15:36:38 +0000
@@ -0,0 +1,46 @@
1#
2# @file tools/geisview/Makefile.am
3# @brief automake recipe for the geisview tool
4#
5# Copyright 2011 Canonical, Ltd.
6#
7# This file is part of the utouch-geis library. This library is free software;
8# you can redistribute it and/or modify it under the terms of the GNU Lesser
9# General Public License as published by the Free Software Foundation; either
10# version 3 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful, but WITHOUT
13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15# details.
16#
17# You should have received a copy of the GNU Lesser General Public License
18# along with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
21geisviewdir = $(pythondir)/geisview
22shareddir = $(datadir)/geisview
23xdgdir = $(datadir)/applications
24
25dist_bin_SCRIPTS = geisview
26dist_shared_DATA = \
27 geisview.ui \
28 filter_definition.ui \
29 filter_list.ui
30
31geisview_PYTHON = \
32 __init__.py \
33 defaults.py \
34 deviceview.py \
35 filter_definition.py \
36 filter_list.py
37
38defaults.py: defaults.py.in Makefile
39 $(AM_V_GEN)$(SED) \
40 -e 's,[@]shareddir[@],$(shareddir),g' \
41 $< >$@
42
43BUILT_SOURCES = defaults.py
44EXTRA_DIST = defaults.py.in
45CLEANFILES = $(BUILT_SOURCES)
46
047
=== added file 'tools/geisview/__init__.py'
--- tools/geisview/__init__.py 1970-01-01 00:00:00 +0000
+++ tools/geisview/__init__.py 2011-05-27 15:36:38 +0000
@@ -0,0 +1,24 @@
1#!/usr/bin/python
2#
3# @file geisview/__init__.py
4# @brief Module __init__ for geisview
5#
6# This program is a handy diagnostic tool for viewing the raw data produced
7# through the GEIS multi-touch and gesture interface.
8#
9# Copyright (C) 2011 Canonical Ltd
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 3 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program. If not, see <http://www.gnu.org/licenses/>.
23#
24
025
=== added file 'tools/geisview/defaults.py.in'
--- tools/geisview/defaults.py.in 1970-01-01 00:00:00 +0000
+++ tools/geisview/defaults.py.in 2011-05-27 15:36:38 +0000
@@ -0,0 +1,62 @@
1#
2# @file geisview/defaults.py
3# @brief Default values for geisview.
4#
5# Copyright (C) 2011 Canonical Ltd
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21import os
22import gettext
23
24
25root_dir = os.path.dirname(__file__)
26if os.path.exists(os.path.join(root_dir, "Makefile.am")):
27 # running in source directory
28 data_dir = root_dir
29 locale_dir = os.path.join(data_dir, "locale")
30 ui_dir = data_dir
31else:
32 # running from installed
33 data_dir = os.path.join("@shareddir@")
34 locale_dir = os.path.join(data_dir, "locale")
35 ui_dir = data_dir
36
37
38i18n_domain = "geisview"
39gettext.bindtextdomain(i18n_domain, locale_dir)
40gettext.textdomain(i18n_domain)
41from gettext import gettext as _
42
43version = "1.0"
44appname = _("GEIS Viewer")
45appname_short = _("geisview")
46copyright = 'Copyright 2011 Canonical, Ltd.'
47description = _("A GEIS data viewer.\n\nGEIS Viewer is a part of "
48 "the Canonical uTouch gesture recognition stack.")
49authors = ["Stephen M. Webb <stephen.webb@canonical.com"]
50
51LICENSE = _("%s is free software; you can redistribute it and/or modify "
52 "it under the terms of the GNU General Public License as published by "
53 "the Free Software Foundation; either version 2 of the License, or "
54 "(at your option) any later version.\n\n").replace("%s", appname),
55_("%s is distributed in the hope that it will be useful, "
56 "but WITHOUT ANY WARRANTY; without even the implied warranty of "
57 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
58 "GNU General Public License for more details.\n\n").replace("%s", appname),
59_("You should have received a copy of the GNU General Public License "
60 "along with this program. If not, see <http://www.gnu.org/licenses/>.")
61
62
063
=== added file 'tools/geisview/deviceview.py'
--- tools/geisview/deviceview.py 1970-01-01 00:00:00 +0000
+++ tools/geisview/deviceview.py 2011-05-27 15:36:38 +0000
@@ -0,0 +1,46 @@
1#
2# @file geisview/deviceview.py
3# @brief Device viewer for geisview.
4#
5# Copyright (C) 2011 Canonical Ltd
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21import pygtk
22pygtk.require('2.0')
23import gtk
24
25class DeviceView(gtk.Window):
26
27 def __init__(self, devices):
28 gtk.Window.__init__(self)
29 self.set_title("GEIS Devices")
30 self.set_size_request(200, 200)
31
32 self._devices = devices
33 self._tree_store = gtk.TreeStore(str)
34 for device in devices:
35 it = self._tree_store.append(None, ["%s" % device])
36 self._tree_view = gtk.TreeView(self._tree_store)
37 self._tree_view.set_mode(gtk.SELECTION_SINGLE)
38 cell = gtk.CellRendererText()
39 col = gtk.TreeViewColumn('Label')
40 col.pack_start(cell, True)
41 col.add_attribute(cell, 'text', 0)
42 self._tree_view.append_column(col)
43
44 self.add(self._tree_view)
45 self.show_all()
46
047
=== added file 'tools/geisview/filter_definition.py'
--- tools/geisview/filter_definition.py 1970-01-01 00:00:00 +0000
+++ tools/geisview/filter_definition.py 2011-05-27 15:36:38 +0000
@@ -0,0 +1,135 @@
1#
2# @file geisview/filter_definition.py
3# @brief A GEIS filter definition dialog
4#
5# Copyright (C) 2011 Canonical Ltd
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21import geis
22import geisview.defaults
23import os
24import pygtk
25pygtk.require("2.0")
26import gtk
27
28# A list of filter facilities to choose from
29geis_filter_facilities = ('GEIS_FILTER_REGION',
30 'GEIS_FILTER_DEVICE',
31 'GEIS_FILTER_CLASS')
32
33geis_region_terms = ('GEIS_REGION_ATTRIBUTE_WINDOWID')
34
35geis_device_terms = ('GEIS_DEVICE_ATTRIBUTE_ID',
36 'GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH')
37
38geis_gesture_terms = ('GEIS_GESTURE_ATTRIBUTE_TOUCHES',
39 'GEIS_CLASS_ATTRIBUTE_NAME')
40
41geis_term_op = {'GEIS_FILTER_OP_EQ': '==',
42 'GEIS_FILTER_OP_NE': '!=',
43 'GEIS_FILTER_OP_GT': '>',
44 'GEIS_FILTER_OP_GE': '>=',
45 'GEIS_FILTER_OP_LT': '<',
46 'GEIS_FILTER_OP_LE': '<='}
47
48facility_combo_name_col = 0
49facility_combo_value_col = 1
50
51
52def populate_term_op(store):
53 for (name, symbol) in geis_term_op:
54 row = store.append()
55 store.set(row, symbol, geis.__dict__[name])
56
57
58class FilterDefinition(object):
59
60 def __init__(self):
61 print "FilterDefinition.__init__() begins"
62 builder = gtk.Builder()
63 builder.add_from_file(os.path.join(geisview.defaults.ui_dir,
64 "filter_definition.ui"))
65 builder.connect_signals(self)
66
67 # prime the name field
68 self._dialog = builder.get_object("filter_definition");
69 self._name_entry = builder.get_object("name_entry");
70
71 # prime the facility combo
72 self._facility_store = builder.get_object("facility_store");
73 for fac in geis_filter_facilities:
74 row = self._facility_store.append()
75 self._facility_store.set(row,
76 facility_combo_name_col, fac,
77 facility_combo_value_col, geis.__dict__[fac])
78 self._facility_combo = builder.get_object("facility_combo");
79 self._facility_combo.set_active(0)
80
81 # prime the filter terms
82 self._term_list_view = builder.get_object("term_list_view");
83 self._term_list_store = builder.get_object("term_list_store")
84
85 self._ok_button = builder.get_object("ok_button");
86 self._dialog.show_all()
87 print "FilterDefinition.__init__() ends"
88
89 def run(self):
90 print "FilterDefinition.run() begins"
91 response = self._dialog.run()
92 if (response):
93 name = self._name_entry.get_text()
94 print "FilterDefinition.run() name=%s" % name
95 print "FilterDefinition.run() facility=%s" % self._facility_store[self._facility_combo.get_active()][facility_combo_value_col]
96 self._dialog.destroy()
97 print "FilterDefinition.run() ends, response=%s" % response
98
99 def on_name_changed(self, widget, data=None):
100 name = self._name_entry.get_text()
101 if len(name) > 0:
102 self._ok_button.set_sensitive(True)
103 else:
104 self._ok_button.set_sensitive(False)
105
106 def on_add_term(self, widget, data=None):
107 print "FilterDefinition.on_add_term()"
108 row = self._term_list_store.append()
109 self._term_list_store.set(row,
110 0, "<attr name>",
111 1, "==",
112 2, "<value>")
113
114 def on_edit_term(self, widget, data=None):
115 print "FilterDefinition.on_edit_term()"
116
117 def on_remove_term(self, widget, data=None):
118 print "FilterDefinition.on_remove_term()"
119
120 def on_term_attr_editing_started(self, widget, entry, path, data=None):
121 print "FilterDefinition.on_term_attr_editing_started()"
122 choices = gtk.ListStore(str, str)
123 for c in geis_gesture_terms:
124 choices.append([c, geis.__dict__[c]])
125 completion = gtk.EntryCompletion()
126 completion.set_model(choices)
127 completion.set_text_column(0)
128 completion.set_inline_completion(True)
129 completion.set_popup_completion(False)
130 entry.set_completion(completion)
131 entry.set_text("")
132
133 def on_term_op_edited(self, widget, path, new_text, data=None):
134 print "FilterDefinition.on_term_op_edited(%s, %s, %s)" % (widget, path, new_text)
135
0136
=== added file 'tools/geisview/filter_definition.ui'
--- tools/geisview/filter_definition.ui 1970-01-01 00:00:00 +0000
+++ tools/geisview/filter_definition.ui 2011-05-27 15:36:38 +0000
@@ -0,0 +1,329 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<interface>
3 <requires lib="gtk+" version="2.24"/>
4 <!-- interface-naming-policy project-wide -->
5 <object class="GtkListStore" id="facility_store">
6 <columns>
7 <!-- column-name name -->
8 <column type="gchararray"/>
9 <!-- column-name value -->
10 <column type="gint"/>
11 </columns>
12 </object>
13 <object class="GtkDialog" id="filter_definition">
14 <property name="can_focus">False</property>
15 <property name="border_width">5</property>
16 <property name="modal">True</property>
17 <property name="window_position">center-on-parent</property>
18 <property name="default_width">320</property>
19 <property name="default_height">260</property>
20 <property name="destroy_with_parent">True</property>
21 <property name="type_hint">dialog</property>
22 <child internal-child="vbox">
23 <object class="GtkVBox" id="dialog-vbox1">
24 <property name="visible">True</property>
25 <property name="can_focus">False</property>
26 <property name="spacing">2</property>
27 <child internal-child="action_area">
28 <object class="GtkHButtonBox" id="dialog-action_area1">
29 <property name="visible">True</property>
30 <property name="can_focus">False</property>
31 <property name="layout_style">end</property>
32 <child>
33 <object class="GtkButton" id="cancel">
34 <property name="label">gtk-cancel</property>
35 <property name="visible">True</property>
36 <property name="can_focus">True</property>
37 <property name="receives_default">True</property>
38 <property name="use_action_appearance">False</property>
39 <property name="use_stock">True</property>
40 </object>
41 <packing>
42 <property name="expand">False</property>
43 <property name="fill">False</property>
44 <property name="position">0</property>
45 </packing>
46 </child>
47 <child>
48 <object class="GtkButton" id="ok_button">
49 <property name="label">gtk-ok</property>
50 <property name="visible">True</property>
51 <property name="sensitive">False</property>
52 <property name="can_focus">True</property>
53 <property name="can_default">True</property>
54 <property name="has_default">True</property>
55 <property name="receives_default">True</property>
56 <property name="use_action_appearance">False</property>
57 <property name="use_stock">True</property>
58 </object>
59 <packing>
60 <property name="expand">False</property>
61 <property name="fill">False</property>
62 <property name="position">1</property>
63 </packing>
64 </child>
65 </object>
66 <packing>
67 <property name="expand">False</property>
68 <property name="fill">True</property>
69 <property name="pack_type">end</property>
70 <property name="position">0</property>
71 </packing>
72 </child>
73 <child>
74 <object class="GtkTable" id="table1">
75 <property name="visible">True</property>
76 <property name="can_focus">False</property>
77 <property name="n_rows">2</property>
78 <property name="n_columns">2</property>
79 <child>
80 <object class="GtkLabel" id="label2">
81 <property name="visible">True</property>
82 <property name="can_focus">False</property>
83 <property name="xalign">0</property>
84 <property name="label" translatable="yes">Filter _Name:</property>
85 <property name="use_underline">True</property>
86 </object>
87 <packing>
88 <property name="x_options">GTK_FILL</property>
89 <property name="x_padding">6</property>
90 </packing>
91 </child>
92 <child>
93 <object class="GtkLabel" id="label3">
94 <property name="visible">True</property>
95 <property name="can_focus">False</property>
96 <property name="xalign">0</property>
97 <property name="label" translatable="yes">Filter _Facility:</property>
98 <property name="use_underline">True</property>
99 </object>
100 <packing>
101 <property name="top_attach">1</property>
102 <property name="bottom_attach">2</property>
103 <property name="x_options">GTK_FILL</property>
104 <property name="x_padding">6</property>
105 </packing>
106 </child>
107 <child>
108 <object class="GtkEntry" id="name_entry">
109 <property name="visible">True</property>
110 <property name="can_focus">True</property>
111 <property name="invisible_char">•</property>
112 <signal name="changed" handler="on_name_changed" swapped="no"/>
113 </object>
114 <packing>
115 <property name="left_attach">1</property>
116 <property name="right_attach">2</property>
117 <property name="y_options"></property>
118 </packing>
119 </child>
120 <child>
121 <object class="GtkComboBox" id="facility_combo">
122 <property name="visible">True</property>
123 <property name="can_focus">True</property>
124 <property name="model">facility_store</property>
125 <property name="active">0</property>
126 <child>
127 <object class="GtkCellRendererText" id="name"/>
128 <attributes>
129 <attribute name="text">0</attribute>
130 </attributes>
131 </child>
132 </object>
133 <packing>
134 <property name="left_attach">1</property>
135 <property name="right_attach">2</property>
136 <property name="top_attach">1</property>
137 <property name="bottom_attach">2</property>
138 <property name="y_options"></property>
139 </packing>
140 </child>
141 </object>
142 <packing>
143 <property name="expand">False</property>
144 <property name="fill">False</property>
145 <property name="position">1</property>
146 </packing>
147 </child>
148 <child>
149 <object class="GtkVBox" id="vbox1">
150 <property name="visible">True</property>
151 <property name="can_focus">False</property>
152 <child>
153 <object class="GtkLabel" id="label1">
154 <property name="visible">True</property>
155 <property name="can_focus">False</property>
156 <property name="xalign">0</property>
157 <property name="label" translatable="yes">Filter _Terms:</property>
158 <property name="use_underline">True</property>
159 </object>
160 <packing>
161 <property name="expand">False</property>
162 <property name="fill">True</property>
163 <property name="padding">6</property>
164 <property name="position">0</property>
165 </packing>
166 </child>
167 <child>
168 <object class="GtkHBox" id="hbox1">
169 <property name="visible">True</property>
170 <property name="can_focus">False</property>
171 <child>
172 <object class="GtkScrolledWindow" id="scrolledwindow1">
173 <property name="visible">True</property>
174 <property name="can_focus">True</property>
175 <property name="hscrollbar_policy">automatic</property>
176 <property name="vscrollbar_policy">automatic</property>
177 <property name="shadow_type">etched-in</property>
178 <child>
179 <object class="GtkTreeView" id="term_list_view">
180 <property name="visible">True</property>
181 <property name="can_focus">True</property>
182 <property name="model">term_list_store</property>
183 <child>
184 <object class="GtkTreeViewColumn" id="attr">
185 <property name="title" translatable="yes">Attribute</property>
186 <property name="clickable">True</property>
187 <child>
188 <object class="GtkCellRendererText" id="term_attr">
189 <property name="editable">True</property>
190 <signal name="editing-started" handler="on_term_attr_editing_started" swapped="no"/>
191 </object>
192 <attributes>
193 <attribute name="text">0</attribute>
194 </attributes>
195 </child>
196 </object>
197 </child>
198 <child>
199 <object class="GtkTreeViewColumn" id="op">
200 <property name="title" translatable="yes">Operator</property>
201 <property name="clickable">True</property>
202 <child>
203 <object class="GtkCellRendererCombo" id="term_op">
204 <property name="editable">True</property>
205 </object>
206 <attributes>
207 <attribute name="text">1</attribute>
208 <attribute name="model">1</attribute>
209 </attributes>
210 </child>
211 </object>
212 </child>
213 <child>
214 <object class="GtkTreeViewColumn" id="value">
215 <property name="title" translatable="yes">Value</property>
216 <property name="clickable">True</property>
217 <child>
218 <object class="GtkCellRendererText" id="term_value">
219 <property name="editable">True</property>
220 </object>
221 <attributes>
222 <attribute name="text">2</attribute>
223 </attributes>
224 </child>
225 </object>
226 </child>
227 </object>
228 </child>
229 </object>
230 <packing>
231 <property name="expand">True</property>
232 <property name="fill">True</property>
233 <property name="position">0</property>
234 </packing>
235 </child>
236 <child>
237 <object class="GtkVButtonBox" id="vbuttonbox1">
238 <property name="visible">True</property>
239 <property name="can_focus">False</property>
240 <property name="layout_style">start</property>
241 <child>
242 <object class="GtkButton" id="add_term">
243 <property name="label">gtk-add</property>
244 <property name="visible">True</property>
245 <property name="can_focus">True</property>
246 <property name="receives_default">True</property>
247 <property name="use_action_appearance">False</property>
248 <property name="use_stock">True</property>
249 <signal name="clicked" handler="on_add_term" swapped="no"/>
250 </object>
251 <packing>
252 <property name="expand">False</property>
253 <property name="fill">False</property>
254 <property name="position">0</property>
255 </packing>
256 </child>
257 <child>
258 <object class="GtkButton" id="edit_term">
259 <property name="label">gtk-edit</property>
260 <property name="visible">True</property>
261 <property name="can_focus">True</property>
262 <property name="receives_default">True</property>
263 <property name="use_action_appearance">False</property>
264 <property name="use_stock">True</property>
265 <signal name="clicked" handler="on_edit_term" swapped="no"/>
266 </object>
267 <packing>
268 <property name="expand">False</property>
269 <property name="fill">False</property>
270 <property name="position">1</property>
271 </packing>
272 </child>
273 <child>
274 <object class="GtkButton" id="remove_term">
275 <property name="label">gtk-remove</property>
276 <property name="visible">True</property>
277 <property name="can_focus">True</property>
278 <property name="receives_default">True</property>
279 <property name="use_action_appearance">False</property>
280 <property name="use_stock">True</property>
281 <signal name="clicked" handler="on_remove_term" swapped="no"/>
282 </object>
283 <packing>
284 <property name="expand">False</property>
285 <property name="fill">False</property>
286 <property name="position">2</property>
287 </packing>
288 </child>
289 </object>
290 <packing>
291 <property name="expand">False</property>
292 <property name="fill">True</property>
293 <property name="padding">6</property>
294 <property name="position">1</property>
295 </packing>
296 </child>
297 </object>
298 <packing>
299 <property name="expand">True</property>
300 <property name="fill">True</property>
301 <property name="position">1</property>
302 </packing>
303 </child>
304 </object>
305 <packing>
306 <property name="expand">True</property>
307 <property name="fill">True</property>
308 <property name="padding">6</property>
309 <property name="position">2</property>
310 </packing>
311 </child>
312 </object>
313 </child>
314 <action-widgets>
315 <action-widget response="0">cancel</action-widget>
316 <action-widget response="1">ok_button</action-widget>
317 </action-widgets>
318 </object>
319 <object class="GtkListStore" id="term_list_store">
320 <columns>
321 <!-- column-name attr_name -->
322 <column type="gchararray"/>
323 <!-- column-name op -->
324 <column type="gchararray"/>
325 <!-- column-name value -->
326 <column type="gchararray"/>
327 </columns>
328 </object>
329</interface>
0330
=== added file 'tools/geisview/filter_list.py'
--- tools/geisview/filter_list.py 1970-01-01 00:00:00 +0000
+++ tools/geisview/filter_list.py 2011-05-27 15:36:38 +0000
@@ -0,0 +1,59 @@
1#
2# @file geisview/filter_list.py
3# @brief A geisview filter list dialog
4#
5# Copyright (C) 2011 Canonical Ltd
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21import geisview.defaults
22import geisview.filter_definition
23import os
24import pygtk
25pygtk.require("2.0")
26import gtk
27
28class FilterList(object):
29
30 def __init__(self):
31 self._builder = gtk.Builder()
32 self._builder.add_from_file(os.path.join(geisview.defaults.ui_dir,
33 "filter_list.ui"))
34 self._builder.connect_signals(self)
35
36 self._dialog = self._builder.get_object("filter_list");
37 self._name_entry = self._builder.get_object("name_entry");
38 self._facility_combo = self._builder.get_object("facility_combo");
39 self._filter_list_store = self._builder.get_object("filter_list_store")
40
41 self._dialog.show_all()
42
43 def run(self):
44 print "FilterList.run() begins"
45 response = self._dialog.run()
46 self._dialog.destroy()
47 print "FilterList.run() ends, response=%s" % response
48
49 def on_add_filter(self, widget, data=None):
50 print "FilterList.on_add_filter()"
51 dlg = geisview.filter_definition.FilterDefinition()
52 dlg.run()
53
54 def on_edit_filter(self, widget, data=None):
55 print "FilterList.on_edit_filter()"
56
57 def on_remove_filter(self, widget, data=None):
58 print "FilterList.on_remove_filter()"
59
060
=== added file 'tools/geisview/filter_list.ui'
--- tools/geisview/filter_list.ui 1970-01-01 00:00:00 +0000
+++ tools/geisview/filter_list.ui 2011-05-27 15:36:38 +0000
@@ -0,0 +1,174 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<interface>
3 <requires lib="gtk+" version="2.24"/>
4 <!-- interface-naming-policy project-wide -->
5 <object class="GtkDialog" id="filter_list">
6 <property name="can_focus">False</property>
7 <property name="border_width">5</property>
8 <property name="title" translatable="yes">GEIS Filters</property>
9 <property name="modal">True</property>
10 <property name="window_position">center-on-parent</property>
11 <property name="destroy_with_parent">True</property>
12 <property name="type_hint">dialog</property>
13 <child internal-child="vbox">
14 <object class="GtkVBox" id="dialog-vbox1">
15 <property name="visible">True</property>
16 <property name="can_focus">False</property>
17 <child internal-child="action_area">
18 <object class="GtkHButtonBox" id="dialog-action_area1">
19 <property name="visible">True</property>
20 <property name="can_focus">False</property>
21 <property name="layout_style">end</property>
22 <child>
23 <object class="GtkButton" id="cancel">
24 <property name="label">gtk-cancel</property>
25 <property name="visible">True</property>
26 <property name="can_focus">True</property>
27 <property name="receives_default">True</property>
28 <property name="use_action_appearance">False</property>
29 <property name="use_stock">True</property>
30 </object>
31 <packing>
32 <property name="expand">False</property>
33 <property name="fill">False</property>
34 <property name="position">0</property>
35 </packing>
36 </child>
37 <child>
38 <object class="GtkButton" id="ok">
39 <property name="label">gtk-ok</property>
40 <property name="visible">True</property>
41 <property name="can_focus">True</property>
42 <property name="can_default">True</property>
43 <property name="has_default">True</property>
44 <property name="receives_default">True</property>
45 <property name="use_action_appearance">False</property>
46 <property name="use_stock">True</property>
47 </object>
48 <packing>
49 <property name="expand">False</property>
50 <property name="fill">False</property>
51 <property name="position">1</property>
52 </packing>
53 </child>
54 </object>
55 <packing>
56 <property name="expand">False</property>
57 <property name="fill">True</property>
58 <property name="pack_type">end</property>
59 <property name="position">0</property>
60 </packing>
61 </child>
62 <child>
63 <object class="GtkHBox" id="hbox1">
64 <property name="visible">True</property>
65 <property name="can_focus">False</property>
66 <property name="spacing">3</property>
67 <child>
68 <object class="GtkScrolledWindow" id="scrolledwindow1">
69 <property name="visible">True</property>
70 <property name="can_focus">True</property>
71 <property name="hscrollbar_policy">automatic</property>
72 <property name="vscrollbar_policy">automatic</property>
73 <property name="shadow_type">etched-in</property>
74 <child>
75 <object class="GtkTreeView" id="filter_list_view">
76 <property name="visible">True</property>
77 <property name="can_focus">True</property>
78 <property name="headers_visible">False</property>
79 <property name="headers_clickable">False</property>
80 </object>
81 </child>
82 </object>
83 <packing>
84 <property name="expand">True</property>
85 <property name="fill">True</property>
86 <property name="position">0</property>
87 </packing>
88 </child>
89 <child>
90 <object class="GtkVButtonBox" id="vbuttonbox1">
91 <property name="visible">True</property>
92 <property name="can_focus">False</property>
93 <property name="spacing">3</property>
94 <property name="layout_style">start</property>
95 <child>
96 <object class="GtkButton" id="add_filter">
97 <property name="label">gtk-add</property>
98 <property name="visible">True</property>
99 <property name="can_focus">True</property>
100 <property name="receives_default">True</property>
101 <property name="use_action_appearance">False</property>
102 <property name="use_stock">True</property>
103 <signal name="clicked" handler="on_add_filter" swapped="no"/>
104 </object>
105 <packing>
106 <property name="expand">False</property>
107 <property name="fill">False</property>
108 <property name="position">0</property>
109 </packing>
110 </child>
111 <child>
112 <object class="GtkButton" id="edit_filter">
113 <property name="label">gtk-edit</property>
114 <property name="visible">True</property>
115 <property name="can_focus">True</property>
116 <property name="receives_default">True</property>
117 <property name="use_action_appearance">False</property>
118 <property name="use_stock">True</property>
119 <signal name="clicked" handler="on_edit_filter" swapped="no"/>
120 </object>
121 <packing>
122 <property name="expand">False</property>
123 <property name="fill">False</property>
124 <property name="position">1</property>
125 </packing>
126 </child>
127 <child>
128 <object class="GtkButton" id="remove_filter">
129 <property name="label">gtk-remove</property>
130 <property name="visible">True</property>
131 <property name="can_focus">True</property>
132 <property name="receives_default">True</property>
133 <property name="use_action_appearance">False</property>
134 <property name="use_stock">True</property>
135 <signal name="clicked" handler="on_remove_filter" swapped="no"/>
136 </object>
137 <packing>
138 <property name="expand">False</property>
139 <property name="fill">False</property>
140 <property name="position">2</property>
141 </packing>
142 </child>
143 </object>
144 <packing>
145 <property name="expand">False</property>
146 <property name="fill">True</property>
147 <property name="padding">6</property>
148 <property name="position">1</property>
149 </packing>
150 </child>
151 </object>
152 <packing>
153 <property name="expand">True</property>
154 <property name="fill">True</property>
155 <property name="position">1</property>
156 </packing>
157 </child>
158 <child>
159 <placeholder/>
160 </child>
161 </object>
162 </child>
163 <action-widgets>
164 <action-widget response="0">cancel</action-widget>
165 <action-widget response="1">ok</action-widget>
166 </action-widgets>
167 </object>
168 <object class="GtkListStore" id="filter_list_model">
169 <columns>
170 <!-- column-name name -->
171 <column type="gchararray"/>
172 </columns>
173 </object>
174</interface>
0175
=== added file 'tools/geisview/geisview'
--- tools/geisview/geisview 1970-01-01 00:00:00 +0000
+++ tools/geisview/geisview 2011-05-27 15:36:38 +0000
@@ -0,0 +1,250 @@
1#!/usr/bin/python
2#
3# @file geisview
4# @brief A viewer for raw GEIS data.
5#
6# This program is a handy diagnostic tool for viewing the raw data produced
7# through the GEIS multi-touch and gesture interface.
8#
9# Copyright (C) 2011 Canonical Ltd
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 3 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program. If not, see <http://www.gnu.org/licenses/>.
23#
24
25import argparse
26import geis
27import geisview.defaults
28import geisview.deviceview
29import geisview.filter_list
30from gettext import gettext as _
31import glib
32import os
33import sys
34
35import pygtk
36pygtk.require("2.0")
37import gtk
38
39
40
41class GeisViewer(object):
42 """Provides a GUI client to display raw GEIS data.
43 """
44
45 def __init__(self):
46 self._builder = gtk.Builder()
47 self._builder.add_from_file(os.path.join(geisview.defaults.ui_dir,
48 "geisview.ui"))
49 self._builder.connect_signals(self)
50
51 self._main_window = self._builder.get_object("main_window")
52 self._filters_dialog = self._builder.get_object("filters_dialog")
53
54 self._geis = geis.Geis(geis.GEIS_INIT_TRACK_DEVICES,
55 geis.GEIS_INIT_TRACK_GESTURE_CLASSES)
56 self._geis_event_store = self._builder.get_object("geis_event_store")
57
58 geis_fd = self._geis.get_configuration(geis.GEIS_CONFIGURATION_FD)
59 glib.io_add_watch(geis_fd, glib.IO_IN, self._dispatch_geis_events)
60
61 self._devices = {}
62
63 self._sub = geis.Subscription(self._geis)
64
65 self._main_window.show()
66
67 def gtk_main_quit(self, widget, data=None):
68 gtk.main_quit()
69
70 def on_menu_item_save(self, widget, data=None):
71 print "on_menu_item_save"
72
73 def on_menu_item_save_as(self, widget, data=None):
74 print "on_menu_item_save_as"
75
76 def on_edit_clear_events_menu_item(self, widget, data=None):
77 self._geis_event_store.clear()
78
79 def on_edit_filters_menu_item_activate(self, widget, data=None):
80 print "on_edit_filters_menu_item_activate"
81 filter_list_dialog = geisview.filter_list.FilterList()
82 filter_list_dialog.run()
83
84 def on_view_device_menu_item_activate(self, widget, data=None):
85 device_view = geisview.deviceview.DeviceView(self._devices)
86
87 def on_menu_item_about(self, widget, data=None):
88 about = gtk.AboutDialog()
89 about.set_transient_for(self._main_window)
90 about.set_name(geisview.defaults.appname)
91 about.set_version(geisview.defaults.version)
92 about.set_copyright(geisview.defaults.copyright)
93 about.set_license(geisview.defaults.license)
94 about.set_wrap_license(True)
95 about.set_comments(geisview.defaults.description)
96 about.set_authors(geisview.defaults.authors)
97 about.set_logo_icon_name("geisview")
98 about.set_translator_credits(geisview.defaults.translator_credit)
99 about.connect("response", lambda d, r: d.destroy())
100 about.show()
101
102 def _detail_touches(self, event_row, touchset):
103 count_label = _("touches: %i") % len(touchset)
104 slot_label = _("touch slot %i")
105 touch_row = self._geis_event_store.append(event_row)
106 self._geis_event_store.set(touch_row, 0, count_label)
107 for touch in touchset:
108 slot_row = self._geis_event_store.append(touch_row)
109 self._geis_event_store.set(slot_row, 0, slot_label % touch.id())
110 for (k, v) in touch.attrs().iteritems():
111 attr_row = self._geis_event_store.append(slot_row)
112 self._geis_event_store.set(attr_row, 0, "%s: %s" % (k, v))
113
114 def _detail_frame(self, group_row, frame):
115 """Extracts and display the details of a gesture frame.
116 """
117 frame_label = _("frame: %i") % frame.id()
118 touch_label = _("touch indexes %s") % frame.touches()
119
120 dev = None
121
122 frame_row = self._geis_event_store.append(group_row)
123 self._geis_event_store.set(frame_row, 0, frame_label)
124 for (k, v) in frame.attrs().iteritems():
125 row = self._geis_event_store.append(frame_row)
126 self._geis_event_store.set(row, 0, "%s: %s" % (k, v))
127 if k == geis.GEIS_GESTURE_ATTRIBUTE_DEVICE_ID and v in self._devices:
128 dev = self._devices[v]
129 self._geis_event_store.append(frame_row, [touch_label, None, None])
130
131 if dev:
132 print "device %s extents %s" % (dev.id(), dev.extents())
133
134
135 def _detail_gesture(self, event_row, attrs):
136 touchset = attrs[geis.GEIS_EVENT_ATTRIBUTE_TOUCHSET]
137 groupset = attrs[geis.GEIS_EVENT_ATTRIBUTE_GROUPSET]
138 self._detail_touches(event_row, touchset)
139 count_label = _("groups: %i") % len(touchset)
140 group_label = _("group %i")
141 it = self._geis_event_store.append(event_row, [count_label, None, None])
142 for group in groupset:
143 group_row = self._geis_event_store.append(it,
144 [group_label % group.id(), None, None])
145 for frame in group:
146 self._detail_frame(group_row, frame)
147
148 def _detail_gesture_class(self, event_row, gesture_class):
149 for (k, v) in gesture_class.attrs().iteritems():
150 row = self._geis_event_store.append(event_row)
151 self._geis_event_store.set(row, 0, "%s: %s" % (k, v))
152
153 def _detail_device(self, event_row, device):
154 for (k, v) in device.attrs().iteritems():
155 row = self._geis_event_store.append(event_row)
156 self._geis_event_store.set(row, 0, "%s: %s" % (k, v))
157
158 def _do_gesture_begin(self, event):
159 it = self._geis_event_store.append(None)
160 self._geis_event_store.set(it, 0, _("Gesture Begin"))
161 self._detail_gesture(it, event.attrs())
162
163 def _do_gesture_update(self, event):
164 it = self._geis_event_store.append(None)
165 self._geis_event_store.set(it, 0, _("Gesture Update"))
166 self._detail_gesture(it, event.attrs())
167
168 def _do_gesture_end(self, event):
169 it = self._geis_event_store.append(None)
170 self._geis_event_store.set(it, 0, _("Gesture End"))
171 self._detail_gesture(it, event.attrs())
172
173 def _do_class_added(self, event):
174 gclass = event.attrs()[geis.GEIS_EVENT_ATTRIBUTE_CLASS]
175 it = self._geis_event_store.append(None)
176 self._geis_event_store.set(it,
177 0, _("Class %s Added: %s") % (gclass.id(), gclass.name()))
178 self._detail_gesture_class(it, gclass)
179
180 def _do_device_added(self, event):
181 device = event.attrs()[geis.GEIS_EVENT_ATTRIBUTE_DEVICE]
182 self._devices[device.id()] = device
183 it = self._geis_event_store.append(None)
184 self._geis_event_store.set(it,
185 0, _("Device %s Added: %s") % (device.id(), device.name()))
186 self._detail_device(it, device)
187
188 def _do_init_complete(self, event):
189 it = self._geis_event_store.append(None)
190 self._geis_event_store.set(it,
191 0, _("GEIS initialization complete"))
192 f = geis.Filter(self._geis, "filter")
193 f.add_term(geis.GEIS_FILTER_CLASS,
194 (geis.GEIS_GESTURE_ATTRIBUTE_TOUCHES, geis.GEIS_FILTER_OP_GE, 2))
195 self._sub.add_filter(f)
196 self._sub.activate()
197
198 def _do_other_event(self, event):
199 event_label = _("Unknown Event")
200 it = self._geis_event_store.append(None, [event_label, None, None])
201
202 def _dispatch_geis_events(self, fd, condition):
203 """ Performs GEIS event loop processing. """
204 _geis_event_action = {
205 geis.GEIS_EVENT_GESTURE_BEGIN: self._do_gesture_begin,
206 geis.GEIS_EVENT_GESTURE_UPDATE: self._do_gesture_update,
207 geis.GEIS_EVENT_GESTURE_END: self._do_gesture_end,
208 geis.GEIS_EVENT_CLASS_AVAILABLE: self._do_class_added,
209 geis.GEIS_EVENT_DEVICE_AVAILABLE: self._do_device_added,
210 geis.GEIS_EVENT_INIT_COMPLETE: self._do_init_complete
211 }
212
213 status = self._geis.dispatch_events()
214 while status == geis.GEIS_STATUS_CONTINUE:
215 status = self._geis.dispatch_events()
216
217 try:
218 while True:
219 event = self._geis.next_event()
220 _geis_event_action.get(event.type(), self._do_other_event)(event)
221 except geis.NoMoreEvents:
222 pass
223 return True
224
225
226
227class Options(argparse.ArgumentParser):
228 """Handles the geisviewer command-line arguments.
229 """
230
231 def __init__(self):
232 argparse.ArgumentParser.__init__(self,
233 description="monitor uTouch gestures")
234 self.add_argument('-V', '--version', action='version', version='1.0')
235
236
237def main():
238 options = Options()
239 try:
240 options.parse_args()
241 except argparse.ArgumentError, ex:
242 print ex
243 sys.exit(1)
244
245 geis_viewer = GeisViewer()
246 gtk.main()
247
248
249if __name__ == '__main__':
250 main()
0251
=== added file 'tools/geisview/geisview.ui'
--- tools/geisview/geisview.ui 1970-01-01 00:00:00 +0000
+++ tools/geisview/geisview.ui 2011-05-27 15:36:38 +0000
@@ -0,0 +1,333 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<interface>
3 <requires lib="gtk+" version="2.24"/>
4 <!-- interface-naming-policy project-wide -->
5 <object class="GtkListStore" id="geis_event_detail">
6 <columns>
7 <!-- column-name label -->
8 <column type="gchararray"/>
9 <!-- column-name value -->
10 <column type="gchararray"/>
11 </columns>
12 </object>
13 <object class="GtkTreeStore" id="geis_event_store">
14 <columns>
15 <!-- column-name event_type -->
16 <column type="gchararray"/>
17 <!-- column-name value -->
18 <column type="gchararray"/>
19 <!-- column-name data -->
20 <column type="gpointer"/>
21 </columns>
22 </object>
23 <object class="GtkImage" id="image1">
24 <property name="visible">True</property>
25 <property name="can_focus">False</property>
26 <property name="stock">gtk-missing-image</property>
27 </object>
28 <object class="GtkWindow" id="main_window">
29 <property name="can_focus">False</property>
30 <property name="default_width">480</property>
31 <property name="default_height">420</property>
32 <signal name="destroy" handler="gtk_main_quit" swapped="no"/>
33 <child>
34 <object class="GtkVBox" id="vbox1">
35 <property name="visible">True</property>
36 <property name="can_focus">False</property>
37 <child>
38 <object class="GtkMenuBar" id="menubar1">
39 <property name="visible">True</property>
40 <property name="can_focus">False</property>
41 <child>
42 <object class="GtkMenuItem" id="menu_file">
43 <property name="visible">True</property>
44 <property name="can_focus">False</property>
45 <property name="use_action_appearance">False</property>
46 <property name="label" translatable="yes">_File</property>
47 <property name="use_underline">True</property>
48 <child type="submenu">
49 <object class="GtkMenu" id="menu1">
50 <property name="visible">True</property>
51 <property name="can_focus">False</property>
52 <child>
53 <object class="GtkImageMenuItem" id="menu_item_new">
54 <property name="label">gtk-new</property>
55 <property name="visible">True</property>
56 <property name="can_focus">False</property>
57 <property name="use_action_appearance">False</property>
58 <property name="use_underline">True</property>
59 <property name="use_stock">True</property>
60 </object>
61 </child>
62 <child>
63 <object class="GtkImageMenuItem" id="menu_item_open">
64 <property name="label">gtk-open</property>
65 <property name="visible">True</property>
66 <property name="can_focus">False</property>
67 <property name="use_action_appearance">False</property>
68 <property name="use_underline">True</property>
69 <property name="use_stock">True</property>
70 </object>
71 </child>
72 <child>
73 <object class="GtkImageMenuItem" id="menu_item_save">
74 <property name="label">gtk-save</property>
75 <property name="visible">True</property>
76 <property name="can_focus">False</property>
77 <property name="use_action_appearance">False</property>
78 <property name="use_underline">True</property>
79 <property name="use_stock">True</property>
80 <signal name="activate-item" handler="on_menu_item_save" swapped="no"/>
81 </object>
82 </child>
83 <child>
84 <object class="GtkImageMenuItem" id="menu_item_save_as">
85 <property name="label">gtk-save-as</property>
86 <property name="visible">True</property>
87 <property name="can_focus">False</property>
88 <property name="use_action_appearance">False</property>
89 <property name="use_underline">True</property>
90 <property name="use_stock">True</property>
91 <signal name="activate-item" handler="on_menu_item_save_as" swapped="no"/>
92 </object>
93 </child>
94 <child>
95 <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
96 <property name="visible">True</property>
97 <property name="can_focus">False</property>
98 <property name="use_action_appearance">False</property>
99 </object>
100 </child>
101 <child>
102 <object class="GtkImageMenuItem" id="quit_menu_item">
103 <property name="label">gtk-quit</property>
104 <property name="visible">True</property>
105 <property name="can_focus">False</property>
106 <property name="use_action_appearance">False</property>
107 <property name="use_underline">True</property>
108 <property name="use_stock">True</property>
109 <signal name="activate-item" handler="gtk_main_quit" swapped="no"/>
110 <signal name="activate" handler="gtk_main_quit" swapped="no"/>
111 </object>
112 </child>
113 </object>
114 </child>
115 </object>
116 </child>
117 <child>
118 <object class="GtkMenuItem" id="menu_edit">
119 <property name="visible">True</property>
120 <property name="can_focus">False</property>
121 <property name="use_action_appearance">False</property>
122 <property name="label" translatable="yes">_Edit</property>
123 <property name="use_underline">True</property>
124 <child type="submenu">
125 <object class="GtkMenu" id="menu2">
126 <property name="visible">True</property>
127 <property name="can_focus">False</property>
128 <child>
129 <object class="GtkImageMenuItem" id="menu_item_cut">
130 <property name="label">gtk-cut</property>
131 <property name="visible">True</property>
132 <property name="can_focus">False</property>
133 <property name="use_action_appearance">False</property>
134 <property name="use_underline">True</property>
135 <property name="use_stock">True</property>
136 </object>
137 </child>
138 <child>
139 <object class="GtkImageMenuItem" id="menu_item_copy">
140 <property name="label">gtk-copy</property>
141 <property name="visible">True</property>
142 <property name="can_focus">False</property>
143 <property name="use_action_appearance">False</property>
144 <property name="use_underline">True</property>
145 <property name="use_stock">True</property>
146 </object>
147 </child>
148 <child>
149 <object class="GtkImageMenuItem" id="menu_item_paste">
150 <property name="label">gtk-paste</property>
151 <property name="visible">True</property>
152 <property name="can_focus">False</property>
153 <property name="use_action_appearance">False</property>
154 <property name="use_underline">True</property>
155 <property name="use_stock">True</property>
156 </object>
157 </child>
158 <child>
159 <object class="GtkImageMenuItem" id="menu_item_delete">
160 <property name="label">gtk-delete</property>
161 <property name="visible">True</property>
162 <property name="can_focus">False</property>
163 <property name="use_action_appearance">False</property>
164 <property name="use_underline">True</property>
165 <property name="use_stock">True</property>
166 </object>
167 </child>
168 <child>
169 <object class="GtkMenuItem" id="edit_clear_events_menu_item">
170 <property name="visible">True</property>
171 <property name="can_focus">False</property>
172 <property name="use_action_appearance">False</property>
173 <property name="label" translatable="yes">Clear Events</property>
174 <property name="use_underline">True</property>
175 <signal name="activate" handler="on_edit_clear_events_menu_item" swapped="no"/>
176 </object>
177 </child>
178 <child>
179 <object class="GtkMenuItem" id="edit_filters_menu_item">
180 <property name="visible">True</property>
181 <property name="can_focus">False</property>
182 <property name="use_action_appearance">False</property>
183 <property name="label" translatable="yes">Filters...</property>
184 <property name="use_underline">True</property>
185 <signal name="activate" handler="on_edit_filters_menu_item_activate" swapped="no"/>
186 </object>
187 </child>
188 </object>
189 </child>
190 </object>
191 </child>
192 <child>
193 <object class="GtkMenuItem" id="menu_view">
194 <property name="visible">True</property>
195 <property name="can_focus">False</property>
196 <property name="use_action_appearance">False</property>
197 <property name="label" translatable="yes">_View</property>
198 <property name="use_underline">True</property>
199 <child type="submenu">
200 <object class="GtkMenu" id="menu4">
201 <property name="visible">True</property>
202 <property name="can_focus">False</property>
203 <child>
204 <object class="GtkImageMenuItem" id="view_device_menu_item">
205 <property name="label" translatable="yes">Show _Devices</property>
206 <property name="visible">True</property>
207 <property name="can_focus">False</property>
208 <property name="use_action_appearance">False</property>
209 <property name="use_underline">True</property>
210 <property name="image">image1</property>
211 <property name="use_stock">False</property>
212 <signal name="activate" handler="on_view_device_menu_item_activate" swapped="no"/>
213 </object>
214 </child>
215 </object>
216 </child>
217 </object>
218 </child>
219 <child>
220 <object class="GtkMenuItem" id="menu_help">
221 <property name="visible">True</property>
222 <property name="can_focus">False</property>
223 <property name="use_action_appearance">False</property>
224 <property name="label" translatable="yes">_Help</property>
225 <property name="use_underline">True</property>
226 <child type="submenu">
227 <object class="GtkMenu" id="menu3">
228 <property name="visible">True</property>
229 <property name="can_focus">False</property>
230 <child>
231 <object class="GtkImageMenuItem" id="menu_item_about">
232 <property name="label">gtk-about</property>
233 <property name="visible">True</property>
234 <property name="can_focus">False</property>
235 <property name="use_action_appearance">False</property>
236 <property name="use_underline">True</property>
237 <property name="use_stock">True</property>
238 <signal name="activate-item" handler="gtk_main_quit" swapped="no"/>
239 <signal name="activate" handler="on_menu_item_about" swapped="no"/>
240 </object>
241 </child>
242 </object>
243 </child>
244 </object>
245 </child>
246 </object>
247 <packing>
248 <property name="expand">False</property>
249 <property name="fill">True</property>
250 <property name="position">0</property>
251 </packing>
252 </child>
253 <child>
254 <object class="GtkVPaned" id="vpaned1">
255 <property name="visible">True</property>
256 <property name="can_focus">True</property>
257 <child>
258 <object class="GtkScrolledWindow" id="scrolledwindow1">
259 <property name="visible">True</property>
260 <property name="can_focus">True</property>
261 <property name="hscrollbar_policy">automatic</property>
262 <property name="vscrollbar_policy">automatic</property>
263 <property name="window_placement_set">True</property>
264 <property name="shadow_type">etched-in</property>
265 <child>
266 <object class="GtkTreeView" id="event_treeview">
267 <property name="visible">True</property>
268 <property name="can_focus">True</property>
269 <property name="border_width">1</property>
270 <property name="model">geis_event_store</property>
271 <property name="headers_visible">False</property>
272 <property name="headers_clickable">False</property>
273 <child>
274 <object class="GtkTreeViewColumn" id="label">
275 <property name="title" translatable="yes">column</property>
276 <child>
277 <object class="GtkCellRendererText" id="cellrenderertext1"/>
278 <attributes>
279 <attribute name="text">0</attribute>
280 </attributes>
281 </child>
282 </object>
283 </child>
284 </object>
285 </child>
286 </object>
287 <packing>
288 <property name="resize">False</property>
289 <property name="shrink">True</property>
290 </packing>
291 </child>
292 <child>
293 <object class="GtkScrolledWindow" id="scrolledwindow2">
294 <property name="can_focus">True</property>
295 <property name="hscrollbar_policy">automatic</property>
296 <property name="vscrollbar_policy">automatic</property>
297 <property name="shadow_type">in</property>
298 <child>
299 <object class="GtkTreeView" id="treeview2">
300 <property name="visible">True</property>
301 <property name="can_focus">True</property>
302 <property name="model">geis_event_detail</property>
303 </object>
304 </child>
305 </object>
306 <packing>
307 <property name="resize">True</property>
308 <property name="shrink">True</property>
309 </packing>
310 </child>
311 </object>
312 <packing>
313 <property name="expand">True</property>
314 <property name="fill">True</property>
315 <property name="position">1</property>
316 </packing>
317 </child>
318 <child>
319 <object class="GtkStatusbar" id="statusbar1">
320 <property name="visible">True</property>
321 <property name="can_focus">False</property>
322 <property name="spacing">2</property>
323 </object>
324 <packing>
325 <property name="expand">False</property>
326 <property name="fill">True</property>
327 <property name="position">2</property>
328 </packing>
329 </child>
330 </object>
331 </child>
332 </object>
333</interface>

Subscribers

People subscribed via source and target branches