2
* Copyright 2010 Inalogic Inc.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 3, as published
6
* by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranties of
10
* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11
* PURPOSE. See the GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* version 3 along with this program. If not, see
15
* <http://www.gnu.org/licenses/>
17
* Authored by: Jay Taoko <jaytaoko@inalogic.com>
22
#include <X11/extensions/XTest.h>
23
#include <X11/keysym.h>
24
#include "nux_automated_test_framework.h"
27
int NuxAutomatedTestFramework::mouse_motion_time_span = 1000; // milliseconds
28
int NuxAutomatedTestFramework::mouse_click_time_span = 300; // milliseconds
29
int NuxAutomatedTestFramework::minimum_sleep_time = 600; // milliseconds
30
int NuxAutomatedTestFramework::safety_border_inside_view = 1; // pixels
32
NuxAutomatedTestFramework::NuxAutomatedTestFramework(nux::WindowThread *window_thread)
34
ready_to_start_ = false;
36
window_thread_ = window_thread;
41
terminate_when_test_over_ = false;
44
NuxAutomatedTestFramework::~NuxAutomatedTestFramework()
46
XCloseDisplay(display_);
49
void NuxAutomatedTestFramework::SetTerminateProgramWhenDone(bool terminate)
51
terminate_when_test_over_ = terminate;
54
bool NuxAutomatedTestFramework::WhenDoneTerminateProgram()
56
return terminate_when_test_over_;
59
void NuxAutomatedTestFramework::Startup()
61
display_ = XOpenDisplay(NULL);
62
nux::Geometry rect = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
63
//nuxDebugMsg("Window geometry: (%d, %d, %d, %d)", rect.x, rect.y, rect.width, rect.height);
67
window_width_ = rect.width;
68
window_height_ = rect.height;
71
void NuxAutomatedTestFramework::ViewSendMouseClick(nux::View *view, int button)
76
r = view->GetAbsoluteGeometry();
77
r.OffsetPosition(window_x_ + r.width/2, window_y_ + r.height/2);
81
r = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
82
r.OffsetPosition(r.width/2, r.height/2);
85
SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span);
86
SendFakeMouseEvent(button, true);
87
nux::SleepForMilliseconds(NuxAutomatedTestFramework::mouse_click_time_span);
88
SendFakeMouseEvent(button, false);
90
XSync(display_, False);
91
nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time);
94
void NuxAutomatedTestFramework::ViewSendMouseDoubleClick(nux::View *view, int button)
99
r = view->GetAbsoluteGeometry();
100
r.OffsetPosition(window_x_ + r.width/2, window_y_ + r.height/2);
104
r = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
105
r.OffsetPosition(r.width/2, r.height/2);
108
// Send the mouse to the center of the view
109
SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span);
111
XTestFakeButtonEvent(display_, button, true, CurrentTime);
112
XTestFakeButtonEvent(display_, button, false, CurrentTime);
113
XTestFakeButtonEvent(display_, button, true, CurrentTime);
114
XTestFakeButtonEvent(display_, button, false, CurrentTime);
115
XSync(display_, False);
116
nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time);
119
void NuxAutomatedTestFramework::ViewSendMouseDown(nux::View *view, int button)
122
/* Get the current pointer position */
123
XQueryPointer(display_, RootWindow(display_, 0),
124
&event.xbutton.root, &event.xbutton.window,
125
&event.xbutton.x_root, &event.xbutton.y_root,
126
&event.xbutton.x, &event.xbutton.y,
127
&event.xbutton.state);
129
int current_x = event.xbutton.x - window_x_;
130
int current_y = event.xbutton.y - window_y_;
132
nux::Rect r = view->GetAbsoluteGeometry();
134
if (!r.IsInside(nux::Point(current_x, current_y)))
136
// The mouse pointer is not inside the view.
137
// Move the mouse pointer to the center of the view.
138
r.OffsetPosition(window_x_, window_y_);
140
// Go to the center of the view
141
int view_center_x = r.x + r.width/2;
142
int view_center_y = r.y + r.height/2;
143
SendFakeMouseMotionEvent(view_center_x, view_center_y, NuxAutomatedTestFramework::mouse_motion_time_span);
144
nux::SleepForMilliseconds(minimum_sleep_time);
146
SendFakeMouseEvent(button, true);
149
void NuxAutomatedTestFramework::ViewSendMouseUp(nux::View *view, int button)
151
// nux::Rect r = view->GetAbsoluteGeometry();
152
// r.OffsetPosition(window_x_, window_y_);
154
// int view_center_x = r.x + r.width/2;
155
// int view_center_y = r.y + r.height/2;
157
// SendFakeMouseMotionEvent(view_center_x, view_center_y, 1000);
158
// nux::SleepForMilliseconds(minimum_sleep_time);
159
SendFakeMouseEvent(button, false);
162
void NuxAutomatedTestFramework::ViewSendMouseDrag(nux::View *view, int button_index, int x0, int y0, int x1, int y1)
164
nux::Rect r0 = view->GetAbsoluteGeometry();
165
nux::Rect r1 = view->GetAbsoluteGeometry();
166
r0.OffsetPosition(window_x_ + x0, window_y_ + y0);
167
r1.OffsetPosition(window_x_ + x1, window_y_ + y1);
170
SendFakeMouseMotionEvent(r0.x, r0.y, NuxAutomatedTestFramework::mouse_motion_time_span);
171
nux::SleepForMilliseconds(minimum_sleep_time);
174
ViewSendMouseDown(view, button_index);
176
// Drag to second point
177
SendFakeMouseMotionEvent(r1.x, r1.y, NuxAutomatedTestFramework::mouse_motion_time_span);
178
nux::SleepForMilliseconds(minimum_sleep_time);
181
ViewSendMouseUp(view, button_index);
184
void NuxAutomatedTestFramework::ViewSendMouseMotionTo(nux::View *view, int x, int y)
189
r = view->GetAbsoluteGeometry();
190
r.OffsetPosition(window_x_ + x, window_y_ + y);
194
r = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
195
r.OffsetPosition(x, y);
198
SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span);
201
void NuxAutomatedTestFramework::ViewSendMouseMotionToCenter(nux::View *view)
206
r = view->GetAbsoluteGeometry();
207
r.OffsetPosition(window_x_, window_y_);
211
r = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
214
int view_center_x = r.x + r.width/2;
215
int view_center_y = r.y + r.height/2;
217
SendFakeMouseMotionEvent(view_center_x, view_center_y, NuxAutomatedTestFramework::mouse_motion_time_span);
220
void NuxAutomatedTestFramework::ViewSendMouseMotionToTopLeft(nux::View *view)
222
nux::Rect r = view->GetAbsoluteGeometry();
223
r.OffsetPosition(window_x_, window_y_);
225
SendFakeMouseMotionEvent(r.x + safety_border_inside_view, r.y + safety_border_inside_view, NuxAutomatedTestFramework::mouse_motion_time_span);
228
void NuxAutomatedTestFramework::ViewSendMouseMotionToTopRight(nux::View *view)
230
nux::Rect r = view->GetAbsoluteGeometry();
231
r.OffsetPosition(window_x_, window_y_);
233
SendFakeMouseMotionEvent(r.x + r.width-1, r.y+safety_border_inside_view, NuxAutomatedTestFramework::mouse_motion_time_span);
236
void NuxAutomatedTestFramework::ViewSendMouseMotionToBottomLeft(nux::View *view)
238
nux::Rect r = view->GetAbsoluteGeometry();
239
r.OffsetPosition(window_x_, window_y_);
241
SendFakeMouseMotionEvent(r.x+safety_border_inside_view, r.y + r.height-1, NuxAutomatedTestFramework::mouse_motion_time_span);
244
void NuxAutomatedTestFramework::ViewSendMouseMotionToBottomRight(nux::View *view)
246
nux::Rect r = view->GetAbsoluteGeometry();
247
r.OffsetPosition(window_x_, window_y_);
249
SendFakeMouseMotionEvent(r.x + r.width-1, r.y + r.height-1, NuxAutomatedTestFramework::mouse_motion_time_span);
252
void NuxAutomatedTestFramework::ViewSendChar(const char c)
256
if ((c >= 'A') && (c <= 'Z'))
258
modifier = XK_Shift_L;
262
SendFakeKeyEvent(XStringToKeysym(s.c_str()), modifier);
263
nux::SleepForMilliseconds(300);
266
void NuxAutomatedTestFramework::ViewSendString(const std::string &str)
268
int l = str.length();
279
if ((c >= 'A') && (c <= 'Z'))
281
modifier = XK_Shift_L;
285
SendFakeKeyEvent(XStringToKeysym(s.c_str()), modifier);
286
nux::SleepForMilliseconds(300);
290
void NuxAutomatedTestFramework::ViewSendKeyCombo(KeySym modsym0, KeySym modsym1, KeySym modsym2, const char c)
293
KeyCode modcode0 = 0;
294
KeyCode modcode1 = 0;
295
KeyCode modcode2 = 0;
298
keycode = XKeysymToKeycode(display_, XStringToKeysym(s.c_str()));
299
XTestGrabControl(display_, True);
301
/* Generate modkey press */
304
modcode0 = XKeysymToKeycode(display_, modsym0);
305
XTestFakeKeyEvent(display_, modcode0, True, 0);
309
modcode1 = XKeysymToKeycode(display_, modsym1);
310
XTestFakeKeyEvent(display_, modcode1, True, 0);
314
modcode2 = XKeysymToKeycode(display_, modsym2);
315
XTestFakeKeyEvent(display_, modcode2, True, 0);
318
/* Generate regular key press and release */
319
XTestFakeKeyEvent(display_, keycode, True, 0);
320
XTestFakeKeyEvent(display_, keycode, False, 0);
322
/* Generate modkey release */
325
XTestFakeKeyEvent(display_, modcode0, False, 0);
329
XTestFakeKeyEvent(display_, modcode1, False, 0);
333
XTestFakeKeyEvent(display_, modcode2, False, 0);
336
XSync(display_, False);
337
XTestGrabControl(display_, False);
340
void NuxAutomatedTestFramework::ViewSendCtrlA()
342
ViewSendKeyCombo(XK_Control_L, 0, 0, 'a');
345
void NuxAutomatedTestFramework::ViewSendDelete()
347
SendFakeKeyEvent(XK_Delete, 0);
350
void NuxAutomatedTestFramework::ViewSendBackspace()
352
SendFakeKeyEvent(XK_BackSpace, 0);
355
void NuxAutomatedTestFramework::ViewSendEscape()
357
SendFakeKeyEvent(XK_Escape, 0);
360
void NuxAutomatedTestFramework::ViewSendTab()
362
SendFakeKeyEvent(XK_Tab, 0);
365
void NuxAutomatedTestFramework::ViewSendReturn()
367
SendFakeKeyEvent(XK_Return, 0);
370
void NuxAutomatedTestFramework::PutMouseAt(int x, int y)
372
XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), x, y, CurrentTime);
373
XSync(display_, False);
376
void NuxAutomatedTestFramework::SendFakeKeyEvent(KeySym keysym, KeySym modsym)
381
keycode = XKeysymToKeycode(display_, keysym);
382
XTestGrabControl(display_, True);
384
/* Generate modkey press */
387
modcode = XKeysymToKeycode(display_, modsym);
388
XTestFakeKeyEvent(display_, modcode, True, 0);
391
/* Generate regular key press and release */
392
XTestFakeKeyEvent(display_, keycode, True, 0);
393
XTestFakeKeyEvent(display_, keycode, False, 0);
395
/* Generate modkey release */
398
XTestFakeKeyEvent(display_, modcode, False, 0);
401
XSync(display_, False);
402
XTestGrabControl(display_, False);
405
void NuxAutomatedTestFramework::SendFakeMouseEvent(int mouse_button_index, bool pressed)
407
XTestFakeButtonEvent(display_, mouse_button_index, pressed, CurrentTime);
408
XSync(display_, False);
411
void NuxAutomatedTestFramework::SendFakeMouseMotionEvent(int x, int y, int ms_delay)
414
/* Get the current pointer position */
415
XQueryPointer(display_, RootWindow(display_, 0),
416
&event.xbutton.root, &event.xbutton.window,
417
&event.xbutton.x_root, &event.xbutton.y_root,
418
&event.xbutton.x, &event.xbutton.y,
419
&event.xbutton.state);
421
int old_x = event.xbutton.x;
422
int old_y = event.xbutton.y;
424
int n_iteration = ms_delay / 16.0f;
426
//nuxDebugMsg("n_iteration: %d", n_iteration);
433
XSync(display_, False);
435
for (int i = 0; i < n_iteration; i++)
437
float t = ((float)i + 1.0f) / n_iteration;
439
int cx = (1.0f - t) * old_x + t * x;
440
int cy = (1.0f - t) * old_y + t * y;
441
XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), cx, cy, CurrentTime);
442
XSync(display_, False);
446
XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), x, y, CurrentTime);
447
XSync(display_, False);
448
nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time);
451
void NuxAutomatedTestFramework::TestReportMsg(bool b, const char* msg)
455
nuxOkMsg("%s: %s", msg, "Ok");
459
nuxAlertMsg("%s: %s", msg, "Failed");
b'\\ No newline at end of file'