Lines 1-211
Link Here
|
1 |
--- src/input/evdev.c.orig 2023-10-11 15:50:11 UTC |
1 |
--- src/input/evdev.c.orig 2023-11-03 06:08:34 UTC |
2 |
+++ src/input/evdev.c |
2 |
+++ src/input/evdev.c |
3 |
@@ -38,10 +38,16 @@ |
3 |
@@ -38,9 +38,15 @@ |
4 |
#include <limits.h> |
4 |
#include <limits.h> |
5 |
#include <unistd.h> |
5 |
#include <unistd.h> |
6 |
#include <pthread.h> |
6 |
#include <pthread.h> |
7 |
-#include <endian.h> |
7 |
+#ifdef __linux__ |
|
|
8 |
#include <endian.h> |
9 |
+#else |
8 |
+#include <sys/endian.h> |
10 |
+#include <sys/endian.h> |
|
|
11 |
+#endif |
9 |
#include <math.h> |
12 |
#include <math.h> |
10 |
|
13 |
|
11 |
-#if __BYTE_ORDER == __LITTLE_ENDIAN |
14 |
+static bool isUseKbdmux = false; |
12 |
+extern bool isNoSdl; |
|
|
13 |
+bool iskeyboardgrab = false; |
14 |
+void grab_window(bool grabstat); |
15 |
+static bool waitingToSwitchGrabOnModifierUp = false; |
16 |
+static bool isgrabkeyrelease = false; |
17 |
+ |
15 |
+ |
18 |
+#if _BYTE_ORDER == _LITTLE_ENDIAN |
16 |
#if __BYTE_ORDER == __LITTLE_ENDIAN |
19 |
#define int16_to_le(val) val |
17 |
#define int16_to_le(val) val |
20 |
#else |
18 |
#else |
21 |
#define int16_to_le(val) ((((val) >> 8) & 0x00FF) | (((val) << 8) & 0xFF00)) |
19 |
@@ -66,8 +72,13 @@ struct input_device { |
22 |
@@ -66,8 +72,8 @@ struct input_device { |
|
|
23 |
int hats_state[3][2]; |
20 |
int hats_state[3][2]; |
24 |
int fd; |
21 |
int fd; |
25 |
char modifiers; |
22 |
char modifiers; |
26 |
- __s32 mouseDeltaX, mouseDeltaY, mouseVScroll, mouseHScroll; |
23 |
+ #ifdef __linux__ |
27 |
- __s32 touchDownX, touchDownY, touchX, touchY; |
24 |
__s32 mouseDeltaX, mouseDeltaY, mouseVScroll, mouseHScroll; |
|
|
25 |
__s32 touchDownX, touchDownY, touchX, touchY; |
26 |
+ #else |
28 |
+ int32_t mouseDeltaX, mouseDeltaY, mouseVScroll, mouseHScroll; |
27 |
+ int32_t mouseDeltaX, mouseDeltaY, mouseVScroll, mouseHScroll; |
29 |
+ int32_t touchDownX, touchDownY, touchX, touchY; |
28 |
+ int32_t touchDownX, touchDownY, touchX, touchY; |
|
|
29 |
+ #endif |
30 |
struct timeval touchDownTime; |
30 |
struct timeval touchDownTime; |
31 |
struct timeval btnDownTime; |
31 |
struct timeval btnDownTime; |
32 |
short controllerId; |
32 |
short controllerId; |
33 |
@@ -127,6 +133,7 @@ int evdev_gamepads = 0; |
33 |
@@ -749,7 +760,7 @@ static int evdev_handle(int fd) { |
34 |
|
|
|
35 |
#define ACTION_MODIFIERS (MODIFIER_SHIFT|MODIFIER_ALT|MODIFIER_CTRL) |
36 |
#define QUIT_KEY KEY_Q |
37 |
+#define GRAB_KEY KEY_Z |
38 |
#define QUIT_BUTTONS (PLAY_FLAG|BACK_FLAG|LB_FLAG|RB_FLAG) |
39 |
|
40 |
static bool (*handler) (struct input_event*, struct input_device*); |
41 |
@@ -139,6 +146,22 @@ static int evdev_get_map(int* map, int length, int val |
42 |
return -1; |
43 |
} |
44 |
|
45 |
+static short keystatlist[0xFF]; |
46 |
+static void keyrelease(int keycode) { |
47 |
+ keystatlist[keycode] = 0; |
48 |
+} |
49 |
+static void keypress(int keycode) { |
50 |
+ keystatlist[keycode] = 1; |
51 |
+} |
52 |
+static void freeallkey () { |
53 |
+ for (int i=0;i<0xFF;i++) { |
54 |
+ if (keystatlist[i] == 1) { |
55 |
+ keystatlist[i] = 0; |
56 |
+ LiSendKeyboardEvent(0x80 << 8 | keyCodes[i], KEY_ACTION_UP, 0); |
57 |
+ } |
58 |
+ } |
59 |
+} |
60 |
+ |
61 |
static bool evdev_init_parms(struct input_device *dev, struct input_abs_parms *parms, int code) { |
62 |
int abs = evdev_get_map(dev->abs_map, ABS_MAX, code); |
63 |
|
64 |
@@ -343,7 +366,7 @@ static bool evdev_handle_event(struct input_event *ev, |
65 |
if (dev->mouseHScroll != 0) { |
66 |
LiSendHScrollEvent(dev->mouseHScroll); |
67 |
dev->mouseHScroll = 0; |
68 |
- } |
69 |
+ } |
70 |
if (dev->gamepadModified) { |
71 |
if (dev->controllerId < 0) { |
72 |
for (int i = 0; i < MAX_GAMEPADS; i++) { |
73 |
@@ -398,15 +421,41 @@ static bool evdev_handle_event(struct input_event *ev, |
74 |
} |
75 |
|
76 |
// After the quit key combo is pressed, quit once all keys are raised |
77 |
- if ((dev->modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && |
78 |
- ev->code == QUIT_KEY && ev->value != 0) { |
79 |
- waitingToExitOnModifiersUp = true; |
80 |
- return true; |
81 |
- } else if (waitingToExitOnModifiersUp && dev->modifiers == 0) |
82 |
+ if ((dev->modifiers & ACTION_MODIFIERS) == ACTION_MODIFIERS && ev->value != 0) { |
83 |
+ if (ev->code == QUIT_KEY) { |
84 |
+ waitingToExitOnModifiersUp = true; |
85 |
+ return true; |
86 |
+ } else if (ev->code == GRAB_KEY && iskeyboardgrab) { |
87 |
+ waitingToSwitchGrabOnModifierUp = true; |
88 |
+ return true; |
89 |
+ } |
90 |
+ } |
91 |
+ if (waitingToSwitchGrabOnModifierUp) { |
92 |
+ if (ev->code == GRAB_KEY && ev->value == 0) { |
93 |
+ isgrabkeyrelease = true; |
94 |
+ if (dev->modifiers != 0) |
95 |
+ return true; |
96 |
+ } |
97 |
+ if (dev->modifiers == 0 && isgrabkeyrelease) { |
98 |
+ waitingToSwitchGrabOnModifierUp = false; |
99 |
+ isgrabkeyrelease = false; |
100 |
+ freeallkey(); |
101 |
+ grab_window(!iskeyboardgrab); |
102 |
+ return true; |
103 |
+ } |
104 |
+ } else if (waitingToExitOnModifiersUp && dev->modifiers == 0) { |
105 |
+ freeallkey(); |
106 |
+ grab_window(false); |
107 |
return false; |
108 |
+ } |
109 |
|
110 |
+ if (ev->value) |
111 |
+ keypress(ev->code); |
112 |
+ else |
113 |
+ keyrelease(ev->code); |
114 |
short code = 0x80 << 8 | keyCodes[ev->code]; |
115 |
LiSendKeyboardEvent(code, ev->value?KEY_ACTION_DOWN:KEY_ACTION_UP, dev->modifiers); |
116 |
+ |
117 |
} else { |
118 |
int mouseCode = 0; |
119 |
int gamepadCode = 0; |
120 |
@@ -749,8 +798,10 @@ static int evdev_handle(int fd) { |
121 |
struct input_event ev; |
34 |
struct input_event ev; |
122 |
while ((rc = libevdev_next_event(devices[i].dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) >= 0) { |
35 |
while ((rc = libevdev_next_event(devices[i].dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) >= 0) { |
123 |
if (rc == LIBEVDEV_READ_STATUS_SYNC) |
36 |
if (rc == LIBEVDEV_READ_STATUS_SYNC) |
124 |
- fprintf(stderr, "Error: cannot keep up\n"); |
37 |
- fprintf(stderr, "Error: cannot keep up\n"); |
125 |
+ fprintf(stderr, "Error:%s(%d) cannot keep up\n", libevdev_get_name(devices[i].dev), i); |
38 |
+ fprintf(stderr, "Error:%s(%d) cannot keep up\n", libevdev_get_name(devices[i].dev), i); |
126 |
else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) { |
39 |
else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) { |
127 |
+ if (!iskeyboardgrab) |
|
|
128 |
+ break; |
129 |
if (!handler(&ev, &devices[i])) |
40 |
if (!handler(&ev, &devices[i])) |
130 |
return LOOP_RETURN; |
41 |
return LOOP_RETURN; |
131 |
} |
42 |
@@ -766,6 +777,39 @@ static int evdev_handle(int fd) { |
132 |
@@ -840,7 +891,28 @@ void evdev_create(const char* device, struct mapping* |
43 |
return LOOP_OK; |
|
|
44 |
} |
45 |
|
46 |
+void is_use_kbdmux() { |
47 |
+ const char* tryFirstInput = "/dev/input/event0"; |
48 |
+ const char* trySecondInput = "/dev/input/event1"; |
49 |
+ |
50 |
+ int fdFirst = open(tryFirstInput, O_RDWR|O_NONBLOCK); |
51 |
+ int fdSecond = open(trySecondInput, O_RDWR|O_NONBLOCK); |
52 |
+ if (fdFirst <= 0 && fdSecond <= 0) { |
53 |
+ //Suppose use kbdmux because of default behavior |
54 |
+ isUseKbdmux = true; |
55 |
+ return; |
56 |
+ } |
57 |
+ |
58 |
+ struct libevdev *evdevFirst = libevdev_new(); |
59 |
+ libevdev_set_fd(evdevFirst, fdFirst); |
60 |
+ const char* nameFirst = libevdev_get_name(evdevFirst); |
61 |
+ struct libevdev *evdevSecond = libevdev_new(); |
62 |
+ libevdev_set_fd(evdevSecond, fdSecond); |
63 |
+ const char* nameSecond = libevdev_get_name(evdevSecond); |
64 |
+ |
65 |
+ libevdev_free(evdevFirst); |
66 |
+ libevdev_free(evdevSecond); |
67 |
+ close(fdFirst); |
68 |
+ close(fdSecond); |
69 |
+ |
70 |
+ if (strcmp(nameFirst, "System keyboard multiplexer") == 0 || |
71 |
+ strcmp(nameSecond, "System keyboard multiplexer") == 0) { |
72 |
+ isUseKbdmux = true; |
73 |
+ return; |
74 |
+ } |
75 |
+ |
76 |
+ return; |
77 |
+} |
78 |
+ |
79 |
void evdev_create(const char* device, struct mapping* mappings, bool verbose, int rotate) { |
80 |
int fd = open(device, O_RDWR|O_NONBLOCK); |
81 |
if (fd <= 0) { |
82 |
@@ -840,6 +884,33 @@ void evdev_create(const char* device, struct mapping* |
133 |
libevdev_has_event_code(evdev, EV_ABS, ABS_WHEEL) || |
83 |
libevdev_has_event_code(evdev, EV_ABS, ABS_WHEEL) || |
134 |
libevdev_has_event_code(evdev, EV_ABS, ABS_GAS) || |
84 |
libevdev_has_event_code(evdev, EV_ABS, ABS_GAS) || |
135 |
libevdev_has_event_code(evdev, EV_ABS, ABS_BRAKE)); |
85 |
libevdev_has_event_code(evdev, EV_ABS, ABS_BRAKE)); |
136 |
+ bool is_acpibutton = |
86 |
+ bool is_acpibutton = |
137 |
+ is_keyboard && |
87 |
+ strcmp(name, "Sleep Button") == 0 || |
138 |
+ (strcmp(libevdev_get_name(evdev), "Sleep Button") == 0 || |
88 |
+ strcmp(name, "Power Button") == 0; |
139 |
+ strcmp(libevdev_get_name(evdev), "Power Button") == 0); |
89 |
+ // Just use System keyboard multiplexer for FreeBSD,see kbdcontrol(1) and kbdmux(4) |
140 |
+ bool is_likekeyboard = |
90 |
+ // Trying to grab kbdmux0 and keyboard it's self at the same time results in |
141 |
+ is_keyboard && |
91 |
+ // the keyboard becoming unresponsive on FreeBSD. |
142 |
+ (libevdev_get_id_version(evdev) > 1000 || |
92 |
+ bool is_likekeyboard = |
143 |
+ libevdev_get_id_bustype(evdev) <= 3); |
93 |
+ is_keyboard && isUseKbdmux && strcmp(name, "System keyboard multiplexer") != 0; |
144 |
|
94 |
+/* |
|
|
95 |
+ (is_keyboard && guid[0] <= 3) || |
96 |
+ strcmp(name, "AT keyboard") == 0; |
97 |
+*/ |
98 |
+ |
145 |
+ // In some cases,acpibutton can be mistaken for a keyboard and freeze the keyboard when tring grab. |
99 |
+ // In some cases,acpibutton can be mistaken for a keyboard and freeze the keyboard when tring grab. |
146 |
+ if (is_acpibutton) { |
100 |
+ if (is_acpibutton) { |
147 |
+ if (verbose) |
101 |
+ if (verbose) |
148 |
+ printf("Do Not grab acpibutton: %s\n", libevdev_get_name(evdev)); |
102 |
+ printf("Skip acpibutton: %s\n", name); |
149 |
+ is_keyboard = false; |
103 |
+ libevdev_free(evdev); |
|
|
104 |
+ close(fd); |
105 |
+ return; |
150 |
+ } |
106 |
+ } |
151 |
+ // In some cases,tring grab "Logitech USB Receiver Keyboard" will freeze the keyboard. |
107 |
+ // In some cases,Do not grab likekeyboard for avoiding keyboard unresponsive |
152 |
+ if (is_likekeyboard) { |
108 |
+ if (is_likekeyboard) { |
153 |
+ if (verbose) |
109 |
+ if (verbose) |
154 |
+ printf("Do Not grab likekeyboard: %s,version: %d,bustype: %d\n", libevdev_get_name(evdev), libevdev_get_id_version(evdev), libevdev_get_id_bustype(evdev)); |
110 |
+ printf("Do NOT grab like-keyboard: %s,version: %d,bustype: %d\n", name, guid[6], guid[0]); |
155 |
+ is_keyboard = false; |
111 |
+ is_keyboard = false; |
156 |
+ } |
112 |
+ } |
157 |
+ |
113 |
|
158 |
if (is_accelerometer) { |
114 |
if (is_accelerometer) { |
159 |
if (verbose) |
115 |
if (verbose) |
160 |
printf("Ignoring accelerometer: %s\n", name); |
|
|
161 |
@@ -850,6 +922,13 @@ void evdev_create(const char* device, struct mapping* |
162 |
} |
163 |
|
164 |
if (is_gamepad) { |
165 |
+ if (!isNoSdl) { |
166 |
+ if (verbose) |
167 |
+ printf("Gamepad %s ignored,use sdl instead.\n", name); |
168 |
+ libevdev_free(evdev); |
169 |
+ close(fd); |
170 |
+ return; |
171 |
+ } |
172 |
evdev_gamepads++; |
173 |
|
174 |
if (mappings == NULL) { |
175 |
@@ -1054,11 +1133,7 @@ void evdev_start() { |
176 |
// code looks for. For this reason, we wait to grab until |
177 |
// we're ready to take input events. Ctrl+C works up until |
178 |
// this point. |
179 |
- for (int i = 0; i < numDevices; i++) { |
180 |
- if ((devices[i].is_keyboard || devices[i].is_mouse || devices[i].is_touchscreen) && ioctl(devices[i].fd, EVIOCGRAB, 1) < 0) { |
181 |
- fprintf(stderr, "EVIOCGRAB failed with error %d\n", errno); |
182 |
- } |
183 |
- } |
184 |
+ grab_window(true); |
185 |
|
186 |
// Any new input devices detected after this point will be grabbed immediately |
187 |
grabbingDevices = true; |
188 |
@@ -1111,4 +1186,23 @@ void evdev_rumble(unsigned short controller_id, unsign |
189 |
event.value = 1; |
190 |
write(device->fd, (const void*) &event, sizeof(event)); |
191 |
device->haptic_effect_id = effect.id; |
192 |
+} |
193 |
+ |
194 |
+void grab_window(bool grabstat) { |
195 |
+ if (grabstat != iskeyboardgrab) { |
196 |
+ int grabnum; |
197 |
+ if (iskeyboardgrab) { |
198 |
+ grabnum = 0; |
199 |
+ iskeyboardgrab = false; |
200 |
+ } else { |
201 |
+ grabnum = 1; |
202 |
+ iskeyboardgrab = true; |
203 |
+ } |
204 |
+ for (int i = 0; i < numDevices; i++) { |
205 |
+ if (devices[i].is_keyboard || devices[i].is_mouse || devices[i].is_touchscreen) { |
206 |
+ if (ioctl(devices[i].fd, EVIOCGRAB, grabnum) < 0) |
207 |
+ fprintf(stderr, "EVIOCGRAB failed with error %d\n", errno); |
208 |
+ } |
209 |
+ } |
210 |
+ } |
211 |
} |