/
main.c
124 lines (105 loc) · 2.92 KB
/
main.c
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
/* Written by Nick Welch in the year 2008. Author disclaims copyright. */
#include <SDL/SDL.h>
#include <SDL/SDL_joystick.h>
#include <SDL/SDL_events.h>
#include <X11/extensions/XTest.h>
#include <X11/Xlib.h>
#include <X11/X.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#define THRESHOLD 2000
#define HORZ 0
#define VERT 1
SDL_Joystick ** sticks = NULL;
int nsticks = 0;
Display * dpy = NULL;
void quit(int return_code)
{
for(int i = 0; i < nsticks; ++i)
SDL_JoystickClose(sticks[i]);
if(sticks)
free(sticks);
if(dpy)
XCloseDisplay(dpy);
SDL_Quit();
exit(return_code);
}
void die(const char * message)
{
fprintf(stderr, "fatal: %s\n", message);
quit(1);
}
int open_joysticks(void)
{
int nreported = SDL_NumJoysticks();
if(!nreported)
return 0;
sticks = malloc(sizeof(SDL_Joystick *) * nreported);
SDL_Joystick ** current = sticks;
for(int i = 0; i < nreported; ++i)
{
SDL_Joystick * stick = SDL_JoystickOpen(i);
if(!stick)
{
fprintf(stderr, "could not open joystick %d: %s\n",
i, SDL_JoystickName(i));
continue;
}
*current = stick;
current++;
nsticks++;
}
return !!sticks;
}
int main(void)
{
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
die("could not init SDL");
SDL_JoystickEventState(SDL_ENABLE);
if(!open_joysticks())
die("could not initialize any joysticks");
Display * dpy = XOpenDisplay(NULL);
if(!dpy)
die("could not connect to X display");
int _;
if(!XQueryExtension(dpy, "XTEST", &_, &_, &_))
die("XTEST extension is not supported by X server");
SDL_Event ev;
int horz = 0;
int vert = 0;
for(;;)
{
for(int i = 0; i < 10; ++i)
{
while(SDL_PollEvent(&ev))
{
if(ev.type == SDL_QUIT)
quit(0);
if(ev.type != SDL_JOYAXISMOTION)
continue;
int val = ev.jaxis.value;
if(abs(val) < THRESHOLD)
val = 0;
if(ev.jaxis.axis % 2 == 0)
horz = val;
else
vert = val;
}
usleep(1000);
}
// abs() the value passed to pow() since it can't handle a negative
// with a non-int exponent, and then turn the result back into a
// negative if needed
int horz_px = (int)pow(abs(horz) * 0.0001, 2.7) * (horz >= 0 ? 1 : -1);
int vert_px = (int)pow(abs(vert) * 0.0001, 2.7) * (vert >= 0 ? 1 : -1);
if(horz_px != 0 || vert_px != 0)
{
//fprintf(stderr, "ev %d %d -> %d %d\n", horz, vert, horz_px, vert_px);
XTestFakeRelativeMotionEvent(dpy, horz_px, vert_px, CurrentTime);
XSync(dpy, False);
}
}
quit(0);
}