Merge lp:~oif-team/ginn/scroll-pointer-fixes into lp:ginn

Proposed by Chase Douglas
Status: Merged
Merged at revision: 84
Proposed branch: lp:~oif-team/ginn/scroll-pointer-fixes
Merge into: lp:ginn
Diff against target: 1451 lines (+695/-639)
6 files modified
etc/wishes.xml (+2/-2)
src/bamf.c (+27/-30)
src/config.c (+162/-137)
src/config.h (+17/-17)
src/ginn.c (+409/-402)
src/xt.c (+78/-51)
To merge this branch: bzr merge lp:~oif-team/ginn/scroll-pointer-fixes
Reviewer Review Type Date Requested Status
Mohamed IKBEL Boulabiar (community) Approve
Review via email: mp+53649@code.launchpad.net

Description of the change

* Use pointer buttons for scrolling
* Reindent source code for uniformity
* Move the cursor to the location of the gesture

You probably will want to review the commits individually due to the reindentation. I can split the merge request up into individual requests if that's preferred.

To post a comment you must log in.
Revision history for this message
Mohamed IKBEL Boulabiar (boulabiar) wrote :

Everything looks fine !
Thanks Chase !

Once merged, I think the indentation (rev85) can be seen a part, so it's OK for me !

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'etc/wishes.xml'
--- etc/wishes.xml 2010-12-21 17:56:26 +0000
+++ etc/wishes.xml 2011-03-16 16:26:15 +0000
@@ -4,13 +4,13 @@
4 <wish gesture="Drag" fingers="2">4 <wish gesture="Drag" fingers="2">
5 <action name="action5" when="update">5 <action name="action5" when="update">
6 <trigger prop="delta y" min="20" max="80"/>6 <trigger prop="delta y" min="20" max="80"/>
7 <key>Down</key>7 <button>4</button>
8 </action>8 </action>
9 </wish>9 </wish>
10 <wish gesture="Drag" fingers="2">10 <wish gesture="Drag" fingers="2">
11 <action name="action6" when="update">11 <action name="action6" when="update">
12 <trigger prop="delta y" min="-80" max="-20"/>12 <trigger prop="delta y" min="-80" max="-20"/>
13 <key>Up</key>13 <button>5</button>
14 </action>14 </action>
15 </wish>15 </wish>
1616
1717
=== modified file 'src/bamf.c'
--- src/bamf.c 2011-02-03 09:59:19 +0000
+++ src/bamf.c 2011-03-16 16:26:15 +0000
@@ -19,33 +19,30 @@
19#include <libbamf/bamf-matcher.h>19#include <libbamf/bamf-matcher.h>
20#include <string.h>20#include <string.h>
2121
22char *22char *getName(char *deskfile)
23getName(char * deskfile)23{
24{24 char *temp;
25 char *temp;25 temp = strdup(strrchr(deskfile, '/'));
26 temp = strdup(strrchr(deskfile, '/'));26 return strndup(temp + 1, strlen(temp) - 9);
27 return strndup(temp+1, strlen(temp)-9);27}
28}28
2929char *getCurrentApp()
30char *30{
31getCurrentApp()31 g_type_init();
32{32 char *deskfile, *appName;
33 g_type_init();33 char *temp;
34 char *deskfile, *appName; 34
35 char* temp;35 BamfApplication *app =
3636 bamf_matcher_get_active_application(bamf_matcher_get_default());
37 BamfApplication * app = bamf_matcher_get_active_application(bamf_matcher_get_default());37 if (app) {
38 if (app) {38 appName = (char *) bamf_view_get_name(BAMF_VIEW(app));
39 appName = (char*)bamf_view_get_name(BAMF_VIEW(app));39 temp = bamf_application_get_desktop_file(app);
40 temp = bamf_application_get_desktop_file(app);40
4141 if (strchr(appName, ' ') && temp)
42 if (strchr(appName,' ') && temp)42 return getName((char *) temp);
43 return getName((char*)temp);43 else
44 else 44 return appName;
45 return appName;45 } else
46 }46 return "";
47 else47
48 return "";48}
49
50}
51
5249
=== modified file 'src/config.c'
--- src/config.c 2010-12-02 12:37:14 +0000
+++ src/config.c 2011-03-16 16:26:15 +0000
@@ -19,157 +19,182 @@
19#include "config.h"19#include "config.h"
20#include <libxml/parser.h>20#include <libxml/parser.h>
2121
22void22void debugOut(struct wish *wp)
23debugOut(struct wish * wp) {23{
24 int i;24 int i;
25 printf("\n key : %s ", wp->key);25 printf("\n key : %s ", wp->key);
26 printf("\n button : %d ", wp->button);26 printf("\n button : %d ", wp->button);
27 for(i=0 ; i<4 ; i++)27 for (i = 0; i < 4; i++)
28 printf("\t mod%d : %s ", i, wp->modifiers[i]);28 printf("\t mod%d : %s ", i, wp->modifiers[i]);
29 for(i=0 ; i<4 ; i++ ) {29 for (i = 0; i < 4; i++) {
30 printf("\n attrName : %s ", wp->config_attr[i].attrName);30 printf("\n attrName : %s ", wp->config_attr[i].attrName);
31 printf("\t val : %.2f ", wp->config_attr[i].val);31 printf("\t val : %.2f ", wp->config_attr[i].val);
32 printf("\t valMax : %.2f", wp->config_attr[i].valMax);32 printf("\t valMax : %.2f", wp->config_attr[i].valMax);
33 }33 }
34 printf("\n pMe : %x pNext : %x ", wp, wp->next);34 printf("\n pMe : %x pNext : %x ", wp, wp->next);
35 printf("\n===================================================");35 printf("\n===================================================");
36}36}
3737
38int ginn_config_open(struct ginn_config *cfg, const char *path)38int ginn_config_open(struct ginn_config *cfg, const char *path)
39{39{
40 memset(cfg, 0, sizeof(*cfg));40 memset(cfg, 0, sizeof(*cfg));
41 cfg->doc = xmlReadFile(path, NULL, 0);41 cfg->doc = xmlReadFile(path, NULL, 0);
42 if (cfg->doc == NULL) {42 if (cfg->doc == NULL) {
43 fprintf(stderr, "Failed to parse %s\n", path);43 fprintf(stderr, "Failed to parse %s\n", path);
44 return -1;44 return -1;
45 }45 }
46 return 0;46 return 0;
47}47}
4848
49void ginn_config_close(struct ginn_config *cfg)49void ginn_config_close(struct ginn_config *cfg)
50{50{
51 xmlFreeDoc(cfg->doc);51 xmlFreeDoc(cfg->doc);
52}52}
5353
5454static void print_node(const xmlNode * root, int depth)
55static void print_node(const xmlNode *root, int depth)55{
56{56 xmlNode *node;
57 xmlNode *node;57 for (node = root; node; node = node->next) {
58 for (node = root; node; node = node->next) {58 int i;
59 int i;59 if (node->type != XML_ELEMENT_NODE)
60 if (node->type != XML_ELEMENT_NODE)60 continue;
61 continue;61 for (i = 0; i < depth; i++)
62 for (i = 0; i < depth; i++)62 printf(" ");
63 printf(" ");63 printf("%s\n", node->name);
64 printf("%s\n", node->name);64 print_node(node->children, depth + 1);
65 print_node(node->children, depth + 1);65 }
66 }66}
67}67
6868static int ginn_str2state(const char *str)
69static int ginn_str2state(const char *str){69{
70 if (str == NULL) return -1;70 if (str == NULL)
71 if (strcmp(str, "start") == 0) return GINN_START;71 return -1;
72 if (strcmp(str, "update") == 0) return GINN_UPDATE;72 if (strcmp(str, "start") == 0)
73 if (strcmp(str, "finish") == 0) return GINN_FINISH;73 return GINN_START;
74 fprintf(stderr, "ERROR: Undefined state: %s\n", str);74 if (strcmp(str, "update") == 0)
75 return -2;75 return GINN_UPDATE;
76}76 if (strcmp(str, "finish") == 0)
7777 return GINN_FINISH;
78static int ginn_str2bool(const char *str){78 fprintf(stderr, "ERROR: Undefined state: %s\n", str);
79 if (str == NULL) return -1;79 return -2;
80 if (strcmp(str, "true") == 0) return 1;80}
81 if (strcmp(str, "false") == 0) return 0;81
82 fprintf(stderr, "ERROR: Invalid value for boolean attribute: %s\n", str);82static int ginn_str2bool(const char *str)
83 return -2;83{
84}84 if (str == NULL)
8585 return -1;
86void store_1config(xmlNode *node, struct wish *wp, int *position)86 if (strcmp(str, "true") == 0)
87{87 return 1;
88 if (0==strcmp(node->name, "wish")) {88 if (strcmp(str, "false") == 0)
89 // printf(" gesture %s fingers %s ",(xmlGetProp(node, "gesture")),(xmlGetProp(node, "fingers")));89 return 0;
90 wp->config_attr[0].attrName = "gesture name";90 fprintf(stderr, "ERROR: Invalid value for boolean attribute: %s\n",
91 switch (xmlGetProp(node, "gesture")[0]) {91 str);
92 case 'D': wp->config_attr[0].val=wp->config_attr[0].valMax= 0; break; 92 return -2;
93 case 'P': wp->config_attr[0].val=wp->config_attr[0].valMax= 1; break; 93}
94 case 'R': wp->config_attr[0].val=wp->config_attr[0].valMax= 2; break; 94
95 case 'T': wp->config_attr[0].val=wp->config_attr[0].valMax=15; break; 95void store_1config(xmlNode * node, struct wish *wp, int *position)
96 }96{
97 wp->config_attr[1].attrName = "touches";97 if (0 == strcmp(node->name, "wish")) {
98 wp->config_attr[1].val = atoi(xmlGetProp(node, "fingers"));98 // printf(" gesture %s fingers %s ",(xmlGetProp(node, "gesture")),(xmlGetProp(node, "fingers")));
99 wp->config_attr[1].valMax = atoi(xmlGetProp(node, "fingers"));99 wp->config_attr[0].attrName = "gesture name";
100 }100 switch (xmlGetProp(node, "gesture")[0]) {
101 if (0==strcmp(node->name, "action")) {101 case 'D':
102 wp->when = ginn_str2state(xmlGetProp(node, "when"));102 wp->config_attr[0].val = wp->config_attr[0].valMax = 0;
103 if (wp->when < 0)103 break;
104 fprintf(stderr, "ERROR: you must provide property 'when' to the action: %s\n", xmlGetProp(node, "name"));104 case 'P':
105 }105 wp->config_attr[0].val = wp->config_attr[0].valMax = 1;
106 if (0==strcmp(node->name, "trigger")) {106 break;
107 wp->config_attr[*position].attrName = xmlGetProp(node, "prop");107 case 'R':
108 wp->config_attr[*position].val = atof(xmlGetProp(node, "min"));108 wp->config_attr[0].val = wp->config_attr[0].valMax = 2;
109 wp->config_attr[*position].valMax = atof(xmlGetProp(node, "max"));109 break;
110 int acc = ginn_str2bool(xmlGetProp(node, "accumulate"));110 case 'T':
111 wp->config_attr[*position].accumulate = acc == -1 ? GINN_DEFAULT_ACCUMULATE : acc;111 wp->config_attr[0].val = wp->config_attr[0].valMax = 15;
112 wp->config_attr[*position].accumVal = 0;112 break;
113 (*position)++;113 }
114 }114 wp->config_attr[1].attrName = "touches";
115 if (0==strcmp(node->name, "key") || 0==strcmp(node->name, "button")) {115 wp->config_attr[1].val = atoi(xmlGetProp(node, "fingers"));
116 if (xmlGetProp(node, "modifier1"))116 wp->config_attr[1].valMax = atoi(xmlGetProp(node, "fingers"));
117 wp->modifiers[0] = xmlGetProp(node, "modifier1"); 117 }
118 if (xmlGetProp(node, "modifier2"))118 if (0 == strcmp(node->name, "action")) {
119 wp->modifiers[1] = xmlGetProp(node, "modifier2"); 119 wp->when = ginn_str2state(xmlGetProp(node, "when"));
120 if (xmlGetProp(node, "modifier3"))120 if (wp->when < 0)
121 wp->modifiers[2] = xmlGetProp(node, "modifier3"); 121 fprintf(stderr,
122 if (xmlGetProp(node, "modifier4"))122 "ERROR: you must provide property 'when' to the action: %s\n",
123 wp->modifiers[3] = xmlGetProp(node, "modifier4");123 xmlGetProp(node, "name"));
124 }124 }
125 if (0==strcmp(node->name, "key")) 125 if (0 == strcmp(node->name, "trigger")) {
126 wp->key = xmlNodeGetContent(node);126 wp->config_attr[*position].attrName = xmlGetProp(node, "prop");
127 if (0==strcmp(node->name, "button")) 127 wp->config_attr[*position].val = atof(xmlGetProp(node, "min"));
128 wp->button = atoi(xmlNodeGetContent(node));128 wp->config_attr[*position].valMax = atof(xmlGetProp(node, "max"));
129 if (0==strcmp(node->name, "button")) 129 int acc = ginn_str2bool(xmlGetProp(node, "accumulate"));
130 printf("Button : %d ", wp->button);130 wp->config_attr[*position].accumulate =
131}131 acc == -1 ? GINN_DEFAULT_ACCUMULATE : acc;
132132 wp->config_attr[*position].accumVal = 0;
133void parse_node(const xmlNode *root, int depth, struct wish *wp, struct apps *ap)133 (*position)++;
134{134 }
135 xmlNode *node;135 if (0 == strcmp(node->name, "key")
136 int position=2;136 || 0 == strcmp(node->name, "button")) {
137 for (node = root; node; node = node->next) {137 if (xmlGetProp(node, "modifier1"))
138 if (node->type != XML_ELEMENT_NODE)138 wp->modifiers[0] = xmlGetProp(node, "modifier1");
139 continue;139 if (xmlGetProp(node, "modifier2"))
140140 wp->modifiers[1] = xmlGetProp(node, "modifier2");
141 if ( (0==strcmp(node->name, "application")) ) {141 if (xmlGetProp(node, "modifier3"))
142 if (0!=strcmp(ap->appName, "")) {142 wp->modifiers[2] = xmlGetProp(node, "modifier3");
143 ap = ap->next = (struct apps *) malloc(sizeof(struct apps));143 if (xmlGetProp(node, "modifier4"))
144 inita(ap);144 wp->modifiers[3] = xmlGetProp(node, "modifier4");
145 }145 }
146 ap->appName=xmlGetProp(node, "name");146 if (0 == strcmp(node->name, "key"))
147 wp = ap->wp = (struct wish *) malloc(sizeof(struct wish));147 wp->key = xmlNodeGetContent(node);
148 initw(wp);148 if (0 == strcmp(node->name, "button"))
149 }149 wp->button = atoi(xmlNodeGetContent(node));
150 if ( (0==strcmp(node->name, "wish")) && (0==strcmp(wp->config_attr[0].attrName, "gesture name")) ) {150 if (0 == strcmp(node->name, "button"))
151 if (!(wp->next)) { 151 printf("Button : %d ", wp->button);
152 wp->next = (struct wish *) malloc(sizeof(struct wish));152}
153 initw(wp->next);153
154 }154void
155 wp = wp->next;155parse_node(const xmlNode * root, int depth, struct wish *wp,
156 position=2;156 struct apps *ap)
157 }157{
158 store_1config(node, wp, &position);158 xmlNode *node;
159 parse_node(node->children, depth + 1, wp, ap);159 int position = 2;
160 }160 for (node = root; node; node = node->next) {
161}161 if (node->type != XML_ELEMENT_NODE)
162162 continue;
163163
164void ginn_config_store(const struct ginn_config *cfg, struct wish *w, struct apps *a)164 if ((0 == strcmp(node->name, "application"))) {
165{165 if (0 != strcmp(ap->appName, "")) {
166 const xmlNode *root = xmlDocGetRootElement(cfg->doc);166 ap = ap->next =
167 parse_node(root, 0, w, a);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);
168}194}
169195
170void ginn_config_print(const struct ginn_config *cfg)196void ginn_config_print(const struct ginn_config *cfg)
171{197{
172 const xmlNode *root = xmlDocGetRootElement(cfg->doc);198 const xmlNode *root = xmlDocGetRootElement(cfg->doc);
173 print_node(root, 0);199 print_node(root, 0);
174}200}
175
176201
=== modified file 'src/config.h'
--- src/config.h 2011-02-04 13:35:41 +0000
+++ src/config.h 2011-03-16 16:26:15 +0000
@@ -28,31 +28,31 @@
28#define GINN_DEFAULT_ACCUMULATE 128#define GINN_DEFAULT_ACCUMULATE 1
2929
30typedef struct ginn_config {30typedef struct ginn_config {
31 xmlDocPtr doc;31 xmlDocPtr doc;
32 xmlNodePtr root;32 xmlNodePtr root;
33} cfg;33} cfg;
3434
35typedef struct att {35typedef struct att {
36 char *attrName ;36 char *attrName;
37 float val ;37 float val;
38 float valMax;38 float valMax;
39 int accumulate;39 int accumulate;
40 float accumVal;40 float accumVal;
41} att;41} att;
4242
43typedef struct wish {43typedef struct wish {
44 att config_attr[25];44 att config_attr[25];
45 char *key;45 char *key;
46 int button;46 int button;
47 char *modifiers[4];47 char *modifiers[4];
48 struct wish* next;48 struct wish *next;
49 int when;49 int when;
50} wish;50} wish;
5151
52typedef struct apps {52typedef struct apps {
53 char *appName;53 char *appName;
54 struct wish *wp;54 struct wish *wp;
55 struct apps *next;55 struct apps *next;
56} apps;56} apps;
5757
58#endif /* GINN_CONFIG_H */58#endif /* GINN_CONFIG_H */
5959
=== modified file 'src/ginn.c'
--- src/ginn.c 2011-02-04 16:04:30 +0000
+++ src/ginn.c 2011-03-16 16:26:15 +0000
@@ -33,432 +33,439 @@
33#include <X11/Xlib.h>33#include <X11/Xlib.h>
34#include <X11/keysym.h>34#include <X11/keysym.h>
3535
36att config_attr[25] = { [0 ... 24] = {.attrName="", .val=0, .valMax=0 } };36att config_attr[25] = {[0 ... 24] = {.attrName = "",.val = 0,.valMax = 0}
37};
3738
38wish w1 = { .config_attr = { [0 ... 24] = {.attrName="", .val=0, .valMax=0 } },39wish w1 = {.config_attr = {[0 ... 24] =
39 .key ="",40 {.attrName = "",.val = 0,.valMax = 0}
40 .next=NULL };41 }
42,
43.key = "",
44.next = NULL
45};
4146
42wish *wp, *wpEnd;47wish *wp, *wpEnd;
43apps *ap;48apps *ap;
4449
45static int50static int inside(float x, float a, float b)
46inside (float x, float a, float b){51{
47 return ((x<=b) && (x>=a));52 return ((x <= b) && (x >= a));
48}53}
4954
50void55void initw(struct wish *wp)
51initw(struct wish *wp) {56{
52 int i;57 int i;
53 wp->button=0;58 wp->button = 0;
54 wp->key="";59 wp->key = "";
55 wp->next=NULL;60 wp->next = NULL;
56 for(i=0 ; i<4 ; i++)61 for (i = 0; i < 4; i++)
57 wp->modifiers[i]="";62 wp->modifiers[i] = "";
58 for(i=0 ; i<25 ; i++ ) {63 for (i = 0; i < 25; i++) {
59 wp->config_attr[i].attrName="";64 wp->config_attr[i].attrName = "";
60 wp->config_attr[i].val=0;65 wp->config_attr[i].val = 0;
61 wp->config_attr[i].valMax=0;66 wp->config_attr[i].valMax = 0;
62 }67 }
63}68}
6469
65void70void inita(struct apps *ap)
66inita(struct apps *ap) {71{
67 ap->next=NULL;72 ap->next = NULL;
68 ap->wp =NULL;73 ap->wp = NULL;
69 ap->appName="";74 ap->appName = "";
70}75}
7176
72static void clear_accum_attrs(att *attrs){77static void clear_accum_attrs(att * attrs)
73 int i = 0;78{
74 while (strcmp(attrs[i].attrName, "") != 0){79 int i = 0;
75 if (attrs[i].accumulate) attrs[i].accumVal = 0;80 while (strcmp(attrs[i].attrName, "") != 0) {
76 i++;81 if (attrs[i].accumulate)
77 }82 attrs[i].accumVal = 0;
78}83 i++;
7984 }
80static void85}
81update_wishes()86
82{87static void update_wishes()
83 char *activeApp;88{
84 apps* tmpAp = ap;89 char *activeApp;
85 int diff=0;90 apps *tmpAp = ap;
8691 int diff = 0;
87 activeApp = (char*)getCurrentApp();92
88 printf(" --ActiveApp %s\n",activeApp);93 activeApp = (char *) getCurrentApp();
89 if (activeApp)94 printf(" --ActiveApp %s\n", activeApp);
90 diff = strcmp(activeApp,ap->appName);95 if (activeApp)
9196 diff = strcmp(activeApp, ap->appName);
92 while ( diff && ap->next ) {97
93 ap = ap->next;98 while (diff && ap->next) {
94 diff = strcmp(activeApp,ap->appName);99 ap = ap->next;
95 }100 diff = strcmp(activeApp, ap->appName);
96101 }
97 if (!diff)102
98 wpEnd->next = ap->wp;103 if (!diff)
99 else 104 wpEnd->next = ap->wp;
100 wpEnd->next = NULL;105 else
101106 wpEnd->next = NULL;
102 ap = tmpAp;107
103}108 ap = tmpAp;
104109}
105static void110
106gesture_match( GeisGestureType gesture_type,111static void
107 GeisGestureId gesture_id,112gesture_match(GeisGestureType gesture_type,
108 GeisSize attr_count,113 GeisGestureId gesture_id,
109 GeisGestureAttr *attrs,114 GeisSize attr_count, GeisGestureAttr * attrs, int state)
110 int state)115{
111{116 struct wish *topw;
112 struct wish *topw;117 topw = wp;
113 topw=wp;118 update_wishes();
114 update_wishes();119 while (wp && (0 != strcmp(wp->key, "") || wp->button)) {
115 while (wp && ( 0!=strcmp(wp->key,"") || wp->button )) {120 int valid = 1;
116 int valid=1;121 if (gesture_type == wp->config_attr[0].val
117 if (gesture_type==wp->config_attr[0].val && attrs[8].integer_val==wp->config_attr[1].val) {122 && attrs[8].integer_val == wp->config_attr[1].val) {
118 int attrsI=9, cAttrI=2;123 int attrsI = 9, cAttrI = 2;
119 do {124 do {
120 if (0==strcmp(attrs[attrsI].name, wp->config_attr[cAttrI].attrName)){125 if (0 ==
121 printf("DEBUG -- comparing %s %s : ", attrs[attrsI].name, wp->config_attr[cAttrI].attrName);126 strcmp(attrs[attrsI].name,
122 printf("%.2f %.2f %.2f \n", attrs[attrsI].float_val, wp->config_attr[cAttrI].val, wp->config_attr[cAttrI].valMax);127 wp->config_attr[cAttrI].attrName)) {
123 printf("%i \n", inside(attrs[attrsI].float_val, wp->config_attr[cAttrI].val, wp->config_attr[cAttrI].valMax));128 printf("DEBUG -- comparing %s %s : ",
124 if (wp->config_attr[cAttrI].accumulate){129 attrs[attrsI].name,
125 wp->config_attr[cAttrI].accumVal += attrs[attrsI].float_val; 130 wp->config_attr[cAttrI].attrName);
126 valid= valid && inside(wp->config_attr[cAttrI].accumVal, wp->config_attr[cAttrI].val, wp->config_attr[cAttrI].valMax);131 printf("%.2f %.2f %.2f \n",
127 }132 attrs[attrsI].float_val,
128 else valid = valid && inside(attrs[attrsI].float_val, wp->config_attr[cAttrI].val, wp->config_attr[cAttrI].valMax);133 wp->config_attr[cAttrI].val,
129 attrsI++; cAttrI++;134 wp->config_attr[cAttrI].valMax);
130 } else attrsI++;135 printf("%i \n",
131 } while ( (0!=strcmp(wp->config_attr[cAttrI].attrName,"")) && attrsI<18 );136 inside(attrs[attrsI].float_val,
132 if (valid && wp->when == state){137 wp->config_attr[cAttrI].val,
133 if ((0!=wp->button) && (0 != strcmp(wp->key, "")))138 wp->config_attr[cAttrI].valMax));
134 { injMixBtnKey(XStringToKeysym(wp->key), wp->button, wp->modifiers);139 if (wp->config_attr[cAttrI].accumulate) {
135 printf("MIX -- MIX");140 wp->config_attr[cAttrI].accumVal +=
136}141 attrs[attrsI].float_val;
137 else {142 valid = valid
138 if (0!=wp->button)143 && inside(wp->config_attr
139 injButton(wp->button, wp->modifiers); 144 [cAttrI].accumVal,
140 if (0 != strcmp(wp->key, ""))145 wp->config_attr
141 injKey(XStringToKeysym(wp->key), wp->modifiers);146 [cAttrI].val,
142 }147 wp->config_attr[cAttrI].valMax);
143 clear_accum_attrs(wp->config_attr);148 } else
144 }149 valid = valid
145 }150 && inside(attrs[attrsI].float_val,
146 if (state == GINN_FINISH) clear_accum_attrs(wp->config_attr);151 wp->config_attr
147 wp=wp->next;152 [cAttrI].val,
148 }153 wp->config_attr[cAttrI].valMax);
149 wp=topw;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;
150}180}
151181
152static Window getRootWindow()182static Window getRootWindow()
153{183{
154 Display *display = NULL;184 Display *display = NULL;
155 Window window = 0;185 Window window = 0;
156 186
157 display = XOpenDisplay(NULL);187 display = XOpenDisplay(NULL);
158 if (!display)188 if (!display) {
159 {189 fprintf(stderr, "error opening X11 display.\n");
160 fprintf(stderr, "error opening X11 display.\n");190 exit(1);
161 exit(1);191 }
162 }192
163193 window = DefaultRootWindow(display);
164 window = DefaultRootWindow(display);194
165195 XCloseDisplay(display);
166 XCloseDisplay(display);196
167197 return window;
168 return window;
169}198}
170199
171static void200static void print_attr(GeisGestureAttr * attr)
172print_attr(GeisGestureAttr *attr)
173{201{
174 fprintf(stdout, "\tattr %s=", attr->name);202 fprintf(stdout, "\tattr %s=", attr->name);
175 switch (attr->type)203 switch (attr->type) {
176 {
177 case GEIS_ATTR_TYPE_BOOLEAN:204 case GEIS_ATTR_TYPE_BOOLEAN:
178 fprintf(stdout, "%s\n", attr->boolean_val ? "true" : "false");205 fprintf(stdout, "%s\n", attr->boolean_val ? "true" : "false");
179 break;206 break;
180 case GEIS_ATTR_TYPE_FLOAT:207 case GEIS_ATTR_TYPE_FLOAT:
181 fprintf(stdout, "%f\n", attr->float_val);208 fprintf(stdout, "%f\n", attr->float_val);
182 break;209 break;
183 case GEIS_ATTR_TYPE_INTEGER:210 case GEIS_ATTR_TYPE_INTEGER:
184 fprintf(stdout, "%d\n", attr->integer_val);211 fprintf(stdout, "%d\n", attr->integer_val);
185 break;212 break;
186 case GEIS_ATTR_TYPE_STRING:213 case GEIS_ATTR_TYPE_STRING:
187 fprintf(stdout, "\"%s\"\n", attr->string_val);214 fprintf(stdout, "\"%s\"\n", attr->string_val);
188 break;215 break;
189 default:216 default:
190 fprintf(stdout, "<unknown>\n");217 fprintf(stdout, "<unknown>\n");
191 break;218 break;
192 }219 }
193}220}
194221
195static void222static void
196gesture_added(void *cookie,223gesture_added(void *cookie,
197 GeisGestureType gesture_type,224 GeisGestureType gesture_type,
198 GeisGestureId gesture_id,225 GeisGestureId gesture_id,
199 GeisSize attr_count,226 GeisSize attr_count, GeisGestureAttr * attrs)
200 GeisGestureAttr *attrs)227{
201{228 int i = 0;
202 int i = 0;229 fprintf(stdout, "Gesture type %d added\n", gesture_type);
203 fprintf(stdout, "Gesture type %d added\n", gesture_type);230 for (i = 0; i < attr_count; ++i)
204 for (i = 0; i < attr_count; ++i)231 print_attr(&attrs[i]);
205 print_attr(&attrs[i]);232}
206}233
207234static void
208static void235gesture_removed(void *cookie,
209gesture_removed(void *cookie,236 GeisGestureType gesture_type,
210 GeisGestureType gesture_type,237 GeisGestureId gesture_id,
211 GeisGestureId gesture_id,238 GeisSize attr_count, GeisGestureAttr * attrs)
212 GeisSize attr_count,239{
213 GeisGestureAttr *attrs)240 int i = 0;
214{241 fprintf(stdout, "Gesture type %d removed\n", gesture_type);
215 int i = 0;242 for (i = 0; i < attr_count; ++i)
216 fprintf(stdout, "Gesture type %d removed\n", gesture_type);243 print_attr(&attrs[i]);
217 for (i = 0; i < attr_count; ++i)244}
218 print_attr(&attrs[i]);245
219}246static void
220247gesture_start(void *cookie,
221static void248 GeisGestureType gesture_type,
222gesture_start(void *cookie,249 GeisGestureId gesture_id,
223 GeisGestureType gesture_type,250 GeisSize attr_count, GeisGestureAttr * attrs)
224 GeisGestureId gesture_id,251{
225 GeisSize attr_count,252 int i = 0;
226 GeisGestureAttr *attrs)253 fprintf(stdout, "Gesture type %d started\n", gesture_type);
227{254 for (i = 0; i < attr_count; ++i)
228 int i = 0;255 print_attr(&attrs[i]);
229 fprintf(stdout, "Gesture type %d started\n", gesture_type);256
230 for (i = 0; i < attr_count; ++i)257 // In GEIS v1, we know that the focus coords are in attrs 5 and 6
231 print_attr(&attrs[i]);258 movePointer((int)attrs[5].float_val, (int)attrs[6].float_val);
232}259}
233260
234static void261static void
235gesture_update(void *cookie,262gesture_update(void *cookie,
236 GeisGestureType gesture_type,263 GeisGestureType gesture_type,
237 GeisGestureId gesture_id,264 GeisGestureId gesture_id,
238 GeisSize attr_count,265 GeisSize attr_count, GeisGestureAttr * attrs)
239 GeisGestureAttr *attrs)266{
240{267 int i = 0;
241 int i = 0;268 fprintf(stdout, "Gesture type %d updated\n", gesture_type);
242 fprintf(stdout, "Gesture type %d updated\n", gesture_type);269 for (i = 0; i < attr_count; ++i)
243 for (i = 0; i < attr_count; ++i)270 print_attr(&attrs[i]);
244 print_attr(&attrs[i]);271 gesture_match(gesture_type, gesture_id, attr_count, attrs,
245 gesture_match(gesture_type, gesture_id, attr_count, attrs, GINN_UPDATE);272 GINN_UPDATE);
246}273}
247274
248static void275static void
249gesture_finish(void *cookie,276gesture_finish(void *cookie,
250 GeisGestureType gesture_type,277 GeisGestureType gesture_type,
251 GeisGestureId gesture_id,278 GeisGestureId gesture_id,
252 GeisSize attr_count,279 GeisSize attr_count, GeisGestureAttr * attrs)
253 GeisGestureAttr *attrs)280{
254{281 int i = 0;
255 int i = 0;282 fprintf(stdout, "Gesture type %d finished\n", gesture_type);
256 fprintf(stdout, "Gesture type %d finished\n", gesture_type);283 for (i = 0; i < attr_count; ++i); //print_attr(&attrs[i]);
257 for (i = 0; i < attr_count; ++i)284 gesture_match(gesture_type, gesture_id, attr_count, attrs,
258 ;//print_attr(&attrs[i]);285 GINN_FINISH);
259 gesture_match(gesture_type, gesture_id, attr_count, attrs, GINN_FINISH);286}
260}
261
262287
263GeisGestureFuncs gesture_funcs = {288GeisGestureFuncs gesture_funcs = {
264 gesture_added,289 gesture_added,
265 gesture_removed,290 gesture_removed,
266 gesture_start,291 gesture_start,
267 gesture_update,292 gesture_update,
268 gesture_finish293 gesture_finish
269};294};
270295
271
272/*296/*
273 * Searches for a default config file.297 * Searches for a default config file.
274 *298 *
275 * Returns a pointer to a config file name (which must be freed) or NULL299 * Returns a pointer to a config file name (which must be freed) or NULL
276 * if no default config file was found.300 * if no default config file was found.
277 */301 */
278static char *302static char *ginn_default_config()
279ginn_default_config()303{
280{304 static const char default_file_name[] = "/wishes.xml";
281 static const char default_file_name[] = "/wishes.xml";305 static const char *search_paths[] = {
282 static const char *search_paths[] =306 "etc",
283 {307 "../etc",
284 "etc",308 ".",
285 "../etc",309 "$HOME/.ginn",
286 ".",310 GINN_CONFIG_DIR
287 "$HOME/.ginn",311 };
288 GINN_CONFIG_DIR312 static const int num_paths =
289 };313 sizeof(search_paths) / sizeof(const char *);
290 static const int num_paths = sizeof(search_paths) / sizeof(const char *);314 int i;
291 int i;315
292316 for (i = 0; i < num_paths; ++i) {
293 for (i=0; i < num_paths; ++i)317 struct stat sbuf;
294 {318 char *file_name = NULL;
295 struct stat sbuf;319
296 char *file_name = NULL;320 if (strstr(search_paths[i], "$HOME")) {
297321 char *home_dir = getenv("HOME");
298 if (strstr(search_paths[i], "$HOME"))322 if (!home_dir) {
299 {323 continue;
300 char *home_dir = getenv("HOME");324 } else {
301 if (!home_dir)325 char *cdr = index(search_paths[i], '/');
302 {326 size_t file_name_length = strlen(home_dir)
303 continue;327 + strlen(cdr)
304 }328 + strlen(default_file_name)
305 else329 + 1;
306 {330 file_name = calloc(file_name_length, sizeof(char));
307 char *cdr = index(search_paths[i], '/');331 strcpy(file_name, home_dir);
308 size_t file_name_length = strlen(home_dir)332 strcat(file_name, cdr);
309 + strlen(cdr)333 }
310 + strlen(default_file_name)334 } else {
311 + 1;335 size_t file_name_length = strlen(search_paths[i])
312 file_name = calloc(file_name_length, sizeof(char));336 + strlen(default_file_name)
313 strcpy(file_name, home_dir);337 + 1;
314 strcat(file_name, cdr);338 file_name = calloc(file_name_length, sizeof(char));
315 }339 strcpy(file_name, search_paths[i]);
316 }340 }
317 else341 strcat(file_name, default_file_name);
318 {342 int sres = stat(file_name, &sbuf);
319 size_t file_name_length = strlen(search_paths[i])343 if (sres == 0) {
320 + strlen(default_file_name)344 fprintf(stdout, "Using wishes file %s\n", file_name);
321 + 1;345 return file_name;
322 file_name = calloc(file_name_length, sizeof(char));346 }
323 strcpy(file_name, search_paths[i]);347 free(file_name);
324 }348 }
325 strcat(file_name, default_file_name);349
326 int sres = stat(file_name, &sbuf);350 return NULL;
327 if (sres == 0)351}
328 {352
329 fprintf(stdout, "Using wishes file %s\n", file_name);353int main(int argc, char *argv[])
330 return file_name;354{
331 }355 GeisStatus status = GEIS_UNKNOWN_ERROR;
332 free(file_name);356 GeisXcbWinInfo xcb_win_info = {
333 }357 .display_name = NULL,
334358 .screenp = NULL,
335 return NULL;359 .window_id = getRootWindow()
336}360 };
337361 GeisWinInfo win_info = {
338362 GEIS_XCB_FULL_WINDOW,
339int main(int argc, char* argv[])363 &xcb_win_info
340{364 };
341 GeisStatus status = GEIS_UNKNOWN_ERROR;365 GeisInstance instance;
342 GeisXcbWinInfo xcb_win_info = {366 struct ginn_config cfg;
343 .display_name = NULL,367
344 .screenp = NULL,368 const char *sub_gestures_list[] = {
345 .window_id = getRootWindow()369 GEIS_GESTURE_TYPE_DRAG2, GEIS_GESTURE_TYPE_DRAG3,
346 };370 GEIS_GESTURE_TYPE_DRAG4, GEIS_GESTURE_TYPE_DRAG5,
347 GeisWinInfo win_info = {371 GEIS_GESTURE_TYPE_PINCH2, GEIS_GESTURE_TYPE_PINCH3,
348 GEIS_XCB_FULL_WINDOW,372 GEIS_GESTURE_TYPE_PINCH4, GEIS_GESTURE_TYPE_PINCH5,
349 &xcb_win_info373 GEIS_GESTURE_TYPE_ROTATE2, GEIS_GESTURE_TYPE_ROTATE3,
350 };374 GEIS_GESTURE_TYPE_ROTATE4, GEIS_GESTURE_TYPE_ROTATE5,
351 GeisInstance instance;375 GEIS_GESTURE_TYPE_TAP2, GEIS_GESTURE_TYPE_TAP3,
352 struct ginn_config cfg;376 GEIS_GESTURE_TYPE_TAP4, GEIS_GESTURE_TYPE_TAP5, NULL
353377 };
354 const char * sub_gestures_list[]= {378 {
355 GEIS_GESTURE_TYPE_DRAG2, GEIS_GESTURE_TYPE_DRAG3, 379 char *config_file_name = NULL;
356 GEIS_GESTURE_TYPE_DRAG4,GEIS_GESTURE_TYPE_DRAG5, 380 if (argc < 2) {
357 GEIS_GESTURE_TYPE_PINCH2, GEIS_GESTURE_TYPE_PINCH3, 381 fprintf(stderr, "usage: %s <configxml>\n", argv[0]);
358 GEIS_GESTURE_TYPE_PINCH4,GEIS_GESTURE_TYPE_PINCH5, 382 config_file_name = ginn_default_config();
359 GEIS_GESTURE_TYPE_ROTATE2, GEIS_GESTURE_TYPE_ROTATE3, 383 if (config_file_name) {
360 GEIS_GESTURE_TYPE_ROTATE4,GEIS_GESTURE_TYPE_ROTATE5, 384 fprintf(stderr,
361 GEIS_GESTURE_TYPE_TAP2, GEIS_GESTURE_TYPE_TAP3, 385 "using default configuration file %s ... \n",
362 GEIS_GESTURE_TYPE_TAP4,GEIS_GESTURE_TYPE_TAP5, NULL };386 config_file_name);
363 {387 }
364 char * config_file_name = NULL;388 } else {
365 if (argc < 2) {389 config_file_name = strdup(argv[1]);
366 fprintf(stderr, "usage: %s <configxml>\n", argv[0]);390 }
367 config_file_name = ginn_default_config();391 if (NULL == config_file_name) {
368 if (config_file_name)392 fprintf(stderr, "Could not find Ginn wishes\n");
369 {393 return -1;
370 fprintf(stderr, "using default configuration file %s ... \n",394 }
371 config_file_name);395
372 }396 if (ginn_config_open(&cfg, config_file_name)) {
373 }397 fprintf(stderr, "Could not load Ginn wishes\n");
374 else398 return -1;
375 {399 }
376 config_file_name = strdup(argv[1]);400 free(config_file_name);
377 }401 }
378 if (NULL == config_file_name)402
379 {403 ginn_config_print(&cfg);
380 fprintf(stderr, "Could not find Ginn wishes\n");404 ap = (struct apps *) malloc(sizeof(struct apps));
381 return -1;405 inita(ap);
382 }406 wp = (struct wish *) malloc(sizeof(struct wish));
383407 initw(wp);
384 if ( ginn_config_open(&cfg, config_file_name) ) {408 ginn_config_store(&cfg, wp, ap);
385 fprintf(stderr, "Could not load Ginn wishes\n");409 wpEnd = wp;
386 return -1;410 while (wpEnd->next)
387 }411 wpEnd = wpEnd->next;
388 free(config_file_name);412
389 }413 int pos = 0;
390414 printf("\n");
391 ginn_config_print(&cfg);415 while (strcmp(config_attr[pos].attrName, "")) {
392 ap = (struct apps *) malloc(sizeof(struct apps)); inita(ap);416 printf("DEBUG %d %s %.2f %.2f \n", pos,
393 wp = (struct wish *) malloc(sizeof(struct wish)); initw(wp);417 config_attr[pos].attrName, config_attr[pos].val,
394 ginn_config_store(&cfg, wp, ap);418 config_attr[pos].valMax);
395 wpEnd=wp;419 pos++;
396 while (wpEnd->next)420 }
397 wpEnd=wpEnd->next;421
398422 status = geis_init(&win_info, &instance);
399 int pos=0;423 if (status != GEIS_STATUS_SUCCESS) {
400 printf("\n");424 fprintf(stderr, "error in geis_init\n");
401 while (strcmp(config_attr[pos].attrName,"")) {425 return 1;
402 printf("DEBUG %d %s %.2f %.2f \n", pos, config_attr[pos].attrName, config_attr[pos].val, config_attr[pos].valMax); 426 }
403 pos++;427
404 }428 status = geis_configuration_supported(instance, GEIS_CONFIG_UNIX_FD);
405429 if (status != GEIS_STATUS_SUCCESS) {
406 status = geis_init(&win_info, &instance);430 fprintf(stderr, "GEIS does not support Unix fd\n");
407 if (status != GEIS_STATUS_SUCCESS)431 return 1;
408 {432 }
409 fprintf(stderr, "error in geis_init\n");433
410 return 1;434 int fd = -1;
411 }435 status =
412436 geis_configuration_get_value(instance, GEIS_CONFIG_UNIX_FD, &fd);
413 status = geis_configuration_supported(instance, GEIS_CONFIG_UNIX_FD);437 if (status != GEIS_STATUS_SUCCESS) {
414 if (status != GEIS_STATUS_SUCCESS)438 fprintf(stderr, "error retrieving GEIS fd\n");
415 {439 return 1;
416 fprintf(stderr, "GEIS does not support Unix fd\n");440 }
417 return 1;441
418 }442 status = geis_subscribe(instance, GEIS_ALL_INPUT_DEVICES, sub_gestures_list, // GEIS_ALL_GESTURES,
419443 &gesture_funcs, NULL);
420 int fd = -1;444 if (status != GEIS_STATUS_SUCCESS) {
421 status = geis_configuration_get_value(instance, GEIS_CONFIG_UNIX_FD, &fd);445 fprintf(stderr, "error subscribing to gestures\n");
422 if (status != GEIS_STATUS_SUCCESS)446 return 1;
423 {447 }
424 fprintf(stderr, "error retrieving GEIS fd\n");448
425 return 1;449 openDisplay();
426 }450
427451 while (1) {
428 status = geis_subscribe(instance,452 fd_set read_fds;
429 GEIS_ALL_INPUT_DEVICES,453 FD_ZERO(&read_fds);
430 sub_gestures_list, // GEIS_ALL_GESTURES,454 FD_SET(fd, &read_fds);
431 &gesture_funcs,455 int sstat = select(fd + 1, &read_fds, NULL, NULL, NULL);
432 NULL);456 if (sstat < 0) {
433 if (status != GEIS_STATUS_SUCCESS)457 fprintf(stderr, "error %d in select(): %s\n", errno,
434 {458 strerror(errno));
435 fprintf(stderr, "error subscribing to gestures\n");459 break;
436 return 1;460 }
437 }461
438 462 if (FD_ISSET(fd, &read_fds)) {
439 openDisplay();463 geis_event_dispatch(instance);
440464 }
441 while(1)465 }
442 {466
443 fd_set read_fds;467 geis_finish(instance);
444 FD_ZERO(&read_fds);468 closeDisplay();
445 FD_SET(fd, &read_fds);469 free(wp);
446 int sstat = select(fd+1, &read_fds, NULL, NULL, NULL);470 return 0;
447 if (sstat < 0)471}
448 {
449 fprintf(stderr, "error %d in select(): %s\n", errno, strerror(errno));
450 break;
451 }
452
453 if (FD_ISSET(fd, &read_fds))
454 {
455 geis_event_dispatch(instance);
456 }
457 }
458
459 geis_finish(instance);
460 closeDisplay();
461 free(wp);
462 return 0;
463}
464
465472
=== modified file 'src/xt.c'
--- src/xt.c 2011-02-03 08:48:38 +0000
+++ src/xt.c 2011-03-16 16:26:15 +0000
@@ -21,61 +21,88 @@
21#include <X11/extensions/XTest.h>21#include <X11/extensions/XTest.h>
22#include <X11/keysym.h>22#include <X11/keysym.h>
2323
24static Display* disp = NULL;24static Display *disp = NULL;
2525
26void openDisplay()26void openDisplay()
27{27{
28 disp = XOpenDisplay(NULL);28 disp = XOpenDisplay(NULL);
29}29}
3030
31void closeDisplay()31void closeDisplay()
32{32{
33 XCloseDisplay(disp);33 XCloseDisplay(disp);
34}34}
3535
36void36void movePointer(int x, int y)
37injKey(KeySym ks, char * modifiers[])37{
38{38 XTestFakeMotionEvent(disp, 0, x, y, CurrentTime);
39 int i;39}
4040
41 for (i=0 ; i<4 && 0!=strcmp(modifiers[i],"") ; i++)41void injKey(KeySym ks, char *modifiers[])
42 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, XStringToKeysym(modifiers[i])), True, CurrentTime);42{
43 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime);43 int i;
44 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False, CurrentTime);44
45 for (i=0 ; i<4 && 0!=strcmp(modifiers[i],"") ; i++)45 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
46 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, XStringToKeysym(modifiers[i])), False, CurrentTime);46 XTestFakeKeyEvent(disp,
4747 XKeysymToKeycode(disp,
48 XFlush(disp);48 XStringToKeysym(modifiers
49}49 [i])), True,
5050 CurrentTime);
51void51 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime);
52injButton(int btn, char * modifiers[])52 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False,
53{53 CurrentTime);
54 int i;54 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
5555 XTestFakeKeyEvent(disp,
56 for (i=0 ; i<4 && 0!=strcmp(modifiers[i],"") ; i++)56 XKeysymToKeycode(disp,
57 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, XStringToKeysym(modifiers[i])), True, CurrentTime);57 XStringToKeysym(modifiers
58 XTestFakeButtonEvent(disp, btn, True, CurrentTime);58 [i])), False,
59 XTestFakeButtonEvent(disp, btn, False, CurrentTime);59 CurrentTime);
60 for (i=0 ; i<4 && 0!=strcmp(modifiers[i],"") ; i++)60
61 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, XStringToKeysym(modifiers[i])), False, CurrentTime);61 XFlush(disp);
6262}
63 XFlush(disp);63
64}64void injButton(int btn, char *modifiers[])
6565{
66void66 int i;
67injMixBtnKey(KeySym ks, int btn, char * modifiers[])67
68{68 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
69 int i;69 XTestFakeKeyEvent(disp,
7070 XKeysymToKeycode(disp,
71 XTestFakeButtonEvent(disp, btn, True, CurrentTime);71 XStringToKeysym(modifiers
72 for (i=0 ; i<4 && 0!=strcmp(modifiers[i],"") ; i++)72 [i])), True,
73 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, XStringToKeysym(modifiers[i])), True, CurrentTime);73 CurrentTime);
74 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), True, CurrentTime);74 XTestFakeButtonEvent(disp, btn, True, CurrentTime);
75 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, ks), False, CurrentTime);75 XTestFakeButtonEvent(disp, btn, False, CurrentTime);
76 for (i=0 ; i<4 && 0!=strcmp(modifiers[i],"") ; i++)76 for (i = 0; i < 4 && 0 != strcmp(modifiers[i], ""); i++)
77 XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, XStringToKeysym(modifiers[i])), False, CurrentTime);77 XTestFakeKeyEvent(disp,
78 XTestFakeButtonEvent(disp, btn, False, CurrentTime);78 XKeysymToKeycode(disp,
79 XFlush(disp);79 XStringToKeysym(modifiers
80}80 [i])), False,
8181 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}