blob: 8abf0550f6ef70eae1a48f41f8b204a052761bf2 [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <fcntl.h>
20#include <dirent.h>
21#include <sys/poll.h>
22#include <limits.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040023#include <linux/input.h>
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +010024#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
Ethan Yonkerc798c9c2015-10-09 11:15:26 -050027#include <stdio.h>
28#include <string.h>
notsyncingc7c78d22018-06-06 20:26:47 +080029#include <fstream>
Dees_Troy51a0e822012-09-05 15:24:24 -040030
Mohd Farazbc576cd2020-05-30 21:06:32 +053031#ifdef USE_QTI_HAPTICS
32#include <android/hardware/vibrator/1.2/IVibrator.h>
33#endif
34
nebrassy76224bd2021-04-05 11:52:44 +020035#ifdef USE_QTI_AIDL_HAPTICS
36#include <aidl/android/hardware/vibrator/IVibrator.h>
37#include <android/binder_manager.h>
38using ::aidl::android::hardware::vibrator::IVibrator;
39static const std::string kVibratorInstance = std::string(IVibrator::descriptor) + "/default";
40#endif
41
bigbiff1f9e4842020-10-31 11:33:15 -040042#include "common.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040043
bigbiffd81833a2021-01-17 11:06:57 -050044#include "minuitwrp/minui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040045
46//#define _EVENT_LOGGING
47
Dees_Troy3f23d9e2013-05-03 21:04:05 +000048#define MAX_DEVICES 32
Dees_Troy51a0e822012-09-05 15:24:24 -040049
50#define VIBRATOR_TIMEOUT_FILE "/sys/class/timed_output/vibrator/enable"
51#define VIBRATOR_TIME_MS 50
52
notsyncingc7c78d22018-06-06 20:26:47 +080053#define LEDS_HAPTICS_DURATION_FILE "/sys/class/leds/vibrator/duration"
54#define LEDS_HAPTICS_ACTIVATE_FILE "/sys/class/leds/vibrator/activate"
55
Dees_Troyf7596752012-09-28 13:21:36 -040056#ifndef SYN_REPORT
Dees_Troy51a0e822012-09-05 15:24:24 -040057#define SYN_REPORT 0x00
Dees_Troyf7596752012-09-28 13:21:36 -040058#endif
59#ifndef SYN_CONFIG
Dees_Troy51a0e822012-09-05 15:24:24 -040060#define SYN_CONFIG 0x01
Dees_Troyf7596752012-09-28 13:21:36 -040061#endif
62#ifndef SYN_MT_REPORT
Dees_Troy51a0e822012-09-05 15:24:24 -040063#define SYN_MT_REPORT 0x02
Dees_Troyf7596752012-09-28 13:21:36 -040064#endif
Dees_Troy51a0e822012-09-05 15:24:24 -040065
66#define ABS_MT_POSITION 0x2a /* Group a set of X and Y */
67#define ABS_MT_AMPLITUDE 0x2b /* Group a set of Z and W */
68#define ABS_MT_SLOT 0x2f
69#define ABS_MT_TOUCH_MAJOR 0x30
70#define ABS_MT_TOUCH_MINOR 0x31
71#define ABS_MT_WIDTH_MAJOR 0x32
72#define ABS_MT_WIDTH_MINOR 0x33
73#define ABS_MT_ORIENTATION 0x34
74#define ABS_MT_POSITION_X 0x35
75#define ABS_MT_POSITION_Y 0x36
76#define ABS_MT_TOOL_TYPE 0x37
77#define ABS_MT_BLOB_ID 0x38
78#define ABS_MT_TRACKING_ID 0x39
79#define ABS_MT_PRESSURE 0x3a
80#define ABS_MT_DISTANCE 0x3b
81
82enum {
83 DOWN_NOT,
84 DOWN_SENT,
85 DOWN_RELEASED,
86};
87
88struct virtualkey {
89 int scancode;
90 int centerx, centery;
91 int width, height;
92};
93
94struct position {
95 int x, y;
96 int synced;
97 struct input_absinfo xi, yi;
98};
99
100struct ev {
101 struct pollfd *fd;
102
103 struct virtualkey *vks;
104 int vk_count;
105
106 char deviceName[64];
107
108 int ignored;
109
110 struct position p, mt_p;
111 int down;
112};
113
114static struct pollfd ev_fds[MAX_DEVICES];
115static struct ev evs[MAX_DEVICES];
116static unsigned ev_count = 0;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100117static struct timeval lastInputStat;
Ethan Yonker58f21322018-08-24 11:17:36 -0500118static time_t lastInputMTime;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100119static int has_mouse = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400120
121static inline int ABS(int x) {
122 return x<0?-x:x;
123}
124
notsyncingc7c78d22018-06-06 20:26:47 +0800125int write_to_file(const std::string& fn, const std::string& line) {
126 FILE *file;
127 file = fopen(fn.c_str(), "w");
128 if (file != NULL) {
129 fwrite(line.c_str(), line.size(), 1, file);
130 fclose(file);
131 return 0;
132 }
133 LOGI("Cannot find file %s\n", fn.c_str());
134 return -1;
135}
136
bigbiff bigbiff3ed778a2019-03-12 19:28:31 -0400137#ifndef TW_NO_HAPTICS
LameMonster824ef96a62020-06-04 13:31:12 +0200138#ifndef TW_HAPTICS_TSPDRV
Dees_Troy51a0e822012-09-05 15:24:24 -0400139int vibrate(int timeout_ms)
140{
Samer Diab (S.a.M.e.R_d)71e9b042014-01-07 20:18:47 +0000141 if (timeout_ms > 10000) timeout_ms = 1000;
Dees Troy9a4d7402019-03-21 14:17:28 -0400142 char tout[6];
143 sprintf(tout, "%i", timeout_ms);
Samer Diab (S.a.M.e.R_d)71e9b042014-01-07 20:18:47 +0000144
Mohd Farazbc576cd2020-05-30 21:06:32 +0530145#ifdef USE_QTI_HAPTICS
146 android::sp<android::hardware::vibrator::V1_2::IVibrator> vib = android::hardware::vibrator::V1_2::IVibrator::getService();
147 if (vib != nullptr) {
148 vib->on((uint32_t)timeout_ms);
149 }
nebrassy76224bd2021-04-05 11:52:44 +0200150#elif defined(USE_QTI_AIDL_HAPTICS)
151 std::shared_ptr<IVibrator> vib = IVibrator::fromBinder(ndk::SpAIBinder(AServiceManager_getService(kVibratorInstance.c_str())));
152 if (vib != nullptr) {
153 vib->on((uint32_t)timeout_ms, nullptr);
154 }
Mohd Farazbc576cd2020-05-30 21:06:32 +0530155#else
notsyncingc7c78d22018-06-06 20:26:47 +0800156 if (std::ifstream(LEDS_HAPTICS_ACTIVATE_FILE).good()) {
Dees Troy9a4d7402019-03-21 14:17:28 -0400157 write_to_file(LEDS_HAPTICS_DURATION_FILE, tout);
notsyncingc7c78d22018-06-06 20:26:47 +0800158 write_to_file(LEDS_HAPTICS_ACTIVATE_FILE, "1");
159 } else
Dees Troy9a4d7402019-03-21 14:17:28 -0400160 write_to_file(VIBRATOR_TIMEOUT_FILE, tout);
Mohd Farazbc576cd2020-05-30 21:06:32 +0530161#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400162 return 0;
163}
bigbiff bigbiff3ed778a2019-03-12 19:28:31 -0400164#endif
LameMonster824ef96a62020-06-04 13:31:12 +0200165#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400166
167/* Returns empty tokens */
168static char *vk_strtok_r(char *str, const char *delim, char **save_str)
169{
170 if(!str)
171 {
172 if(!*save_str)
173 return NULL;
174
175 str = (*save_str) + 1;
176 }
177 *save_str = strpbrk(str, delim);
178
179 if (*save_str)
180 **save_str = '\0';
181
182 return str;
183}
184
185static int vk_init(struct ev *e)
186{
187 char vk_path[PATH_MAX] = "/sys/board_properties/virtualkeys.";
188 char vks[2048], *ts = NULL;
189 ssize_t len;
190 int vk_fd;
191 int i;
192
193 e->vk_count = 0;
194
195 len = strlen(vk_path);
196 len = ioctl(e->fd->fd, EVIOCGNAME(sizeof(e->deviceName)), e->deviceName);
197 if (len <= 0)
198 {
Matt Mower9b4d8dd2017-02-13 16:10:38 -0600199 LOGE("Unable to query event object.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400200 return -1;
201 }
202#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000203 printf("Event object: %s\n", e->deviceName);
Dees_Troy51a0e822012-09-05 15:24:24 -0400204#endif
205
Flemmardf4674612014-01-10 09:14:44 +0100206#ifdef WHITELIST_INPUT
207 if (strcmp(e->deviceName, EXPAND(WHITELIST_INPUT)) != 0)
208 {
209 e->ignored = 1;
210 }
211#else
Ethan Yonker5742a402014-08-12 14:52:49 -0500212#ifndef TW_INPUT_BLACKLIST
Ethan Yonker64dbd0d2016-08-10 12:30:10 -0500213 // Blacklist these "input" devices, use TW_INPUT_BLACKLIST := "accelerometer\x0atest1\x0atest2" using the \x0a as a separator between input devices
Ethan Yonker3c4ac3b2014-08-14 11:15:32 -0500214 if (strcmp(e->deviceName, "bma250") == 0 || strcmp(e->deviceName, "bma150") == 0)
Dees_Troy51a0e822012-09-05 15:24:24 -0400215 {
Matt Mower9b4d8dd2017-02-13 16:10:38 -0600216 LOGI("Blacklisting input device: %s\n", e->deviceName);
Dees_Troy51a0e822012-09-05 15:24:24 -0400217 e->ignored = 1;
218 }
Ethan Yonker5742a402014-08-12 14:52:49 -0500219#else
220 char* bl = strdup(EXPAND(TW_INPUT_BLACKLIST));
221 char* blacklist = strtok(bl, "\n");
222
223 while (blacklist != NULL) {
224 if (strcmp(e->deviceName, blacklist) == 0) {
Matt Mower9b4d8dd2017-02-13 16:10:38 -0600225 LOGI("Blacklisting input device: %s\n", blacklist);
Ethan Yonker5742a402014-08-12 14:52:49 -0500226 e->ignored = 1;
227 }
228 blacklist = strtok(NULL, "\n");
229 }
230 free(bl);
231#endif
Flemmardf4674612014-01-10 09:14:44 +0100232#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400233
234 strcat(vk_path, e->deviceName);
235
236 // Some devices split the keys from the touchscreen
237 e->vk_count = 0;
238 vk_fd = open(vk_path, O_RDONLY);
239 if (vk_fd >= 0)
240 {
241 len = read(vk_fd, vks, sizeof(vks)-1);
242 close(vk_fd);
243 if (len <= 0)
244 return -1;
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500245
Dees_Troy51a0e822012-09-05 15:24:24 -0400246 vks[len] = '\0';
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500247
Dees_Troy51a0e822012-09-05 15:24:24 -0400248 /* Parse a line like:
249 keytype:keycode:centerx:centery:width:height:keytype2:keycode2:centerx2:...
250 */
251 for (ts = vks, e->vk_count = 1; *ts; ++ts) {
252 if (*ts == ':')
253 ++e->vk_count;
254 }
255
256 if (e->vk_count % 6) {
Matt Mower9b4d8dd2017-02-13 16:10:38 -0600257 LOGI("minui: %s is %d %% 6\n", vk_path, e->vk_count % 6);
Dees_Troy51a0e822012-09-05 15:24:24 -0400258 }
259 e->vk_count /= 6;
260 if (e->vk_count <= 0)
261 return -1;
262
263 e->down = DOWN_NOT;
264 }
265
266 ioctl(e->fd->fd, EVIOCGABS(ABS_X), &e->p.xi);
267 ioctl(e->fd->fd, EVIOCGABS(ABS_Y), &e->p.yi);
268 e->p.synced = 0;
269#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000270 printf("EV: ST minX: %d maxX: %d minY: %d maxY: %d\n", e->p.xi.minimum, e->p.xi.maximum, e->p.yi.minimum, e->p.yi.maximum);
Dees_Troy51a0e822012-09-05 15:24:24 -0400271#endif
272
273 ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_X), &e->mt_p.xi);
274 ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_Y), &e->mt_p.yi);
275 e->mt_p.synced = 0;
276#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000277 printf("EV: MT minX: %d maxX: %d minY: %d maxY: %d\n", e->mt_p.xi.minimum, e->mt_p.xi.maximum, e->mt_p.yi.minimum, e->mt_p.yi.maximum);
Dees_Troy51a0e822012-09-05 15:24:24 -0400278#endif
279
Ethan Yonkerfbb43532015-12-28 21:54:50 +0100280 e->vks = (virtualkey *)malloc(sizeof(*e->vks) * e->vk_count);
Dees_Troy51a0e822012-09-05 15:24:24 -0400281
282 for (i = 0; i < e->vk_count; ++i) {
283 char *token[6];
284 int j;
285
286 for (j = 0; j < 6; ++j) {
287 token[j] = vk_strtok_r((i||j)?NULL:vks, ":", &ts);
288 }
289
290 if (strcmp(token[0], "0x01") != 0) {
291 /* Java does string compare, so we do too. */
Matt Mower9b4d8dd2017-02-13 16:10:38 -0600292 LOGI("minui: %s: ignoring unknown virtual key type %s\n", vk_path, token[0]);
Dees_Troy51a0e822012-09-05 15:24:24 -0400293 continue;
294 }
295
296 e->vks[i].scancode = strtol(token[1], NULL, 0);
297 e->vks[i].centerx = strtol(token[2], NULL, 0);
298 e->vks[i].centery = strtol(token[3], NULL, 0);
299 e->vks[i].width = strtol(token[4], NULL, 0);
300 e->vks[i].height = strtol(token[5], NULL, 0);
301 }
302
303 return 0;
304}
305
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100306#define BITS_PER_LONG (sizeof(long) * 8)
307#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
308#define OFF(x) ((x)%BITS_PER_LONG)
309#define LONG(x) ((x)/BITS_PER_LONG)
310#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
Vojtech Bocek971d3182014-02-20 21:43:28 +0100311
312// Check for EV_REL (REL_X and REL_Y) and, because touchscreens can have those too,
313// check also for EV_KEY (BTN_LEFT and BTN_RIGHT)
Ethan Yonker64dbd0d2016-08-10 12:30:10 -0500314static void check_mouse(int fd, const char* deviceName)
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100315{
316 if(has_mouse)
317 return;
318
319 unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
320 memset(bit, 0, sizeof(bit));
321 ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
322
Vojtech Bocek971d3182014-02-20 21:43:28 +0100323 if(!test_bit(EV_REL, bit[0]) || !test_bit(EV_KEY, bit[0]))
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100324 return;
325
326 ioctl(fd, EVIOCGBIT(EV_REL, KEY_MAX), bit[EV_REL]);
Vojtech Bocek971d3182014-02-20 21:43:28 +0100327 if(!test_bit(REL_X, bit[EV_REL]) || !test_bit(REL_Y, bit[EV_REL]))
328 return;
329
330 ioctl(fd, EVIOCGBIT(EV_KEY, KEY_MAX), bit[EV_KEY]);
331 if(!test_bit(BTN_LEFT, bit[EV_KEY]) || !test_bit(BTN_RIGHT, bit[EV_KEY]))
332 return;
333
Matt Mower9b4d8dd2017-02-13 16:10:38 -0600334 LOGI("Found mouse '%s'\n", deviceName);
Vojtech Bocek971d3182014-02-20 21:43:28 +0100335 has_mouse = 1;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100336}
337
338int ev_has_mouse(void)
339{
340 return has_mouse;
341}
342
Dees_Troy51a0e822012-09-05 15:24:24 -0400343int ev_init(void)
344{
345 DIR *dir;
346 struct dirent *de;
347 int fd;
348
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100349 has_mouse = 0;
350
Dees_Troy51a0e822012-09-05 15:24:24 -0400351 dir = opendir("/dev/input");
352 if(dir != 0) {
353 while((de = readdir(dir))) {
Matt Mower9b4d8dd2017-02-13 16:10:38 -0600354#ifdef _EVENT_LOGGING
355 fprintf(stderr,"/dev/input/%s\n", de->d_name);
356#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400357 if(strncmp(de->d_name,"event",5)) continue;
358 fd = openat(dirfd(dir), de->d_name, O_RDONLY);
359 if(fd < 0) continue;
360
361 ev_fds[ev_count].fd = fd;
362 ev_fds[ev_count].events = POLLIN;
363 evs[ev_count].fd = &ev_fds[ev_count];
364
365 /* Load virtualkeys if there are any */
Ethan Yonker64dbd0d2016-08-10 12:30:10 -0500366 vk_init(&evs[ev_count]);
Dees_Troy51a0e822012-09-05 15:24:24 -0400367
Ethan Yonker64dbd0d2016-08-10 12:30:10 -0500368 if (!evs[ev_count].ignored)
369 check_mouse(fd, evs[ev_count].deviceName);
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100370
Dees_Troy51a0e822012-09-05 15:24:24 -0400371 ev_count++;
372 if(ev_count == MAX_DEVICES) break;
373 }
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100374 closedir(dir);
Dees_Troy51a0e822012-09-05 15:24:24 -0400375 }
376
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100377 struct stat st;
378 if(stat("/dev/input", &st) >= 0)
379 lastInputMTime = st.st_mtime;
380 gettimeofday(&lastInputStat, NULL);
381
Dees_Troy51a0e822012-09-05 15:24:24 -0400382 return 0;
383}
384
385void ev_exit(void)
386{
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100387 while (ev_count-- > 0) {
388 if (evs[ev_count].vk_count) {
389 free(evs[ev_count].vks);
390 evs[ev_count].vk_count = 0;
391 }
392 close(ev_fds[ev_count].fd);
Dees_Troy51a0e822012-09-05 15:24:24 -0400393 }
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100394 ev_count = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400395}
396
Ethan Yonker58f21322018-08-24 11:17:36 -0500397/*static int vk_inside_display(__s32 value, struct input_absinfo *info, int screen_size)
Dees_Troy51a0e822012-09-05 15:24:24 -0400398{
399 int screen_pos;
400
401 if (info->minimum == info->maximum)
402 return 0;
403
404 screen_pos = (value - info->minimum) * (screen_size - 1) / (info->maximum - info->minimum);
405 return (screen_pos >= 0 && screen_pos < screen_size);
Ethan Yonker58f21322018-08-24 11:17:36 -0500406}*/
Dees_Troy51a0e822012-09-05 15:24:24 -0400407
Dees_Troyb7ecc092013-08-24 12:15:41 +0000408static int vk_tp_to_screen(struct position *p, int *x, int *y)
Dees_Troy51a0e822012-09-05 15:24:24 -0400409{
410 if (p->xi.minimum == p->xi.maximum || p->yi.minimum == p->yi.maximum)
411 {
412 // In this case, we assume the screen dimensions are the same.
413 *x = p->x;
414 *y = p->y;
415 return 0;
416 }
417
Dees_Troyb7ecc092013-08-24 12:15:41 +0000418#ifdef _EVENT_LOGGING
419 printf("EV: p->x=%d x-range=%d,%d fb-width=%d\n", p->x, p->xi.minimum, p->xi.maximum, gr_fb_width());
420#endif
421
Dees_Troy51a0e822012-09-05 15:24:24 -0400422#ifndef RECOVERY_TOUCHSCREEN_SWAP_XY
Dees_Troyb7ecc092013-08-24 12:15:41 +0000423 int fb_width = gr_fb_width();
424 int fb_height = gr_fb_height();
Dees_Troy51a0e822012-09-05 15:24:24 -0400425#else
426 // We need to swap the scaling sizes, too
Dees_Troyb7ecc092013-08-24 12:15:41 +0000427 int fb_width = gr_fb_height();
428 int fb_height = gr_fb_width();
Dees_Troy51a0e822012-09-05 15:24:24 -0400429#endif
430
431 *x = (p->x - p->xi.minimum) * (fb_width - 1) / (p->xi.maximum - p->xi.minimum);
432 *y = (p->y - p->yi.minimum) * (fb_height - 1) / (p->yi.maximum - p->yi.minimum);
433
434 if (*x >= 0 && *x < fb_width &&
435 *y >= 0 && *y < fb_height)
436 {
437 return 0;
438 }
439
440 return 1;
441}
442
443/* Translate a virtual key in to a real key event, if needed */
444/* Returns non-zero when the event should be consumed */
Dees_Troyb7ecc092013-08-24 12:15:41 +0000445static int vk_modify(struct ev *e, struct input_event *ev)
Dees_Troy51a0e822012-09-05 15:24:24 -0400446{
447 static int downX = -1, downY = -1;
448 static int discard = 0;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100449 static int last_virt_key = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400450 static int lastWasSynReport = 0;
451 static int touchReleaseOnNextSynReport = 0;
Dees_Troyd86400b2013-05-13 19:04:35 +0000452 static int use_tracking_id_negative_as_touch_release = 0; // On some devices, type: 3 code: 39 value: -1, aka EV_ABS ABS_MT_TRACKING_ID -1 indicates a true touch release
Dees_Troy51a0e822012-09-05 15:24:24 -0400453 int i;
454 int x, y;
455
456 // This is used to ditch useless event handlers, like an accelerometer
457 if (e->ignored) return 1;
458
459 if (ev->type == EV_REL && ev->code == REL_Z)
460 {
461 // This appears to be an accelerometer or another strange input device. It's not the touchscreen.
462#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000463 printf("EV: Device disabled due to non-touchscreen messages.\n");
Dees_Troy51a0e822012-09-05 15:24:24 -0400464#endif
465 e->ignored = 1;
466 return 1;
467 }
468
469#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000470 printf("EV: %s => type: %x code: %x value: %d\n", e->deviceName, ev->type, ev->code, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400471#endif
472
473 // Handle keyboard events, value of 1 indicates key down, 0 indicates key up
474 if (ev->type == EV_KEY) {
475 return 0;
476 }
477
478 if (ev->type == EV_ABS) {
479 switch (ev->code) {
480
481 case ABS_X: //00
482 e->p.synced |= 0x01;
483 e->p.x = ev->value;
484#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000485 printf("EV: %s => EV_ABS ABS_X %d\n", e->deviceName, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400486#endif
487 break;
488
489 case ABS_Y: //01
490 e->p.synced |= 0x02;
491 e->p.y = ev->value;
492#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000493 printf("EV: %s => EV_ABS ABS_Y %d\n", e->deviceName, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400494#endif
495 break;
496
497 case ABS_MT_POSITION: //2a
498 e->mt_p.synced = 0x03;
499 if (ev->value == (1 << 31))
500 {
Ethan Yonker32f68a32014-12-29 08:13:23 -0600501#ifndef TW_IGNORE_MT_POSITION_0
Dees_Troy51a0e822012-09-05 15:24:24 -0400502 e->mt_p.x = 0;
503 e->mt_p.y = 0;
504 lastWasSynReport = 1;
Ethan Yonker32f68a32014-12-29 08:13:23 -0600505#endif
506#ifdef _EVENT_LOGGING
507#ifndef TW_IGNORE_MT_POSITION_0
508 printf("EV: %s => EV_ABS ABS_MT_POSITION %d, set x and y to 0 and lastWasSynReport to 1\n", e->deviceName, ev->value);
509#else
510 printf("Ignoring ABS_MT_POSITION 0\n", e->deviceName, ev->value);
511#endif
512#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400513 }
514 else
515 {
516 lastWasSynReport = 0;
517 e->mt_p.x = (ev->value & 0x7FFF0000) >> 16;
518 e->mt_p.y = (ev->value & 0xFFFF);
Ethan Yonker32f68a32014-12-29 08:13:23 -0600519#ifdef _EVENT_LOGGING
520 printf("EV: %s => EV_ABS ABS_MT_POSITION %d, set x: %d and y: %d and lastWasSynReport to 0\n", e->deviceName, ev->value, (ev->value & 0x7FFF0000) >> 16, (ev->value & 0xFFFF));
521#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400522 }
523 break;
524
525 case ABS_MT_TOUCH_MAJOR: //30
526 if (ev->value == 0)
527 {
Ibrahim Awwal2e9cb012014-01-04 12:38:26 -0800528#ifndef TW_IGNORE_MAJOR_AXIS_0
Dees_Troy51a0e822012-09-05 15:24:24 -0400529 // We're in a touch release, although some devices will still send positions as well
530 e->mt_p.x = 0;
531 e->mt_p.y = 0;
532 touchReleaseOnNextSynReport = 1;
Ibrahim Awwal2e9cb012014-01-04 12:38:26 -0800533#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400534 }
535#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000536 printf("EV: %s => EV_ABS ABS_MT_TOUCH_MAJOR %d\n", e->deviceName, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400537#endif
538 break;
539
540 case ABS_MT_PRESSURE: //3a
541 if (ev->value == 0)
542 {
543 // We're in a touch release, although some devices will still send positions as well
544 e->mt_p.x = 0;
545 e->mt_p.y = 0;
546 touchReleaseOnNextSynReport = 1;
547 }
548#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000549 printf("EV: %s => EV_ABS ABS_MT_PRESSURE %d\n", e->deviceName, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400550#endif
551 break;
552
553 case ABS_MT_POSITION_X: //35
554 e->mt_p.synced |= 0x01;
555 e->mt_p.x = ev->value;
556#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000557 printf("EV: %s => EV_ABS ABS_MT_POSITION_X %d\n", e->deviceName, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400558#endif
559 break;
560
561 case ABS_MT_POSITION_Y: //36
562 e->mt_p.synced |= 0x02;
563 e->mt_p.y = ev->value;
564#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000565 printf("EV: %s => EV_ABS ABS_MT_POSITION_Y %d\n", e->deviceName, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400566#endif
567 break;
568
Dees_Troy51a0e822012-09-05 15:24:24 -0400569 case ABS_MT_TOUCH_MINOR: //31
Dees_Troyd86400b2013-05-13 19:04:35 +0000570#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000571 printf("EV: %s => EV_ABS ABS_MT_TOUCH_MINOR %d\n", e->deviceName, ev->value);
Dees_Troyd86400b2013-05-13 19:04:35 +0000572#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400573 break;
574
575 case ABS_MT_WIDTH_MAJOR: //32
Dees_Troyd86400b2013-05-13 19:04:35 +0000576#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000577 printf("EV: %s => EV_ABS ABS_MT_WIDTH_MAJOR %d\n", e->deviceName, ev->value);
Dees_Troyd86400b2013-05-13 19:04:35 +0000578#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400579 break;
580
581 case ABS_MT_WIDTH_MINOR: //33
Dees_Troyd86400b2013-05-13 19:04:35 +0000582#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000583 printf("EV: %s => EV_ABS ABS_MT_WIDTH_MINOR %d\n", e->deviceName, ev->value);
Dees_Troyd86400b2013-05-13 19:04:35 +0000584#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400585 break;
586
Dees_Troyd86400b2013-05-13 19:04:35 +0000587 case ABS_MT_TRACKING_ID: //39
Ethan Yonkerd6821a12015-08-26 15:29:23 -0500588#ifdef TW_IGNORE_ABS_MT_TRACKING_ID
589#ifdef _EVENT_LOGGING
590 printf("EV: %s => EV_ABS ABS_MT_TRACKING_ID %d ignored\n", e->deviceName, ev->value);
591#endif
592 return 1;
593#endif
Dees_Troyd86400b2013-05-13 19:04:35 +0000594 if (ev->value < 0) {
595 e->mt_p.x = 0;
596 e->mt_p.y = 0;
597 touchReleaseOnNextSynReport = 2;
598 use_tracking_id_negative_as_touch_release = 1;
599#ifdef _EVENT_LOGGING
600 if (use_tracking_id_negative_as_touch_release)
601 printf("using ABS_MT_TRACKING_ID value -1 to indicate touch releases\n");
602#endif
603 }
604#ifdef _EVENT_LOGGING
605 printf("EV: %s => EV_ABS ABS_MT_TRACKING_ID %d\n", e->deviceName, ev->value);
606#endif
607 break;
608
609#ifdef _EVENT_LOGGING
610 // These are for touch logging purposes only
Dees_Troy51a0e822012-09-05 15:24:24 -0400611 case ABS_MT_ORIENTATION: //34
Dees_Troy2673cec2013-04-02 20:22:16 +0000612 printf("EV: %s => EV_ABS ABS_MT_ORIENTATION %d\n", e->deviceName, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400613 return 1;
614 break;
615
616 case ABS_MT_TOOL_TYPE: //37
617 LOGI("EV: %s => EV_ABS ABS_MT_TOOL_TYPE %d\n", e->deviceName, ev->value);
618 return 1;
619 break;
620
621 case ABS_MT_BLOB_ID: //38
Dees_Troy2673cec2013-04-02 20:22:16 +0000622 printf("EV: %s => EV_ABS ABS_MT_BLOB_ID %d\n", e->deviceName, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400623 return 1;
624 break;
625
Dees_Troy51a0e822012-09-05 15:24:24 -0400626 case ABS_MT_DISTANCE: //3b
Dees_Troy2673cec2013-04-02 20:22:16 +0000627 printf("EV: %s => EV_ABS ABS_MT_DISTANCE %d\n", e->deviceName, ev->value);
Dees_Troy51a0e822012-09-05 15:24:24 -0400628 return 1;
629 break;
Ethan Yonkerd6821a12015-08-26 15:29:23 -0500630 case ABS_MT_SLOT:
631 printf("EV: %s => ABS_MT_SLOT %d\n", e->deviceName, ev->value);
632 return 1;
633 break;
Dees_Troy51a0e822012-09-05 15:24:24 -0400634#endif
635
636 default:
637 // This is an unhandled message, just skip it
638 return 1;
639 }
640
641 if (ev->code != ABS_MT_POSITION)
642 {
643 lastWasSynReport = 0;
644 return 1;
645 }
646 }
647
648 // Check if we should ignore the message
649 if (ev->code != ABS_MT_POSITION && (ev->type != EV_SYN || (ev->code != SYN_REPORT && ev->code != SYN_MT_REPORT)))
650 {
651 lastWasSynReport = 0;
652 return 0;
653 }
654
655#ifdef _EVENT_LOGGING
Matt Mower9b4d8dd2017-02-13 16:10:38 -0600656 if (ev->type == EV_SYN && ev->code == SYN_REPORT)
657 printf("EV: %s => EV_SYN SYN_REPORT\n", e->deviceName);
658 if (ev->type == EV_SYN && ev->code == SYN_MT_REPORT)
659 printf("EV: %s => EV_SYN SYN_MT_REPORT\n", e->deviceName);
Dees_Troy51a0e822012-09-05 15:24:24 -0400660#endif
661
662 // Discard the MT versions
663 if (ev->code == SYN_MT_REPORT) return 0;
664
Dees_Troyd86400b2013-05-13 19:04:35 +0000665 if (((lastWasSynReport == 1 || touchReleaseOnNextSynReport == 1) && !use_tracking_id_negative_as_touch_release) || (use_tracking_id_negative_as_touch_release && touchReleaseOnNextSynReport == 2))
Dees_Troy51a0e822012-09-05 15:24:24 -0400666 {
667 // Reset the value
668 touchReleaseOnNextSynReport = 0;
669
670 // We are a finger-up state
671 if (!discard)
672 {
673 // Report the key up
674 ev->type = EV_ABS;
675 ev->code = 0;
676 ev->value = (downX << 16) | downY;
677 }
678 downX = -1;
679 downY = -1;
680 if (discard)
681 {
682 discard = 0;
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100683
684 // Send the keyUp event
685 ev->type = EV_KEY;
686 ev->code = last_virt_key;
687 ev->value = 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400688 }
689 return 0;
690 }
691 lastWasSynReport = 1;
692
693 // Retrieve where the x,y position is
694 if (e->p.synced & 0x03)
695 {
Dees_Troyb7ecc092013-08-24 12:15:41 +0000696 vk_tp_to_screen(&e->p, &x, &y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400697 }
698 else if (e->mt_p.synced & 0x03)
699 {
Dees_Troyb7ecc092013-08-24 12:15:41 +0000700 vk_tp_to_screen(&e->mt_p, &x, &y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400701 }
702 else
703 {
704 // We don't have useful information to convey
705 return 1;
706 }
707
708#ifdef RECOVERY_TOUCHSCREEN_SWAP_XY
709 x ^= y;
710 y ^= x;
711 x ^= y;
712#endif
713#ifdef RECOVERY_TOUCHSCREEN_FLIP_X
Dees_Troyb7ecc092013-08-24 12:15:41 +0000714 x = gr_fb_width() - x;
Dees_Troy51a0e822012-09-05 15:24:24 -0400715#endif
716#ifdef RECOVERY_TOUCHSCREEN_FLIP_Y
Dees_Troyb7ecc092013-08-24 12:15:41 +0000717 y = gr_fb_height() - y;
Dees_Troy51a0e822012-09-05 15:24:24 -0400718#endif
719
720#ifdef _EVENT_LOGGING
Dees_Troy2673cec2013-04-02 20:22:16 +0000721 printf("EV: x: %d y: %d\n", x, y);
Dees_Troy51a0e822012-09-05 15:24:24 -0400722#endif
723
724 // Clear the current sync states
725 e->p.synced = e->mt_p.synced = 0;
726
727 // If we have nothing useful to report, skip it
728 if (x == -1 || y == -1) return 1;
729
Ethan Yonker96bc6dd2015-03-18 11:44:34 -0500730 // Special case, we'll ignore touches on 0,0 because it usually means
731 // that we received extra data after our last sync and x and y were
732 // reset to 0. We should not be using 0,0 anyway.
733 if (x == 0 && y == 0)
734 return 1;
735
Dees_Troy51a0e822012-09-05 15:24:24 -0400736 // On first touch, see if we're at a virtual key
737 if (downX == -1)
738 {
739 // Attempt mapping to virtual key
740 for (i = 0; i < e->vk_count; ++i)
741 {
742 int xd = ABS(e->vks[i].centerx - x);
743 int yd = ABS(e->vks[i].centery - y);
744
745 if (xd < e->vks[i].width/2 && yd < e->vks[i].height/2)
746 {
747 ev->type = EV_KEY;
748 ev->code = e->vks[i].scancode;
749 ev->value = 1;
750
Vojtech Bocek0b7fe502014-03-13 17:36:52 +0100751 last_virt_key = e->vks[i].scancode;
752
bigbiff bigbiff3ed778a2019-03-12 19:28:31 -0400753#ifndef TW_NO_HAPTICS
Dees_Troy51a0e822012-09-05 15:24:24 -0400754 vibrate(VIBRATOR_TIME_MS);
bigbiff bigbiff3ed778a2019-03-12 19:28:31 -0400755#endif
Dees_Troy51a0e822012-09-05 15:24:24 -0400756
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500757 // Mark that all further movement until lift is discard,
Dees_Troy51a0e822012-09-05 15:24:24 -0400758 // and make sure we don't come back into this area
759 discard = 1;
760 downX = 0;
761 return 0;
762 }
763 }
764 }
765
766 // If we were originally a button press, discard this event
767 if (discard)
768 {
769 return 1;
770 }
771
772 // Record where we started the touch for deciding if this is a key or a scroll
773 downX = x;
774 downY = y;
775
776 ev->type = EV_ABS;
777 ev->code = 1;
778 ev->value = (x << 16) | y;
779 return 0;
780}
781
thatde72b6d2015-02-08 08:55:00 +0100782int ev_get(struct input_event *ev, int timeout_ms)
Dees_Troy51a0e822012-09-05 15:24:24 -0400783{
784 int r;
785 unsigned n;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100786 struct timeval curr;
Dees_Troy51a0e822012-09-05 15:24:24 -0400787
Ethan Yonkere13fa632015-01-27 11:30:03 -0600788 gettimeofday(&curr, NULL);
789 if(curr.tv_sec - lastInputStat.tv_sec >= 2)
790 {
791 struct stat st;
792 stat("/dev/input", &st);
793 if (st.st_mtime > lastInputMTime)
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100794 {
Matt Mower9b4d8dd2017-02-13 16:10:38 -0600795 LOGI("Reloading input devices\n");
Ethan Yonkere13fa632015-01-27 11:30:03 -0600796 ev_exit();
797 ev_init();
798 lastInputMTime = st.st_mtime;
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100799 }
Ethan Yonkere13fa632015-01-27 11:30:03 -0600800 lastInputStat = curr;
801 }
Vojtech Bocek1fc30fc2014-01-29 18:37:19 +0100802
thatde72b6d2015-02-08 08:55:00 +0100803 r = poll(ev_fds, ev_count, timeout_ms);
Dees_Troy51a0e822012-09-05 15:24:24 -0400804
Ethan Yonkere13fa632015-01-27 11:30:03 -0600805 if(r > 0) {
806 for(n = 0; n < ev_count; n++) {
807 if(ev_fds[n].revents & POLLIN) {
808 r = read(ev_fds[n].fd, ev, sizeof(*ev));
809 if(r == sizeof(*ev)) {
810 if (!vk_modify(&evs[n], ev))
811 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -0400812 }
813 }
814 }
thatc5837f32015-02-01 01:59:43 +0100815 return -1;
Ethan Yonkere13fa632015-01-27 11:30:03 -0600816 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400817
thatc5837f32015-02-01 01:59:43 +0100818 return -2;
Dees_Troy51a0e822012-09-05 15:24:24 -0400819}
820
Ethan Yonker58f21322018-08-24 11:17:36 -0500821int ev_wait(int timeout __unused)
Dees_Troy51a0e822012-09-05 15:24:24 -0400822{
823 return -1;
824}
825
826void ev_dispatch(void)
827{
828 return;
829}
830
Ethan Yonker58f21322018-08-24 11:17:36 -0500831int ev_get_input(int fd __unused, short revents __unused, struct input_event *ev __unused)
Dees_Troy51a0e822012-09-05 15:24:24 -0400832{
833 return -1;
834}