1 /***************************************************************************
2 * Copyright (C) 2009 by Chris Parker *
3 * chrsprkr3@gmail.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the Python License version 2.5 or later. *
8 * This program is distributed in the hope that it will be useful, *
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
11 ***************************************************************************/
20 #include "xaut_keyboard.h"
22 short key_down_delay(short delay
) {
27 logit(LOG_LEVEL_VERBOSE
, "Leaving key down delay at %hu\n",
28 defaults
->key_down_delay
);
29 return defaults
->key_down_delay
;
31 logit(LOG_LEVEL_EXTRA_VERBOSE
,
32 "Keys used to stay down %hu milliseconds when clicked\n",
33 defaults
->key_down_delay
);
34 defaults
->key_down_delay
= delay
;
35 logit(LOG_LEVEL_EXTRA_VERBOSE
,
36 "Keys now stay down %hu milliseconds when clicked\n",
37 defaults
->key_down_delay
);
38 return defaults
->key_down_delay
;
41 short key_click_delay(short delay
) {
46 logit(LOG_LEVEL_VERBOSE
, "Leaving key down delay at %hu\n",
47 defaults
->key_click_delay
);
48 return defaults
->key_click_delay
;
50 logit(LOG_LEVEL_EXTRA_VERBOSE
,
51 "Keys used to wait %hu milliseconds between clicks\n",
52 defaults
->key_click_delay
);
54 defaults
->key_click_delay
= delay
;
55 logit(LOG_LEVEL_EXTRA_VERBOSE
,
56 "Keys now wait %hu milliseconds between clicks\n",
57 defaults
->key_click_delay
);
58 return defaults
->key_click_delay
;
61 BOOL
key_click(unsigned int key
) {
65 int success
= key_down(key
);
67 usleep(MILLI_MULTIPLIER
* defaults
->key_down_delay
);
68 success
= key_up(key
);
73 BOOL
key_down(unsigned int key
) {
78 int success
= XTestFakeKeyEvent(defaults
->display
, key
, TRUE
, CurrentTime
);
79 XFlush(defaults
->display
);
81 logit(LOG_LEVEL_EXTRA_VERBOSE
, "Pressed %d ", key
);
83 fprintf(stderr
, "Failure to press %d ", key
);
85 return (success
!= 0);
88 BOOL
key_up(unsigned int key
) {
92 int release
= XTestFakeKeyEvent(defaults
->display
, key
, FALSE
, CurrentTime
);
93 BOOL success
= (release
!= 0);
94 XFlush(defaults
->display
);
96 logit(LOG_LEVEL_EXTRA_VERBOSE
, "Released %d", key
);
98 fprintf(stderr
, "Failure to release %d\n", key
);
100 return (success
!= 0);
103 void interpret_meta_symbols(BOOL tf
) {
104 //"BOOL" is actually a short - so I'm going
105 //to filter the value sent.
107 char *msg
= "I was %sinterpreting meta symbols\n";
108 char *yn
= defaults
->interpret_meta_symbols
? "" : "not ";
109 logit(LOG_LEVEL_EXTRA_VERBOSE
, msg
, yn
);
111 defaults
->interpret_meta_symbols
= (tf
) ? TRUE
: FALSE
;
113 char *msg
= "Now I will %sinterpret meta symbols\n";
114 char *yn
= defaults
->interpret_meta_symbols
? "" : "not ";
115 logit(LOG_LEVEL_EXTRA_VERBOSE
, msg
, yn
);
119 void print_keycodes() {
120 if (!_check_init()) {
121 fprintf(stderr
, "Unable to print keycodes");
124 printf("Code X11 key symbol name string Shift?\n");
125 printf("---- --------------------------------- -------\n");
126 int min
, max
; //The minumum and maximum codes
127 XDisplayKeycodes(defaults
->display
, &min
, &max
);
129 KeySym symL
, symU
; //Lower and upper symbols
130 char *strL
, *strU
; //Lower and upper strings
131 char *fmt
= "%4d %-33s %-6s\n";
132 for (i
= (min
- 1); i
<= max
; i
++) {
133 symL
= XKeycodeToKeysym(defaults
->display
, i
, FALSE
);
134 symU
= XKeycodeToKeysym(defaults
->display
, i
, TRUE
);
136 strL
= XKeysymToString(symL
);
139 strU
= XKeysymToString(symU
);
142 //If both shifted and unshifted have values
144 if (!strcmp(strL
, strU
)) {
145 //If they're the same
146 printf(fmt
, i
, strL
, "Either");
149 printf(fmt
, i
, strL
, "No");
150 printf(fmt
, i
, strU
, "Yes");
153 //Unshifted only (lower case)
154 printf(fmt
, i
, strL
, "No");
156 //Shifted only (upper case)
157 printf(fmt
, i
, strU
, "Yes");
163 BOOL
type(char *str
) {
164 if (!_check_init()) {
167 logit(LOG_LEVEL_VERBOSE
, "Sending '%s'\n", str
);
172 int meta
[] = { 0, 0, 0, 0 };
173 BOOL shft_pressed
= FALSE
;
174 BOOL ctl_pressed
= FALSE
;
175 BOOL alt_pressed
= FALSE
;
176 BOOL meta_pressed
= FALSE
;
177 unsigned short key
= 0;
178 while (str
[index
] != '\0') {
179 switch (str
[index
]) {
181 if(defaults
->interpret_meta_symbols
) {
184 logit(LOG_LEVEL_VERBOSE
, "%s", "Shift_L down ");
185 success
&= key_down(SHIFT_L
);
186 meta
[down
] = SHIFT_L
;
192 if(defaults
->interpret_meta_symbols
) {
195 logit(LOG_LEVEL_VERBOSE
, "%s", "Control_L down ");
196 success
&= key_down(CONTROL_L
);
197 meta
[down
] = CONTROL_L
;
203 if(defaults
->interpret_meta_symbols
) {
206 success
&= key_down(ALT_L
);
207 logit(LOG_LEVEL_VERBOSE
, "%s", "Alt_L down ");
214 if(defaults
->interpret_meta_symbols
) {
217 success
&= key_down(META_L
);
218 logit(LOG_LEVEL_VERBOSE
, "%s", "META_L down ");
225 if( defaults
->interpret_meta_symbols
) {
226 index
= _handle_keycode(index
, str
);
228 logit(LOG_LEVEL_VERBOSE
, "%s", "Meta keys released ");
232 success
&= key_up(meta
[down
]);
235 shft_pressed
= FALSE
;
238 logit(LOG_LEVEL_VERBOSE
, "%s", "\n");
242 key
= ((unsigned short) (str
[index
]));
243 if (ascii_codes
[key
].ascii
) {
244 int code
= ascii_codes
[key
].code
;
245 if (ascii_codes
[key
].shifted
&& !shft_pressed
) {
247 logit(LOG_LEVEL_VERBOSE
, "Shift_L down ");
248 success
&= key_down(SHIFT_L
);
249 meta
[down
] = SHIFT_L
;
252 if (str
[index
] == ' ') {
253 logit(LOG_LEVEL_VERBOSE
, "%s", "Typing (space) ");
254 } else if (str
[index
] == '\t') {
255 logit(LOG_LEVEL_VERBOSE
, "%s", "Typing (tab) ");
257 logit(LOG_LEVEL_VERBOSE
, "%s", "Typing %c ", str
[index
]);
259 success
&= key_click(code
);
261 logit(LOG_LEVEL_VERBOSE
, "%s", "Meta keys released ");
265 success
&= key_up(meta
[down
]);
268 shft_pressed
= FALSE
;
271 logit(LOG_LEVEL_VERBOSE
, "%s", "\n");
272 XFlush(defaults
->display
);
274 if (str
[index
+ 1]) {
275 usleep(MILLI_MULTIPLIER
* defaults
->key_click_delay
);
278 fprintf(stderr
, "Unable to print %c", str
[index
]);
288 BOOL
type( char *str
) {
289 fprintf( stderr
, "No language defined - skipping" );
294 xautpy_meta_t
*_extract_metakey(char *input
) {
296 BOOL space_char_found
= FALSE
;
297 xautpy_meta_t
*meta
= malloc(sizeof(xautpy_meta_t
));
299 fprintf(stderr
, "Unable to allocate space for metakey");
302 memset(meta
, 0, sizeof(xautpy_meta_t
));
303 while (input
[i
] != '\0') {
304 //First we check to see if there is a space in the string
305 if (input
[i
] == ' ') {
306 space_char_found
= TRUE
;
311 if (space_char_found
) {
312 //Note that i points directly at the space character
313 _extract_metakey_with_count(meta
, input
, i
);
315 meta
->name
= _stringmid(input
, 0, strlen(input
));
318 if (meta
->name
) { //Might be empty, since name is allocated
319 meta
->keysym
= XStringToKeysym(meta
->name
);
321 meta
->keycode
= XKeysymToKeycode(defaults
->display
, meta
->keysym
);
322 _extract_metakey_shifted(meta
);
328 void _extract_metakey_shifted(xautpy_meta_t
*meta
) {
329 //Try no shift key first, since if it doesn't matter
330 // to the code, why worry about it
331 KeySym sym
= XKeycodeToKeysym(defaults
->display
, meta
->keycode
, FALSE
);
332 if (sym
== meta
->keysym
) {
333 meta
->shifted
= FALSE
;
335 sym
= XKeycodeToKeysym(defaults
->display
, meta
->keycode
, TRUE
);
336 if (sym
== meta
->keysym
) {
337 meta
->shifted
= TRUE
;
339 fprintf(stderr
, "Something went wrong with keystring %s\n",
341 meta
->shifted
= FALSE
;
346 void _extract_metakey_with_count(xautpy_meta_t
*meta
, char *input
,
347 size_t space_index
) {
348 //We have to try to extract a string from the left, and
349 // a number from the right.
350 meta
->name
= _stringmid(input
, 0, space_index
- 1);
351 char *numStr
= _stringmid(input
, space_index
+ 1, strlen(input
));
352 int num
= atoi(numStr
);
356 meta
->count
= (unsigned short) num
;
361 size_t _handle_keycode(size_t curr
, char *str
) {
363 BOOL closing_brace_found
= FALSE
;
365 unsigned short count
= 0; //No point in going past 100 characters
366 while (str
[index
] != '\0' && count
< 100) {
367 if (str
[index
] == '}') {
368 closing_brace_found
= TRUE
;
374 if (closing_brace_found
) {
375 //Note: curr points at opening brace {
376 // and index points at closing brace }
377 char *keycode
= _stringmid(str
, curr
+ 1, index
- 1);
378 meta
= _extract_metakey(keycode
);
381 fprintf(stderr
, "Unable to find closing brace in '%s'\n", str
+ curr
);
382 meta
= malloc(sizeof(xautpy_meta_t
));
386 memset(meta
, 0, sizeof(xautpy_meta_t
));
387 index
= curr
; //Point index back at opening brace
389 meta
->keycode
= ascii_codes
['{'].code
;
390 meta
->shifted
= ascii_codes
['{'].shifted
;
391 meta
->name
= _stringmid("{", 0, 1);
393 if (meta
&& meta
->keycode
) {
397 logit(LOG_LEVEL_VERBOSE
, "%s", "Shift_L down ");
399 for (i
= 0; i
< meta
->count
; i
++) {
400 key_click(meta
->keycode
);
401 if (meta
->keycode
== ascii_codes
['{'].code
) {
402 logit(LOG_LEVEL_VERBOSE
, "%s", "Typing { ");
404 logit(LOG_LEVEL_VERBOSE
, "Typing metakey %s ", meta
->name
);
406 if (i
+ 1 < meta
->count
) {
407 usleep(MILLI_MULTIPLIER
* defaults
->key_click_delay
);
412 logit(LOG_LEVEL_VERBOSE
, "%s", "Shift_L up ");
420 unsigned long _handle_keycode( size_t index
, char *str
) {
421 //Skips the remainder if not EN_US
422 while( str
[index
] != '\0' )