-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathxdisplay.h
135 lines (124 loc) · 3.25 KB
/
xdisplay.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#ifndef _ELANBSD_DISPLAY_H_
#define _ELANBSD_DISPLAY_H_
#include "config.h"
#ifdef USE_XTEST
#include <X11/extensions/XTest.h>
#endif
#include <stdio.h>
#include <math.h>
#include "elanbsd.h"
class XDisplay {
int dpy_x, dpy_y;
#ifdef USE_XTEST
Display *display;
int screen_number;
#endif
public:
XDisplay() {
FILE *f = popen("xdotool getdisplaygeometry", "r");
fscanf(f, "%d %d", &dpy_x, &dpy_y);
pclose(f);
#ifdef USE_XTEST
display = XOpenDisplay(NULL);
if (!display)
errexit("fail to open display");
int event_base, err_base, major, minor;
if (!XTestQueryExtension(display, &event_base, &err_base, &major, &minor))
errexit("No XTEST extension found");
printf("using XTEST %d.%d\n", major, minor);
screen_number = -1;
#endif
}
~XDisplay() {
#ifdef USE_XTEST
XCloseDisplay(display);
#endif
}
void get_mouse_pos(int &x, int &y) {
FILE *f = popen("xdotool getmouselocation", "r");
fscanf(f, "x:%d y:%d", &x, &y);
pclose(f);
}
void move(int x, int y) {
printf("dpy:move %d,%d\n", x, y);
#ifdef USE_XTEST
Bool succ = XTestFakeMotionEvent(display, screen_number, x, y, CurrentTime);
if (!succ)
errexit("fail to fake motion event");
XFlush(display);
#else
char buf[1024];
snprintf(buf, sizeof(buf), "xdotool mousemove -- %d %d", x, y);
system(buf);
#endif
}
void move_rel(double dx, double dy, int x_max, int y_max) {
int rx = round(dx * dpy_x * MOVE_X_SCALE / x_max);
int ry = round(-dy * dpy_y * MOVE_Y_SCALE / y_max);
printf("dpy:move_rel %d,%d\n", rx, ry);
if (rx == 0 && ry == 0) return;
#ifdef USE_XTEST
Bool succ = XTestFakeRelativeMotionEvent(display, rx, ry, CurrentTime);
if (!succ)
errexit("fail to fake relative motion event");
XFlush(display);
#else
char buf[1024];
snprintf(buf, sizeof(buf), "xdotool mousemove_relative -- %d %d", rx, ry);
system(buf);
#endif
}
void click(int btn) {
printf("dpy:click %d\n", btn + 1);
#ifdef USE_XTEST
XTestFakeButtonEvent(display, btn + 1, True, CurrentTime);
XTestFakeButtonEvent(display, btn + 1, False, CurrentTime);
XFlush(display);
#else
char buf[1024];
snprintf(buf, sizeof(buf), "xdotool click %d", btn + 1);
system(buf);
#endif
}
void press(bool down, int id) {
printf("dpy:press %d,%s\n", id, down ? "down" : "up");
#ifdef USE_XTEST
XTestFakeButtonEvent(display, id + 1, down ? True : False, CurrentTime);
XFlush(display);
#else
char buf[1024];
snprintf(buf, sizeof(buf), "xdotool mouse%s %d", down ? "down" : "up", id + 1);
system(buf);
#endif
}
int get_keycode(const std::string& str) {
#ifdef USE_XTEST
return XKeysymToKeycode(display, XStringToKeysym(str.c_str()));
#else
char buf[1024];
snprintf(buf, sizeof(buf), "xmodmap -pke | grep ' %s ' | cut -w -f 2-2", str.c_str());
int code;
FILE *f = popen(buf, "r");
if (fscanf(f, "%d", &code) != 1) errexit("fail to obtain keycode");
pclose(f);
return code;
#endif
}
void key_down(int keycode) {
key(true, keycode);
}
void key_up(int keycode) {
key(false, keycode);
}
void key(bool down, int keycode) {
#ifdef USE_XTEST
XTestFakeKeyEvent(display, keycode, down ? True : False, CurrentTime);
XFlush(display);
#else
char buf[1024];
snprintf(buf, sizeof(buf), "xdotool key%s %d", down ? "down" : "up", keycode);
system(buf);
#endif
}
};
#endif // _ELANBSD_DISPLAY_H_