Merge lp:~bijanbina/ginn/GIR into lp:ginn

Proposed by Bijan Binaee
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
Reviewer Review Type Date Requested Status
Chase Douglas (community) Disapprove
Stephen M. Webb (community) Needs Fixing
Review via email: mp+72521@code.launchpad.net

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
---------------------------------------------------------------------------------------------------------------------------------------
##################<Define Gesture Run On Which Device>#####################
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"/>
        <button>4</button>
      </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
-------------------------------------------------------------------------------------------------------------------------------------

To post a comment you must log in.
Revision history for this message
Stephen M. Webb (bregma) 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://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.

review: Needs Fixing
Revision history for this message
Bijan Binaee (bijanbina) wrote :
Download full text (3.4 KiB)

> 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.

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 ...

Read more...

Revision history for this message
Chase Douglas (chasedouglas) wrote :
Download full text (3.5 KiB)

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...

Read more...

review: Disapprove

Unmerged revisions

90. By Bijan Binaee

GIR

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore' (properties changed: -x to +x)
=== added file '.directory'
--- .directory 1970-01-01 00:00:00 +0000
+++ .directory 2011-08-23 04:19:23 +0000
@@ -0,0 +1,6 @@
1[Dolphin]
2Timestamp=2011,8,23,8,9,6
3Version=2
4
5[Settings]
6ShowDotFiles=true
07
=== modified file 'COPYING' (properties changed: -x to +x)
=== modified file 'INSTALL' (properties changed: -x to +x)
=== modified file 'Makefile.am' (properties changed: -x to +x)
=== modified file 'README' (properties changed: -x to +x)
=== modified file 'configure.ac' (properties changed: -x to +x)
--- configure.ac 2011-05-17 12:46:31 +0000
+++ configure.ac 2011-08-23 04:19:23 +0000
@@ -20,6 +20,7 @@
2020
21# Checks for programs.21# Checks for programs.
22AC_PROG_CC22AC_PROG_CC
23AC_PROG_CXX
23AC_PROG_INSTALL24AC_PROG_INSTALL
2425
25PKG_CHECK_MODULES([GEIS], [libutouch-geis >= 1.0.10])26PKG_CHECK_MODULES([GEIS], [libutouch-geis >= 1.0.10])
2627
=== modified file 'etc/Makefile.am' (properties changed: -x to +x)
=== modified file 'etc/appNames' (properties changed: -x to +x)
=== modified file 'etc/attributes' (properties changed: -x to +x)
=== modified file 'etc/buttons' (properties changed: -x to +x)
=== modified file 'etc/ginn.desktop' (properties changed: -x to +x)
=== modified file 'etc/keys' (properties changed: -x to +x)
=== modified file 'etc/wishes.xml' (properties changed: -x to +x)
=== modified file 'ginn.pc.in' (properties changed: -x to +x)
=== modified file 'src/Makefile.am' (properties changed: -x to +x)
--- src/Makefile.am 2011-02-04 16:04:30 +0000
+++ src/Makefile.am 2011-08-23 04:19:23 +0000
@@ -1,8 +1,9 @@
1bin_PROGRAMS = ginn1bin_PROGRAMS = ginn
2man1_MANS = ginn.12man1_MANS = ginn.1
33
4ginn_SOURCES = ginn.c config.h config.c xt.c bamf.c4ginn_SOURCES = bamf.cpp config.cpp ginn.cpp gir.cpp main.cpp xt.cpp
5ginn_CFLAGS = \5
6ginn_CXXFLAGS = \
6 -DGINN_CONFIG_DIR=\"$(sysconfdir)/ginn\" \7 -DGINN_CONFIG_DIR=\"$(sysconfdir)/ginn\" \
7 $(GEIS_CFLAGS) $(XTST_CFLAGS) $(X11_CFLAGS) $(XML2_CFLAGS) $(BAMF_CFLAGS)8 $(GEIS_CFLAGS) $(XTST_CFLAGS) $(X11_CFLAGS) $(XML2_CFLAGS) $(BAMF_CFLAGS)
8ginn_LDFLAGS = $(GEIS_LIBS) $(XTST_LIBS) $(X11_LIBS) $(XML2_LIBS) $(BAMF_LIBS)9ginn_LDFLAGS = $(GEIS_LIBS) $(XTST_LIBS) $(X11_LIBS) $(XML2_LIBS) $(BAMF_LIBS)
910
=== added file 'src/README'
--- src/README 1970-01-01 00:00:00 +0000
+++ src/README 2011-08-23 04:19:23 +0000
@@ -0,0 +1,5 @@
1To compile GIR you need some packages to install theme simply execute install.sh
2
3note: this install script work for just debian base system
4
5Enjoy!!
0\ No newline at end of file6\ No newline at end of file
17
=== removed file 'src/bamf.c'
--- src/bamf.c 2011-05-20 19:34:26 +0000
+++ src/bamf.c 1970-01-01 00:00:00 +0000
@@ -1,48 +0,0 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 3 of the License, or (at your option) any later
7 * version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include <libbamf/bamf-matcher.h>
20#include <string.h>
21
22char *getName(char *deskfile)
23{
24 char *temp;
25 temp = strdup(strrchr(deskfile, '/'));
26 return strndup(temp + 1, strlen(temp) - 9);
27}
28
29char *getCurrentApp()
30{
31 g_type_init();
32 char *deskfile, *appName;
33 char *temp;
34
35 BamfApplication *app =
36 bamf_matcher_get_active_application(bamf_matcher_get_default());
37 if (app) {
38 appName = (char *) bamf_view_get_name(BAMF_VIEW(app));
39 temp = bamf_application_get_desktop_file(app);
40
41 if (strchr(appName, ' ') && temp && strlen(temp) > 1)
42 return getName((char *) temp);
43 else
44 return appName;
45 } else
46 return "";
47
48}
490
=== added file 'src/bamf.cpp'
--- src/bamf.cpp 1970-01-01 00:00:00 +0000
+++ src/bamf.cpp 2011-08-23 04:19:23 +0000
@@ -0,0 +1,48 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 3 of the License, or (at your option) any later
7 * version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include <libbamf/bamf-matcher.h>
20#include <string.h>
21
22char *getName(char *deskfile)
23{
24 char *temp;
25 temp = strdup(strrchr(deskfile, '/'));
26 return strndup(temp + 1, strlen(temp) - 9);
27}
28
29char *getCurrentApp()
30{
31 g_type_init();
32 char *deskfile, *appName;
33 char *temp;
34
35 BamfApplication *app =
36 bamf_matcher_get_active_application(bamf_matcher_get_default());
37 if (app) {
38 appName = (char *) bamf_view_get_name(BAMF_VIEW(app));
39 temp = (char *) bamf_application_get_desktop_file(app);
40
41 if (strchr(appName, ' ') && temp && strlen(temp) > 1)
42 return getName((char *) temp);
43 else
44 return appName;
45 } else
46 return "";
47
48}
049
=== removed file 'src/config.c'
--- src/config.c 2011-03-16 16:19:13 +0000
+++ src/config.c 1970-01-01 00:00:00 +0000
@@ -1,200 +0,0 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 3 of the License, or (at your option) any later
7 * version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "config.h"
20#include <libxml/parser.h>
21
22void debugOut(struct wish *wp)
23{
24 int i;
25 printf("\n key : %s ", wp->key);
26 printf("\n button : %d ", wp->button);
27 for (i = 0; i < 4; i++)
28 printf("\t mod%d : %s ", i, wp->modifiers[i]);
29 for (i = 0; i < 4; i++) {
30 printf("\n attrName : %s ", wp->config_attr[i].attrName);
31 printf("\t val : %.2f ", wp->config_attr[i].val);
32 printf("\t valMax : %.2f", wp->config_attr[i].valMax);
33 }
34 printf("\n pMe : %x pNext : %x ", wp, wp->next);
35 printf("\n===================================================");
36}
37
38int ginn_config_open(struct ginn_config *cfg, const char *path)
39{
40 memset(cfg, 0, sizeof(*cfg));
41 cfg->doc = xmlReadFile(path, NULL, 0);
42 if (cfg->doc == NULL) {
43 fprintf(stderr, "Failed to parse %s\n", path);
44 return -1;
45 }
46 return 0;
47}
48
49void ginn_config_close(struct ginn_config *cfg)
50{
51 xmlFreeDoc(cfg->doc);
52}
53
54static void print_node(const xmlNode * root, int depth)
55{
56 xmlNode *node;
57 for (node = root; node; node = node->next) {
58 int i;
59 if (node->type != XML_ELEMENT_NODE)
60 continue;
61 for (i = 0; i < depth; i++)
62 printf(" ");
63 printf("%s\n", node->name);
64 print_node(node->children, depth + 1);
65 }
66}
67
68static int ginn_str2state(const char *str)
69{
70 if (str == NULL)
71 return -1;
72 if (strcmp(str, "start") == 0)
73 return GINN_START;
74 if (strcmp(str, "update") == 0)
75 return GINN_UPDATE;
76 if (strcmp(str, "finish") == 0)
77 return GINN_FINISH;
78 fprintf(stderr, "ERROR: Undefined state: %s\n", str);
79 return -2;
80}
81
82static int ginn_str2bool(const char *str)
83{
84 if (str == NULL)
85 return -1;
86 if (strcmp(str, "true") == 0)
87 return 1;
88 if (strcmp(str, "false") == 0)
89 return 0;
90 fprintf(stderr, "ERROR: Invalid value for boolean attribute: %s\n",
91 str);
92 return -2;
93}
94
95void store_1config(xmlNode * node, struct wish *wp, int *position)
96{
97 if (0 == strcmp(node->name, "wish")) {
98 // printf(" gesture %s fingers %s ",(xmlGetProp(node, "gesture")),(xmlGetProp(node, "fingers")));
99 wp->config_attr[0].attrName = "gesture name";
100 switch (xmlGetProp(node, "gesture")[0]) {
101 case 'D':
102 wp->config_attr[0].val = wp->config_attr[0].valMax = 0;
103 break;
104 case 'P':
105 wp->config_attr[0].val = wp->config_attr[0].valMax = 1;
106 break;
107 case 'R':
108 wp->config_attr[0].val = wp->config_attr[0].valMax = 2;
109 break;
110 case 'T':
111 wp->config_attr[0].val = wp->config_attr[0].valMax = 15;
112 break;
113 }
114 wp->config_attr[1].attrName = "touches";
115 wp->config_attr[1].val = atoi(xmlGetProp(node, "fingers"));
116 wp->config_attr[1].valMax = atoi(xmlGetProp(node, "fingers"));
117 }
118 if (0 == strcmp(node->name, "action")) {
119 wp->when = ginn_str2state(xmlGetProp(node, "when"));
120 if (wp->when < 0)
121 fprintf(stderr,
122 "ERROR: you must provide property 'when' to the action: %s\n",
123 xmlGetProp(node, "name"));
124 }
125 if (0 == strcmp(node->name, "trigger")) {
126 wp->config_attr[*position].attrName = xmlGetProp(node, "prop");
127 wp->config_attr[*position].val = atof(xmlGetProp(node, "min"));
128 wp->config_attr[*position].valMax = atof(xmlGetProp(node, "max"));
129 int acc = ginn_str2bool(xmlGetProp(node, "accumulate"));
130 wp->config_attr[*position].accumulate =
131 acc == -1 ? GINN_DEFAULT_ACCUMULATE : acc;
132 wp->config_attr[*position].accumVal = 0;
133 (*position)++;
134 }
135 if (0 == strcmp(node->name, "key")
136 || 0 == strcmp(node->name, "button")) {
137 if (xmlGetProp(node, "modifier1"))
138 wp->modifiers[0] = xmlGetProp(node, "modifier1");
139 if (xmlGetProp(node, "modifier2"))
140 wp->modifiers[1] = xmlGetProp(node, "modifier2");
141 if (xmlGetProp(node, "modifier3"))
142 wp->modifiers[2] = xmlGetProp(node, "modifier3");
143 if (xmlGetProp(node, "modifier4"))
144 wp->modifiers[3] = xmlGetProp(node, "modifier4");
145 }
146 if (0 == strcmp(node->name, "key"))
147 wp->key = xmlNodeGetContent(node);
148 if (0 == strcmp(node->name, "button"))
149 wp->button = atoi(xmlNodeGetContent(node));
150 if (0 == strcmp(node->name, "button"))
151 printf("Button : %d ", wp->button);
152}
153
154void
155parse_node(const xmlNode * root, int depth, struct wish *wp,
156 struct apps *ap)
157{
158 xmlNode *node;
159 int position = 2;
160 for (node = root; node; node = node->next) {
161 if (node->type != XML_ELEMENT_NODE)
162 continue;
163
164 if ((0 == strcmp(node->name, "application"))) {
165 if (0 != strcmp(ap->appName, "")) {
166 ap = ap->next =
167 (struct apps *) malloc(sizeof(struct apps));
168 inita(ap);
169 }
170 ap->appName = xmlGetProp(node, "name");
171 wp = ap->wp = (struct wish *) malloc(sizeof(struct wish));
172 initw(wp);
173 }
174 if ((0 == strcmp(node->name, "wish"))
175 && (0 == strcmp(wp->config_attr[0].attrName, "gesture name"))) {
176 if (!(wp->next)) {
177 wp->next = (struct wish *) malloc(sizeof(struct wish));
178 initw(wp->next);
179 }
180 wp = wp->next;
181 position = 2;
182 }
183 store_1config(node, wp, &position);
184 parse_node(node->children, depth + 1, wp, ap);
185 }
186}
187
188void
189ginn_config_store(const struct ginn_config *cfg, struct wish *w,
190 struct apps *a)
191{
192 const xmlNode *root = xmlDocGetRootElement(cfg->doc);
193 parse_node(root, 0, w, a);
194}
195
196void ginn_config_print(const struct ginn_config *cfg)
197{
198 const xmlNode *root = xmlDocGetRootElement(cfg->doc);
199 print_node(root, 0);
200}
2010
=== added file 'src/config.cpp'
--- src/config.cpp 1970-01-01 00:00:00 +0000
+++ src/config.cpp 2011-08-23 04:19:23 +0000
@@ -0,0 +1,202 @@
1/*
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 3 of the License, or (at your option) any later
7 * version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "config.h"
20
21void debugOut(Gwish *wp)
22{
23 int i;
24 cout << "\n key : " << wp->key;
25 printf("\n button : %d ", wp->button);
26 for (i = 0; i < 4; i++)
27 cout << "\t mod" << i << " : " << wp->modifiers[i];
28 for (i = 0; i < 4; i++) {
29 cout << "\n attrName : " << wp->config_attr[i].attrName;
30 printf("\t val : %.2f ", wp->config_attr[i].val);
31 printf("\t valMax : %.2f", wp->config_attr[i].valMax);
32 }
33 printf("\n pMe : %x pNext : %x ", wp, wp->next);
34 printf("\n===================================================");
35}
36
37int ginn_config_open(struct ginn_config *cfg, const char *path)
38{
39 memset(cfg, 0, sizeof(*cfg));
40 cfg->doc = xmlReadFile(path, NULL, 0);
41 if (cfg->doc == NULL)
42 {
43 cerr << "Failed to parse " << path << endl;
44 return -1;
45 }
46 return 0;
47}
48
49void ginn_config_close(struct ginn_config *cfg)
50{
51 xmlFreeDoc(cfg->doc);
52}
53
54static void print_node(const xmlNode * root, int depth)
55{
56 const xmlNode *node;
57 for (node = root; node; node = node->next)
58 {
59 if (node->type != XML_ELEMENT_NODE)
60 {
61 continue;
62 }
63 for (int i = 0; i < depth; i++)
64 printf(" ");
65 cout << node->name << endl;
66 print_node(node->children, depth + 1);
67 }
68}
69
70static int ginn_str2state(const char *str)
71{
72 if (str == NULL)
73 return -1;
74 if (strcmp(str, "start") == 0)
75 return GINN_START;
76 if (strcmp(str, "update") == 0)
77 return GINN_UPDATE;
78 if (strcmp(str, "finish") == 0)
79 return GINN_FINISH;
80 cerr << "ERROR: Undefined state: " << str << endl;
81 return -2;
82}
83
84static int ginn_str2bool(const char *str)
85{
86 if (str == NULL)
87 return -1;
88 if (strcmp(str, "true") == 0)
89 return 1;
90 if (strcmp(str, "false") == 0)
91 return 0;
92 cerr << "ERROR: Invalid value for boolean attribute: " << str << endl;
93 return -2;
94}
95
96void store_1config(xmlNode * node, Gwish *wp, int *position)
97{
98 string nodeName = (char *)node->name;
99 if (nodeName == "wish")
100 {
101 // printf(" gesture %s fingers %s ",(xmlGetProp(node, "gesture")),(xmlGetProp(node, "fingers")));
102 switch (xmlGetProp(node, (xmlChar*)"gesture") [0])
103 {
104 case 'D':
105 wp->Type = GINN_Drag;
106 break;
107 case 'P':
108 wp->Type = GINN_Pinch;
109 break;
110 case 'R':
111 wp->Type = GINN_Rotate;
112 break;
113 case 'T':
114 wp->Type = GINN_Tap;
115 break;
116 }
117 wp->TouchNum = atoi((char *) xmlGetProp(node, (xmlChar*)"fingers"));
118 wp->DirectTouch = ginn_str2bool((char *) xmlGetProp(node, (xmlChar*)"screen"));
119 }
120 if (nodeName == "action")
121 {
122 wp->when = ginn_str2state((char *) xmlGetProp(node, (xmlChar*)"when"));
123 if (wp->when < 0)
124 cerr << "ERROR: you must provide property 'when' to the action: " << xmlGetProp(node, (xmlChar*)"name") << endl;
125 }
126 if (nodeName == "trigger")
127 {
128 wp->config_attr[*position].attrName = (char *)xmlGetProp(node, (xmlChar*)"prop");
129 wp->config_attr[*position].val = atof((char *)xmlGetProp(node, (xmlChar*)"min"));
130 wp->config_attr[*position].valMax = atof((char *)xmlGetProp(node, (xmlChar*)"max"));
131 int acc = ginn_str2bool((char *)xmlGetProp(node, (xmlChar*)"accumulate"));
132 wp->config_attr[*position].accumulate =
133 acc == -1 ? GINN_DEFAULT_ACCUMULATE : acc;
134 wp->config_attr[*position].accumVal = 0;
135 (*position)++;
136 }
137 if (nodeName == "key" || nodeName == "button")
138 {
139 if (xmlGetProp(node, (xmlChar*)"modifier1"))
140 wp->modifiers[0] = (char *)xmlGetProp(node, (xmlChar*)"modifier1");
141 if (xmlGetProp(node, (xmlChar*)"modifier2"))
142 wp->modifiers[1] = (char *)xmlGetProp(node, (xmlChar*)"modifier2");
143 if (xmlGetProp(node, (xmlChar*)"modifier3"))
144 wp->modifiers[2] = (char *)xmlGetProp(node, (xmlChar*)"modifier3");
145 if (xmlGetProp(node, (xmlChar*)"modifier4"))
146 wp->modifiers[3] = (char *)xmlGetProp(node, (xmlChar*)"modifier4");
147 }
148 if (nodeName == "key")
149 wp->key = (char *)xmlNodeGetContent(node);
150 if (nodeName == "button")
151 {
152 wp->button = atoi((char *)xmlNodeGetContent(node));
153 }
154}
155
156void parse_node(const xmlNode * root, int depth, Gwish *wp, Gapps *ap)
157{
158 xmlNode *node;
159
160 int position = 2;
161 for (node = const_cast <xmlNode *> (root); node; node = node->next)
162 {
163 if (node->type != XML_ELEMENT_NODE)
164 {
165 if (node->type == XML_TEXT_NODE)
166
167 continue;
168 }
169
170 if ((0 == strcmp((char *)node->name, "application")))
171 {
172 if (!ap->appName.empty())
173 {
174 ap = ap->next = new Gapps;//Save The previon and create new
175 }
176 ap->appName = (char *) xmlGetProp(node, (xmlChar*)"name");
177 wp = ap->wp = new Gwish; //Save The previon and create new
178 }
179 if ((0 == strcmp((char *)node->name, "wish"))
180 && wp->Type != -1)
181 {
182 if (!(wp->next))
183 wp->next = new Gwish;
184 wp = wp->next;
185 position = 2;
186 }
187 store_1config(node, wp, &position);
188 parse_node(node->children, depth + 1, wp, ap);
189 }
190}
191
192void ginn_config_store(const struct ginn_config *cfg, Gwish *w, struct Gapps *a)
193{
194 const xmlNode *root = xmlDocGetRootElement(cfg->doc);
195 parse_node(root, 0, w, a);
196}
197
198void ginn_config_print(const struct ginn_config *cfg)
199{
200 const xmlNode *root = xmlDocGetRootElement(cfg->doc);
201 print_node(root, 0);
202}
0203
=== modified file 'src/config.h' (properties changed: -x to +x)
--- src/config.h 2011-03-16 16:19:13 +0000
+++ src/config.h 2011-08-23 04:19:23 +0000
@@ -18,8 +18,7 @@
18#ifndef GINN_CONFIG_H18#ifndef GINN_CONFIG_H
19#define GINN_CONFIG_H19#define GINN_CONFIG_H
2020
21#include <libxml/tree.h>21#include "header.h"
22#include <string.h>
2322
24#define GINN_START 023#define GINN_START 0
25#define GINN_UPDATE 124#define GINN_UPDATE 1
@@ -27,32 +26,76 @@
2726
28#define GINN_DEFAULT_ACCUMULATE 127#define GINN_DEFAULT_ACCUMULATE 1
2928
30typedef struct ginn_config {29struct ginn_config
30{
31 xmlDocPtr doc;31 xmlDocPtr doc;
32 xmlNodePtr root;32 xmlNodePtr root;
33} cfg;33};
3434
35typedef struct att {35struct att
36 char *attrName;36{
37 float val;37 string attrName;
38 float valMax;38 float val;
39 int accumulate;39 float valMax;
40 float accumVal;40 int accumulate;
41} att;41 float accumVal;
4242};
43typedef struct wish {43
44 att config_attr[25];44///
45 char *key;45/// Use to classify Gesture Type (For Example pinch)
46 int button;46///
47 char *modifiers[4];47enum GestureType
48 struct wish *next;48{
49 int when;49 GINN_Drag = 0,GINN_Pinch=1,GINN_Rotate=2,GINN_Tap=15
50} wish;50};
5151
52typedef struct apps {52///
53 char *appName;53/// GWish provide gesture information and the reaction for gesture called Wish
54 struct wish *wp;54///
55 struct apps *next;55class Gwish
56} apps;56{
57public:
58 Gwish();
59//Variable:
60 att config_attr[25];
61 int button;
62 int Type; //Indicate The gusture Type (-1 Mean it's NULL)
63 int TouchNum; //Indicate The Number of finger for gusture
64 int DirectTouch; //use this to Detect Touchpad from Touchscreen
65 string key;
66 string modifiers[4];
67 Gwish *next;
68 int when;
69};
70
71///
72/// Use This class for save application information
73///
74class Gapps
75{
76public:
77 Gapps();
78//Variable:
79 string appName;
80 Gwish *wp;
81 Gapps *next;
82};
83
84///
85/// Use this struct to save device attribute (GD reffered to GINN device and att reffered to attribute)
86///
87struct GD_att
88{
89 string name; //Device Name
90 int ID; //Device ID that is unique (use to find devive)
91 int TouchNum; //Define how many parallel finger touch can support
92 bool isDirectTouch; //Define it is a touch screen or not(a pad)
93};
94
95
96//Decleare in config.cpp
97int ginn_config_open(struct ginn_config *cfg, const char *path);
98void ginn_config_print(const struct ginn_config *cfg);
99void ginn_config_store(const struct ginn_config *cfg, Gwish *w, Gapps *a);
57100
58#endif /* GINN_CONFIG_H */101#endif /* GINN_CONFIG_H */
59102
=== removed file 'src/ginn.c'
--- src/ginn.c 2011-08-12 15:40:51 +0000
+++ src/ginn.c 1970-01-01 00:00:00 +0000
@@ -1,592 +0,0 @@
1/**
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 3 of the License, or (at your option) any later
7 * version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Authors:
19 * Mohamed-Ikbel Boulabiar <boulabiar@gmail.com>
20 * Henrik Rydberg <rydberg@bitmath.org>
21 * Stephen M. Webb <stephen.webb@canonical.com>
22 *
23 */
24#include "config.h"
25#include <geis/geis.h>
26#include <errno.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <sys/select.h>
31#include <sys/stat.h>
32#include <unistd.h>
33#include <X11/Xlib.h>
34#include <X11/keysym.h>
35
36att config_attr[25] = {[0 ... 24] = {.attrName = "",.val = 0,.valMax = 0}
37};
38
39wish w1 = {.config_attr = {[0 ... 24] =
40 {.attrName = "",.val = 0,.valMax = 0}
41 }
42,
43.key = "",
44.next = NULL
45};
46
47wish *wp, *wpEnd;
48apps *ap;
49
50static int inside(float x, float a, float b)
51{
52 return ((x <= b) && (x >= a));
53}
54
55void initw(struct wish *wp)
56{
57 int i;
58 wp->button = 0;
59 wp->key = "";
60 wp->next = NULL;
61 for (i = 0; i < 4; i++)
62 wp->modifiers[i] = "";
63 for (i = 0; i < 25; i++) {
64 wp->config_attr[i].attrName = "";
65 wp->config_attr[i].val = 0;
66 wp->config_attr[i].valMax = 0;
67 }
68}
69
70void inita(struct apps *ap)
71{
72 ap->next = NULL;
73 ap->wp = NULL;
74 ap->appName = "";
75}
76
77static void clear_accum_attrs(att * attrs)
78{
79 int i = 0;
80 while (strcmp(attrs[i].attrName, "") != 0) {
81 if (attrs[i].accumulate)
82 attrs[i].accumVal = 0;
83 i++;
84 }
85}
86
87static void update_wishes()
88{
89 char *activeApp;
90 apps *tmpAp = ap;
91 int diff = 0;
92
93 activeApp = (char *) getCurrentApp();
94 printf(" --ActiveApp %s\n", activeApp);
95 if (activeApp)
96 diff = strcmp(activeApp, ap->appName);
97
98 while (diff && ap->next) {
99 ap = ap->next;
100 diff = strcmp(activeApp, ap->appName);
101 }
102
103 if (!diff)
104 wpEnd->next = ap->wp;
105 else
106 wpEnd->next = NULL;
107
108 ap = tmpAp;
109}
110
111static void
112gesture_match(GeisGestureType gesture_type,
113 GeisGestureId gesture_id,
114 GeisSize attr_count, GeisGestureAttr * attrs, int state)
115{
116 struct wish *topw;
117 topw = wp;
118 update_wishes();
119 while (wp && (0 != strcmp(wp->key, "") || wp->button)) {
120 int valid = 1;
121 if (gesture_type == wp->config_attr[0].val
122 && attrs[8].integer_val == wp->config_attr[1].val) {
123 int attrsI = 9, cAttrI = 2;
124 do {
125 if (0 ==
126 strcmp(attrs[attrsI].name,
127 wp->config_attr[cAttrI].attrName)) {
128 printf("DEBUG -- comparing %s %s : ",
129 attrs[attrsI].name,
130 wp->config_attr[cAttrI].attrName);
131 printf("%.2f %.2f %.2f \n",
132 attrs[attrsI].float_val,
133 wp->config_attr[cAttrI].val,
134 wp->config_attr[cAttrI].valMax);
135 printf("%i \n",
136 inside(attrs[attrsI].float_val,
137 wp->config_attr[cAttrI].val,
138 wp->config_attr[cAttrI].valMax));
139 if (wp->config_attr[cAttrI].accumulate) {
140 wp->config_attr[cAttrI].accumVal +=
141 attrs[attrsI].float_val;
142 valid = valid
143 && inside(wp->config_attr
144 [cAttrI].accumVal,
145 wp->config_attr
146 [cAttrI].val,
147 wp->config_attr[cAttrI].valMax);
148 } else
149 valid = valid
150 && inside(attrs[attrsI].float_val,
151 wp->config_attr
152 [cAttrI].val,
153 wp->config_attr[cAttrI].valMax);
154 attrsI++;
155 cAttrI++;
156 } else
157 attrsI++;
158 } while ((0 != strcmp(wp->config_attr[cAttrI].attrName, ""))
159 && attrsI < 18);
160 if (valid && wp->when == state) {
161 if ((0 != wp->button)
162 && (0 != strcmp(wp->key, ""))) {
163 injMixBtnKey(XStringToKeysym(wp->key),
164 wp->button, wp->modifiers);
165 printf("MIX -- MIX");
166 } else {
167 if (0 != wp->button)
168 injButton(wp->button, wp->modifiers);
169 if (0 != strcmp(wp->key, ""))
170 injKey(XStringToKeysym(wp->key), wp->modifiers);
171 }
172 clear_accum_attrs(wp->config_attr);
173 }
174 }
175 if (state == GINN_FINISH)
176 clear_accum_attrs(wp->config_attr);
177 wp = wp->next;
178 }
179 wp = topw;
180}
181
182static Window getRootWindow()
183{
184 Display *display = NULL;
185 Window window = 0;
186
187 display = XOpenDisplay(NULL);
188 if (!display) {
189 fprintf(stderr, "error opening X11 display.\n");
190 exit(1);
191 }
192
193 window = DefaultRootWindow(display);
194
195 XCloseDisplay(display);
196
197 return window;
198}
199
200static void print_attr(GeisGestureAttr * attr)
201{
202 fprintf(stdout, "\tattr %s=", attr->name);
203 switch (attr->type) {
204 case GEIS_ATTR_TYPE_BOOLEAN:
205 fprintf(stdout, "%s\n", attr->boolean_val ? "true" : "false");
206 break;
207 case GEIS_ATTR_TYPE_FLOAT:
208 fprintf(stdout, "%f\n", attr->float_val);
209 break;
210 case GEIS_ATTR_TYPE_INTEGER:
211 fprintf(stdout, "%d\n", attr->integer_val);
212 break;
213 case GEIS_ATTR_TYPE_STRING:
214 fprintf(stdout, "\"%s\"\n", attr->string_val);
215 break;
216 default:
217 fprintf(stdout, "<unknown>\n");
218 break;
219 }
220}
221
222static void
223gesture_added(void *cookie,
224 GeisGestureType gesture_type,
225 GeisGestureId gesture_id,
226 GeisSize attr_count, GeisGestureAttr * attrs)
227{
228 int i = 0;
229 fprintf(stdout, "Gesture type %d added\n", gesture_type);
230 for (i = 0; i < attr_count; ++i)
231 print_attr(&attrs[i]);
232}
233
234static void
235gesture_removed(void *cookie,
236 GeisGestureType gesture_type,
237 GeisGestureId gesture_id,
238 GeisSize attr_count, GeisGestureAttr * attrs)
239{
240 int i = 0;
241 fprintf(stdout, "Gesture type %d removed\n", gesture_type);
242 for (i = 0; i < attr_count; ++i)
243 print_attr(&attrs[i]);
244}
245
246static void
247gesture_start(void *cookie,
248 GeisGestureType gesture_type,
249 GeisGestureId gesture_id,
250 GeisSize attr_count, GeisGestureAttr * attrs)
251{
252 int i = 0;
253 fprintf(stdout, "Gesture type %d started\n", gesture_type);
254 for (i = 0; i < attr_count; ++i)
255 print_attr(&attrs[i]);
256
257 // In GEIS v1, we know that the focus coords are in attrs 5 and 6
258 movePointer((int)attrs[5].float_val, (int)attrs[6].float_val);
259}
260
261static void
262gesture_update(void *cookie,
263 GeisGestureType gesture_type,
264 GeisGestureId gesture_id,
265 GeisSize attr_count, GeisGestureAttr * attrs)
266{
267 int i = 0;
268 fprintf(stdout, "Gesture type %d updated\n", gesture_type);
269 for (i = 0; i < attr_count; ++i)
270 print_attr(&attrs[i]);
271 gesture_match(gesture_type, gesture_id, attr_count, attrs,
272 GINN_UPDATE);
273}
274
275static void
276gesture_finish(void *cookie,
277 GeisGestureType gesture_type,
278 GeisGestureId gesture_id,
279 GeisSize attr_count, GeisGestureAttr * attrs)
280{
281 int i = 0;
282 fprintf(stdout, "Gesture type %d finished\n", gesture_type);
283 for (i = 0; i < attr_count; ++i); //print_attr(&attrs[i]);
284 gesture_match(gesture_type, gesture_id, attr_count, attrs,
285 GINN_FINISH);
286}
287
288GeisGestureFuncs gesture_funcs = {
289 gesture_added,
290 gesture_removed,
291 gesture_start,
292 gesture_update,
293 gesture_finish
294};
295
296/*
297 * Searches for a default config file.
298 *
299 * Returns a pointer to a config file name (which must be freed) or NULL
300 * if no default config file was found.
301 */
302static char *ginn_default_config()
303{
304 static const char default_file_name[] = "/wishes.xml";
305 static const char *search_paths[] = {
306 "etc",
307 "../etc",
308 ".",
309 "$HOME/.ginn",
310 GINN_CONFIG_DIR
311 };
312 static const int num_paths =
313 sizeof(search_paths) / sizeof(const char *);
314 int i;
315
316 for (i = 0; i < num_paths; ++i) {
317 struct stat sbuf;
318 char *file_name = NULL;
319
320 if (strstr(search_paths[i], "$HOME")) {
321 char *home_dir = getenv("HOME");
322 if (!home_dir) {
323 continue;
324 } else {
325 char *cdr = index(search_paths[i], '/');
326 size_t file_name_length = strlen(home_dir)
327 + strlen(cdr)
328 + strlen(default_file_name)
329 + 1;
330 file_name = calloc(file_name_length, sizeof(char));
331 strcpy(file_name, home_dir);
332 strcat(file_name, cdr);
333 }
334 } else {
335 size_t file_name_length = strlen(search_paths[i])
336 + strlen(default_file_name)
337 + 1;
338 file_name = calloc(file_name_length, sizeof(char));
339 strcpy(file_name, search_paths[i]);
340 }
341 strcat(file_name, default_file_name);
342 int sres = stat(file_name, &sbuf);
343 if (sres == 0) {
344 fprintf(stdout, "Using wishes file %s\n", file_name);
345 return file_name;
346 }
347 free(file_name);
348 }
349
350 return NULL;
351}
352
353int main(int argc, char *argv[])
354{
355 GeisStatus status = GEIS_UNKNOWN_ERROR;
356 GeisXcbWinInfo xcb_win_info = {
357 .display_name = NULL,
358 .screenp = NULL,
359 .window_id = getRootWindow()
360 };
361 GeisWinInfo win_info = {
362 GEIS_XCB_FULL_WINDOW,
363 &xcb_win_info
364 };
365 GeisInstance instance;
366 struct ginn_config cfg;
367
368 {
369 char *config_file_name = NULL;
370 if (argc < 2) {
371 fprintf(stderr, "usage: %s <configxml>\n", argv[0]);
372 config_file_name = ginn_default_config();
373 if (config_file_name) {
374 fprintf(stderr,
375 "using default configuration file %s ... \n",
376 config_file_name);
377 }
378 } else {
379 config_file_name = strdup(argv[1]);
380 }
381 if (NULL == config_file_name) {
382 fprintf(stderr, "Could not find Ginn wishes\n");
383 return -1;
384 }
385
386 if (ginn_config_open(&cfg, config_file_name)) {
387 fprintf(stderr, "Could not load Ginn wishes\n");
388 return -1;
389 }
390 free(config_file_name);
391 }
392
393 ginn_config_print(&cfg);
394 ap = (struct apps *) malloc(sizeof(struct apps));
395 inita(ap);
396 wp = (struct wish *) malloc(sizeof(struct wish));
397 initw(wp);
398 ginn_config_store(&cfg, wp, ap);
399 wpEnd = wp;
400 while (wpEnd->next)
401 wpEnd = wpEnd->next;
402
403 int pos = 0;
404 printf("\n");
405 while (strcmp(config_attr[pos].attrName, "")) {
406 printf("DEBUG %d %s %.2f %.2f \n", pos,
407 config_attr[pos].attrName, config_attr[pos].val,
408 config_attr[pos].valMax);
409 pos++;
410 }
411
412 /**
413 * Check the loaded wishes to see which gestures are used
414 * and add these gestures to a NULL terminated list "sub_gestures_list"
415 *
416 * This list is used to subscribe only the necessary gestures
417 * to GEIS. This will avoid issues with 2 finger scrolls and other gestues
418 * being dropped when not accounted for in the wishes file.
419 **/
420
421 apps * appPtr = ap;
422 wish * wishPtr;
423 char * sub_gestures_list[17] = {NULL};
424 int finished = 0;
425
426 /**
427 * Loop through each wish inside ap
428 * After all of the wishes in ap are accounted for
429 * add global wishes
430 **/
431
432 while(finished != 1)
433 {
434 // Check if we are finished with the application wishes
435 if(appPtr == NULL)
436 {
437 wishPtr = wp;
438 finished = 1;
439 }else{
440 wishPtr = appPtr->wp;
441 }
442
443 // Loop through each wish
444 while(wishPtr)
445 {
446 int i;
447 for(i = 0; i < 25; i ++)
448 {
449
450 char *sub_gesture = malloc(sizeof(char[16]));
451 int pos = 0;
452
453 // Check for Drag gesture
454 if(strcmp(wishPtr->config_attr[i].attrName, "delta x") == 0 ||
455 strcmp(wishPtr->config_attr[i].attrName, "delta y") == 0 ||
456 strcmp(wishPtr->config_attr[i].attrName, "velocity x") == 0 ||
457 strcmp(wishPtr->config_attr[i].attrName, "velocity y") == 0
458 )
459 {
460 sprintf(sub_gesture, "Drag,touch=%i", (int)wishPtr->config_attr[1].val);
461 }
462
463 // Check for Rotate gesture
464 else if(strcmp(wishPtr->config_attr[i].attrName, "angle delta") == 0 ||
465 strcmp(wishPtr->config_attr[i].attrName, "angular velocity") == 0 ||
466 strcmp(wishPtr->config_attr[i].attrName, "angle") == 0
467 )
468 {
469 sprintf(sub_gesture, "Rotate,touch=%i", (int)wishPtr->config_attr[1].val);
470 }
471
472 // Check for Pinch gesture
473 else if(strcmp(wishPtr->config_attr[i].attrName, "radius delta") == 0 ||
474 strcmp(wishPtr->config_attr[i].attrName, "radial velocity") == 0 ||
475 strcmp(wishPtr->config_attr[i].attrName, "radius") == 0
476 )
477 {
478 sprintf(sub_gesture, "Pinch,touch=%i", (int)wishPtr->config_attr[1].val);
479 }
480
481 // Check for Tap gesture
482 else if(strcmp(wishPtr->config_attr[i].attrName, "tap time") == 0)
483 {
484 sprintf(sub_gesture, "Tap,touch=%i", (int)wishPtr->config_attr[1].val);
485 }
486
487 // Deallocate sub_gesture if no gesture was found
488 else
489 {
490 free(sub_gesture);
491 sub_gesture = NULL;
492 continue;
493 }
494
495 /** Check the current gesture list
496 * Only add if the gesture is not already in the list
497 * Store in index of the first NULL found
498 **/
499
500 while(pos < 17)
501 {
502 if(sub_gestures_list[pos] == NULL)
503 {
504 sub_gestures_list[pos] = sub_gesture;
505 break;
506 }else if(strcmp(sub_gestures_list[pos], sub_gesture) == 0)
507 {
508 break;
509 }
510 pos ++;
511 }
512
513
514 }
515 // Iterate to the next wish
516 wishPtr = wishPtr->next;
517 }
518
519 // If there are more applications, iterate to the next
520
521 if(finished != 1)
522 {
523 appPtr = appPtr->next;
524 }
525 }
526
527 // Show which gestures were subscribed
528 printf("Gestures subscribed:\n");
529
530 pos = 0;
531 while(pos < 17)
532 {
533 if(sub_gestures_list[pos] != NULL)
534 {
535 printf("%s\n", sub_gestures_list[pos]);
536 }
537
538 pos ++;
539 }
540
541 // End sub gesture list creation
542
543 status = geis_init(&win_info, &instance);
544 if (status != GEIS_STATUS_SUCCESS) {
545 fprintf(stderr, "error in geis_init\n");
546 return 1;
547 }
548
549 status = geis_configuration_supported(instance, GEIS_CONFIG_UNIX_FD);
550 if (status != GEIS_STATUS_SUCCESS) {
551 fprintf(stderr, "GEIS does not support Unix fd\n");
552 return 1;
553 }
554
555 int fd = -1;
556 status =
557 geis_configuration_get_value(instance, GEIS_CONFIG_UNIX_FD, &fd);
558 if (status != GEIS_STATUS_SUCCESS) {
559 fprintf(stderr, "error retrieving GEIS fd\n");
560 return 1;
561 }
562
563 status = geis_subscribe(instance, GEIS_ALL_INPUT_DEVICES, sub_gestures_list, // GEIS_ALL_GESTURES,
564 &gesture_funcs, NULL);
565 if (status != GEIS_STATUS_SUCCESS) {
566 fprintf(stderr, "error subscribing to gestures\n");
567 return 1;
568 }
569
570 openDisplay();
571
572 while (1) {
573 fd_set read_fds;
574 FD_ZERO(&read_fds);
575 FD_SET(fd, &read_fds);
576 int sstat = select(fd + 1, &read_fds, NULL, NULL, NULL);
577 if (sstat < 0) {
578 fprintf(stderr, "error %d in select(): %s\n", errno,
579 strerror(errno));
580 break;
581 }
582
583 if (FD_ISSET(fd, &read_fds)) {
584 geis_event_dispatch(instance);
585 }
586 }
587
588 geis_finish(instance);
589 closeDisplay();
590 free(wp);
591 return 0;
592}
5930
=== added file 'src/ginn.cpp'
--- src/ginn.cpp 1970-01-01 00:00:00 +0000
+++ src/ginn.cpp 2011-08-23 04:19:23 +0000
@@ -0,0 +1,555 @@
1#include "ginn.h"
2
3GINN::GINN()
4{
5 //Set Default value
6 config_load = false;
7 ap = new Gapps;
8 wp = new Gwish;
9 //
10 att att_default;
11 att_default.attrName = "";
12 att_default.val = 0 ;
13 att_default.valMax = 0 ;
14
15 for (int i = 0; i < 25;i++)
16 config_attr[i] = att_default;
17
18 for (int i = 0; i < 25;i++)
19 w1.config_attr[i] = config_attr[i];
20 w1.key = "";
21 w1.next = NULL;
22}
23
24int GINN::inside(float x, float a, float b)
25{
26 return ((x <= b) && (x >= a));
27}
28
29void GINN::clear_accum_attrs(att * attrs)
30{
31 int i = 2;
32 while (!attrs[i].attrName.empty())
33 {
34 if (attrs[i].accumulate)
35 attrs[i].accumVal = 0;
36 i++;
37 }
38}
39
40void GINN::update_wishes()
41{
42 string activeApp;
43 Gapps *tmpAp = ap;
44 int diff = 0;
45
46 activeApp = (char *) getCurrentApp();
47 //cout << " --ActiveApp " << activeApp << endl; ;
48 if (!activeApp.empty())
49 diff = !(activeApp == ap->appName);
50
51 while (diff && ap->next)
52 {
53 ap = ap->next;
54 diff = !(activeApp == ap->appName);
55 }
56
57 if (!diff)
58 wpEnd->next = ap->wp;
59 else
60 wpEnd->next = NULL;
61
62 ap = tmpAp;
63}
64
65void GINN::Gmatch(GeisGestureType gesture_type,GeisGestureId gesture_id,
66 GeisSize attr_count, GeisGestureAttr * attrs, int state)
67{
68 Gwish *topw;
69 int DeviceID = attrs[0].integer_val;
70 int Dindex = DId2Index(DeviceID); //Device index on device_list
71 topw = wp;
72 update_wishes();
73 while (wp && (!wp->key.empty() || wp->button))
74 {
75 int valid = 1;
76 if (gesture_type == wp->Type && attrs[8].integer_val == wp->TouchNum &&
77 (device_list[Dindex].isDirectTouch == wp->DirectTouch || wp->DirectTouch == -1)) //wp->DirectTouch is -1 if no screen option define in wish tag
78 {
79 int attrsI = 9, cAttrI = 2;
80 do
81 {
82 if (attrs[attrsI].name == wp->config_attr[cAttrI].attrName)
83 {
84// cout << "DEBUG -- comparing " << attrs[attrsI].name << wp->config_attr[cAttrI].attrName << ": ";
85// cout << attrs[attrsI].float_val << wp->config_attr[cAttrI].val << wp->config_attr[cAttrI].valMax << endl;
86// cout << inside(attrs[attrsI].float_val,wp->config_attr[cAttrI].val, wp->config_attr[cAttrI].valMax) << endl;
87 if (wp->config_attr[cAttrI].accumulate)
88 {
89 wp->config_attr[cAttrI].accumVal += attrs[attrsI].float_val;
90 valid = valid
91 && inside(wp->config_attr
92 [cAttrI].accumVal,
93 wp->config_attr
94 [cAttrI].val,
95 wp->config_attr[cAttrI].valMax);
96 }
97 else
98 valid = valid && inside(attrs[attrsI].float_val, wp->config_attr
99 [cAttrI].val, wp->config_attr[cAttrI].valMax);
100 attrsI++;
101 cAttrI++;
102 }
103 else
104 attrsI++;
105 } while (!wp->config_attr[cAttrI].attrName.empty() && attrsI < 18);
106
107 if (valid && wp->when == state)
108 {
109 if ((0 != wp->button) && (!wp->key.empty()))
110 {
111 injMixBtnKey(XStringToKeysym(wp->key.c_str()), wp->button, wp->modifiers);
112 cout << "MIX -- MIX";
113 }
114 else
115 {
116 if (0 != wp->button)
117 injButton(wp->button, wp->modifiers);
118 if (!wp->key.empty())
119 injKey(XStringToKeysym(wp->key.c_str()), wp->modifiers);
120 }
121 clear_accum_attrs(wp->config_attr);
122 break;
123 }
124 }
125 if (state == GINN_FINISH)
126 clear_accum_attrs(wp->config_attr);
127 wp = wp->next;
128 }
129 wp = topw;
130}
131
132Window GINN::getRootWindow()
133{
134 Display *display = NULL;
135 Window window = 0;
136
137 display = XOpenDisplay(NULL);
138 if (!display)
139 {
140 cerr << "error opening X11 display.\n";
141 exit(1);
142 }
143
144 window = DefaultRootWindow(display);
145
146 XCloseDisplay(display);
147
148 return window;
149}
150
151void GINN::print_attr(GeisGestureAttr * attr)
152{
153 fprintf(stdout, "\tattr %s=", attr->name);
154 switch (attr->type) {
155 case GEIS_ATTR_TYPE_BOOLEAN:
156 fprintf(stdout, "%s\n", attr->boolean_val ? "true" : "false");
157 break;
158 case GEIS_ATTR_TYPE_FLOAT:
159 fprintf(stdout, "%f\n", attr->float_val);
160 break;
161 case GEIS_ATTR_TYPE_INTEGER:
162 fprintf(stdout, "%d\n", attr->integer_val);
163 break;
164 case GEIS_ATTR_TYPE_STRING:
165 fprintf(stdout, "\"%s\"\n", attr->string_val);
166 break;
167 default:
168 fprintf(stdout, "<unknown>\n");
169 break;
170 }
171}
172
173void GINN::Gadded(GeisGestureType gesture_type,GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs)
174{
175 int i = 0;
176 fprintf(stdout, "Gesture type %d added\n", gesture_type);
177 for (i = 0; i < attr_count; ++i)
178 print_attr(&attrs[i]);
179}
180
181void GINN::Gremoved(GeisGestureType gesture_type, GeisGestureId gesture_id,GeisSize attr_count, GeisGestureAttr * attrs)
182{
183 int i = 0;
184 fprintf(stdout, "Gesture type %d removed\n", gesture_type);
185 for (i = 0; i < attr_count; ++i)
186 print_attr(&attrs[i]);
187}
188
189void GINN::Gstart(GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs)
190{
191 int i = 0;
192 fprintf(stdout, "Gesture type %d started\n", gesture_type);
193 for (i = 0; i < attr_count; ++i)
194 print_attr(&attrs[i]);
195
196 // In GEIS v1, we know that the focus coords are in attrs 5 and 6
197 movePointer((int)attrs[5].float_val, (int)attrs[6].float_val);
198}
199
200void GINN::Gupdate(GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs)
201{
202 int i = 0;
203 cout << "Gesture type " << gesture_type << " updated\n";
204 for (i = 0; i < attr_count; ++i)
205 print_attr(&attrs[i]);
206 Gmatch(gesture_type, gesture_id, attr_count, attrs,GINN_UPDATE);
207}
208
209void GINN::Gfinish(GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs)
210{
211 int i = 0;
212 fprintf(stdout, "Gesture type %d finished\n", gesture_type);
213 for (i = 0; i < attr_count; ++i); //print_attr(&attrs[i]);
214 Gmatch(gesture_type, gesture_id, attr_count, attrs, GINN_FINISH);
215}
216
217/*
218 * Searches for a default config file.
219 *
220 * Returns a pointer to a config file name (which must be freed) or NULL
221 * if no default config file was found.
222 */
223string GINN::ginn_default_config()
224{
225 string default_file_name = "/wishes.xml";
226 static char *search_paths[] = {"etc","../etc",".","$HOME/.ginn" , "/etc/ginn" , "/etc" };
227 static const int num_paths = sizeof(search_paths) / sizeof(const char *);
228 int i;
229
230 for (i = 0; i < num_paths; ++i)
231 {
232 struct stat sbuf;
233 string file_name;
234
235 if (strstr(search_paths[i], "$HOME"))
236 {
237 char *home_dir = getenv("HOME");
238 if (!home_dir)
239 {
240 continue;
241 }
242 else
243 {
244 char *cdr = index(search_paths[i], '/');
245 file_name = home_dir;
246 file_name += cdr;
247 }
248 }
249 else
250 {
251 file_name = search_paths[i];
252 }
253 file_name += default_file_name;
254 int sres = stat(file_name.c_str(), &sbuf);
255 if (sres == 0)
256 {
257 cout << "Using wishes file " << file_name << endl;
258 return file_name;
259 }
260 }
261
262 return "";
263}
264//! find out is the device is Direct Touch for example touchscreen is but touchpad not!
265bool GINN::isDirectTouch(int deviceID)
266{
267 GeisDevice device;
268 int count = geis_device_attr_count (device);
269 for (int i =0;i<count;i++)
270 {
271 GeisGestureAttr *buffer = (GeisGestureAttr *) geis_device_attr(device,i);
272 if (!strcmp(buffer->name , GEIS_DEVICE_ATTRIBUTE_DIRECT_TOUCH))
273 {
274 return buffer->boolean_val;
275 }
276 }
277}
278//! set Gesture functon callback for GEIS API.
279void GINN::setGFuncton(GCallback GaddedP, GCallback GremovedP, GCallback GstartP, GCallback GupdateP, GCallback GfinishP)
280{
281 gesture_funcs.added = GaddedP;
282 gesture_funcs.removed = GremovedP;
283 gesture_funcs.start = GstartP;
284 gesture_funcs.update = GupdateP;
285 gesture_funcs.finish = GfinishP;
286}
287//! get Gesture functon callback (More info on setGFuncton).
288GeisGestureFuncs GINN::getGFuncton()
289{
290 return gesture_funcs;
291}
292//! Open (even from argv) and Check Wish file automatically and if any problem emit error and print it.
293void GINN::loadConfig(int argc, char *argv[])
294{
295 if (argc < 2)
296 {
297 cerr << "usage: " << argv[0] << " <configxml>\n";
298 cfg_path = ginn_default_config();
299 if (cfg_path.empty())
300 {
301 cerr << "using default configuration file " << cfg_path << "... \n";
302 }
303 }
304 else
305 {
306 cfg_path = strdup(argv[1]);
307 }
308 if (cfg_path.empty())
309 {
310 cerr << "Could not find Ginn wishes\n";
311 exit (-1);
312 }
313
314 if (ginn_config_open(&cfg, cfg_path.c_str()))
315 {
316 cerr << "Could not load Ginn wishes\n";
317 exit (-1);
318 }
319 config_load = true;
320}
321//! Print the config file.
322void GINN::printConfig()
323{
324 if (config_load)
325 ginn_config_print(&cfg);
326}
327//! Store the config file and process it
328void GINN::StoreConfig()
329{
330 if (config_load)
331 ginn_config_store(&cfg, wp, ap);
332}
333
334//! subscribe all gesture callback and other value on GEIS
335GeisStatus GINN::Gsubscribe(GeisInstance geis_instance, GeisInputDeviceId *input_list, const char **gesture_list)
336{
337 return geis_subscribe(geis_instance, input_list, gesture_list, &gesture_funcs, this);
338}
339//! set Device functon callback for GEIS API.
340void GINN::setDFuncton(DCallback DaddedP, DCallback DchangedP, DCallback DremovedP)
341{
342 device_funcs.added = DaddedP;
343 device_funcs.removed = DremovedP;
344 device_funcs.changed = DchangedP;
345}
346//! get Device functon callback (More info on setDFuncton).
347GeisInputFuncs GINN::getDFuncton()
348{
349 return device_funcs;
350}
351//! subscribe all Device callback and other value on GEIS
352GeisStatus GINN::Dsubscribe(GeisInstance geis_instance)
353{
354 return geis_input_devices(geis_instance, &device_funcs, this);
355}
356//! when a touch device add this function called
357void GINN::Dadded(GeisInputDeviceId device_id, void *attrs)
358{
359 GeisGestureAttr *a = (GeisGestureAttr *)attrs;
360 GD_att buffer;
361 try
362 {
363 buffer.ID = device_id;
364 buffer.name = a[0].string_val;
365 buffer.isDirectTouch = a[2].boolean_val;
366 buffer.TouchNum = a[3].integer_val;
367 device_list.push_back(buffer);
368 }
369 catch(error_t error)
370 {
371 cerr << "Erorr on read Device atrribute for device with ID: " << device_id << endl;
372 }
373}
374//! when a touch device attributes changed this function called
375void GINN::Dchanged(GeisInputDeviceId device_id, void *attrs)
376{
377 ;
378}
379//! when a touch device removed this function called
380void GINN::Dremoved(GeisInputDeviceId device_id, void *attrs)
381{
382 int index = DId2Index(device_id);
383 device_list.erase(device_list.begin() + index);
384}
385//! return Device index in device_list from deviceID ; return -1 if the device not found
386int GINN::DId2Index(int DeviceID)
387{
388 for (int i=0;i<device_list.size();i++)
389 {
390 if(device_list[i].ID == DeviceID)
391 return i;
392 }
393 return -1;
394}
395
396/**
397 * Check the loaded wishes to see which gestures are used
398 * and add these gestures to a NULL terminated list "sub_gestures_list"
399 *
400 * This list is used to subscribe only the necessary gestures
401 * to GEIS. This will avoid issues with 2 finger scrolls and other gestues
402 * being dropped when not accounted for in the wishes file.
403**/
404vector<string> GINN::extract_gesture()
405{
406 Gapps * appPtr = ap;
407 Gwish * wishPtr;
408 int finished = 0;
409 vector<string> sub_gestures_list(17);
410 /**
411 * Loop through each wish inside ap
412 * After all of the wishes in ap are accounted for
413 * add global wishes
414 **/
415
416 while(finished != 1)
417 {
418 // Check if we are finished with the application wishes
419 if(appPtr == NULL)
420 {
421 wishPtr = wp;
422 finished = 1;
423 }
424 else
425 {
426 wishPtr = appPtr->wp;
427 }
428
429 // Loop through each wish
430 while(wishPtr)
431 {
432 int i;
433 for(i = 0; i < 25; i ++)
434 {
435
436 string sub_gesture;
437 char buffer[100];
438 int pos = 0;
439
440 // Check for Drag gesture
441 if(wishPtr->config_attr[i].attrName == "delta x" || wishPtr->config_attr[i].attrName == "delta y" ||
442 wishPtr->config_attr[i].attrName == "velocity x" || wishPtr->config_attr[i].attrName == "velocity y")
443 {
444 sprintf(buffer, "Drag,touch=%i", (int)wishPtr->config_attr[1].val);
445 }
446
447 // Check for Rotate gesture
448 else if(wishPtr->config_attr[i].attrName == "angle delta"||
449 wishPtr->config_attr[i].attrName == "angular velocity"||
450 wishPtr->config_attr[i].attrName == "angle")
451 {
452 sprintf(buffer, "Rotate,touch=%i", (int)wishPtr->config_attr[1].val);
453 }
454
455 // Check for Pinch gesture
456 else if(wishPtr->config_attr[i].attrName == "radius delta" ||wishPtr->config_attr[i].attrName == "radial velocity" ||
457 wishPtr->config_attr[i].attrName == "radius")
458 {
459 sprintf(buffer, "Pinch,touch=%i", (int)wishPtr->config_attr[1].val);
460 }
461
462 // Check for Tap gesture
463 else if(wishPtr->config_attr[i].attrName == "tap time")
464 {
465 sprintf(buffer, "Tap,touch=%i", (int)wishPtr->config_attr[1].val);
466 }
467
468 // Deallocate sub_gesture if no gesture was found
469 else
470 {
471 buffer[0] = NULL;
472 continue;
473 }
474 sub_gesture = buffer;
475
476 /** Check the current gesture list
477 * Only add if the gesture is not already in the list
478 * Store in index of the first NULL found
479 **/
480
481 while(pos < 17)
482 {
483 if(sub_gestures_list[pos].empty())
484 {
485 sub_gestures_list[pos] = sub_gesture;
486 break;
487 }
488 else if(sub_gesture == sub_gestures_list[pos])
489 {
490 break;
491 }
492 pos ++;
493 }
494
495
496 }
497 // Iterate to the next wish
498 wishPtr = wishPtr->next;
499 }
500
501 // If there are more applications, iterate to the next
502
503 if(finished != 1)
504 {
505 appPtr = appPtr->next;
506 }
507 }
508 return sub_gestures_list;
509}
510
511//! print the Subscribe gesture list
512void GINN::print_SGL(const char **sub_gestures_list)
513{
514 // Show which gestures were subscribed
515 cout << "Gestures subscribed:" << endl;
516
517 int pos = 0;
518 while(pos < 17)
519 {
520 if(sub_gestures_list[pos] != NULL)
521 {
522 cout << sub_gestures_list[pos] << endl;
523 }
524
525 pos ++;
526 }
527}
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
0556
=== added file 'src/ginn.h'
--- src/ginn.h 1970-01-01 00:00:00 +0000
+++ src/ginn.h 2011-08-23 04:19:23 +0000
@@ -0,0 +1,60 @@
1#ifndef GINN_H
2#define GINN_H
3
4#include "config.h"
5
6typedef GeisGestureCallback GCallback;
7typedef GeisInputCallback DCallback;
8
9class GINN
10{
11public:
12 GINN();
13 void Gmatch(GeisGestureType gesture_type, GeisGestureId gesture_id,GeisSize attr_count,GeisGestureAttr * attrs, int state);
14 int inside(float x, float a, float b);
15 bool isDirectTouch(int deviceID);
16 void clear_accum_attrs(att * attrs);
17 void update_wishes();
18 void print_SGL(const char **sub_gestures_list);
19 void print_attr(GeisGestureAttr * attr);
20 Window getRootWindow();
21 string ginn_default_config();
22 vector<string> extract_gesture();
23//New Interfaces:
24 int DId2Index(int DeviceID);
25 void printConfig();
26 void StoreConfig();
27 void loadConfig(int argc, char *argv[]);
28 void setGFuncton(GCallback GaddedP, GCallback GremovedP, GCallback GstartP, GCallback GupdateP, GCallback GfinishP);
29 GeisGestureFuncs getGFuncton();
30 void setDFuncton(DCallback DaddedP, DCallback DchangedP, DCallback DremovedP);
31 GeisInputFuncs getDFuncton();
32 GeisStatus Gsubscribe(GeisInstance geis_instance, GeisInputDeviceId *input_list, const char **gesture_list);
33 GeisStatus Dsubscribe(GeisInstance geis_instance);
34//CallBacks:
35 //Gesture CallBacks
36 void Gadded (GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs);
37 void Gremoved(GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs);
38 void Gstart (GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs);
39 void Gupdate (GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs);
40 void Gfinish (GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs);
41 //Device CallBacks (D in Dadded referred to Device)
42 void Dadded (GeisInputDeviceId device_id, void *attrs);
43 void Dchanged(GeisInputDeviceId device_id, void *attrs);
44 void Dremoved(GeisInputDeviceId device_id, void *attrs);
45//Variable:
46 Gwish *wp, *wpEnd;
47 Gapps *ap;
48 att config_attr[25];
49 Gwish w1;
50private:
51 GeisGestureFuncs gesture_funcs;
52 GeisInputFuncs device_funcs;
53 ginn_config cfg;
54 string cfg_path;
55 vector<GD_att> device_list; //save Device list and device attribute
56 bool config_load;
57};
58
59
60#endif // GINN_H
061
=== modified file 'src/ginn.pod' (properties changed: -x to +x)
=== added file 'src/gir.cpp'
--- src/gir.cpp 1970-01-01 00:00:00 +0000
+++ src/gir.cpp 2011-08-23 04:19:23 +0000
@@ -0,0 +1,47 @@
1#include "gir.h"
2
3Gapps::Gapps()
4{
5 next = NULL;
6 wp = NULL;
7 appName = "";
8}
9
10Gwish::Gwish()
11{
12 //Default Value
13 Type = -1;
14 TouchNum = 0;
15 DirectTouch = -1;
16 //
17 int i;
18 button = 0;
19 key = "";
20 next = NULL;
21 for (i = 0; i < 4; i++)
22 modifiers[i] = "";
23 for (i = 0; i < 25; i++)
24 {
25 config_attr[i].attrName = "";
26 config_attr[i].val = 0;
27 config_attr[i].valMax = 0;
28 }
29}
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
048
=== added file 'src/gir.h'
--- src/gir.h 1970-01-01 00:00:00 +0000
+++ src/gir.h 2011-08-23 04:19:23 +0000
@@ -0,0 +1,70 @@
1/**
2 * New Implemetion for GINN Include C++ Callback
3 */
4
5#ifndef GIR_H
6#define GIR_H
7
8#include "ginn.h"
9
10/** Gesure CallBack Interface Start Decration HERE! These function recieve events from GEIS and send it to
11related object as well as a postman!
12***/
13static void gesture_added(void *cookie,GeisGestureType gesture_type, GeisGestureId gesture_id,
14 GeisSize attr_count, GeisGestureAttr * attrs)
15{
16 GINN *buffer = (GINN *) cookie;
17 buffer->Gadded(gesture_type,gesture_id,attr_count,attrs);
18}
19
20static void gesture_removed(void *cookie, GeisGestureType gesture_type, GeisGestureId gesture_id,
21 GeisSize attr_count, GeisGestureAttr * attrs)
22{
23 GINN *buffer = (GINN *) cookie;
24 buffer->Gadded(gesture_type,gesture_id,attr_count,attrs);
25}
26
27static void gesture_start(void *cookie, GeisGestureType gesture_type, GeisGestureId gesture_id,
28 GeisSize attr_count, GeisGestureAttr * attrs)
29{
30 GINN *buffer = (GINN *) cookie;
31 buffer->Gstart(gesture_type,gesture_id,attr_count,attrs);
32}
33
34static void gesture_update(void *cookie, GeisGestureType gesture_type,
35 GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs)
36{
37 GINN *buffer = (GINN *) cookie;
38 buffer->Gupdate(gesture_type,gesture_id,attr_count,attrs);
39}
40
41static void gesture_finish(void *cookie, GeisGestureType gesture_type,
42 GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr * attrs)
43{
44 GINN *buffer = (GINN *) cookie;
45 buffer->Gfinish(gesture_type,gesture_id,attr_count,attrs);
46}
47
48/** Device CallBack Interface Start Decration HERE! These function recieve events from GEIS and send it to
49related object as well as a postman!
50***/
51static void device_added(void *cookie, GeisInputDeviceId device_id, void *attrs)
52{
53 GINN *buffer = (GINN *) cookie;
54 buffer->Dadded(device_id,attrs);
55}
56
57
58static void device_changed(void *cookie, GeisInputDeviceId device_id, void *attrs)
59{
60 GINN *buffer = (GINN *) cookie;
61 buffer->Dchanged(device_id,attrs);
62}
63
64
65static void device_removed(void *cookie, GeisInputDeviceId device_id, void *attrs)
66{
67 GINN *buffer = (GINN *) cookie;
68 buffer->Dremoved(device_id,attrs);
69}
70#endif // GIR_H
071
=== added file 'src/header.h'
--- src/header.h 1970-01-01 00:00:00 +0000
+++ src/header.h 2011-08-23 04:19:23 +0000
@@ -0,0 +1,38 @@
1#ifndef HEADER_H
2#define HEADER_H
3
4//Standart C and C++ Header
5#include <string>
6#include <vector>
7#include <cstring>
8#include <errno.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>
13#include <iostream>
14//X window Header
15#include <X11/X.h>
16#include <X11/Xlib.h>
17#include <X11/keysym.h>
18#include <X11/extensions/XTest.h>
19//Other
20#include <sys/select.h>
21#include <sys/stat.h>
22#include <libxml/tree.h>
23#include <geis/geis.h>
24#include <libxml/parser.h>
25
26using namespace std;
27
28//Function Prototypes
29char *getCurrentApp();
30//Decleare in xt.cpp
31void injMixBtnKey (KeySym ks, int btn, string *modifiers);
32void injButton (int btn, string *modifiers);
33void injKey (KeySym ks, string *modifiers);
34void movePointer (int x, int y);
35void openDisplay ( );
36void closeDisplay ( );
37
38#endif // HEADER_H
039
=== added file 'src/main.cpp'
--- src/main.cpp 1970-01-01 00:00:00 +0000
+++ src/main.cpp 2011-08-23 04:19:23 +0000
@@ -0,0 +1,137 @@
1/**
2 * Copyright 2010 Canonical Ltd.
3 *
4 * This library is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 3 of the License, or (at your option) any later
7 * version.
8 *
9 * This library is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51
16 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Authors:
19 * Mohamed-Ikbel Boulabiar <boulabiar@gmail.com>
20 * Henrik Rydberg <rydberg@bitmath.org>
21 * Stephen M. Webb <stephen.webb@canonical.com>
22 * Bijan Binaee <bijanbina@gmail.com>
23 *
24 */
25
26#include "gir.h"
27
28int main(int argc, char *argv[])
29{
30 GeisStatus status = GEIS_UNKNOWN_ERROR;
31 GeisXcbWinInfo xcb_win_info;
32 GINN local;
33 //Initizalize xcb_win_info
34 xcb_win_info.display_name = NULL;
35 xcb_win_info.screenp = NULL;
36 xcb_win_info.window_id = local.getRootWindow();
37 //Initialize win_info
38 GeisWinInfo win_info = {GEIS_XCB_FULL_WINDOW,&xcb_win_info};
39 GeisInstance instance;
40 //Initializ GINN Class
41 local.setGFuncton(gesture_added, gesture_removed, gesture_start, gesture_update, gesture_finish);
42 local.setDFuncton(device_added,device_changed,device_removed);
43
44 local.loadConfig(argc,argv);
45 //local.printConfig();
46 local.StoreConfig();
47
48
49 local.wpEnd = local.wp;
50 while (local.wpEnd->next)
51 local.wpEnd = local.wpEnd->next;
52
53 int pos = 2;
54 cout << endl;
55 while (!local.config_attr[pos].attrName.empty())
56 {
57 cout << "DEBUG " << pos << local.config_attr[pos].attrName << local.config_attr[pos].val << local.config_attr[pos].valMax << endl;
58 pos++;
59 }
60
61 //Use Dynamic sub gestures list
62 vector<string> SGL = local.extract_gesture();//sub gestures list buffer
63 const char *sub_gestures_list[SGL.size()];
64 //convert to const char
65 for (int i =0;i<SGL.size();i++)
66 {
67 sub_gestures_list[i] = (char *)(SGL[i].c_str());
68 if (SGL[i].empty())
69 sub_gestures_list[i]= NULL;
70 }
71 local.print_SGL(sub_gestures_list);
72 //End Use Dynamic sub gestures list
73
74 status = geis_init(&win_info, &instance);
75 if (status != GEIS_STATUS_SUCCESS) {
76 cerr << "error in geis_init\n";
77 return 1;
78 }
79
80 status = geis_configuration_supported(instance, GEIS_CONFIG_UNIX_FD);
81 if (status != GEIS_STATUS_SUCCESS) {
82 cerr << "GEIS does not support Unix fd\n";
83 return 1;
84 }
85
86 int fd = -1;
87 status = geis_configuration_get_value(instance, GEIS_CONFIG_UNIX_FD, &fd);
88 if (status != GEIS_STATUS_SUCCESS)
89 {
90 cerr << "error retrieving GEIS fd\n";
91 return 1;
92 }
93 //Subscribe Device input callback
94 status = local.Dsubscribe(instance);// GEIS_ALL_GESTURES,
95 if (status != GEIS_STATUS_SUCCESS)
96 {
97 cerr << "error on subscribing to Device\n";
98 return 1;
99 }
100 //Subscribe gesture callback
101 status = local.Gsubscribe(instance, GEIS_ALL_INPUT_DEVICES, const_cast <const char**>(sub_gestures_list));// GEIS_ALL_GESTURES,
102 if (status != GEIS_STATUS_SUCCESS)
103 {
104 cerr << "error on subscribing to gestures\n";
105 return 1;
106 }
107
108 openDisplay();
109
110 while (1)
111 {
112 fd_set read_fds;
113 FD_ZERO(&read_fds);
114 FD_SET(fd, &read_fds);
115 int sstat = select(fd + 1, &read_fds, NULL, NULL, NULL);
116 if (sstat < 0)
117 {
118 cerr << "error " << errno << "in select(): " << strerror(errno) << endl;
119 break;
120 }
121
122 if (FD_ISSET(fd, &read_fds))
123 geis_event_dispatch(instance);
124 }
125
126 delete local.wp;
127 geis_finish(instance);
128 closeDisplay();
129
130 return 0;
131}
132
133
134
135
136
137
0138
=== modified file 'src/todo' (properties changed: -x to +x)
=== removed file 'src/xt.c'
--- src/xt.c 2011-03-16 16:23:21 +0000
+++ src/xt.c 1970-01-01 00:00:00 +0000
@@ -1,108 +0,0 @@
1/*
2 * Copyright (C) 2010 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: Mohamed-Ikbel Boulabiar <boulabiar@gmail.com>
18 */
19
20#include <X11/X.h>
21#include <X11/extensions/XTest.h>
22#include <X11/keysym.h>
23
24static Display *disp = NULL;
25
26void openDisplay()
27{
28 disp = XOpenDisplay(NULL);
29}
30
31void closeDisplay()
32{
33 XCloseDisplay(disp);
34}
35
36void movePointer(int x, int y)
37{
38 XTestFakeMotionEvent(disp, 0, x, y, CurrentTime);
39}
40
41void injKey(KeySym ks, char *modifiers[])
42{
43 int i;
44
45 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
46 XTestFakeKeyEvent(disp,
47 XKeysymToKeycode(disp,
48 XStringToKeysym(modifiers
49 [i])), True,
50 CurrentTime);
51 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime);
52 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False,
53 CurrentTime);
54 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
55 XTestFakeKeyEvent(disp,
56 XKeysymToKeycode(disp,
57 XStringToKeysym(modifiers
58 [i])), False,
59 CurrentTime);
60
61 XFlush(disp);
62}
63
64void injButton(int btn, char *modifiers[])
65{
66 int i;
67
68 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
69 XTestFakeKeyEvent(disp,
70 XKeysymToKeycode(disp,
71 XStringToKeysym(modifiers
72 [i])), True,
73 CurrentTime);
74 XTestFakeButtonEvent(disp, btn, True, CurrentTime);
75 XTestFakeButtonEvent(disp, btn, False, CurrentTime);
76 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
77 XTestFakeKeyEvent(disp,
78 XKeysymToKeycode(disp,
79 XStringToKeysym(modifiers
80 [i])), False,
81 CurrentTime);
82
83 XFlush(disp);
84}
85
86void injMixBtnKey(KeySym ks, int btn, char *modifiers[])
87{
88 int i;
89
90 XTestFakeButtonEvent(disp, btn, True, CurrentTime);
91 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
92 XTestFakeKeyEvent(disp,
93 XKeysymToKeycode(disp,
94 XStringToKeysym(modifiers
95 [i])), True,
96 CurrentTime);
97 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime);
98 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False,
99 CurrentTime);
100 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
101 XTestFakeKeyEvent(disp,
102 XKeysymToKeycode(disp,
103 XStringToKeysym(modifiers
104 [i])), False,
105 CurrentTime);
106 XTestFakeButtonEvent(disp, btn, False, CurrentTime);
107 XFlush(disp);
108}
1090
=== added file 'src/xt.cpp'
--- src/xt.cpp 1970-01-01 00:00:00 +0000
+++ src/xt.cpp 2011-08-23 04:19:23 +0000
@@ -0,0 +1,97 @@
1/*
2 * Copyright (C) 2010 Canonical, Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: Mohamed-Ikbel Boulabiar <boulabiar@gmail.com>
18 */
19#include "header.h"
20
21static Display *disp = NULL;
22
23void openDisplay()
24{
25 disp = XOpenDisplay(NULL);
26}
27
28void closeDisplay()
29{
30 XCloseDisplay(disp);
31}
32
33void movePointer(int x, int y)
34{
35 XTestFakeMotionEvent(disp, 0, x, y, CurrentTime);
36}
37
38void injKey(KeySym ks, string *modifiers)
39{
40 int i;
41
42 for (i = 0; i < 4 && !modifiers[i].empty(); i++)
43 XTestFakeKeyEvent(disp,
44 XKeysymToKeycode(disp,
45 XStringToKeysym(modifiers[i].c_str())), True,
46 CurrentTime);
47 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime);
48 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False,
49 CurrentTime);
50 for (i = 0; i < 4 && !modifiers[i].empty(); i++)
51 XTestFakeKeyEvent(disp,
52 XKeysymToKeycode(disp,
53 XStringToKeysym(modifiers[i].c_str())), False,
54 CurrentTime);
55
56 XFlush(disp);
57}
58
59void injButton(int btn, string *modifiers)
60{
61 int i;
62
63 for (i = 0; i < 4 && !modifiers[i].empty(); i++)
64 XTestFakeKeyEvent(disp,
65 XKeysymToKeycode(disp,
66 XStringToKeysym(modifiers[i].c_str())), True,
67 CurrentTime);
68 XTestFakeButtonEvent(disp, btn, True, CurrentTime);
69 XTestFakeButtonEvent(disp, btn, False, CurrentTime);
70 for (i = 0; i < 4 && !modifiers[i].empty(); i++)
71 XTestFakeKeyEvent(disp,
72 XKeysymToKeycode(disp,
73 XStringToKeysym(modifiers[i].c_str())), False,
74 CurrentTime);
75
76 XFlush(disp);
77}
78
79void injMixBtnKey(KeySym ks, int btn, string *modifiers)
80{
81 int i;
82
83 XTestFakeButtonEvent(disp, btn, True, CurrentTime);
84 for (i = 0; i < 4 && !modifiers[i].empty(); i++)
85 XTestFakeKeyEvent(disp,
86 XKeysymToKeycode(disp, XStringToKeysym(modifiers [i].c_str())), True,
87 CurrentTime);
88 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime);
89 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False,
90 CurrentTime);
91 for (i = 0; i < 4 && !modifiers[i].empty(); i++)
92 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp,
93 XStringToKeysym(modifiers [i].c_str())), False,
94 CurrentTime);
95 XTestFakeButtonEvent(disp, btn, False, CurrentTime);
96 XFlush(disp);
97}