CEBL  2.1
X11Controller.cpp
Go to the documentation of this file.
1 #include <X11/Xlibint.h>
2 #include <X11/Xlib.h>
3 #include <X11/Xutil.h>
4 #include <X11/cursorfont.h>
5 #include <X11/keysymdef.h>
6 #include <X11/keysym.h>
7 #include <X11/extensions/XTest.h>
8 #include <sys/shm.h>
9 #include <time.h>
10 
11 #include <stdio.h>
12 #include <string>
13 #include <iostream>
14 using std::cerr;
15 using std::string;
16 using std::cout;
17 
18 #include "X11Controller.hpp"
19 
21 {
22  display = XOpenDisplay(getenv("DISPLAY"));
23 
24  if(display == NULL)
25  {
26  cerr << "Failed to open display.\n";
27  }
28  srand(time(NULL));
29 }
30 
31 
33 {
34  if(display != NULL)
35  {
36  XCloseDisplay(display);
37  }
38 }
39 
40 
41 //----------------------------------------------------------------------
42 //FUNCTIONS
43 
44 Window X11Controller::getWindowByNameRecursive(Window root, const char * search_name, int level)
45 {
46  Window root_window, parent_window, result, *child_windows;
47  unsigned int num_children = 0;
48  char * name;
49  //get list of windows
50  int ret = XQueryTree(display,
51  root,
52  &root_window, &parent_window,
53  &child_windows, &num_children);
54  if(ret)
55  {
56  for(unsigned int i=0; i<num_children; i++)
57  {
58  //check if this is the right window
59  ret = XFetchName(display,child_windows[i],&name);
60  if(ret)
61  {
62  string str1 = name;
63  string str2 = search_name;
64  if(str1 == str2)
65  {
66  result = child_windows[i];
67  XFree(child_windows);
68  return result;
69  }
70  XFree(name);
71  }
72  // no, this isn't the right window, maybe one of its children are
73  result = getWindowByNameRecursive(child_windows[i],
74  search_name, level + 1);
75  if(result > 0)
76  {
77  XFree(child_windows);
78  return result;
79  }
80  }//end of outer window children loop
81  }//end of if(ret)
82  if(child_windows != NULL ) XFree(child_windows);
83  return 0;
84 }
85 
86 Window X11Controller::getWindowByName(const char *search_name)
87 {
88  Window ret = getWindowByNameRecursive(XDefaultRootWindow(display), search_name, 0);
89  return ret;
90 }
91 
93 {
94  Window root_return, child_return;
95  int win_x_return, win_y_return;
96  unsigned int mask_return;
97  bool ret = XQueryPointer(display, XDefaultRootWindow(display),
98  &root_return, &child_return,
99  x,y,
100  &win_x_return, &win_y_return,
101  &mask_return);
102  return ret;
103 }
104 
105 bool X11Controller::getWindowXYAbsolute(Window window, int *x, int *y)
106 {
107  XWindowAttributes win_attributes;
108  Window not_needed;
109  if(XGetWindowAttributes(display, window, &win_attributes))
110  {
111  return XTranslateCoordinates (display, window, win_attributes.root,
112  -win_attributes.border_width,
113  -win_attributes.border_width,
114  x, y, &not_needed);
115  }
116  else
117  {
118  return false;
119  }
120 }
121 
122 bool X11Controller::getWindowSize(Window window, int *width, int *height)
123 {
124  XWindowAttributes win_attributes;
125  if(XGetWindowAttributes(display, window, &win_attributes))
126  {
127  *width = win_attributes.width - win_attributes.border_width;
128  *height = win_attributes.height - win_attributes.border_width;
129  return true;
130  }
131  else
132  {
133  return false;
134  }
135 }
136 
138 {
139  int cursor_x, cursor_y, window_x, window_y, diffx, diffy;
140  getCursorXYAbsolute(&cursor_x,&cursor_y);
141  getWindowXYAbsolute(window,&window_x,&window_y);
142  diffx = window_x - cursor_x;
143  diffy = window_y - cursor_y;
144  XWarpPointer(display, None, None, 0, 0, 0, 0, diffx, diffy);
145  bool ret = XWarpPointer(display, None, None, 0, 0, 0, 0, diffx, diffy);
146  XFlush(display);
147  return ret;
148 }
149 
150 
151 bool X11Controller::moveCursorAbsoluteInWindow(Window window, int x, int y)
152 {
153  int cursor_x, cursor_y, diffx, diffy;
154  getCursorXYAbsolute(&cursor_x,&cursor_y);
155  diffx = cursor_x + x;
156  diffy = cursor_y + y;
157 
158  bool ret = XWarpPointer(display, None, window, 0, 0, 0, 0, x, y);
159  XFlush(display);
160  return ret;
161 }
162 
164 {
165  bool ret = XWarpPointer(display, None, None, 0, 0, 0, 0, x, y);
166  XFlush(display);
167  return ret;
168 }
169 
170 //----------------------------------------------------------------------
171 // Clicking
172 
173 bool X11Controller::buttonPress(unsigned int button)
174 {
175  bool ret = XTestFakeButtonEvent(display, button, true, 10);
176  XFlush(display);
177  return ret;
178 }
179 
180 bool X11Controller::buttonRelease(unsigned int button)
181 {
182  bool ret = XTestFakeButtonEvent(display, button, false, 10);
183  XFlush(display);
184  return ret;
185 }
186 
188 {
189  bool r1 = buttonPress(1);
190  pause();
191  bool r2 = buttonRelease(1);
192  return r1 && r2;
193 }
194 
196 {
197  bool r1 = buttonPress(3);
198  pause();
199  bool r2 = buttonRelease(3);
200  return r1 && r2;
201 }
202 
204 {
205  bool r1 = buttonPress(2);
206  pause();
207  bool r2 = buttonRelease(2);
208  return r1 && r2;
209 }
210 
212 {
213  bool r1 = leftClick();
214  pause();
215  bool r2 = leftClick();
216  return r1 && r2;
217 }
218 
219 //----------------------------------------------------------------------
220 // Key Events
221 KeyCode X11Controller::getKeyCodeFromString(const char * key)
222 {
223  KeySym ks = XStringToKeysym(key);
224  KeyCode kc = XKeysymToKeycode(display, ks);
225  return kc;
226 }
227 
228 bool X11Controller::keyPress(const char * key)
229 {
230  KeyCode kc = getKeyCodeFromString(key);
231  if(kc == 0)
232  return false;
233  else
234  {
235  bool ret = XTestFakeKeyEvent(display, kc, true, 10);
236  XFlush(display);
237  return ret;
238  }
239 }
240 
241 bool X11Controller::keyRelease(const char * key)
242 {
243  KeyCode kc = getKeyCodeFromString(key);
244  if(kc == 0)
245  return false;
246  else
247  {
248  bool ret = XTestFakeKeyEvent(display, kc, false, 10);
249  XFlush(display);
250  return ret;
251  }
252 }
253 
254 bool X11Controller::keySend(const char * key)
255 {
256  bool r1 = keyPress(key);
257  pause();
258  bool r2 = keyRelease(key);
259  return r1 && r2;
260 }
261 
262 bool X11Controller::stringSend(const char * str)
263 {
264  bool ret = true;
265  char send[32];
266  for(unsigned i = 0; i < strlen(str); i++)
267  {
268  char c = str[i];
269  switch(c)
270  {
271  case ' ':
272  strcpy(send,"space");
273  break;
274  case '\t':
275  strcpy(send,"tab");
276  break;
277  case '\n':
278  strcpy(send,"Return");
279  break;
280  default:
281  send[0] = c;
282  send[1] = '\0';
283  }
284  ret = ret && keySend(send);
285  }
286  return ret;
287 }
288 
289 //----------------------------------------------------------------------
290 // cleaning up functions
291 
293 {
294  if(display != NULL)
295  {
296  XCloseDisplay(display);
297  display = NULL;
298  }
299 }
300 
301 
302 //----------------------------------------------------------------------
303 // utility functions
304 int X11Controller::msleep(unsigned long milisec)
305 {
306  struct timespec req={0};
307  time_t sec=(int)(milisec/1000);
308  milisec=milisec-(sec*1000);
309  req.tv_sec=sec;
310  req.tv_nsec=milisec*1000000L;
311  while(nanosleep(&req,&req)==-1)
312  continue;
313  return 1;
314 }
315 
316 int X11Controller::randrange(int low, int high)
317 {
318  return (rand() % (high - low)) + low;
319 }
320 
321 void X11Controller::pause()
322 {
323  msleep(10);
324 }