1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3
* Linux Desktop Testing Project http://ldtp.freedesktop.org
6
* Prashanth Mohan <prashmohan@gmail.com>
8
* Copyright 2004 - 2006 Novell, Inc.
10
* This program is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU Lesser General Public
12
* License as published by the Free Software Foundation; either
13
* version 2 of the License, or (at your option) any later version.
15
* This library is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
* Lesser General Public License for more details.
20
* You should have received a copy of the GNU Lesser General Public
21
* License along with this program; if not, write to the
22
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23
* Boston, MA 02110, USA.
28
#include "ldtp-error.h"
29
#include "ldtp-logger.h"
30
#include "ldtp-command.h"
31
#include "ldtp-gui-comp.h"
34
struct NonPrint_Key_Synth NonPrint_Key_Synth_Vals[300];
37
mouse_left_click (Accessible *object, FILE *log_fp)
41
long int x = 0, y = 0;
45
if (Accessible_isComponent (object)) {
46
AccessibleComponent *component;
47
component = Accessible_getComponent (object);
48
if (!AccessibleComponent_grabFocus (component)) {
49
Accessible_unref (component);
50
error = LDTP_ERROR_UNABLE_TO_GRAB_FOCUS;
51
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
55
AccessibleComponent_getExtents (component, &x, &y, &width,
56
&height, SPI_COORD_TYPE_SCREEN);
57
Accessible_unref (component);
59
error = LDTP_ERROR_UNABLE_TO_GET_COMPONENT_HANDLE;
60
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
63
flag = SPI_generateMouseEvent (x + width / 2, y + height / 2, "b1c");
65
error = LDTP_ERROR_CLICK_FAILED;
66
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
69
return LDTP_ERROR_SUCCESS;
73
mouse_right_click (Accessible *object, FILE *log_fp)
77
long int x = 0, y = 0;
81
if (Accessible_isComponent (object)) {
82
AccessibleComponent *component;
83
component = Accessible_getComponent (object);
84
if (!AccessibleComponent_grabFocus (component)) {
85
Accessible_unref (component);
86
error = LDTP_ERROR_UNABLE_TO_GRAB_FOCUS;
87
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
91
AccessibleComponent_getExtents (component, &x, &y, &width,
92
&height, SPI_COORD_TYPE_SCREEN);
93
Accessible_unref (component);
95
error = LDTP_ERROR_UNABLE_TO_GET_COMPONENT_HANDLE;
96
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
99
flag = SPI_generateMouseEvent (x + width / 2, y + height / 2, "b3c");
101
error = LDTP_ERROR_RIGHT_CLICK_FAILED;
102
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
105
return LDTP_ERROR_SUCCESS;
109
mouse_move (Accessible *object, FILE *log_fp)
112
AccessibleCoordType screen_cood = SPI_COORD_TYPE_SCREEN;
115
//long int width, height;
117
if (Accessible_isComponent (object)) {
118
AccessibleComponent *accessible_component;
119
accessible_component = Accessible_getComponent (object);
120
if (!AccessibleComponent_grabFocus (accessible_component)) {
121
Accessible_unref (accessible_component);
122
error = LDTP_ERROR_UNABLE_TO_GRAB_FOCUS;
125
AccessibleComponent_getPosition (accessible_component, &xpos, &ypos, screen_cood);
126
Accessible_unref (accessible_component);
129
error = LDTP_ERROR_UNABLE_TO_GET_COMPONENT_HANDLE;
132
flag = SPI_generateMouseEvent (xpos, ypos, "abs");
134
error = LDTP_ERROR_UNABLE_TO_MOVE_MOUSE;
137
error = LDTP_ERROR_SUCCESS;
140
if (error != LDTP_ERROR_SUCCESS)
141
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
145
static struct KeyValue
146
get_key_value (gchar *keyval)
148
static int Char_Key_Synth_Vals[] = {38, 56, 54, 40, 26, 41, 42, 43, 31,
149
44, 45, 46, 58, 57, 32, 33, 24, 27,
150
39, 28, 30, 55, 25, 53, 29, 52}; /* A - Z */
151
static int Digit_Key_Synth_Vals[] = {19, 10, 11, 12, 13, 14, 15, 16, 17, 18}; /* 0 - 9 */
152
static struct Symbol_Key_Synth Symbol_Key_Synth_Vals[] = {{'-', 20}, {'=', 21}, {'[', 34},
153
{']', 35}, {';', 47}, {'\'', 48},
154
{'`', 49}, {'\\', 51}, {',', 59},
155
{'.', 60}, {'/', 61}, {' ', 65},
156
{'!', 10}, {'@', 11}, {'#', 12},
157
{'$', 13}, {'%', 14}, {'^', 15},
158
{'&', 16}, {'*', 17}, {'(', 18},
159
{')', 19}, {'_', 20}, {'+', 21},
160
{'{', 34}, {'}', 35}, {':', 47},
161
{'\"',48}, {'~', 49}, {'|', 51},
162
{'<', 59}, {'>', 60}, {'\?', 61}};
164
struct KeyValue return_val; /* will contain the return values */
167
if (strlen (keyval) == 1) {
168
/* This will identify small characters */
169
if (*keyval >= 'a' && *keyval <= 'z') {
170
return_val.shift = FALSE;
171
return_val.capslck = FALSE;
172
return_val.non_print_key = FALSE;
173
return_val.value = Char_Key_Synth_Vals[*keyval-'a'];
177
/* This will identify Capital Charaters i.e. Shift+Small
179
else if (*keyval >= 'A' && *keyval <= 'Z') {
180
return_val.shift = FALSE;
181
return_val.capslck = TRUE;
182
return_val.non_print_key = FALSE;
183
return_val.value = Char_Key_Synth_Vals[*keyval-'A'];
187
/* This will identify Digits */
188
else if (*keyval >= '0' && *keyval <='9') {
189
return_val.shift = FALSE;
190
return_val.capslck = FALSE;
191
return_val.non_print_key = FALSE;
192
return_val.value = Digit_Key_Synth_Vals[*keyval-'0'];
196
/* This will identify Symbols */
198
/* Symbols obtained without using Shift Key */
199
for (index = 0; index < DOWNCHAR; index++)
200
if (*keyval == Symbol_Key_Synth_Vals[index].sym) {
201
return_val.shift = FALSE;
202
return_val.capslck = FALSE;
203
return_val.non_print_key = FALSE;
204
return_val.value = Symbol_Key_Synth_Vals[index].KeyVal;
207
/* Symbols produced with a key combination
208
including Shift Key */
209
for ( ; index < DOWNCHAR + UPCHAR; index++)
210
if (*keyval == Symbol_Key_Synth_Vals[index].sym) {
211
return_val.shift = TRUE;
212
return_val.capslck = FALSE;
213
return_val.non_print_key = FALSE;
214
return_val.value = Symbol_Key_Synth_Vals[index].KeyVal;
219
/* This is for identifying non printing keys like numlock,
221
for (index = 0; NonPrint_Key_Synth_Vals[index].sym; index++)
222
if (g_ascii_strcasecmp (NonPrint_Key_Synth_Vals[index].sym,
224
return_val.shift = FALSE;
225
return_val.capslck = FALSE;
226
return_val.non_print_key = TRUE;
227
return_val.value = NonPrint_Key_Synth_Vals[index].KeyVal;
233
return_val.shift = FALSE;
234
return_val.capslck = FALSE;
235
return_val.non_print_key = FALSE;
236
return_val.value = UNDEFINED_KEY;
241
get_keyval_id (gchar *input_string, struct KeyValue *keyvals)
243
struct KeyValue key_val;
245
gint keyval_index = 0;
246
gchar token[MAX_TOK_SIZE + 1];
248
while (*input_string && keyval_index < MAX_TOKENS) {
250
if (*input_string == '<') {
251
/* Identified a Non Printing Key */
253
while (*input_string != '>' && *input_string != '\0' && index < MAX_TOK_SIZE) {
254
token[index] = *input_string;
258
if (*input_string != '>') {
259
/* Premature end of string without an opening '<' */
260
g_print ("ERROR:: premature EOS\n");
261
return LDTP_ERROR_INVALID_FORMAT;
264
token[index] = *input_string;
270
key_val = get_key_value (token);
271
if (key_val.value == UNDEFINED_KEY) {
272
g_print ("Invalid Key\n");
273
return LDTP_ERROR_TOKEN_NOT_FOUND;
275
g_print ("KEY_ID :: %d\n",key_val.value);
276
keyvals[keyval_index] = key_val;
279
if (keyval_index == MAX_TOKENS) {
280
g_print ("ERROR :: Too many tokens\n");
281
return LDTP_ERROR_INVALID_FORMAT;
283
keyvals [keyval_index].value = UNDEFINED_KEY; /* End Delimiter */
284
return LDTP_ERROR_SUCCESS;
288
press_key (char *input_string, FILE *log_fp)
291
struct KeyValue keyval[MAX_TOKENS+1];
295
error = get_keyval_id (input_string, keyval);
296
if (error != LDTP_ERROR_SUCCESS) {
300
for (index=0; keyval[index].value != UNDEFINED_KEY && index < MAX_TOKENS;index++) {
301
g_print ("Generating Key Board Value: %d\n", keyval [index].value);
302
flag = SPI_generateKeyboardEvent (keyval [index].value, NULL, SPI_KEY_PRESS);
304
error = LDTP_ERROR_UNABLE_TO_ENTER_KEY;
310
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
315
release_key (char *input_string, FILE *log_fp)
318
struct KeyValue keyval[MAX_TOKENS+1];
322
error = get_keyval_id (input_string, keyval);
323
if (error != LDTP_ERROR_SUCCESS) {
327
for (index=0; keyval[index].value != UNDEFINED_KEY && index < MAX_TOKENS;index++) {
328
g_print ("Generating Key Board Value: %d\n", keyval [index].value);
329
flag = SPI_generateKeyboardEvent (keyval [index].value, NULL, SPI_KEY_RELEASE);
331
error = LDTP_ERROR_UNABLE_TO_ENTER_KEY;
337
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
342
generate_keyboard_sequence (char *input_string, FILE *log_fp)
345
AccessibleKeySynthType type = SPI_KEY_PRESS;
346
struct KeyValue keyval[MAX_TOKENS+1];
347
gint index, history_index;
350
error = get_keyval_id (input_string, keyval);
351
if (error != LDTP_ERROR_SUCCESS) {
355
for (index=0; keyval[index].value != UNDEFINED_KEY && index < MAX_TOKENS;index++) {
356
g_print ("Generating Key Board Value: %d\n",keyval[index].value);
357
if (keyval[index].non_print_key == TRUE)
358
type = SPI_KEY_PRESS;
360
type = SPI_KEY_PRESSRELEASE;
361
if (keyval[index].shift == 1)
362
SPI_generateKeyboardEvent (50, NULL, SPI_KEY_PRESS); // press shift
363
if (keyval[index].capslck == 1) {
364
SPI_generateKeyboardEvent (66, NULL, SPI_KEY_PRESS); // press capslck
365
SPI_generateKeyboardEvent (66, NULL, SPI_KEY_RELEASE); // release capslck
367
flag = SPI_generateKeyboardEvent (keyval[index].value, NULL, type);
368
if (keyval[index].shift == 1)
369
SPI_generateKeyboardEvent (50, NULL, SPI_KEY_RELEASE); // release shift
370
if (keyval[index].capslck == 1) {
371
SPI_generateKeyboardEvent (66, NULL, SPI_KEY_PRESS); // press capslck
372
SPI_generateKeyboardEvent (66, NULL, SPI_KEY_RELEASE); // release capslck
375
error = LDTP_ERROR_UNABLE_TO_ENTER_KEY;
378
if (keyval[index].non_print_key == FALSE) {
379
history_index = index;
380
type = SPI_KEY_RELEASE;
382
if (keyval[index].non_print_key == FALSE)
384
g_print ("Releasing: %d\n", keyval [index].value);
385
flag = SPI_generateKeyboardEvent (keyval [index].value, NULL, type);
387
error = LDTP_ERROR_UNABLE_TO_ENTER_KEY;
391
index = history_index;
394
type = SPI_KEY_RELEASE;
396
if (keyval[index].non_print_key == FALSE)
398
g_print ("Releasing: %d\n", keyval [index].value);
399
flag = SPI_generateKeyboardEvent (keyval [index].value, NULL, type);
401
error = LDTP_ERROR_UNABLE_TO_ENTER_KEY;
407
log_msg (LDTP_LOG_CAUSE, ldtp_error_get_message (error), log_fp);
412
device_main (LDTPClientContext* cctxt, int command)
416
case LDTP_CMD_MOUSELEFTCLICK:
417
error = mouse_left_click (cctxt->gui_handle->handle, cctxt->log_fp);
419
case LDTP_CMD_MOUSERIGHTCLICK:
420
error = mouse_right_click (cctxt->gui_handle->handle, cctxt->log_fp);
422
case LDTP_CMD_MOUSEMOVE:
423
error = mouse_move (cctxt->gui_handle->handle, cctxt->log_fp);
425
case LDTP_CMD_KBDENTER:
426
error = grab_focus (cctxt->gui_handle->handle, cctxt->log_fp);
427
if (error != LDTP_ERROR_SUCCESS)
429
error = generate_keyboard_sequence (cctxt->req->arg_list->data, cctxt->log_fp);
431
case LDTP_CMD_GENERATEKEYEVENT:
432
error = generate_keyboard_sequence (cctxt->req->context, cctxt->log_fp);
434
case LDTP_CMD_KEYPRESS:
435
error = press_key (cctxt->req->context, cctxt->log_fp);
437
case LDTP_CMD_KEYRELEASE:
438
error = release_key (cctxt->req->context, cctxt->log_fp);
441
error = LDTP_ERROR_COMMAND_NOT_IMPLEMENTED;
447
get_keyboard_keycodes() {
451
//char *keycode_symbol_start;
458
struct NonPrint_Key_Synth old_NonPrint_Key_Synth_Vals[] = {{"escape", 9}, {"esc", 9}, {"backspace", 22},
459
{"bksp", 22}, {"ctrl", 37}, {"windowskey", 115},
460
{"tab", 23}, {"return", 36}, {"enter", 36},
461
{"shift", 50}, {"shiftl", 50}, {"shiftr", 62},
462
{"home", 97}, {"end", 103}, {"window", 115},
463
{"alt", 64}, {"altl", 64}, {"altr", 113},
464
{"up", 98}, {"down", 104}, {"right", 102},
465
{"left", 100}, {"space", 65}, {"capslock", 66},
466
{"caps", 66}, {"menu", 117}, {"ins", 106},
467
{"del", 107}, {"insert", 106}, {"delete", 107},
468
{"pageup", 99}, {"pagedown", 105}, {"pgup", 99},
469
{"pgdown", 105}, {"numlock", 77}, {"scrolllock", 78},
470
{"F1", 67}, {"F2", 68}, {"F3", 69}, {"F4", 70},
471
{"F5", 71}, {"F6", 72}, {"F7", 73}, {"F8", 74},
472
{"F9", 75}, {"F10", 76}, {"F11", 95}, {"F12", 96},
476
src = (char *) malloc(sizeof(char) * 100);
479
fd = popen("xmodmap -pke 2>/dev/null", "r");
481
while ( ! feof(fd)) {
482
readed += fread(src + readed, 1, 100, fd);
483
src = (char *) realloc(src, sizeof(char)*(readed+100));
489
lines = g_strsplit(src, "\n", 0);
491
for (index=0; lines != NULL && strcmp(*lines, ""); lines++) {
495
split = g_strsplit(line, "=", 2);
496
keycode = atoi(split[0] + 7);
498
if (strlen(split[1]) > 0) {
499
gchar **space_split = g_strsplit(split[1], " ", 3);
500
NonPrint_Key_Synth_Vals[index].sym = space_split[1];
501
NonPrint_Key_Synth_Vals[index].KeyVal = keycode;
510
int old_len = sizeof(old_NonPrint_Key_Synth_Vals) / sizeof(struct NonPrint_Key_Synth);
512
for(i = 0 ; index < 300 && i < old_len; index++, i++)
513
NonPrint_Key_Synth_Vals[index] = old_NonPrint_Key_Synth_Vals[i];
515
NonPrint_Key_Synth_Vals[index].sym = NULL;
516
NonPrint_Key_Synth_Vals[index].KeyVal = 0;