-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxcurstic.cpp
131 lines (120 loc) · 3.88 KB
/
xcurstic.cpp
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
#include <math.h>
#include <fcntl.h>
#include <stdio.h>
#include <X11/X.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/keysymdef.h>
#include <linux/joystick.h>
#include <X11/extensions/XTest.h>
const int MAX_SPEED = 8;
const int CLICK_DELAY = 50;
const int SCROLL_MULTIPLIER = 1;
const int CURSOR_UPDATE_FREQUENCY = 160;
const double MAX_VELOCITY = 50.0;
const double MAX_JOYSTICK = 32676;
const double JOYSTICK_CENTER_THRESHOLD = 0.1;
int main() {
int joy_fd, num_of_axis;
char const *device = "/dev/input/js0";
Display *display;
Window root_window;
int dx = 0, dy = 0;
double magnitude = 0;
double joystick_center_x = 0, joystick_center_y = 0;
struct js_event js;
// Initialize X11 display and root window
display = XOpenDisplay(NULL);
root_window = XRootWindow(display, 0);
joy_fd = open(device, O_RDONLY);
if (joy_fd < 0) {
std::cerr << "Error: Failed to detect Xbox One Controller (is it on?)." << std::endl;
return 1;
}
// Set joystick to non-blocking mode
fcntl(joy_fd, F_SETFL, O_NONBLOCK);
while (true) {
ssize_t bytes = read(joy_fd, &js, sizeof(js_event));
if (bytes == -1 && errno == EAGAIN) {
// No data available, continue loop
continue;
} else if (bytes == -1) {
// Handle error
continue;
} else if (bytes != sizeof(js_event)) {
// Handle incomplete or partial structure
continue;
}
switch (js.type & ~JS_EVENT_INIT) {
case JS_EVENT_AXIS:
if (js.number == 0) {
// Left joystick X-axis
dx = js.value;
} else if (js.number == 1 ) {
// Left joystick Y-axis
dy = js.value;
} else if (js.number == 3) {
// Right joystick Y-axis
static int scroll_accum = 0;
int scroll_speed = -js.value / (MAX_JOYSTICK / 2);
scroll_accum += scroll_speed;
if (scroll_accum >= 1 || scroll_accum <= -1) {
int scroll_steps = scroll_accum / 2 * SCROLL_MULTIPLIER;
for (int i = 0; i < abs(scroll_steps); i++) {
XTestFakeButtonEvent(display, scroll_steps > 0 ? Button4 : Button5, True, CurrentTime);
XTestFakeButtonEvent(display, scroll_steps > 0 ? Button4 : Button5, False, CurrentTime);
}
scroll_accum -= scroll_steps * 1.2;
XFlush(display);
}
}
break;
case JS_EVENT_BUTTON:
// Left click
if (js.number == 0 && js.value == 1) {
XTestFakeButtonEvent(display, 1, True, CurrentTime);
XFlush(display);
usleep(CLICK_DELAY * 1000);
XTestFakeButtonEvent(display, 1, False, CurrentTime);
XFlush(display);
// Right click
} else if (js.number == 1 && js.value == 1) {
XTestFakeButtonEvent(display, 3, True, CurrentTime);
XFlush(display);
usleep(CLICK_DELAY * 1000);
XTestFakeButtonEvent(display, 3, False, CurrentTime);
XFlush(display);
// Super key
} else if (js.number == 12 && js.value == 1) {
XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Super_L), True, CurrentTime);
XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Super_L), False, CurrentTime);
XFlush(display);
}
std::cout << "js.number " << static_cast<int>(js.number) << " " << (js.value ? "pressed" : "released") << std::endl;
break;
default:
break;
}
// Calculate cursor movement based on left joystick input
magnitude = sqrt(dx * dx + dy * dy);
if (magnitude > MAX_JOYSTICK) {
magnitude = MAX_JOYSTICK;
}
if (magnitude > JOYSTICK_CENTER_THRESHOLD * MAX_JOYSTICK) {
double scale = (magnitude - JOYSTICK_CENTER_THRESHOLD * MAX_JOYSTICK) / (MAX_JOYSTICK - JOYSTICK_CENTER_THRESHOLD * MAX_JOYSTICK);
int speed = round(MAX_SPEED * scale);
int x_speed = round(speed * dx / magnitude);
int y_speed = round(speed * dy / magnitude);
XTestFakeRelativeMotionEvent(display, x_speed, y_speed, 0);
XFlush(display);
}
usleep(1000);
}
// Close joystick device and X11 display
close(joy_fd);
XCloseDisplay(display);
return 0;
}