Status: | Rejected | ||||||||
---|---|---|---|---|---|---|---|---|---|
Rejected by: | Stephen M. Webb | ||||||||
Proposed branch: | lp:~bijanbina/ginn/GIR | ||||||||
Merge into: | lp:ginn | ||||||||
Diff against target: |
2447 lines (+1339/-977) 18 files modified
.directory (+6/-0) configure.ac (+1/-0) src/Makefile.am (+3/-2) src/README (+5/-0) src/bamf.c (+0/-48) src/bamf.cpp (+48/-0) src/config.c (+0/-200) src/config.cpp (+202/-0) src/config.h (+70/-27) src/ginn.c (+0/-592) src/ginn.cpp (+555/-0) src/ginn.h (+60/-0) src/gir.cpp (+47/-0) src/gir.h (+70/-0) src/header.h (+38/-0) src/main.cpp (+137/-0) src/xt.c (+0/-108) src/xt.cpp (+97/-0) |
||||||||
To merge this branch: | bzr merge lp:~bijanbina/ginn/GIR | ||||||||
Related bugs: |
|
||||||||
Related blueprints: |
Sroll gesture with single touch
(Undefined)
GINN Reimplimention
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Chase Douglas (community) | Disapprove | ||
Stephen M. Webb (community) | Needs Fixing | ||
Review via email: mp+72521@code.launchpad.net |
Commit message
Description of the change
1. port GINN to c++
2. use string instead of char *
3. fix all error with c++ compiler
4. create Gwish class instead of wish struct
5. add Gwish Type (geusture Type) instead of config_attr[0] to make code more readable and replace it in all part of code
6. add Gwish TouchNum (Number of finger for gesture) instead of config_attr[1] to make code more readable and replace it to all part of code
5. create GINN object and create a dynamic callback for GINN object
6. use "new" instead of memloc
7. remove all global variable and embed all of them in class
8. create qt project file for ginn
9. use cout and cerr instead of fprintf
10. abstract the main file and create the code more functionally
11. test all new changes and check are they stable or not
12. create constractor for apps and make Gapps object instead it
13. create callback for device add , remove and change with object oriented concept
14. create GD_att struct to save and access device attributes
15. create device list vector
16. find device attribute with just having device ID!(perfectly useful)
17. make code more readable
18. add comment to code and use simple name for variable
19. add some option to wish.xml to define some gesture for only touchscreen
20. add some option to wish.xml to define some gesture for only touchpad
21. compatible fully with last GINN branch
-------
#######
1. open wish.xml
2. find what gesture you want to classify for example you select some thing like this:
<wish gesture="Drag" fingers="2">
<action name="action5" when="update">
<trigger prop="delta y" min="20" max="80"/>
</action>
</wish>
3. change <wish gesture="Drag" fingers="2"> to
<wish gesture="Drag" fingers="2" screen="true">
4. if you want to your gesture run only on touchpad change screen prop to false else now your
gesture only run on touch screen
-------
Bijan Binaee (bijanbina) wrote : | # |
> I have a number of issues with this proposal.
>
> (1) You need to explicitly justify moving from C to C++. In particular,
> renaming all existing C sources to C++. What does the project gain from this?
> What are the possible repercussions (ie. what new problems are introduced and
> what new potential for error is obtained)? The renaming introduces a lot of
> noise that makes it difficult to evaluate the rest of the change.
>
> (2) This merge marks most sources as executable. That is undesirable.
>
> (3) What is the .directory file? It does not appear to be necessary to build
> the project.
>
> (4) Please do not use ///-style or //!-style comments, use Javadoc-style (/**)
> comments for consistency with the style of other uTouch projects.
>
> (5) The various classes implement their own containers. Is there a good
> reason not to use the (tested, dependable) standard library instead? One of
> the main advantages to porting to C++ is the ability to use the C++ library.
>
> (6) None of this code is exception safe. When errors are encountered,
> resources are leaked or undefined behaviour is encountered.
>
> (7) There is no cleanup: objects are created using new but never deleted.
>
> (8) Class constructors are assigning initial values to members in the
> constructor body instead of using initializer lists. Most of the classes are
> C structs that rely on external code to maintain their invariants: what is
> the point of converting to C++ if the code is just non-OO style C? See
> http://
>
> (9) Why add a capital G or D to classes and function names? This does not
> contribute to readability in a positive way. If this is to represent words
> like "device" or "gesture", use those words. We are not experiencing a
> shortage of ASCII.
>
> (10) Some variable names could reflect their purpose better: for example,
> what is "local" used for?
>
> (11) "header.h" is not an acceptable header file name. Also, please do not
> create a single header file to include all other header files any source file
> might need. Headers should pull in only the minimal subset of headers they
> need to compile on their own. Never put a "using namespace" directive in a
> header file.
>
> (12) GINN::Dadded catches an exception of type error_t, but there is no code
> inside the try-block that can throw such a type. The only exception possible
> from the try-block is std::bad_alloc.
>
> (13) Please leave at least one blank line between function definitions for
> readability.
1: if you think renaming is getting you to trouble so i must do what to port to c++
2: No why you think so
3: i remove it if the code accepted
4: the comment is not part of code! please review the code not comment!
5: can you make instance in my code
6: can you make instance in my code
7: it's the c++ advantage unlike C it delete them automatically
8: it's only on some classes and it is because if we change it need to recreate a code fuly again!!
9: if you use a very long function name you made the developer get to pitfall it's the best way to simple the develop process and have various advantage
10: it use to create a local copy ...
Chase Douglas (chasedouglas) wrote : | # |
First, Stephen has noted many issues with the changes. I agree with all of them, so it makes sense to have them fixed before doing any further review of the code.
> 1: if you think renaming is getting you to trouble so i must do what to port
> to c++
It's not the renaming that is the problem. If the renaming provided some benefits it would be acceptable. However, the renaming here is to allow for C++ compilation. Thus, there needs to be worthwhile C++ usage or else we could just leave it as C.
This hits at a big issue with the changes. I don't think you fully understand C++, how to use it properly, and how to make code better and more readable with it. Ginn could benefit greatly from being converted to C++. However, these changes do not make the code better.
> 2: No why you think so
See the preview diff below. There are lines like:
=== modified file 'COPYING' (properties changed: -x to +x)
> 3: i remove it if the code accepted
The way to fix this is to remove it in your branch, commit the change, and then push it to this branch on launchpad.net. That will update the merge proposal.
> 4: the comment is not part of code! please review the code not comment!
Comments are just as important as the code. Style matters in keeping things readable. Thus, we review comments too.
> 5: can you make instance in my code
> 6: can you make instance in my code
These are very basic and fundamental concepts of how to write C++. You are asking us to teach you C++. Unfortunately, we don't have enough time to do that. Instead, please try to learn C++ best practices by reading books or searching online for information.
> 7: it's the c++ advantage unlike C it delete them automatically
No, that is incorrect. You must delete C++ objects created with new.
> 8: it's only on some classes and it is because if we change it need to
> recreate a code fuly again!!
This is part of the fundamental aspects of C++. It needs to conform to normal C++ coding standards.
> 9: if you use a very long function name you made the developer get to pitfall
> it's the best way to simple the develop process and have various advantage
There are many possible ways to name functions, with many different reasons for why they are named a certain way. Normally, you should try to stay consistent with the existing code, and ensure that the names are obvious. Adding 'G' and 'D' to the beginning of function names does not have an obvious meaning.
> 10: it use to create a local copy of ginn object that is load for device .it's
> show the duty fully
You can name it "ginn" or something more descriptive. "local" is too generic for a variable name.
> 11: i like this way;also adding header not make your software slow!
You can add a header, that's not the issue. The issue is that the name of the header is too generic. The name needs to give some idea as to what is defined in the header.
> 12: it's an static error ,add error_t is for just through of the compiler
> error. also use error_t for dynamic error.
I don't think you understand how exceptions work. Please look up C++ exception handling.
> 13: the comment is not part of code! please review the code not comment!
This has nothing t...
Unmerged revisions
- 90. By Bijan Binaee
-
GIR
Preview Diff
1 | === modified file '.bzrignore' (properties changed: -x to +x) |
2 | === added file '.directory' |
3 | --- .directory 1970-01-01 00:00:00 +0000 |
4 | +++ .directory 2011-08-23 04:19:23 +0000 |
5 | @@ -0,0 +1,6 @@ |
6 | +[Dolphin] |
7 | +Timestamp=2011,8,23,8,9,6 |
8 | +Version=2 |
9 | + |
10 | +[Settings] |
11 | +ShowDotFiles=true |
12 | |
13 | === modified file 'COPYING' (properties changed: -x to +x) |
14 | === modified file 'INSTALL' (properties changed: -x to +x) |
15 | === modified file 'Makefile.am' (properties changed: -x to +x) |
16 | === modified file 'README' (properties changed: -x to +x) |
17 | === modified file 'configure.ac' (properties changed: -x to +x) |
18 | --- configure.ac 2011-05-17 12:46:31 +0000 |
19 | +++ configure.ac 2011-08-23 04:19:23 +0000 |
20 | @@ -20,6 +20,7 @@ |
21 | |
22 | # Checks for programs. |
23 | AC_PROG_CC |
24 | +AC_PROG_CXX |
25 | AC_PROG_INSTALL |
26 | |
27 | PKG_CHECK_MODULES([GEIS], [libutouch-geis >= 1.0.10]) |
28 | |
29 | === modified file 'etc/Makefile.am' (properties changed: -x to +x) |
30 | === modified file 'etc/appNames' (properties changed: -x to +x) |
31 | === modified file 'etc/attributes' (properties changed: -x to +x) |
32 | === modified file 'etc/buttons' (properties changed: -x to +x) |
33 | === modified file 'etc/ginn.desktop' (properties changed: -x to +x) |
34 | === modified file 'etc/keys' (properties changed: -x to +x) |
35 | === modified file 'etc/wishes.xml' (properties changed: -x to +x) |
36 | === modified file 'ginn.pc.in' (properties changed: -x to +x) |
37 | === modified file 'src/Makefile.am' (properties changed: -x to +x) |
38 | --- src/Makefile.am 2011-02-04 16:04:30 +0000 |
39 | +++ src/Makefile.am 2011-08-23 04:19:23 +0000 |
40 | @@ -1,8 +1,9 @@ |
41 | bin_PROGRAMS = ginn |
42 | man1_MANS = ginn.1 |
43 | |
44 | -ginn_SOURCES = ginn.c config.h config.c xt.c bamf.c |
45 | -ginn_CFLAGS = \ |
46 | +ginn_SOURCES = bamf.cpp config.cpp ginn.cpp gir.cpp main.cpp xt.cpp |
47 | + |
48 | +ginn_CXXFLAGS = \ |
49 | -DGINN_CONFIG_DIR=\"$(sysconfdir)/ginn\" \ |
50 | $(GEIS_CFLAGS) $(XTST_CFLAGS) $(X11_CFLAGS) $(XML2_CFLAGS) $(BAMF_CFLAGS) |
51 | ginn_LDFLAGS = $(GEIS_LIBS) $(XTST_LIBS) $(X11_LIBS) $(XML2_LIBS) $(BAMF_LIBS) |
52 | |
53 | === added file 'src/README' |
54 | --- src/README 1970-01-01 00:00:00 +0000 |
55 | +++ src/README 2011-08-23 04:19:23 +0000 |
56 | @@ -0,0 +1,5 @@ |
57 | +To compile GIR you need some packages to install theme simply execute install.sh |
58 | + |
59 | +note: this install script work for just debian base system |
60 | + |
61 | +Enjoy!! |
62 | \ No newline at end of file |
63 | |
64 | === removed file 'src/bamf.c' |
65 | --- src/bamf.c 2011-05-20 19:34:26 +0000 |
66 | +++ src/bamf.c 1970-01-01 00:00:00 +0000 |
67 | @@ -1,48 +0,0 @@ |
68 | -/* |
69 | - * Copyright 2010 Canonical Ltd. |
70 | - * |
71 | - * This library is free software; you can redistribute it and/or modify it under |
72 | - * the terms of the GNU General Public License as published by the Free Software |
73 | - * Foundation; either version 3 of the License, or (at your option) any later |
74 | - * version. |
75 | - * |
76 | - * This library is distributed in the hope that it will be useful, but WITHOUT |
77 | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
78 | - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
79 | - * details. |
80 | - * |
81 | - * You should have received a copy of the GNU General Public License along with |
82 | - * this program; if not, write to the Free Software Foundation, Inc., 51 |
83 | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
84 | - */ |
85 | - |
86 | -#include <libbamf/bamf-matcher.h> |
87 | -#include <string.h> |
88 | - |
89 | -char *getName(char *deskfile) |
90 | -{ |
91 | - char *temp; |
92 | - temp = strdup(strrchr(deskfile, '/')); |
93 | - return strndup(temp + 1, strlen(temp) - 9); |
94 | -} |
95 | - |
96 | -char *getCurrentApp() |
97 | -{ |
98 | - g_type_init(); |
99 | - char *deskfile, *appName; |
100 | - char *temp; |
101 | - |
102 | - BamfApplication *app = |
103 | - bamf_matcher_get_active_application(bamf_matcher_get_default()); |
104 | - if (app) { |
105 | - appName = (char *) bamf_view_get_name(BAMF_VIEW(app)); |
106 | - temp = bamf_application_get_desktop_file(app); |
107 | - |
108 | - if (strchr(appName, ' ') && temp && strlen(temp) > 1) |
109 | - return getName((char *) temp); |
110 | - else |
111 | - return appName; |
112 | - } else |
113 | - return ""; |
114 | - |
115 | -} |
116 | |
117 | === added file 'src/bamf.cpp' |
118 | --- src/bamf.cpp 1970-01-01 00:00:00 +0000 |
119 | +++ src/bamf.cpp 2011-08-23 04:19:23 +0000 |
120 | @@ -0,0 +1,48 @@ |
121 | +/* |
122 | + * Copyright 2010 Canonical Ltd. |
123 | + * |
124 | + * This library is free software; you can redistribute it and/or modify it under |
125 | + * the terms of the GNU General Public License as published by the Free Software |
126 | + * Foundation; either version 3 of the License, or (at your option) any later |
127 | + * version. |
128 | + * |
129 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
130 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
131 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
132 | + * details. |
133 | + * |
134 | + * You should have received a copy of the GNU General Public License along with |
135 | + * this program; if not, write to the Free Software Foundation, Inc., 51 |
136 | + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
137 | + */ |
138 | + |
139 | +#include <libbamf/bamf-matcher.h> |
140 | +#include <string.h> |
141 | + |
142 | +char *getName(char *deskfile) |
143 | +{ |
144 | + char *temp; |
145 | + temp = strdup(strrchr(deskfile, '/')); |
146 | + return strndup(temp + 1, strlen(temp) - 9); |
147 | +} |
148 | + |
149 | +char *getCurrentApp() |
150 | +{ |
151 | + g_type_init(); |
152 | + char *deskfile, *appName; |
153 | + char *temp; |
154 | + |
155 | + BamfApplication *app = |
156 | + bamf_matcher_get_active_application(bamf_matcher_get_default()); |
157 | + if (app) { |
158 | + appName = (char *) bamf_view_get_name(BAMF_VIEW(app)); |
159 | + temp = (char *) bamf_application_get_desktop_file(app); |
160 | + |
161 | + if (strchr(appName, ' ') && temp && strlen(temp) > 1) |
162 | + return getName((char *) temp); |
163 | + else |
164 | + return appName; |
165 | + } else |
166 | + return ""; |
167 | + |
168 | +} |
169 | |
170 | === removed file 'src/config.c' |
171 | --- src/config.c 2011-03-16 16:19:13 +0000 |
172 | +++ src/config.c 1970-01-01 00:00:00 +0000 |
173 | @@ -1,200 +0,0 @@ |
174 | -/* |
175 | - * Copyright 2010 Canonical Ltd. |
176 | - * |
177 | - * This library is free software; you can redistribute it and/or modify it under |
178 | - * the terms of the GNU General Public License as published by the Free Software |
179 | - * Foundation; either version 3 of the License, or (at your option) any later |
180 | - * version. |
181 | - * |
182 | - * This library is distributed in the hope that it will be useful, but WITHOUT |
183 | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
184 | - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
185 | - * details. |
186 | - * |
187 | - * You should have received a copy of the GNU General Public License along with |
188 | - * this program; if not, write to the Free Software Foundation, Inc., 51 |
189 | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
190 | - */ |
191 | - |
192 | -#include "config.h" |
193 | -#include <libxml/parser.h> |
194 | - |
195 | -void debugOut(struct wish *wp) |
196 | -{ |
197 | - int i; |
198 | - printf("\n key : %s ", wp->key); |
199 | - printf("\n button : %d ", wp->button); |
200 | - for (i = 0; i < 4; i++) |
201 | - printf("\t mod%d : %s ", i, wp->modifiers[i]); |
202 | - for (i = 0; i < 4; i++) { |
203 | - printf("\n attrName : %s ", wp->config_attr[i].attrName); |
204 | - printf("\t val : %.2f ", wp->config_attr[i].val); |
205 | - printf("\t valMax : %.2f", wp->config_attr[i].valMax); |
206 | - } |
207 | - printf("\n pMe : %x pNext : %x ", wp, wp->next); |
208 | - printf("\n==================================================="); |
209 | -} |
210 | - |
211 | -int ginn_config_open(struct ginn_config *cfg, const char *path) |
212 | -{ |
213 | - memset(cfg, 0, sizeof(*cfg)); |
214 | - cfg->doc = xmlReadFile(path, NULL, 0); |
215 | - if (cfg->doc == NULL) { |
216 | - fprintf(stderr, "Failed to parse %s\n", path); |
217 | - return -1; |
218 | - } |
219 | - return 0; |
220 | -} |
221 | - |
222 | -void ginn_config_close(struct ginn_config *cfg) |
223 | -{ |
224 | - xmlFreeDoc(cfg->doc); |
225 | -} |
226 | - |
227 | -static void print_node(const xmlNode * root, int depth) |
228 | -{ |
229 | - xmlNode *node; |
230 | - for (node = root; node; node = node->next) { |
231 | - int i; |
232 | - if (node->type != XML_ELEMENT_NODE) |
233 | - continue; |
234 | - for (i = 0; i < depth; i++) |
235 | - printf(" "); |
236 | - printf("%s\n", node->name); |
237 | - print_node(node->children, depth + 1); |
238 | - } |
239 | -} |
240 | - |
241 | -static int ginn_str2state(const char *str) |
242 | -{ |
243 | - if (str == NULL) |
244 | - return -1; |
245 | - if (strcmp(str, "start") == 0) |
246 | - return GINN_START; |
247 | - if (strcmp(str, "update") == 0) |
248 | - return GINN_UPDATE; |
249 | - if (strcmp(str, "finish") == 0) |
250 | - return GINN_FINISH; |
251 | - fprintf(stderr, "ERROR: Undefined state: %s\n", str); |
252 | - return -2; |
253 | -} |
254 | - |
255 | -static int ginn_str2bool(const char *str) |
256 | -{ |
257 | - if (str == NULL) |
258 | - return -1; |
259 | - if (strcmp(str, "true") == 0) |
260 | - return 1; |
261 | - if (strcmp(str, "false") == 0) |
262 | - return 0; |
263 | - fprintf(stderr, "ERROR: Invalid value for boolean attribute: %s\n", |
264 | - str); |
265 | - return -2; |
266 | -} |
267 | - |
268 | -void store_1config(xmlNode * node, struct wish *wp, int *position) |
269 | -{ |
270 | - if (0 == strcmp(node->name, "wish")) { |
271 | - // printf(" gesture %s fingers %s ",(xmlGetProp(node, "gesture")),(xmlGetProp(node, "fingers"))); |
272 | - wp->config_attr[0].attrName = "gesture name"; |
273 | - switch (xmlGetProp(node, "gesture")[0]) { |
274 | - case 'D': |
275 | - wp->config_attr[0].val = wp->config_attr[0].valMax = 0; |
276 | - break; |
277 | - case 'P': |
278 | - wp->config_attr[0].val = wp->config_attr[0].valMax = 1; |
279 | - break; |
280 | - case 'R': |
281 | - wp->config_attr[0].val = wp->config_attr[0].valMax = 2; |
282 | - break; |
283 | - case 'T': |
284 | - wp->config_attr[0].val = wp->config_attr[0].valMax = 15; |
285 | - break; |
286 | - } |
287 | - wp->config_attr[1].attrName = "touches"; |
288 | - wp->config_attr[1].val = atoi(xmlGetProp(node, "fingers")); |
289 | - wp->config_attr[1].valMax = atoi(xmlGetProp(node, "fingers")); |
290 | - } |
291 | - if (0 == strcmp(node->name, "action")) { |
292 | - wp->when = ginn_str2state(xmlGetProp(node, "when")); |
293 | - if (wp->when < 0) |
294 | - fprintf(stderr, |
295 | - "ERROR: you must provide property 'when' to the action: %s\n", |
296 | - xmlGetProp(node, "name")); |
297 | - } |
298 | - if (0 == strcmp(node->name, "trigger")) { |
299 | - wp->config_attr[*position].attrName = xmlGetProp(node, "prop"); |
300 | - wp->config_attr[*position].val = atof(xmlGetProp(node, "min")); |
301 | - wp->config_attr[*position].valMax = atof(xmlGetProp(node, "max")); |
302 | - int acc = ginn_str2bool(xmlGetProp(node, "accumulate")); |
303 | - wp->config_attr[*position].accumulate = |
304 | - acc == -1 ? GINN_DEFAULT_ACCUMULATE : acc; |
305 | - wp->config_attr[*position].accumVal = 0; |
306 | - (*position)++; |
307 | - } |
308 | - if (0 == strcmp(node->name, "key") |
309 | - || 0 == strcmp(node->name, "button")) { |
310 | - if (xmlGetProp(node, "modifier1")) |
311 | - wp->modifiers[0] = xmlGetProp(node, "modifier1"); |
312 | - if (xmlGetProp(node, "modifier2")) |
313 | - wp->modifiers[1] = xmlGetProp(node, "modifier2"); |
314 | - if (xmlGetProp(node, "modifier3")) |
315 | - wp->modifiers[2] = xmlGetProp(node, "modifier3"); |
316 | - if (xmlGetProp(node, "modifier4")) |
317 | - wp->modifiers[3] = xmlGetProp(node, "modifier4"); |
318 | - } |
319 | - if (0 == strcmp(node->name, "key")) |
320 | - wp->key = xmlNodeGetContent(node); |
321 | - if (0 == strcmp(node->name, "button")) |
322 | - wp->button = atoi(xmlNodeGetContent(node)); |
323 | - if (0 == strcmp(node->name, "button")) |
324 | - printf("Button : %d ", wp->button); |
325 | -} |
326 | - |
327 | -void |
328 | -parse_node(const xmlNode * root, int depth, struct wish *wp, |
329 | - struct apps *ap) |
330 | -{ |
331 | - xmlNode *node; |
332 | - int position = 2; |
333 | - for (node = root; node; node = node->next) { |
334 | - if (node->type != XML_ELEMENT_NODE) |
335 | - continue; |
336 | - |
337 | - if ((0 == strcmp(node->name, "application"))) { |
338 | - if (0 != strcmp(ap->appName, "")) { |
339 | - ap = ap->next = |
340 | - (struct apps *) malloc(sizeof(struct apps)); |
341 | - inita(ap); |
342 | - } |
343 | - ap->appName = xmlGetProp(node, "name"); |
344 | - wp = ap->wp = (struct wish *) malloc(sizeof(struct wish)); |
345 | - initw(wp); |
346 | - } |
347 | - if ((0 == strcmp(node->name, "wish")) |
348 | - && (0 == strcmp(wp->config_attr[0].attrName, "gesture name"))) { |
349 | - if (!(wp->next)) { |
350 | - wp->next = (struct wish *) malloc(sizeof(struct wish)); |
351 | - initw(wp->next); |
352 | - } |
353 | - wp = wp->next; |
354 | - position = 2; |
355 | - } |
356 | - store_1config(node, wp, &position); |
357 | - parse_node(node->children, depth + 1, wp, ap); |
358 | - } |
359 | -} |
360 | - |
361 | -void |
362 | -ginn_config_store(const struct ginn_config *cfg, struct wish *w, |
363 | - struct apps *a) |
364 | -{ |
365 | - const xmlNode *root = xmlDocGetRootElement(cfg->doc); |
366 | - parse_node(root, 0, w, a); |
367 | -} |
368 | - |
369 | -void ginn_config_print(const struct ginn_config *cfg) |
370 | -{ |
371 | - const xmlNode *root = xmlDocGetRootElement(cfg->doc); |
372 | - print_node(root, 0); |
373 | -} |
374 | |
375 | === added file 'src/config.cpp' |
376 | --- src/config.cpp 1970-01-01 00:00:00 +0000 |
377 | +++ src/config.cpp 2011-08-23 04:19:23 +0000 |
378 | @@ -0,0 +1,202 @@ |
379 | +/* |
380 | + * Copyright 2010 Canonical Ltd. |
381 | + * |
382 | + * This library is free software; you can redistribute it and/or modify it under |
383 | + * the terms of the GNU General Public License as published by the Free Software |
384 | + * Foundation; either version 3 of the License, or (at your option) any later |
385 | + * version. |
386 | + * |
387 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
388 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
389 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
390 | + * details. |
391 | + * |
392 | + * You should have received a copy of the GNU General Public License along with |
393 | + * this program; if not, write to the Free Software Foundation, Inc., 51 |
394 | + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
395 | + */ |
396 | + |
397 | +#include "config.h" |
398 | + |
399 | +void debugOut(Gwish *wp) |
400 | +{ |
401 | + int i; |
402 | + cout << "\n key : " << wp->key; |
403 | + printf("\n button : %d ", wp->button); |
404 | + for (i = 0; i < 4; i++) |
405 | + cout << "\t mod" << i << " : " << wp->modifiers[i]; |
406 | + for (i = 0; i < 4; i++) { |
407 | + cout << "\n attrName : " << wp->config_attr[i].attrName; |
408 | + printf("\t val : %.2f ", wp->config_attr[i].val); |
409 | + printf("\t valMax : %.2f", wp->config_attr[i].valMax); |
410 | + } |
411 | + printf("\n pMe : %x pNext : %x ", wp, wp->next); |
412 | + printf("\n==================================================="); |
413 | +} |
414 | + |
415 | +int ginn_config_open(struct ginn_config *cfg, const char *path) |
416 | +{ |
417 | + memset(cfg, 0, sizeof(*cfg)); |
418 | + cfg->doc = xmlReadFile(path, NULL, 0); |
419 | + if (cfg->doc == NULL) |
420 | + { |
421 | + cerr << "Failed to parse " << path << endl; |
422 | + return -1; |
423 | + } |
424 | + return 0; |
425 | +} |
426 | + |
427 | +void ginn_config_close(struct ginn_config *cfg) |
428 | +{ |
429 | + xmlFreeDoc(cfg->doc); |
430 | +} |
431 | + |
432 | +static void print_node(const xmlNode * root, int depth) |
433 | +{ |
434 | + const xmlNode *node; |
435 | + for (node = root; node; node = node->next) |
436 | + { |
437 | + if (node->type != XML_ELEMENT_NODE) |
438 | + { |
439 | + continue; |
440 | + } |
441 | + for (int i = 0; i < depth; i++) |
442 | + printf(" "); |
443 | + cout << node->name << endl; |
444 | + print_node(node->children, depth + 1); |
445 | + } |
446 | +} |
447 | + |
448 | +static int ginn_str2state(const char *str) |
449 | +{ |
450 | + if (str == NULL) |
451 | + return -1; |
452 | + if (strcmp(str, "start") == 0) |
453 | + return GINN_START; |
454 | + if (strcmp(str, "update") == 0) |
455 | + return GINN_UPDATE; |
456 | + if (strcmp(str, "finish") == 0) |
457 | + return GINN_FINISH; |
458 | + cerr << "ERROR: Undefined state: " << str << endl; |
459 | + return -2; |
460 | +} |
461 | + |
462 | +static int ginn_str2bool(const char *str) |
463 | +{ |
464 | + if (str == NULL) |
465 | + return -1; |
466 | + if (strcmp(str, "true") == 0) |
467 | + return 1; |
468 | + if (strcmp(str, "false") == 0) |
469 | + return 0; |
470 | + cerr << "ERROR: Invalid value for boolean attribute: " << str << endl; |
471 | + return -2; |
472 | +} |
473 | + |
474 | +void store_1config(xmlNode * node, Gwish *wp, int *position) |
475 | +{ |
476 | + string nodeName = (char *)node->name; |
477 | + if (nodeName == "wish") |
478 | + { |
479 | + // printf(" gesture %s fingers %s ",(xmlGetProp(node, "gesture")),(xmlGetProp(node, "fingers"))); |
480 | + switch (xmlGetProp(node, (xmlChar*)"gesture") [0]) |
481 | + { |
482 | + case 'D': |
483 | + wp->Type = GINN_Drag; |
484 | + break; |
485 | + case 'P': |
486 | + wp->Type = GINN_Pinch; |
487 | + break; |
488 | + case 'R': |
489 | + wp->Type = GINN_Rotate; |
490 | + break; |
491 | + case 'T': |
492 | + wp->Type = GINN_Tap; |
493 | + break; |
494 | + } |
495 | + wp->TouchNum = atoi((char *) xmlGetProp(node, (xmlChar*)"fingers")); |
496 | + wp->DirectTouch = ginn_str2bool((char *) xmlGetProp(node, (xmlChar*)"screen")); |
497 | + } |
498 | + if (nodeName == "action") |
499 | + { |
500 | + wp->when = ginn_str2state((char *) xmlGetProp(node, (xmlChar*)"when")); |
501 | + if (wp->when < 0) |
502 | + cerr << "ERROR: you must provide property 'when' to the action: " << xmlGetProp(node, (xmlChar*)"name") << endl; |
503 | + } |
504 | + if (nodeName == "trigger") |
505 | + { |
506 | + wp->config_attr[*position].attrName = (char *)xmlGetProp(node, (xmlChar*)"prop"); |
507 | + wp->config_attr[*position].val = atof((char *)xmlGetProp(node, (xmlChar*)"min")); |
508 | + wp->config_attr[*position].valMax = atof((char *)xmlGetProp(node, (xmlChar*)"max")); |
509 | + int acc = ginn_str2bool((char *)xmlGetProp(node, (xmlChar*)"accumulate")); |
510 | + wp->config_attr[*position].accumulate = |
511 | + acc == -1 ? GINN_DEFAULT_ACCUMULATE : acc; |
512 | + wp->config_attr[*position].accumVal = 0; |
513 | + (*position)++; |
514 | + } |
515 | + if (nodeName == "key" || nodeName == "button") |
516 | + { |
517 | + if (xmlGetProp(node, (xmlChar*)"modifier1")) |
518 | + wp->modifiers[0] = (char *)xmlGetProp(node, (xmlChar*)"modifier1"); |
519 | + if (xmlGetProp(node, (xmlChar*)"modifier2")) |
520 | + wp->modifiers[1] = (char *)xmlGetProp(node, (xmlChar*)"modifier2"); |
521 | + if (xmlGetProp(node, (xmlChar*)"modifier3")) |
522 | + wp->modifiers[2] = (char *)xmlGetProp(node, (xmlChar*)"modifier3"); |
523 | + if (xmlGetProp(node, (xmlChar*)"modifier4")) |
524 | + wp->modifiers[3] = (char *)xmlGetProp(node, (xmlChar*)"modifier4"); |
525 | + } |
526 | + if (nodeName == "key") |
527 | + wp->key = (char *)xmlNodeGetContent(node); |
528 | + if (nodeName == "button") |
529 | + { |
530 | + wp->button = atoi((char *)xmlNodeGetContent(node)); |
531 | + } |
532 | +} |
533 | + |
534 | +void parse_node(const xmlNode * root, int depth, Gwish *wp, Gapps *ap) |
535 | +{ |
536 | + xmlNode *node; |
537 | + |
538 | + int position = 2; |
539 | + for (node = const_cast <xmlNode *> (root); node; node = node->next) |
540 | + { |
541 | + if (node->type != XML_ELEMENT_NODE) |
542 | + { |
543 | + if (node->type == XML_TEXT_NODE) |
544 | + |
545 | + continue; |
546 | + } |
547 | + |
548 | + if ((0 == strcmp((char *)node->name, "application"))) |
549 | + { |
550 | + if (!ap->appName.empty()) |
551 | + { |
552 | + ap = ap->next = new Gapps;//Save The previon and create new |
553 | + } |
554 | + ap->appName = (char *) xmlGetProp(node, (xmlChar*)"name"); |
555 | + wp = ap->wp = new Gwish; //Save The previon and create new |
556 | + } |
557 | + if ((0 == strcmp((char *)node->name, "wish")) |
558 | + && wp->Type != -1) |
559 | + { |
560 | + if (!(wp->next)) |
561 | + wp->next = new Gwish; |
562 | + wp = wp->next; |
563 | + position = 2; |
564 | + } |
565 | + store_1config(node, wp, &position); |
566 | + parse_node(node->children, depth + 1, wp, ap); |
567 | + } |
568 | +} |
569 | + |
570 | +void ginn_config_store(const struct ginn_config *cfg, Gwish *w, struct Gapps *a) |
571 | +{ |
572 | + const xmlNode *root = xmlDocGetRootElement(cfg->doc); |
573 | + parse_node(root, 0, w, a); |
574 | +} |
575 | + |
576 | +void ginn_config_print(const struct ginn_config *cfg) |
577 | +{ |
578 | + const xmlNode *root = xmlDocGetRootElement(cfg->doc); |
579 | + print_node(root, 0); |
580 | +} |
581 | |
582 | === modified file 'src/config.h' (properties changed: -x to +x) |
583 | --- src/config.h 2011-03-16 16:19:13 +0000 |
584 | +++ src/config.h 2011-08-23 04:19:23 +0000 |
585 | @@ -18,8 +18,7 @@ |
586 | #ifndef GINN_CONFIG_H |
587 | #define GINN_CONFIG_H |
588 | |
589 | -#include <libxml/tree.h> |
590 | -#include <string.h> |
591 | +#include "header.h" |
592 | |
593 | #define GINN_START 0 |
594 | #define GINN_UPDATE 1 |
595 | @@ -27,32 +26,76 @@ |
596 | |
597 | #define GINN_DEFAULT_ACCUMULATE 1 |
598 | |
599 | -typedef struct ginn_config { |
600 | +struct ginn_config |
601 | +{ |
602 | xmlDocPtr doc; |
603 | xmlNodePtr root; |
604 | -} cfg; |
605 | - |
606 | -typedef struct att { |
607 | - char *attrName; |
608 | - float val; |
609 | - float valMax; |
610 | - int accumulate; |
611 | - float accumVal; |
612 | -} att; |
613 | - |
614 | -typedef struct wish { |
615 | - att config_attr[25]; |
616 | - char *key; |
617 | - int button; |
618 | - char *modifiers[4]; |
619 | - struct wish *next; |
620 | - int when; |
621 | -} wish; |
622 | - |
623 | -typedef struct apps { |
624 | - char *appName; |
625 | - struct wish *wp; |
626 | - struct apps *next; |
627 | -} apps; |
628 | +}; |
629 | + |
630 | +struct att |
631 | +{ |
632 | + string attrName; |
633 | + float val; |
634 | + float valMax; |
635 | + int accumulate; |
636 | + float accumVal; |
637 | +}; |
638 | + |
639 | +/// |
640 | +/// Use to classify Gesture Type (For Example pinch) |
641 | +/// |
642 | +enum GestureType |
643 | +{ |
644 | + GINN_Drag = 0,GINN_Pinch=1,GINN_Rotate=2,GINN_Tap=15 |
645 | +}; |
646 | + |
647 | +/// |
648 | +/// GWish provide gesture information and the reaction for gesture called Wish |
649 | +/// |
650 | +class Gwish |
651 | +{ |
652 | +public: |
653 | + Gwish(); |
654 | +//Variable: |
655 | + att config_attr[25]; |
656 | + int button; |
657 | + int Type; //Indicate The gusture Type (-1 Mean it's NULL) |
658 | + int TouchNum; //Indicate The Number of finger for gusture |
659 | + int DirectTouch; //use this to Detect Touchpad from Touchscreen |
660 | + string key; |
661 | + string modifiers[4]; |
662 | + Gwish *next; |
663 | + int when; |
664 | +}; |
665 | + |
666 | +/// |
667 | +/// Use This class for save application information |
668 | +/// |
669 | +class Gapps |
670 | +{ |
671 | +public: |
672 | + Gapps(); |
673 | +//Variable: |
674 | + string appName; |
675 | + Gwish *wp; |
676 | + Gapps *next; |
677 | +}; |
678 | + |
679 | +/// |
680 | +/// Use this struct to save device attribute (GD reffered to GINN device and att reffered to attribute) |
681 | +/// |
682 | +struct GD_att |
683 | +{ |
684 | + string name; //Device Name |
685 | + int ID; //Device ID that is unique (use to find devive) |
686 | + int TouchNum; //Define how many parallel finger touch can support |
687 | + bool isDirectTouch; //Define it is a touch screen or not(a pad) |
688 | +}; |
689 | + |
690 | + |
691 | +//Decleare in config.cpp |
692 | +int ginn_config_open(struct ginn_config *cfg, const char *path); |
693 | +void ginn_config_print(const struct ginn_config *cfg); |
694 | +void ginn_config_store(const struct ginn_config *cfg, Gwish *w, Gapps *a); |
695 | |
696 | #endif /* GINN_CONFIG_H */ |
697 | |
698 | === removed file 'src/ginn.c' |
699 | --- src/ginn.c 2011-08-12 15:40:51 +0000 |
700 | +++ src/ginn.c 1970-01-01 00:00:00 +0000 |
701 | @@ -1,592 +0,0 @@ |
702 | -/** |
703 | - * Copyright 2010 Canonical Ltd. |
704 | - * |
705 | - * This library is free software; you can redistribute it and/or modify it under |
706 | - * the terms of the GNU General Public License as published by the Free Software |
707 | - * Foundation; either version 3 of the License, or (at your option) any later |
708 | - * version. |
709 | - * |
710 | - * This library is distributed in the hope that it will be useful, but WITHOUT |
711 | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
712 | - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
713 | - * details. |
714 | - * |
715 | - * You should have received a copy of the GNU General Public License along with |
716 | - * this program; if not, write to the Free Software Foundation, Inc., 51 |
717 | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
718 | - * |
719 | - * Authors: |
720 | - * Mohamed-Ikbel Boulabiar <boulabiar@gmail.com> |
721 | - * Henrik Rydberg <rydberg@bitmath.org> |
722 | - * Stephen M. Webb <stephen.webb@canonical.com> |
723 | - * |
724 | - */ |
725 | -#include "config.h" |
726 | -#include <geis/geis.h> |
727 | -#include <errno.h> |
728 | -#include <stdio.h> |
729 | -#include <stdlib.h> |
730 | -#include <string.h> |
731 | -#include <sys/select.h> |
732 | -#include <sys/stat.h> |
733 | -#include <unistd.h> |
734 | -#include <X11/Xlib.h> |
735 | -#include <X11/keysym.h> |
736 | - |
737 | -att config_attr[25] = {[0 ... 24] = {.attrName = "",.val = 0,.valMax = 0} |
738 | -}; |
739 | - |
740 | -wish w1 = {.config_attr = {[0 ... 24] = |
741 | - {.attrName = "",.val = 0,.valMax = 0} |
742 | - } |
743 | -, |
744 | -.key = "", |
745 | -.next = NULL |
746 | -}; |
747 | - |
748 | -wish *wp, *wpEnd; |
749 | -apps *ap; |
750 | - |
751 | -static int inside(float x, float a, float b) |
752 | -{ |
753 | - return ((x <= b) && (x >= a)); |
754 | -} |
755 | - |
756 | -void initw(struct wish *wp) |
757 | -{ |
758 | - int i; |
759 | - wp->button = 0; |
760 | - wp->key = ""; |
761 | - wp->next = NULL; |
762 | - for (i = 0; i < 4; i++) |
763 | - wp->modifiers[i] = ""; |
764 | - for (i = 0; i < 25; i++) { |
765 | - wp->config_attr[i].attrName = ""; |
766 | - wp->config_attr[i].val = 0; |
767 | - wp->config_attr[i].valMax = 0; |
768 | - } |
769 | -} |
770 | - |
771 | -void inita(struct apps *ap) |
772 | -{ |
773 | - ap->next = NULL; |
774 | - ap->wp = NULL; |
775 | - ap->appName = ""; |
776 | -} |
777 | - |
778 | -static void clear_accum_attrs(att * attrs) |
779 | -{ |
780 | - int i = 0; |
781 | - while (strcmp(attrs[i].attrName, "") != 0) { |
782 | - if (attrs[i].accumulate) |
783 | - attrs[i].accumVal = 0; |
784 | - i++; |
785 | - } |
786 | -} |
787 | - |
788 | -static void update_wishes() |
789 | -{ |
790 | - char *activeApp; |
791 | - apps *tmpAp = ap; |
792 | - int diff = 0; |
793 | - |
794 | - activeApp = (char *) getCurrentApp(); |
795 | - printf(" --ActiveApp %s\n", activeApp); |
796 | - if (activeApp) |
797 | - diff = strcmp(activeApp, ap->appName); |
798 | - |
799 | - while (diff && ap->next) { |
800 | - ap = ap->next; |
801 | - diff = strcmp(activeApp, ap->appName); |
802 | - } |
803 | - |
804 | - if (!diff) |
805 | - wpEnd->next = ap->wp; |
806 | - else |
807 | - wpEnd->next = NULL; |
808 | - |
809 | - ap = tmpAp; |
810 | -} |
811 | - |
812 | -static void |
813 | -gesture_match(GeisGestureType gesture_type, |
814 | - GeisGestureId gesture_id, |
815 | - GeisSize attr_count, GeisGestureAttr * attrs, int state) |
816 | -{ |
817 | - struct wish *topw; |
818 | - topw = wp; |
819 | - update_wishes(); |
820 | - while (wp && (0 != strcmp(wp->key, "") || wp->button)) { |
821 | - int valid = 1; |
822 | - if (gesture_type == wp->config_attr[0].val |
823 | - && attrs[8].integer_val == wp->config_attr[1].val) { |
824 | - int attrsI = 9, cAttrI = 2; |
825 | - do { |
826 | - if (0 == |
827 | - strcmp(attrs[attrsI].name, |
828 | - wp->config_attr[cAttrI].attrName)) { |
829 | - printf("DEBUG -- comparing %s %s : ", |
830 | - attrs[attrsI].name, |
831 | - wp->config_attr[cAttrI].attrName); |
832 | - printf("%.2f %.2f %.2f \n", |
833 | - attrs[attrsI].float_val, |
834 | - wp->config_attr[cAttrI].val, |
835 | - wp->config_attr[cAttrI].valMax); |
836 | - printf("%i \n", |
837 | - inside(attrs[attrsI].float_val, |
838 | - wp->config_attr[cAttrI].val, |
839 | - wp->config_attr[cAttrI].valMax)); |
840 | - if (wp->config_attr[cAttrI].accumulate) { |
841 | - wp->config_attr[cAttrI].accumVal += |
842 | - attrs[attrsI].float_val; |
843 | - valid = valid |
844 | - && inside(wp->config_attr |
845 | - [cAttrI].accumVal, |
846 | - wp->config_attr |
847 | - [cAttrI].val, |
848 | - wp->config_attr[cAttrI].valMax); |
849 | - } else |
850 | - valid = valid |
851 | - && inside(attrs[attrsI].float_val, |
852 | - wp->config_attr |
853 | - [cAttrI].val, |
854 | - wp->config_attr[cAttrI].valMax); |
855 | - attrsI++; |
856 | - cAttrI++; |
857 | - } else |
858 | - attrsI++; |
859 | - } while ((0 != strcmp(wp->config_attr[cAttrI].attrName, "")) |
860 | - && attrsI < 18); |
861 | - if (valid && wp->when == state) { |
862 | - if ((0 != wp->button) |
863 | - && (0 != strcmp(wp->key, ""))) { |
864 | - injMixBtnKey(XStringToKeysym(wp->key), |
865 | - wp->button, wp->modifiers); |
866 | - printf("MIX -- MIX"); |
867 | - } else { |
868 | - if (0 != wp->button) |
869 | - injButton(wp->button, wp->modifiers); |
870 | - if (0 != strcmp(wp->key, "")) |
871 | - injKey(XStringToKeysym(wp->key), wp->modifiers); |
872 | - } |
873 | - clear_accum_attrs(wp->config_attr); |
874 | - } |
875 | - } |
876 | - if (state == GINN_FINISH) |
877 | - clear_accum_attrs(wp->config_attr); |
878 | - wp = wp->next; |
879 | - } |
880 | - wp = topw; |
881 | -} |
882 | - |
883 | -static Window getRootWindow() |
884 | -{ |
885 | - Display *display = NULL; |
886 | - Window window = 0; |
887 | - |
888 | - display = XOpenDisplay(NULL); |
889 | - if (!display) { |
890 | - fprintf(stderr, "error opening X11 display.\n"); |
891 | - exit(1); |
892 | - } |
893 | - |
894 | - window = DefaultRootWindow(display); |
895 | - |
896 | - XCloseDisplay(display); |
897 | - |
898 | - return window; |
899 | -} |
900 | - |
901 | -static void print_attr(GeisGestureAttr * attr) |
902 | -{ |
903 | - fprintf(stdout, "\tattr %s=", attr->name); |
904 | - switch (attr->type) { |
905 | - case GEIS_ATTR_TYPE_BOOLEAN: |
906 | - fprintf(stdout, "%s\n", attr->boolean_val ? "true" : "false"); |
907 | - break; |
908 | - case GEIS_ATTR_TYPE_FLOAT: |
909 | - fprintf(stdout, "%f\n", attr->float_val); |
910 | - break; |
911 | - case GEIS_ATTR_TYPE_INTEGER: |
912 | - fprintf(stdout, "%d\n", attr->integer_val); |
913 | - break; |
914 | - case GEIS_ATTR_TYPE_STRING: |
915 | - fprintf(stdout, "\"%s\"\n", attr->string_val); |
916 | - break; |
917 | - default: |
918 | - fprintf(stdout, "<unknown>\n"); |
919 | - break; |
920 | - } |
921 | -} |
922 | - |
923 | -static void |
924 | -gesture_added(void *cookie, |
925 | - GeisGestureType gesture_type, |
926 | - GeisGestureId gesture_id, |
927 | - GeisSize attr_count, GeisGestureAttr * attrs) |
928 | -{ |
929 | - int i = 0; |
930 | - fprintf(stdout, "Gesture type %d added\n", gesture_type); |
931 | - for (i = 0; i < attr_count; ++i) |
932 | - print_attr(&attrs[i]); |
933 | -} |
934 | - |
935 | -static void |
936 | -gesture_removed(void *cookie, |
937 | - GeisGestureType gesture_type, |
938 | - GeisGestureId gesture_id, |
939 | - GeisSize attr_count, GeisGestureAttr * attrs) |
940 | -{ |
941 | - int i = 0; |
942 | - fprintf(stdout, "Gesture type %d removed\n", gesture_type); |
943 | - for (i = 0; i < attr_count; ++i) |
944 | - print_attr(&attrs[i]); |
945 | -} |
946 | - |
947 | -static void |
948 | -gesture_start(void *cookie, |
949 | - GeisGestureType gesture_type, |
950 | - GeisGestureId gesture_id, |
951 | - GeisSize attr_count, GeisGestureAttr * attrs) |
952 | -{ |
953 | - int i = 0; |
954 | - fprintf(stdout, "Gesture type %d started\n", gesture_type); |
955 | - for (i = 0; i < attr_count; ++i) |
956 | - print_attr(&attrs[i]); |
957 | - |
958 | - // In GEIS v1, we know that the focus coords are in attrs 5 and 6 |
959 | - movePointer((int)attrs[5].float_val, (int)attrs[6].float_val); |
960 | -} |
961 | - |
962 | -static void |
963 | -gesture_update(void *cookie, |
964 | - GeisGestureType gesture_type, |
965 | - GeisGestureId gesture_id, |
966 | - GeisSize attr_count, GeisGestureAttr * attrs) |
967 | -{ |
968 | - int i = 0; |
969 | - fprintf(stdout, "Gesture type %d updated\n", gesture_type); |
970 | - for (i = 0; i < attr_count; ++i) |
971 | - print_attr(&attrs[i]); |
972 | - gesture_match(gesture_type, gesture_id, attr_count, attrs, |
973 | - GINN_UPDATE); |
974 | -} |
975 | - |
976 | -static void |
977 | -gesture_finish(void *cookie, |
978 | - GeisGestureType gesture_type, |
979 | - GeisGestureId gesture_id, |
980 | - GeisSize attr_count, GeisGestureAttr * attrs) |
981 | -{ |
982 | - int i = 0; |
983 | - fprintf(stdout, "Gesture type %d finished\n", gesture_type); |
984 | - for (i = 0; i < attr_count; ++i); //print_attr(&attrs[i]); |
985 | - gesture_match(gesture_type, gesture_id, attr_count, attrs, |
986 | - GINN_FINISH); |
987 | -} |
988 | - |
989 | -GeisGestureFuncs gesture_funcs = { |
990 | - gesture_added, |
991 | - gesture_removed, |
992 | - gesture_start, |
993 | - gesture_update, |
994 | - gesture_finish |
995 | -}; |
996 | - |
997 | -/* |
998 | - * Searches for a default config file. |
999 | - * |
1000 | - * Returns a pointer to a config file name (which must be freed) or NULL |
1001 | - * if no default config file was found. |
1002 | - */ |
1003 | -static char *ginn_default_config() |
1004 | -{ |
1005 | - static const char default_file_name[] = "/wishes.xml"; |
1006 | - static const char *search_paths[] = { |
1007 | - "etc", |
1008 | - "../etc", |
1009 | - ".", |
1010 | - "$HOME/.ginn", |
1011 | - GINN_CONFIG_DIR |
1012 | - }; |
1013 | - static const int num_paths = |
1014 | - sizeof(search_paths) / sizeof(const char *); |
1015 | - int i; |
1016 | - |
1017 | - for (i = 0; i < num_paths; ++i) { |
1018 | - struct stat sbuf; |
1019 | - char *file_name = NULL; |
1020 | - |
1021 | - if (strstr(search_paths[i], "$HOME")) { |
1022 | - char *home_dir = getenv("HOME"); |
1023 | - if (!home_dir) { |
1024 | - continue; |
1025 | - } else { |
1026 | - char *cdr = index(search_paths[i], '/'); |
1027 | - size_t file_name_length = strlen(home_dir) |
1028 | - + strlen(cdr) |
1029 | - + strlen(default_file_name) |
1030 | - + 1; |
1031 | - file_name = calloc(file_name_length, sizeof(char)); |
1032 | - strcpy(file_name, home_dir); |
1033 | - strcat(file_name, cdr); |
1034 | - } |
1035 | - } else { |
1036 | - size_t file_name_length = strlen(search_paths[i]) |
1037 | - + strlen(default_file_name) |
1038 | - + 1; |
1039 | - file_name = calloc(file_name_length, sizeof(char)); |
1040 | - strcpy(file_name, search_paths[i]); |
1041 | - } |
1042 | - strcat(file_name, default_file_name); |
1043 | - int sres = stat(file_name, &sbuf); |
1044 | - if (sres == 0) { |
1045 | - fprintf(stdout, "Using wishes file %s\n", file_name); |
1046 | - return file_name; |
1047 | - } |
1048 | - free(file_name); |
1049 | - } |
1050 | - |
1051 | - return NULL; |
1052 | -} |
1053 | - |
1054 | -int main(int argc, char *argv[]) |
1055 | -{ |
1056 | - GeisStatus status = GEIS_UNKNOWN_ERROR; |
1057 | - GeisXcbWinInfo xcb_win_info = { |
1058 | - .display_name = NULL, |
1059 | - .screenp = NULL, |
1060 | - .window_id = getRootWindow() |
1061 | - }; |
1062 | - GeisWinInfo win_info = { |
1063 | - GEIS_XCB_FULL_WINDOW, |
1064 | - &xcb_win_info |
1065 | - }; |
1066 | - GeisInstance instance; |
1067 | - struct ginn_config cfg; |
1068 | - |
1069 | - { |
1070 | - char *config_file_name = NULL; |
1071 | - if (argc < 2) { |
1072 | - fprintf(stderr, "usage: %s <configxml>\n", argv[0]); |
1073 | - config_file_name = ginn_default_config(); |
1074 | - if (config_file_name) { |
1075 | - fprintf(stderr, |
1076 | - "using default configuration file %s ... \n", |
1077 | - config_file_name); |
1078 | - } |
1079 | - } else { |
1080 | - config_file_name = strdup(argv[1]); |
1081 | - } |
1082 | - if (NULL == config_file_name) { |
1083 | - fprintf(stderr, "Could not find Ginn wishes\n"); |
1084 | - return -1; |
1085 | - } |
1086 | - |
1087 | - if (ginn_config_open(&cfg, config_file_name)) { |
1088 | - fprintf(stderr, "Could not load Ginn wishes\n"); |
1089 | - return -1; |
1090 | - } |
1091 | - free(config_file_name); |
1092 | - } |
1093 | - |
1094 | - ginn_config_print(&cfg); |
1095 | - ap = (struct apps *) malloc(sizeof(struct apps)); |
1096 | - inita(ap); |
1097 | - wp = (struct wish *) malloc(sizeof(struct wish)); |
1098 | - initw(wp); |
1099 | - ginn_config_store(&cfg, wp, ap); |
1100 | - wpEnd = wp; |
1101 | - while (wpEnd->next) |
1102 | - wpEnd = wpEnd->next; |
1103 | - |
1104 | - int pos = 0; |
1105 | - printf("\n"); |
1106 | - while (strcmp(config_attr[pos].attrName, "")) { |
1107 | - printf("DEBUG %d %s %.2f %.2f \n", pos, |
1108 | - config_attr[pos].attrName, config_attr[pos].val, |
1109 | - config_attr[pos].valMax); |
1110 | - pos++; |
1111 | - } |
1112 | - |
1113 | - /** |
1114 | - * Check the loaded wishes to see which gestures are used |
1115 | - * and add these gestures to a NULL terminated list "sub_gestures_list" |
1116 | - * |
1117 | - * This list is used to subscribe only the necessary gestures |
1118 | - * to GEIS. This will avoid issues with 2 finger scrolls and other gestues |
1119 | - * being dropped when not accounted for in the wishes file. |
1120 | - **/ |
1121 | - |
1122 | - apps * appPtr = ap; |
1123 | - wish * wishPtr; |
1124 | - char * sub_gestures_list[17] = {NULL}; |
1125 | - int finished = 0; |
1126 | - |
1127 | - /** |
1128 | - * Loop through each wish inside ap |
1129 | - * After all of the wishes in ap are accounted for |
1130 | - * add global wishes |
1131 | - **/ |
1132 | - |
1133 | - while(finished != 1) |
1134 | - { |
1135 | - // Check if we are finished with the application wishes |
1136 | - if(appPtr == NULL) |
1137 | - { |
1138 | - wishPtr = wp; |
1139 | - finished = 1; |
1140 | - }else{ |
1141 | - wishPtr = appPtr->wp; |
1142 | - } |
1143 | - |
1144 | - // Loop through each wish |
1145 | - while(wishPtr) |
1146 | - { |
1147 | - int i; |
1148 | - for(i = 0; i < 25; i ++) |
1149 | - { |
1150 | - |
1151 | - char *sub_gesture = malloc(sizeof(char[16])); |
1152 | - int pos = 0; |
1153 | - |
1154 | - // Check for Drag gesture |
1155 | - if(strcmp(wishPtr->config_attr[i].attrName, "delta x") == 0 || |
1156 | - strcmp(wishPtr->config_attr[i].attrName, "delta y") == 0 || |
1157 | - strcmp(wishPtr->config_attr[i].attrName, "velocity x") == 0 || |
1158 | - strcmp(wishPtr->config_attr[i].attrName, "velocity y") == 0 |
1159 | - ) |
1160 | - { |
1161 | - sprintf(sub_gesture, "Drag,touch=%i", (int)wishPtr->config_attr[1].val); |
1162 | - } |
1163 | - |
1164 | - // Check for Rotate gesture |
1165 | - else if(strcmp(wishPtr->config_attr[i].attrName, "angle delta") == 0 || |
1166 | - strcmp(wishPtr->config_attr[i].attrName, "angular velocity") == 0 || |
1167 | - strcmp(wishPtr->config_attr[i].attrName, "angle") == 0 |
1168 | - ) |
1169 | - { |
1170 | - sprintf(sub_gesture, "Rotate,touch=%i", (int)wishPtr->config_attr[1].val); |
1171 | - } |
1172 | - |
1173 | - // Check for Pinch gesture |
1174 | - else if(strcmp(wishPtr->config_attr[i].attrName, "radius delta") == 0 || |
1175 | - strcmp(wishPtr->config_attr[i].attrName, "radial velocity") == 0 || |
1176 | - strcmp(wishPtr->config_attr[i].attrName, "radius") == 0 |
1177 | - ) |
1178 | - { |
1179 | - sprintf(sub_gesture, "Pinch,touch=%i", (int)wishPtr->config_attr[1].val); |
1180 | - } |
1181 | - |
1182 | - // Check for Tap gesture |
1183 | - else if(strcmp(wishPtr->config_attr[i].attrName, "tap time") == 0) |
1184 | - { |
1185 | - sprintf(sub_gesture, "Tap,touch=%i", (int)wishPtr->config_attr[1].val); |
1186 | - } |
1187 | - |
1188 | - // Deallocate sub_gesture if no gesture was found |
1189 | - else |
1190 | - { |
1191 | - free(sub_gesture); |
1192 | - sub_gesture = NULL; |
1193 | - continue; |
1194 | - } |
1195 | - |
1196 | - /** Check the current gesture list |
1197 | - * Only add if the gesture is not already in the list |
1198 | - * Store in index of the first NULL found |
1199 | - **/ |
1200 | - |
1201 | - while(pos < 17) |
1202 | - { |
1203 | - if(sub_gestures_list[pos] == NULL) |
1204 | - { |
1205 | - sub_gestures_list[pos] = sub_gesture; |
1206 | - break; |
1207 | - }else if(strcmp(sub_gestures_list[pos], sub_gesture) == 0) |
1208 | - { |
1209 | - break; |
1210 | - } |
1211 | - pos ++; |
1212 | - } |
1213 | - |
1214 | - |
1215 | - } |
1216 | - // Iterate to the next wish |
1217 | - wishPtr = wishPtr->next; |
1218 | - } |
1219 | - |
1220 | - // If there are more applications, iterate to the next |
1221 | - |
1222 | - if(finished != 1) |
1223 | - { |
1224 | - appPtr = appPtr->next; |
1225 | - } |
1226 | - } |
1227 | - |
1228 | - // Show which gestures were subscribed |
1229 | - printf("Gestures subscribed:\n"); |
1230 | - |
1231 | - pos = 0; |
1232 | - while(pos < 17) |
1233 | - { |
1234 | - if(sub_gestures_list[pos] != NULL) |
1235 | - { |
1236 | - printf("%s\n", sub_gestures_list[pos]); |
1237 | - } |
1238 | - |
1239 | - pos ++; |
1240 | - } |
1241 | - |
1242 | - // End sub gesture list creation |
1243 | - |
1244 | - status = geis_init(&win_info, &instance); |
1245 | - if (status != GEIS_STATUS_SUCCESS) { |
1246 | - fprintf(stderr, "error in geis_init\n"); |
1247 | - return 1; |
1248 | - } |
1249 | - |
1250 | - status = geis_configuration_supported(instance, GEIS_CONFIG_UNIX_FD); |
1251 | - if (status != GEIS_STATUS_SUCCESS) { |
1252 | - fprintf(stderr, "GEIS does not support Unix fd\n"); |
1253 | - return 1; |
1254 | - } |
1255 | - |
1256 | - int fd = -1; |
1257 | - status = |
1258 | - geis_configuration_get_value(instance, GEIS_CONFIG_UNIX_FD, &fd); |
1259 | - if (status != GEIS_STATUS_SUCCESS) { |
1260 | - fprintf(stderr, "error retrieving GEIS fd\n"); |
1261 | - return 1; |
1262 | - } |
1263 | - |
1264 | - status = geis_subscribe(instance, GEIS_ALL_INPUT_DEVICES, sub_gestures_list, // GEIS_ALL_GESTURES, |
1265 | - &gesture_funcs, NULL); |
1266 | - if (status != GEIS_STATUS_SUCCESS) { |
1267 | - fprintf(stderr, "error subscribing to gestures\n"); |
1268 | - return 1; |
1269 | - } |
1270 | - |
1271 | - openDisplay(); |
1272 | - |
1273 | - while (1) { |
1274 | - fd_set read_fds; |
1275 | - FD_ZERO(&read_fds); |
1276 | - FD_SET(fd, &read_fds); |
1277 | - int sstat = select(fd + 1, &read_fds, NULL, NULL, NULL); |
1278 | - if (sstat < 0) { |
1279 | - fprintf(stderr, "error %d in select(): %s\n", errno, |
1280 | - strerror(errno)); |
1281 | - break; |
1282 | - } |
1283 | - |
1284 | - if (FD_ISSET(fd, &read_fds)) { |
1285 | - geis_event_dispatch(instance); |
1286 | - } |
1287 | - } |
1288 | - |
1289 | - geis_finish(instance); |
1290 | - closeDisplay(); |
1291 | - free(wp); |
1292 | - return 0; |
1293 | -} |
1294 | |
1295 | === added file 'src/ginn.cpp' |
1296 | --- src/ginn.cpp 1970-01-01 00:00:00 +0000 |
1297 | +++ src/ginn.cpp 2011-08-23 04:19:23 +0000 |
1298 | @@ -0,0 +1,555 @@ |
1299 | +#include "ginn.h" |
1300 | + |
1301 | +GINN::GINN() |
1302 | +{ |
1303 | + //Set Default value |
1304 | + config_load = false; |
1305 | + ap = new Gapps; |
1306 | + wp = new Gwish; |
1307 | + // |
1308 | + att att_default; |
1309 | + att_default.attrName = ""; |
1310 | + att_default.val = 0 ; |
1311 | + att_default.valMax = 0 ; |
1312 | + |
1313 | + for (int i = 0; i < 25;i++) |
1314 | + config_attr[i] = att_default; |
1315 | + |
1316 | + for (int i = 0; i < 25;i++) |
1317 | + w1.config_attr[i] = config_attr[i]; |
1318 | + w1.key = ""; |
1319 | + w1.next = NULL; |
1320 | +} |
1321 | + |
1322 | +int GINN::inside(float x, float a, float b) |
1323 | +{ |
1324 | + return ((x <= b) && (x >= a)); |
1325 | +} |
1326 | + |
1327 | +void GINN::clear_accum_attrs(att * attrs) |
1328 | +{ |
1329 | + int i = 2; |
1330 | + while (!attrs[i].attrName.empty()) |
1331 | + { |
1332 | + if (attrs[i].accumulate) |
1333 | + attrs[i].accumVal = 0; |
1334 | + i++; |
1335 | + } |
1336 | +} |
1337 | + |
1338 | +void GINN::update_wishes() |
1339 | +{ |
1340 | + string activeApp; |
1341 | + Gapps *tmpAp = ap; |
1342 | + int diff = 0; |
1343 | + |
1344 | + activeApp = (char *) getCurrentApp(); |
1345 | + //cout << " --ActiveApp " << activeApp << endl; ; |
1346 | + if (!activeApp.empty()) |
1347 | + diff = !(activeApp == ap->appName); |
1348 | + |
1349 | + while (diff && ap->next) |
1350 | + { |
1351 | + ap = ap->next; |
1352 | + diff = !(activeApp == ap->appName); |
1353 | + } |
1354 | + |
1355 | + if (!diff) |
1356 | + wpEnd->next = ap->wp; |
1357 | + else |
1358 | + wpEnd->next = NULL; |
1359 | + |
1360 | + ap = tmpAp; |
1361 | +} |
1362 | + |
1363 | +void GINN::Gmatch(GeisGestureType gesture_type,GeisGestureId gesture_id, |
1364 | + GeisSize attr_count, GeisGestureAttr * attrs, int state) |
1365 | +{ |
1366 | + Gwish *topw; |
1367 | + int DeviceID = attrs[0].integer_val; |
1368 | + int Dindex = DId2Index(DeviceID); //Device index on device_list |
1369 | + topw = wp; |
1370 | + update_wishes(); |
1371 | + while (wp && (!wp->key.empty() || wp->button)) |
1372 | + { |
1373 | + int valid = 1; |
1374 | + if (gesture_type == wp->Type && attrs[8].integer_val == wp->TouchNum && |
1375 | + (device_list[Dindex].isDirectTouch == wp->DirectTouch || wp->DirectTouch == -1)) //wp->DirectTouch is -1 if no screen option define in wish tag |
1376 | + { |
1377 | + int attrsI = 9, cAttrI = 2; |
1378 | + do |
1379 | + { |
1380 | + if (attrs[attrsI].name == wp->config_attr[cAttrI].attrName) |
1381 | + { |
1382 | +// cout << "DEBUG -- comparing " << attrs[attrsI].name << wp->config_attr[cAttrI].attrName << ": "; |
1383 | +// cout << attrs[attrsI].float_val << wp->config_attr[cAttrI].val << wp->config_attr[cAttrI].valMax << endl; |
1384 | +// cout << inside(attrs[attrsI].float_val,wp->config_attr[cAttrI].val, wp->config_attr[cAttrI].valMax) << endl; |
1385 | + if (wp->config_attr[cAttrI].accumulate) |
1386 | + { |
1387 | + wp->config_attr[cAttrI].accumVal += attrs[attrsI].float_val; |
1388 | + valid = valid |
1389 | + && inside(wp->config_attr |
1390 | + [cAttrI].accumVal, |
1391 | + wp->config_attr |
1392 | + [cAttrI].val, |
1393 | + wp->config_attr[cAttrI].valMax); |
1394 | + } |
1395 | + else |
1396 | + valid = valid && inside(attrs[attrsI].float_val, wp->config_attr |
1397 | + [cAttrI].val, wp->config_attr[cAttrI].valMax); |
1398 | + attrsI++; |
1399 | + cAttrI++; |
1400 | + } |
1401 | + else |
1402 | + attrsI++; |
1403 | + } while (!wp->config_attr[cAttrI].attrName.empty() && attrsI < 18); |
1404 | + |
1405 | + if (valid && wp->when == state) |
1406 | + { |
1407 | + if ((0 != wp->button) && (!wp->key.empty())) |
1408 | + { |
1409 | + injMixBtnKey(XStringToKeysym(wp->key.c_str()), wp->button, wp->modifiers); |
1410 | + cout << "MIX -- MIX"; |
1411 | + } |
1412 | + else |
1413 | + { |
1414 | + if (0 != wp->button) |
1415 | + injButton(wp->button, wp->modifiers); |
1416 | + if (!wp->key.empty()) |
1417 | + injKey(XStringToKeysym(wp->key.c_str()), wp->modifiers); |
1418 | + } |
1419 | + clear_accum_attrs(wp->config_attr); |
1420 | + break; |
1421 | + } |
1422 | + } |
1423 | + if (state == GINN_FINISH) |
1424 | + clear_accum_attrs(wp->config_attr); |
1425 | + wp = wp->next; |
1426 | + } |
1427 | + wp = topw; |
1428 | +} |
1429 | + |
1430 | +Window GINN::getRootWindow() |
1431 | +{ |
1432 | + Display *display = NULL; |
1433 | + Window window = 0; |
1434 | + |
1435 | + display = XOpenDisplay(NULL); |
1436 | + if (!display) |
1437 | + { |
1438 | + cerr << "error opening X11 display.\n"; |
1439 | + exit(1); |
1440 | + } |
1441 | + |
1442 | + window = DefaultRootWindow(display); |
1443 | + |
1444 | + XCloseDisplay(display); |
1445 | + |
1446 | + return window; |
1447 | +} |
1448 | + |
1449 | +void GINN::print_attr(GeisGestureAttr * attr) |
1450 | +{ |
1451 | + fprintf(stdout, "\tattr %s=", attr->name); |
1452 | + switch (attr->type) { |
1453 | + case GEIS_ATTR_TYPE_BOOLEAN: |
1454 | + fprintf(stdout, "%s\n", attr->boolean_val ? "true" : "false"); |
1455 | + break; |
1456 | + case GEIS_ATTR_TYPE_FLOAT: |
1457 | + fprintf(stdout, "%f\n", attr->float_val); |
1458 | + break; |
1459 | + case GEIS_ATTR_TYPE_INTEGER: |
1460 | + fprintf(stdout, "%d\n", attr->integer_val); |
1461 | + break; |
1462 | + case GEIS_ATTR_TYPE_STRING: |
1463 | + fprintf(stdout, "\"%s\"\n", attr->string_val); |
1464 | + break; |
1465 | + default: |
1466 | + fprintf(stdout, "<unknown>\n"); |
1467 | + break; |
1468 | + } |
1469 | +} |
1470 | + |
1471 | +void GINN::Gadded(GeisGestureType gesture_type,GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs) |
1472 | +{ |
1473 | + int i = 0; |
1474 | + fprintf(stdout, "Gesture type %d added\n", gesture_type); |
1475 | + for (i = 0; i < attr_count; ++i) |
1476 | + print_attr(&attrs[i]); |
1477 | +} |
1478 | + |
1479 | +void GINN::Gremoved(GeisGestureType gesture_type, GeisGestureId gesture_id,GeisSize attr_count, GeisGestureAttr * attrs) |
1480 | +{ |
1481 | + int i = 0; |
1482 | + fprintf(stdout, "Gesture type %d removed\n", gesture_type); |
1483 | + for (i = 0; i < attr_count; ++i) |
1484 | + print_attr(&attrs[i]); |
1485 | +} |
1486 | + |
1487 | +void GINN::Gstart(GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs) |
1488 | +{ |
1489 | + int i = 0; |
1490 | + fprintf(stdout, "Gesture type %d started\n", gesture_type); |
1491 | + for (i = 0; i < attr_count; ++i) |
1492 | + print_attr(&attrs[i]); |
1493 | + |
1494 | + // In GEIS v1, we know that the focus coords are in attrs 5 and 6 |
1495 | + movePointer((int)attrs[5].float_val, (int)attrs[6].float_val); |
1496 | +} |
1497 | + |
1498 | +void GINN::Gupdate(GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs) |
1499 | +{ |
1500 | + int i = 0; |
1501 | + cout << "Gesture type " << gesture_type << " updated\n"; |
1502 | + for (i = 0; i < attr_count; ++i) |
1503 | + print_attr(&attrs[i]); |
1504 | + Gmatch(gesture_type, gesture_id, attr_count, attrs,GINN_UPDATE); |
1505 | +} |
1506 | + |
1507 | +void GINN::Gfinish(GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs) |
1508 | +{ |
1509 | + int i = 0; |
1510 | + fprintf(stdout, "Gesture type %d finished\n", gesture_type); |
1511 | + for (i = 0; i < attr_count; ++i); //print_attr(&attrs[i]); |
1512 | + Gmatch(gesture_type, gesture_id, attr_count, attrs, GINN_FINISH); |
1513 | +} |
1514 | + |
1515 | +/* |
1516 | + * Searches for a default config file. |
1517 | + * |
1518 | + * Returns a pointer to a config file name (which must be freed) or NULL |
1519 | + * if no default config file was found. |
1520 | + */ |
1521 | +string GINN::ginn_default_config() |
1522 | +{ |
1523 | + string default_file_name = "/wishes.xml"; |
1524 | + static char *search_paths[] = {"etc","../etc",".","$HOME/.ginn" , "/etc/ginn" , "/etc" }; |
1525 | + static const int num_paths = sizeof(search_paths) / sizeof(const char *); |
1526 | + int i; |
1527 | + |
1528 | + for (i = 0; i < num_paths; ++i) |
1529 | + { |
1530 | + struct stat sbuf; |
1531 | + string file_name; |
1532 | + |
1533 | + if (strstr(search_paths[i], "$HOME")) |
1534 | + { |
1535 | + char *home_dir = getenv("HOME"); |
1536 | + if (!home_dir) |
1537 | + { |
1538 | + continue; |
1539 | + } |
1540 | + else |
1541 | + { |
1542 | + char *cdr = index(search_paths[i], '/'); |
1543 | + file_name = home_dir; |
1544 | + file_name += cdr; |
1545 | + } |
1546 | + } |
1547 | + else |
1548 | + { |
1549 | + file_name = search_paths[i]; |
1550 | + } |
1551 | + file_name += default_file_name; |
1552 | + int sres = stat(file_name.c_str(), &sbuf); |
1553 | + if (sres == 0) |
1554 | + { |
1555 | + cout << "Using wishes file " << file_name << endl; |
1556 | + return file_name; |
1557 | + } |
1558 | + } |
1559 | + |
1560 | + return ""; |
1561 | +} |
1562 | +//! find out is the device is Direct Touch for example touchscreen is but touchpad not! |
1563 | +bool GINN::isDirectTouch(int deviceID) |
1564 | +{ |
1565 | + GeisDevice device; |
1566 | + int count = geis_device_attr_count (device); |
1567 | + for (int i =0;i<count;i++) |
1568 | + { |
1569 | + GeisGestureAttr *buffer = (GeisGestureAttr *) geis_device_attr(device,i); |
1570 | + if (!strcmp(buffer->name , GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH)) |
1571 | + { |
1572 | + return buffer->boolean_val; |
1573 | + } |
1574 | + } |
1575 | +} |
1576 | +//! set Gesture functon callback for GEIS API. |
1577 | +void GINN::setGFuncton(GCallback GaddedP, GCallback GremovedP, GCallback GstartP, GCallback GupdateP, GCallback GfinishP) |
1578 | +{ |
1579 | + gesture_funcs.added = GaddedP; |
1580 | + gesture_funcs.removed = GremovedP; |
1581 | + gesture_funcs.start = GstartP; |
1582 | + gesture_funcs.update = GupdateP; |
1583 | + gesture_funcs.finish = GfinishP; |
1584 | +} |
1585 | +//! get Gesture functon callback (More info on setGFuncton). |
1586 | +GeisGestureFuncs GINN::getGFuncton() |
1587 | +{ |
1588 | + return gesture_funcs; |
1589 | +} |
1590 | +//! Open (even from argv) and Check Wish file automatically and if any problem emit error and print it. |
1591 | +void GINN::loadConfig(int argc, char *argv[]) |
1592 | +{ |
1593 | + if (argc < 2) |
1594 | + { |
1595 | + cerr << "usage: " << argv[0] << " <configxml>\n"; |
1596 | + cfg_path = ginn_default_config(); |
1597 | + if (cfg_path.empty()) |
1598 | + { |
1599 | + cerr << "using default configuration file " << cfg_path << "... \n"; |
1600 | + } |
1601 | + } |
1602 | + else |
1603 | + { |
1604 | + cfg_path = strdup(argv[1]); |
1605 | + } |
1606 | + if (cfg_path.empty()) |
1607 | + { |
1608 | + cerr << "Could not find Ginn wishes\n"; |
1609 | + exit (-1); |
1610 | + } |
1611 | + |
1612 | + if (ginn_config_open(&cfg, cfg_path.c_str())) |
1613 | + { |
1614 | + cerr << "Could not load Ginn wishes\n"; |
1615 | + exit (-1); |
1616 | + } |
1617 | + config_load = true; |
1618 | +} |
1619 | +//! Print the config file. |
1620 | +void GINN::printConfig() |
1621 | +{ |
1622 | + if (config_load) |
1623 | + ginn_config_print(&cfg); |
1624 | +} |
1625 | +//! Store the config file and process it |
1626 | +void GINN::StoreConfig() |
1627 | +{ |
1628 | + if (config_load) |
1629 | + ginn_config_store(&cfg, wp, ap); |
1630 | +} |
1631 | + |
1632 | +//! subscribe all gesture callback and other value on GEIS |
1633 | +GeisStatus GINN::Gsubscribe(GeisInstance geis_instance, GeisInputDeviceId *input_list, const char **gesture_list) |
1634 | +{ |
1635 | + return geis_subscribe(geis_instance, input_list, gesture_list, &gesture_funcs, this); |
1636 | +} |
1637 | +//! set Device functon callback for GEIS API. |
1638 | +void GINN::setDFuncton(DCallback DaddedP, DCallback DchangedP, DCallback DremovedP) |
1639 | +{ |
1640 | + device_funcs.added = DaddedP; |
1641 | + device_funcs.removed = DremovedP; |
1642 | + device_funcs.changed = DchangedP; |
1643 | +} |
1644 | +//! get Device functon callback (More info on setDFuncton). |
1645 | +GeisInputFuncs GINN::getDFuncton() |
1646 | +{ |
1647 | + return device_funcs; |
1648 | +} |
1649 | +//! subscribe all Device callback and other value on GEIS |
1650 | +GeisStatus GINN::Dsubscribe(GeisInstance geis_instance) |
1651 | +{ |
1652 | + return geis_input_devices(geis_instance, &device_funcs, this); |
1653 | +} |
1654 | +//! when a touch device add this function called |
1655 | +void GINN::Dadded(GeisInputDeviceId device_id, void *attrs) |
1656 | +{ |
1657 | + GeisGestureAttr *a = (GeisGestureAttr *)attrs; |
1658 | + GD_att buffer; |
1659 | + try |
1660 | + { |
1661 | + buffer.ID = device_id; |
1662 | + buffer.name = a[0].string_val; |
1663 | + buffer.isDirectTouch = a[2].boolean_val; |
1664 | + buffer.TouchNum = a[3].integer_val; |
1665 | + device_list.push_back(buffer); |
1666 | + } |
1667 | + catch(error_t error) |
1668 | + { |
1669 | + cerr << "Erorr on read Device atrribute for device with ID: " << device_id << endl; |
1670 | + } |
1671 | +} |
1672 | +//! when a touch device attributes changed this function called |
1673 | +void GINN::Dchanged(GeisInputDeviceId device_id, void *attrs) |
1674 | +{ |
1675 | + ; |
1676 | +} |
1677 | +//! when a touch device removed this function called |
1678 | +void GINN::Dremoved(GeisInputDeviceId device_id, void *attrs) |
1679 | +{ |
1680 | + int index = DId2Index(device_id); |
1681 | + device_list.erase(device_list.begin() + index); |
1682 | +} |
1683 | +//! return Device index in device_list from deviceID ; return -1 if the device not found |
1684 | +int GINN::DId2Index(int DeviceID) |
1685 | +{ |
1686 | + for (int i=0;i<device_list.size();i++) |
1687 | + { |
1688 | + if(device_list[i].ID == DeviceID) |
1689 | + return i; |
1690 | + } |
1691 | + return -1; |
1692 | +} |
1693 | + |
1694 | +/** |
1695 | + * Check the loaded wishes to see which gestures are used |
1696 | + * and add these gestures to a NULL terminated list "sub_gestures_list" |
1697 | + * |
1698 | + * This list is used to subscribe only the necessary gestures |
1699 | + * to GEIS. This will avoid issues with 2 finger scrolls and other gestues |
1700 | + * being dropped when not accounted for in the wishes file. |
1701 | +**/ |
1702 | +vector<string> GINN::extract_gesture() |
1703 | +{ |
1704 | + Gapps * appPtr = ap; |
1705 | + Gwish * wishPtr; |
1706 | + int finished = 0; |
1707 | + vector<string> sub_gestures_list(17); |
1708 | + /** |
1709 | + * Loop through each wish inside ap |
1710 | + * After all of the wishes in ap are accounted for |
1711 | + * add global wishes |
1712 | + **/ |
1713 | + |
1714 | + while(finished != 1) |
1715 | + { |
1716 | + // Check if we are finished with the application wishes |
1717 | + if(appPtr == NULL) |
1718 | + { |
1719 | + wishPtr = wp; |
1720 | + finished = 1; |
1721 | + } |
1722 | + else |
1723 | + { |
1724 | + wishPtr = appPtr->wp; |
1725 | + } |
1726 | + |
1727 | + // Loop through each wish |
1728 | + while(wishPtr) |
1729 | + { |
1730 | + int i; |
1731 | + for(i = 0; i < 25; i ++) |
1732 | + { |
1733 | + |
1734 | + string sub_gesture; |
1735 | + char buffer[100]; |
1736 | + int pos = 0; |
1737 | + |
1738 | + // Check for Drag gesture |
1739 | + if(wishPtr->config_attr[i].attrName == "delta x" || wishPtr->config_attr[i].attrName == "delta y" || |
1740 | + wishPtr->config_attr[i].attrName == "velocity x" || wishPtr->config_attr[i].attrName == "velocity y") |
1741 | + { |
1742 | + sprintf(buffer, "Drag,touch=%i", (int)wishPtr->config_attr[1].val); |
1743 | + } |
1744 | + |
1745 | + // Check for Rotate gesture |
1746 | + else if(wishPtr->config_attr[i].attrName == "angle delta"|| |
1747 | + wishPtr->config_attr[i].attrName == "angular velocity"|| |
1748 | + wishPtr->config_attr[i].attrName == "angle") |
1749 | + { |
1750 | + sprintf(buffer, "Rotate,touch=%i", (int)wishPtr->config_attr[1].val); |
1751 | + } |
1752 | + |
1753 | + // Check for Pinch gesture |
1754 | + else if(wishPtr->config_attr[i].attrName == "radius delta" ||wishPtr->config_attr[i].attrName == "radial velocity" || |
1755 | + wishPtr->config_attr[i].attrName == "radius") |
1756 | + { |
1757 | + sprintf(buffer, "Pinch,touch=%i", (int)wishPtr->config_attr[1].val); |
1758 | + } |
1759 | + |
1760 | + // Check for Tap gesture |
1761 | + else if(wishPtr->config_attr[i].attrName == "tap time") |
1762 | + { |
1763 | + sprintf(buffer, "Tap,touch=%i", (int)wishPtr->config_attr[1].val); |
1764 | + } |
1765 | + |
1766 | + // Deallocate sub_gesture if no gesture was found |
1767 | + else |
1768 | + { |
1769 | + buffer[0] = NULL; |
1770 | + continue; |
1771 | + } |
1772 | + sub_gesture = buffer; |
1773 | + |
1774 | + /** Check the current gesture list |
1775 | + * Only add if the gesture is not already in the list |
1776 | + * Store in index of the first NULL found |
1777 | + **/ |
1778 | + |
1779 | + while(pos < 17) |
1780 | + { |
1781 | + if(sub_gestures_list[pos].empty()) |
1782 | + { |
1783 | + sub_gestures_list[pos] = sub_gesture; |
1784 | + break; |
1785 | + } |
1786 | + else if(sub_gesture == sub_gestures_list[pos]) |
1787 | + { |
1788 | + break; |
1789 | + } |
1790 | + pos ++; |
1791 | + } |
1792 | + |
1793 | + |
1794 | + } |
1795 | + // Iterate to the next wish |
1796 | + wishPtr = wishPtr->next; |
1797 | + } |
1798 | + |
1799 | + // If there are more applications, iterate to the next |
1800 | + |
1801 | + if(finished != 1) |
1802 | + { |
1803 | + appPtr = appPtr->next; |
1804 | + } |
1805 | + } |
1806 | + return sub_gestures_list; |
1807 | +} |
1808 | + |
1809 | +//! print the Subscribe gesture list |
1810 | +void GINN::print_SGL(const char **sub_gestures_list) |
1811 | +{ |
1812 | + // Show which gestures were subscribed |
1813 | + cout << "Gestures subscribed:" << endl; |
1814 | + |
1815 | + int pos = 0; |
1816 | + while(pos < 17) |
1817 | + { |
1818 | + if(sub_gestures_list[pos] != NULL) |
1819 | + { |
1820 | + cout << sub_gestures_list[pos] << endl; |
1821 | + } |
1822 | + |
1823 | + pos ++; |
1824 | + } |
1825 | +} |
1826 | + |
1827 | + |
1828 | + |
1829 | + |
1830 | + |
1831 | + |
1832 | + |
1833 | + |
1834 | + |
1835 | + |
1836 | + |
1837 | + |
1838 | + |
1839 | + |
1840 | + |
1841 | + |
1842 | + |
1843 | + |
1844 | + |
1845 | + |
1846 | + |
1847 | + |
1848 | + |
1849 | + |
1850 | + |
1851 | + |
1852 | + |
1853 | + |
1854 | |
1855 | === added file 'src/ginn.h' |
1856 | --- src/ginn.h 1970-01-01 00:00:00 +0000 |
1857 | +++ src/ginn.h 2011-08-23 04:19:23 +0000 |
1858 | @@ -0,0 +1,60 @@ |
1859 | +#ifndef GINN_H |
1860 | +#define GINN_H |
1861 | + |
1862 | +#include "config.h" |
1863 | + |
1864 | +typedef GeisGestureCallback GCallback; |
1865 | +typedef GeisInputCallback DCallback; |
1866 | + |
1867 | +class GINN |
1868 | +{ |
1869 | +public: |
1870 | + GINN(); |
1871 | + void Gmatch(GeisGestureType gesture_type, GeisGestureId gesture_id,GeisSize attr_count,GeisGestureAttr * attrs, int state); |
1872 | + int inside(float x, float a, float b); |
1873 | + bool isDirectTouch(int deviceID); |
1874 | + void clear_accum_attrs(att * attrs); |
1875 | + void update_wishes(); |
1876 | + void print_SGL(const char **sub_gestures_list); |
1877 | + void print_attr(GeisGestureAttr * attr); |
1878 | + Window getRootWindow(); |
1879 | + string ginn_default_config(); |
1880 | + vector<string> extract_gesture(); |
1881 | +//New Interfaces: |
1882 | + int DId2Index(int DeviceID); |
1883 | + void printConfig(); |
1884 | + void StoreConfig(); |
1885 | + void loadConfig(int argc, char *argv[]); |
1886 | + void setGFuncton(GCallback GaddedP, GCallback GremovedP, GCallback GstartP, GCallback GupdateP, GCallback GfinishP); |
1887 | + GeisGestureFuncs getGFuncton(); |
1888 | + void setDFuncton(DCallback DaddedP, DCallback DchangedP, DCallback DremovedP); |
1889 | + GeisInputFuncs getDFuncton(); |
1890 | + GeisStatus Gsubscribe(GeisInstance geis_instance, GeisInputDeviceId *input_list, const char **gesture_list); |
1891 | + GeisStatus Dsubscribe(GeisInstance geis_instance); |
1892 | +//CallBacks: |
1893 | + //Gesture CallBacks |
1894 | + void Gadded (GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs); |
1895 | + void Gremoved(GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs); |
1896 | + void Gstart (GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs); |
1897 | + void Gupdate (GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs); |
1898 | + void Gfinish (GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs); |
1899 | + //Device CallBacks (D in Dadded referred to Device) |
1900 | + void Dadded (GeisInputDeviceId device_id, void *attrs); |
1901 | + void Dchanged(GeisInputDeviceId device_id, void *attrs); |
1902 | + void Dremoved(GeisInputDeviceId device_id, void *attrs); |
1903 | +//Variable: |
1904 | + Gwish *wp, *wpEnd; |
1905 | + Gapps *ap; |
1906 | + att config_attr[25]; |
1907 | + Gwish w1; |
1908 | +private: |
1909 | + GeisGestureFuncs gesture_funcs; |
1910 | + GeisInputFuncs device_funcs; |
1911 | + ginn_config cfg; |
1912 | + string cfg_path; |
1913 | + vector<GD_att> device_list; //save Device list and device attribute |
1914 | + bool config_load; |
1915 | +}; |
1916 | + |
1917 | + |
1918 | +#endif // GINN_H |
1919 | |
1920 | === modified file 'src/ginn.pod' (properties changed: -x to +x) |
1921 | === added file 'src/gir.cpp' |
1922 | --- src/gir.cpp 1970-01-01 00:00:00 +0000 |
1923 | +++ src/gir.cpp 2011-08-23 04:19:23 +0000 |
1924 | @@ -0,0 +1,47 @@ |
1925 | +#include "gir.h" |
1926 | + |
1927 | +Gapps::Gapps() |
1928 | +{ |
1929 | + next = NULL; |
1930 | + wp = NULL; |
1931 | + appName = ""; |
1932 | +} |
1933 | + |
1934 | +Gwish::Gwish() |
1935 | +{ |
1936 | + //Default Value |
1937 | + Type = -1; |
1938 | + TouchNum = 0; |
1939 | + DirectTouch = -1; |
1940 | + // |
1941 | + int i; |
1942 | + button = 0; |
1943 | + key = ""; |
1944 | + next = NULL; |
1945 | + for (i = 0; i < 4; i++) |
1946 | + modifiers[i] = ""; |
1947 | + for (i = 0; i < 25; i++) |
1948 | + { |
1949 | + config_attr[i].attrName = ""; |
1950 | + config_attr[i].val = 0; |
1951 | + config_attr[i].valMax = 0; |
1952 | + } |
1953 | +} |
1954 | + |
1955 | + |
1956 | + |
1957 | + |
1958 | + |
1959 | + |
1960 | + |
1961 | + |
1962 | + |
1963 | + |
1964 | + |
1965 | + |
1966 | + |
1967 | + |
1968 | + |
1969 | + |
1970 | + |
1971 | + |
1972 | |
1973 | === added file 'src/gir.h' |
1974 | --- src/gir.h 1970-01-01 00:00:00 +0000 |
1975 | +++ src/gir.h 2011-08-23 04:19:23 +0000 |
1976 | @@ -0,0 +1,70 @@ |
1977 | +/** |
1978 | + * New Implemetion for GINN Include C++ Callback |
1979 | + */ |
1980 | + |
1981 | +#ifndef GIR_H |
1982 | +#define GIR_H |
1983 | + |
1984 | +#include "ginn.h" |
1985 | + |
1986 | +/** Gesure CallBack Interface Start Decration HERE! These function recieve events from GEIS and send it to |
1987 | +related object as well as a postman! |
1988 | +***/ |
1989 | +static void gesture_added(void *cookie,GeisGestureType gesture_type, GeisGestureId gesture_id, |
1990 | + GeisSize attr_count, GeisGestureAttr * attrs) |
1991 | +{ |
1992 | + GINN *buffer = (GINN *) cookie; |
1993 | + buffer->Gadded(gesture_type,gesture_id,attr_count,attrs); |
1994 | +} |
1995 | + |
1996 | +static void gesture_removed(void *cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, |
1997 | + GeisSize attr_count, GeisGestureAttr * attrs) |
1998 | +{ |
1999 | + GINN *buffer = (GINN *) cookie; |
2000 | + buffer->Gadded(gesture_type,gesture_id,attr_count,attrs); |
2001 | +} |
2002 | + |
2003 | +static void gesture_start(void *cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, |
2004 | + GeisSize attr_count, GeisGestureAttr * attrs) |
2005 | +{ |
2006 | + GINN *buffer = (GINN *) cookie; |
2007 | + buffer->Gstart(gesture_type,gesture_id,attr_count,attrs); |
2008 | +} |
2009 | + |
2010 | +static void gesture_update(void *cookie, GeisGestureType gesture_type, |
2011 | + GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs) |
2012 | +{ |
2013 | + GINN *buffer = (GINN *) cookie; |
2014 | + buffer->Gupdate(gesture_type,gesture_id,attr_count,attrs); |
2015 | +} |
2016 | + |
2017 | +static void gesture_finish(void *cookie, GeisGestureType gesture_type, |
2018 | + GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs) |
2019 | +{ |
2020 | + GINN *buffer = (GINN *) cookie; |
2021 | + buffer->Gfinish(gesture_type,gesture_id,attr_count,attrs); |
2022 | +} |
2023 | + |
2024 | +/** Device CallBack Interface Start Decration HERE! These function recieve events from GEIS and send it to |
2025 | +related object as well as a postman! |
2026 | +***/ |
2027 | +static void device_added(void *cookie, GeisInputDeviceId device_id, void *attrs) |
2028 | +{ |
2029 | + GINN *buffer = (GINN *) cookie; |
2030 | + buffer->Dadded(device_id,attrs); |
2031 | +} |
2032 | + |
2033 | + |
2034 | +static void device_changed(void *cookie, GeisInputDeviceId device_id, void *attrs) |
2035 | +{ |
2036 | + GINN *buffer = (GINN *) cookie; |
2037 | + buffer->Dchanged(device_id,attrs); |
2038 | +} |
2039 | + |
2040 | + |
2041 | +static void device_removed(void *cookie, GeisInputDeviceId device_id, void *attrs) |
2042 | +{ |
2043 | + GINN *buffer = (GINN *) cookie; |
2044 | + buffer->Dremoved(device_id,attrs); |
2045 | +} |
2046 | +#endif // GIR_H |
2047 | |
2048 | === added file 'src/header.h' |
2049 | --- src/header.h 1970-01-01 00:00:00 +0000 |
2050 | +++ src/header.h 2011-08-23 04:19:23 +0000 |
2051 | @@ -0,0 +1,38 @@ |
2052 | +#ifndef HEADER_H |
2053 | +#define HEADER_H |
2054 | + |
2055 | +//Standart C and C++ Header |
2056 | +#include <string> |
2057 | +#include <vector> |
2058 | +#include <cstring> |
2059 | +#include <errno.h> |
2060 | +#include <stdio.h> |
2061 | +#include <stdlib.h> |
2062 | +#include <string.h> |
2063 | +#include <unistd.h> |
2064 | +#include <iostream> |
2065 | +//X window Header |
2066 | +#include <X11/X.h> |
2067 | +#include <X11/Xlib.h> |
2068 | +#include <X11/keysym.h> |
2069 | +#include <X11/extensions/XTest.h> |
2070 | +//Other |
2071 | +#include <sys/select.h> |
2072 | +#include <sys/stat.h> |
2073 | +#include <libxml/tree.h> |
2074 | +#include <geis/geis.h> |
2075 | +#include <libxml/parser.h> |
2076 | + |
2077 | +using namespace std; |
2078 | + |
2079 | +//Function Prototypes |
2080 | +char *getCurrentApp(); |
2081 | +//Decleare in xt.cpp |
2082 | +void injMixBtnKey (KeySym ks, int btn, string *modifiers); |
2083 | +void injButton (int btn, string *modifiers); |
2084 | +void injKey (KeySym ks, string *modifiers); |
2085 | +void movePointer (int x, int y); |
2086 | +void openDisplay ( ); |
2087 | +void closeDisplay ( ); |
2088 | + |
2089 | +#endif // HEADER_H |
2090 | |
2091 | === added file 'src/main.cpp' |
2092 | --- src/main.cpp 1970-01-01 00:00:00 +0000 |
2093 | +++ src/main.cpp 2011-08-23 04:19:23 +0000 |
2094 | @@ -0,0 +1,137 @@ |
2095 | +/** |
2096 | + * Copyright 2010 Canonical Ltd. |
2097 | + * |
2098 | + * This library is free software; you can redistribute it and/or modify it under |
2099 | + * the terms of the GNU General Public License as published by the Free Software |
2100 | + * Foundation; either version 3 of the License, or (at your option) any later |
2101 | + * version. |
2102 | + * |
2103 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
2104 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
2105 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
2106 | + * details. |
2107 | + * |
2108 | + * You should have received a copy of the GNU General Public License along with |
2109 | + * this program; if not, write to the Free Software Foundation, Inc., 51 |
2110 | + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
2111 | + * |
2112 | + * Authors: |
2113 | + * Mohamed-Ikbel Boulabiar <boulabiar@gmail.com> |
2114 | + * Henrik Rydberg <rydberg@bitmath.org> |
2115 | + * Stephen M. Webb <stephen.webb@canonical.com> |
2116 | + * Bijan Binaee <bijanbina@gmail.com> |
2117 | + * |
2118 | + */ |
2119 | + |
2120 | +#include "gir.h" |
2121 | + |
2122 | +int main(int argc, char *argv[]) |
2123 | +{ |
2124 | + GeisStatus status = GEIS_UNKNOWN_ERROR; |
2125 | + GeisXcbWinInfo xcb_win_info; |
2126 | + GINN local; |
2127 | + //Initizalize xcb_win_info |
2128 | + xcb_win_info.display_name = NULL; |
2129 | + xcb_win_info.screenp = NULL; |
2130 | + xcb_win_info.window_id = local.getRootWindow(); |
2131 | + //Initialize win_info |
2132 | + GeisWinInfo win_info = {GEIS_XCB_FULL_WINDOW,&xcb_win_info}; |
2133 | + GeisInstance instance; |
2134 | + //Initializ GINN Class |
2135 | + local.setGFuncton(gesture_added, gesture_removed, gesture_start, gesture_update, gesture_finish); |
2136 | + local.setDFuncton(device_added,device_changed,device_removed); |
2137 | + |
2138 | + local.loadConfig(argc,argv); |
2139 | + //local.printConfig(); |
2140 | + local.StoreConfig(); |
2141 | + |
2142 | + |
2143 | + local.wpEnd = local.wp; |
2144 | + while (local.wpEnd->next) |
2145 | + local.wpEnd = local.wpEnd->next; |
2146 | + |
2147 | + int pos = 2; |
2148 | + cout << endl; |
2149 | + while (!local.config_attr[pos].attrName.empty()) |
2150 | + { |
2151 | + cout << "DEBUG " << pos << local.config_attr[pos].attrName << local.config_attr[pos].val << local.config_attr[pos].valMax << endl; |
2152 | + pos++; |
2153 | + } |
2154 | + |
2155 | + //Use Dynamic sub gestures list |
2156 | + vector<string> SGL = local.extract_gesture();//sub gestures list buffer |
2157 | + const char *sub_gestures_list[SGL.size()]; |
2158 | + //convert to const char |
2159 | + for (int i =0;i<SGL.size();i++) |
2160 | + { |
2161 | + sub_gestures_list[i] = (char *)(SGL[i].c_str()); |
2162 | + if (SGL[i].empty()) |
2163 | + sub_gestures_list[i]= NULL; |
2164 | + } |
2165 | + local.print_SGL(sub_gestures_list); |
2166 | + //End Use Dynamic sub gestures list |
2167 | + |
2168 | + status = geis_init(&win_info, &instance); |
2169 | + if (status != GEIS_STATUS_SUCCESS) { |
2170 | + cerr << "error in geis_init\n"; |
2171 | + return 1; |
2172 | + } |
2173 | + |
2174 | + status = geis_configuration_supported(instance, GEIS_CONFIG_UNIX_FD); |
2175 | + if (status != GEIS_STATUS_SUCCESS) { |
2176 | + cerr << "GEIS does not support Unix fd\n"; |
2177 | + return 1; |
2178 | + } |
2179 | + |
2180 | + int fd = -1; |
2181 | + status = geis_configuration_get_value(instance, GEIS_CONFIG_UNIX_FD, &fd); |
2182 | + if (status != GEIS_STATUS_SUCCESS) |
2183 | + { |
2184 | + cerr << "error retrieving GEIS fd\n"; |
2185 | + return 1; |
2186 | + } |
2187 | + //Subscribe Device input callback |
2188 | + status = local.Dsubscribe(instance);// GEIS_ALL_GESTURES, |
2189 | + if (status != GEIS_STATUS_SUCCESS) |
2190 | + { |
2191 | + cerr << "error on subscribing to Device\n"; |
2192 | + return 1; |
2193 | + } |
2194 | + //Subscribe gesture callback |
2195 | + status = local.Gsubscribe(instance, GEIS_ALL_INPUT_DEVICES, const_cast <const char**>(sub_gestures_list));// GEIS_ALL_GESTURES, |
2196 | + if (status != GEIS_STATUS_SUCCESS) |
2197 | + { |
2198 | + cerr << "error on subscribing to gestures\n"; |
2199 | + return 1; |
2200 | + } |
2201 | + |
2202 | + openDisplay(); |
2203 | + |
2204 | + while (1) |
2205 | + { |
2206 | + fd_set read_fds; |
2207 | + FD_ZERO(&read_fds); |
2208 | + FD_SET(fd, &read_fds); |
2209 | + int sstat = select(fd + 1, &read_fds, NULL, NULL, NULL); |
2210 | + if (sstat < 0) |
2211 | + { |
2212 | + cerr << "error " << errno << "in select(): " << strerror(errno) << endl; |
2213 | + break; |
2214 | + } |
2215 | + |
2216 | + if (FD_ISSET(fd, &read_fds)) |
2217 | + geis_event_dispatch(instance); |
2218 | + } |
2219 | + |
2220 | + delete local.wp; |
2221 | + geis_finish(instance); |
2222 | + closeDisplay(); |
2223 | + |
2224 | + return 0; |
2225 | +} |
2226 | + |
2227 | + |
2228 | + |
2229 | + |
2230 | + |
2231 | + |
2232 | |
2233 | === modified file 'src/todo' (properties changed: -x to +x) |
2234 | === removed file 'src/xt.c' |
2235 | --- src/xt.c 2011-03-16 16:23:21 +0000 |
2236 | +++ src/xt.c 1970-01-01 00:00:00 +0000 |
2237 | @@ -1,108 +0,0 @@ |
2238 | -/* |
2239 | - * Copyright (C) 2010 Canonical, Ltd. |
2240 | - * |
2241 | - * This program is free software: you can redistribute it and/or modify |
2242 | - * it under the terms of the GNU General Public License as published by |
2243 | - * the Free Software Foundation, either version 3 of the License, or |
2244 | - * (at your option) any later version. |
2245 | - |
2246 | - * This program is distributed in the hope that it will be useful, |
2247 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2248 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2249 | - * GNU General Public License for more details. |
2250 | - |
2251 | - * You should have received a copy of the GNU General Public License |
2252 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2253 | - * |
2254 | - * Author: Mohamed-Ikbel Boulabiar <boulabiar@gmail.com> |
2255 | - */ |
2256 | - |
2257 | -#include <X11/X.h> |
2258 | -#include <X11/extensions/XTest.h> |
2259 | -#include <X11/keysym.h> |
2260 | - |
2261 | -static Display *disp = NULL; |
2262 | - |
2263 | -void openDisplay() |
2264 | -{ |
2265 | - disp = XOpenDisplay(NULL); |
2266 | -} |
2267 | - |
2268 | -void closeDisplay() |
2269 | -{ |
2270 | - XCloseDisplay(disp); |
2271 | -} |
2272 | - |
2273 | -void movePointer(int x, int y) |
2274 | -{ |
2275 | - XTestFakeMotionEvent(disp, 0, x, y, CurrentTime); |
2276 | -} |
2277 | - |
2278 | -void injKey(KeySym ks, char *modifiers[]) |
2279 | -{ |
2280 | - int i; |
2281 | - |
2282 | - for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++) |
2283 | - XTestFakeKeyEvent(disp, |
2284 | - XKeysymToKeycode(disp, |
2285 | - XStringToKeysym(modifiers |
2286 | - [i])), True, |
2287 | - CurrentTime); |
2288 | - XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime); |
2289 | - XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False, |
2290 | - CurrentTime); |
2291 | - for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++) |
2292 | - XTestFakeKeyEvent(disp, |
2293 | - XKeysymToKeycode(disp, |
2294 | - XStringToKeysym(modifiers |
2295 | - [i])), False, |
2296 | - CurrentTime); |
2297 | - |
2298 | - XFlush(disp); |
2299 | -} |
2300 | - |
2301 | -void injButton(int btn, char *modifiers[]) |
2302 | -{ |
2303 | - int i; |
2304 | - |
2305 | - for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++) |
2306 | - XTestFakeKeyEvent(disp, |
2307 | - XKeysymToKeycode(disp, |
2308 | - XStringToKeysym(modifiers |
2309 | - [i])), True, |
2310 | - CurrentTime); |
2311 | - XTestFakeButtonEvent(disp, btn, True, CurrentTime); |
2312 | - XTestFakeButtonEvent(disp, btn, False, CurrentTime); |
2313 | - for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++) |
2314 | - XTestFakeKeyEvent(disp, |
2315 | - XKeysymToKeycode(disp, |
2316 | - XStringToKeysym(modifiers |
2317 | - [i])), False, |
2318 | - CurrentTime); |
2319 | - |
2320 | - XFlush(disp); |
2321 | -} |
2322 | - |
2323 | -void injMixBtnKey(KeySym ks, int btn, char *modifiers[]) |
2324 | -{ |
2325 | - int i; |
2326 | - |
2327 | - XTestFakeButtonEvent(disp, btn, True, CurrentTime); |
2328 | - for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++) |
2329 | - XTestFakeKeyEvent(disp, |
2330 | - XKeysymToKeycode(disp, |
2331 | - XStringToKeysym(modifiers |
2332 | - [i])), True, |
2333 | - CurrentTime); |
2334 | - XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime); |
2335 | - XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False, |
2336 | - CurrentTime); |
2337 | - for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++) |
2338 | - XTestFakeKeyEvent(disp, |
2339 | - XKeysymToKeycode(disp, |
2340 | - XStringToKeysym(modifiers |
2341 | - [i])), False, |
2342 | - CurrentTime); |
2343 | - XTestFakeButtonEvent(disp, btn, False, CurrentTime); |
2344 | - XFlush(disp); |
2345 | -} |
2346 | |
2347 | === added file 'src/xt.cpp' |
2348 | --- src/xt.cpp 1970-01-01 00:00:00 +0000 |
2349 | +++ src/xt.cpp 2011-08-23 04:19:23 +0000 |
2350 | @@ -0,0 +1,97 @@ |
2351 | +/* |
2352 | + * Copyright (C) 2010 Canonical, Ltd. |
2353 | + * |
2354 | + * This program is free software: you can redistribute it and/or modify |
2355 | + * it under the terms of the GNU General Public License as published by |
2356 | + * the Free Software Foundation, either version 3 of the License, or |
2357 | + * (at your option) any later version. |
2358 | + |
2359 | + * This program is distributed in the hope that it will be useful, |
2360 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2361 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2362 | + * GNU General Public License for more details. |
2363 | + |
2364 | + * You should have received a copy of the GNU General Public License |
2365 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2366 | + * |
2367 | + * Author: Mohamed-Ikbel Boulabiar <boulabiar@gmail.com> |
2368 | + */ |
2369 | +#include "header.h" |
2370 | + |
2371 | +static Display *disp = NULL; |
2372 | + |
2373 | +void openDisplay() |
2374 | +{ |
2375 | + disp = XOpenDisplay(NULL); |
2376 | +} |
2377 | + |
2378 | +void closeDisplay() |
2379 | +{ |
2380 | + XCloseDisplay(disp); |
2381 | +} |
2382 | + |
2383 | +void movePointer(int x, int y) |
2384 | +{ |
2385 | + XTestFakeMotionEvent(disp, 0, x, y, CurrentTime); |
2386 | +} |
2387 | + |
2388 | +void injKey(KeySym ks, string *modifiers) |
2389 | +{ |
2390 | + int i; |
2391 | + |
2392 | + for (i = 0; i < 4 && !modifiers[i].empty(); i++) |
2393 | + XTestFakeKeyEvent(disp, |
2394 | + XKeysymToKeycode(disp, |
2395 | + XStringToKeysym(modifiers[i].c_str())), True, |
2396 | + CurrentTime); |
2397 | + XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime); |
2398 | + XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False, |
2399 | + CurrentTime); |
2400 | + for (i = 0; i < 4 && !modifiers[i].empty(); i++) |
2401 | + XTestFakeKeyEvent(disp, |
2402 | + XKeysymToKeycode(disp, |
2403 | + XStringToKeysym(modifiers[i].c_str())), False, |
2404 | + CurrentTime); |
2405 | + |
2406 | + XFlush(disp); |
2407 | +} |
2408 | + |
2409 | +void injButton(int btn, string *modifiers) |
2410 | +{ |
2411 | + int i; |
2412 | + |
2413 | + for (i = 0; i < 4 && !modifiers[i].empty(); i++) |
2414 | + XTestFakeKeyEvent(disp, |
2415 | + XKeysymToKeycode(disp, |
2416 | + XStringToKeysym(modifiers[i].c_str())), True, |
2417 | + CurrentTime); |
2418 | + XTestFakeButtonEvent(disp, btn, True, CurrentTime); |
2419 | + XTestFakeButtonEvent(disp, btn, False, CurrentTime); |
2420 | + for (i = 0; i < 4 && !modifiers[i].empty(); i++) |
2421 | + XTestFakeKeyEvent(disp, |
2422 | + XKeysymToKeycode(disp, |
2423 | + XStringToKeysym(modifiers[i].c_str())), False, |
2424 | + CurrentTime); |
2425 | + |
2426 | + XFlush(disp); |
2427 | +} |
2428 | + |
2429 | +void injMixBtnKey(KeySym ks, int btn, string *modifiers) |
2430 | +{ |
2431 | + int i; |
2432 | + |
2433 | + XTestFakeButtonEvent(disp, btn, True, CurrentTime); |
2434 | + for (i = 0; i < 4 && !modifiers[i].empty(); i++) |
2435 | + XTestFakeKeyEvent(disp, |
2436 | + XKeysymToKeycode(disp, XStringToKeysym(modifiers [i].c_str())), True, |
2437 | + CurrentTime); |
2438 | + XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime); |
2439 | + XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False, |
2440 | + CurrentTime); |
2441 | + for (i = 0; i < 4 && !modifiers[i].empty(); i++) |
2442 | + XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, |
2443 | + XStringToKeysym(modifiers [i].c_str())), False, |
2444 | + CurrentTime); |
2445 | + XTestFakeButtonEvent(disp, btn, False, CurrentTime); |
2446 | + XFlush(disp); |
2447 | +} |
I have a number of issues with this proposal.
(1) You need to explicitly justify moving from C to C++. In particular, renaming all existing C sources to C++. What does the project gain from this? What are the possible repercussions (ie. what new problems are introduced and what new potential for error is obtained)? The renaming introduces a lot of noise that makes it difficult to evaluate the rest of the change.
(2) This merge marks most sources as executable. That is undesirable.
(3) What is the .directory file? It does not appear to be necessary to build the project.
(4) Please do not use ///-style or //!-style comments, use Javadoc-style (/**) comments for consistency with the style of other uTouch projects.
(5) The various classes implement their own containers. Is there a good reason not to use the (tested, dependable) standard library instead? One of the main advantages to porting to C++ is the ability to use the C++ library.
(6) None of this code is exception safe. When errors are encountered, resources are leaked or undefined behaviour is encountered.
(7) There is no cleanup: objects are created using new but never deleted.
(8) Class constructors are assigning initial values to members in the constructor body instead of using initializer lists. Most of the classes are C structs that rely on external code to maintain their invariants: what is the point of converting to C++ if the code is just non-OO style C? See http:// en.wikipedia. org/wiki/ Class_invariant.
(9) Why add a capital G or D to classes and function names? This does not contribute to readability in a positive way. If this is to represent words like "device" or "gesture", use those words. We are not experiencing a shortage of ASCII.
(10) Some variable names could reflect their purpose better: for example, what is "local" used for?
(11) "header.h" is not an acceptable header file name. Also, please do not create a single header file to include all other header files any source file might need. Headers should pull in only the minimal subset of headers they need to compile on their own. Never put a "using namespace" directive in a header file.
(12) GINN::Dadded catches an exception of type error_t, but there is no code inside the try-block that can throw such a type. The only exception possible from the try-block is std::bad_alloc.
(13) Please leave at least one blank line between function definitions for readability.