1 /*
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 <string.h>
20 #include <fcntl.h>
21 #include <dirent.h>
22 #include <sys/epoll.h>
23 #include <unistd.h>
24
25 #include <linux/input.h>
26
27 #include "minui.h"
28
29 #include <sys/poll.h>
30 #include "../common.h"
31
32
33 #define MAX_DEVICES 16
34 #define MAX_MISC_FDS 16
35
36 #define BITS_PER_LONG (sizeof(unsigned long) * 8)
37 #define BITS_TO_LONGS(x) (((x) + BITS_PER_LONG - 1) / BITS_PER_LONG)
38
39 #define test_bit(bit, array) \
40 ((array)[(bit)/BITS_PER_LONG] & (1 << ((bit) % BITS_PER_LONG)))
41
42 struct fd_info {
43 int fd;
44 ev_callback cb;
45 void *data;
46 };
47
48 static int epollfd;
49 static struct epoll_event polledevents[MAX_DEVICES + MAX_MISC_FDS];
50 static int npolledevents;
51
52 static struct fd_info ev_fdinfo[MAX_DEVICES + MAX_MISC_FDS];
53
54 static unsigned ev_count = 0;
55 static unsigned ev_dev_count = 0;
56 static unsigned ev_misc_count = 0;
57
58 ///////////////////////////////////////////////////////////////////////////////
59 // add for tp
60 //#define _EVENT_LOGGING 0
61
62 #define VIBRATOR_TIMEOUT_FILE "/sys/class/timed_output/vibrator/enable"
63 #define VIBRATOR_TIME_MS 50
64
65 #define SYN_REPORT 0x00
66 #define SYN_CONFIG 0x01
67 #define SYN_MT_REPORT 0x02
68
69 #define ABS_MT_POSITION 0x2a /* Group a set of X and Y */
70 #define ABS_MT_AMPLITUDE 0x2b /* Group a set of Z and W */
71 #define ABS_MT_SLOT 0x2f
72 #define ABS_MT_TOUCH_MAJOR 0x30
73 #define ABS_MT_TOUCH_MINOR 0x31
74 #define ABS_MT_WIDTH_MAJOR 0x32
75 #define ABS_MT_WIDTH_MINOR 0x33
76 #define ABS_MT_ORIENTATION 0x34
77 #define ABS_MT_POSITION_X 0x35
78 #define ABS_MT_POSITION_Y 0x36
79 #define ABS_MT_TOOL_TYPE 0x37
80 #define ABS_MT_BLOB_ID 0x38
81 #define ABS_MT_TRACKING_ID 0x39
82 #define ABS_MT_PRESSURE 0x3a
83 #define ABS_MT_DISTANCE 0x3b
84
85 enum {
86 DOWN_NOT,
87 DOWN_SENT,
88 DOWN_RELEASED,
89 };
90
91 struct virtualkey {
92 int scancode;
93 int centerx, centery;
94 int width, height;
95 };
96
97 struct position {
98 int x, y;
99 int synced;
100 struct input_absinfo xi, yi;
101 };
102
103 struct ev {
104 struct pollfd *fd;
105
106 struct virtualkey *vks;
107 int vk_count;
108
109 char deviceName[64];
110
111 int ignored;
112
113 struct position p, mt_p;
114 int down;
115 };
116 static struct pollfd ev_fds[MAX_DEVICES];
117 static struct ev evs[MAX_DEVICES];
118
ABS(int x)119 static inline int ABS(int x) {
120 return x<0?-x:x;
121 }
122
vibrate(int timeout_ms)123 int vibrate(int timeout_ms)
124 {
125 char str[20];
126 int fd;
127 int ret;
128
129 fd = open(VIBRATOR_TIMEOUT_FILE, O_WRONLY);
130 if (fd < 0)
131 return -1;
132
133 ret = snprintf(str, sizeof(str), "%d", timeout_ms);
134 ret = write(fd, str, ret);
135 close(fd);
136
137 if (ret < 0)
138 return -1;
139
140 return 0;
141 }
142
143 /* Returns empty tokens */
vk_strtok_r(char * str,const char * delim,char ** save_str)144 static char *vk_strtok_r(char *str, const char *delim, char **save_str)
145 {
146 if(!str)
147 {
148 if(!*save_str)
149 return NULL;
150
151 str = (*save_str) + 1;
152 }
153 *save_str = strpbrk(str, delim);
154
155 if (*save_str)
156 **save_str = '\0';
157
158 return str;
159 }
160
vk_init(struct ev * e)161 static int vk_init(struct ev *e)
162 {
163 char vk_path[PATH_MAX] = "/sys/board_properties/virtualkeys.";
164 char vks[2048], *ts = NULL;
165 ssize_t len;
166 int vk_fd;
167 int i;
168
169 e->vk_count = 0;
170
171 len = strlen(vk_path);
172 len = ioctl(e->fd->fd, EVIOCGNAME(sizeof(e->deviceName)), e->deviceName);
173 if (len <= 0)
174 {
175 LOGE("Unable to query event object.\n");
176 return -1;
177 }
178 #ifdef _EVENT_LOGGING
179 LOGI("Event object: %s\n", e->deviceName);
180 #endif
181
182 // Blacklist these "input" devices
183 if (strcmp(e->deviceName, "bma250") == 0)
184 {
185 e->ignored = 1;
186 }
187
188 strcat(vk_path, e->deviceName);
189
190 // Some devices split the keys from the touchscreen
191 e->vk_count = 0;
192 vk_fd = open(vk_path, O_RDONLY);
193 if (vk_fd >= 0)
194 {
195 len = read(vk_fd, vks, sizeof(vks)-1);
196 close(vk_fd);
197 if (len <= 0)
198 return -1;
199
200 vks[len] = '\0';
201
202 /* Parse a line like:
203 keytype:keycode:centerx:centery:width:height:keytype2:keycode2:centerx2:...
204 */
205 for (ts = vks, e->vk_count = 1; *ts; ++ts) {
206 if (*ts == ':')
207 ++e->vk_count;
208 }
209
210 if (e->vk_count % 6) {
211 LOGW("minui: %s is %d %% 6\n", vk_path, e->vk_count % 6);
212 }
213 e->vk_count /= 6;
214 if (e->vk_count <= 0)
215 return -1;
216
217 e->down = DOWN_NOT;
218 }
219
220 ioctl(e->fd->fd, EVIOCGABS(ABS_X), &e->p.xi);
221 ioctl(e->fd->fd, EVIOCGABS(ABS_Y), &e->p.yi);
222 e->p.synced = 0;
223 #ifdef _EVENT_LOGGING
224 LOGI("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);
225 #endif
226
227 ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_X), &e->mt_p.xi);
228 ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_Y), &e->mt_p.yi);
229 e->mt_p.synced = 0;
230 #ifdef _EVENT_LOGGING
231 LOGI("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);
232 #endif
233
234 e->vks = malloc(sizeof(*e->vks) * e->vk_count);
235
236 for (i = 0; i < e->vk_count; ++i) {
237 char *token[6];
238 int j;
239
240 for (j = 0; j < 6; ++j) {
241 token[j] = vk_strtok_r((i||j)?NULL:vks, ":", &ts);
242 }
243
244 if (strcmp(token[0], "0x01") != 0) {
245 /* Java does string compare, so we do too. */
246 LOGW("minui: %s: ignoring unknown virtual key type %s\n", vk_path, token[0]);
247 continue;
248 }
249
250 e->vks[i].scancode = strtol(token[1], NULL, 0);
251 e->vks[i].centerx = strtol(token[2], NULL, 0);
252 e->vks[i].centery = strtol(token[3], NULL, 0);
253 e->vks[i].width = strtol(token[4], NULL, 0);
254 e->vks[i].height = strtol(token[5], NULL, 0);
255 }
256
257 return 0;
258 }
259
260 ///////////////////////////////////////////////////////////////////////////////
261 // Add for tp
262 //
ev_init(void)263 int ev_init(void)
264 {
265 DIR *dir;
266 struct dirent *de;
267 int fd;
268 char name[80];
269 dir = opendir("/dev/input");
270 if(dir != 0) {
271 while((de = readdir(dir))) {
272 // fprintf(stderr,"/dev/input/%s\n", de->d_name);
273 if(strncmp(de->d_name,"event",5))
274 continue;
275 fd = openat(dirfd(dir), de->d_name, O_RDONLY);
276 if(fd < 0) continue;
277 else
278 {
279 if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1)
280 {
281 name[0] = '\0';
282 }
283 if (!strcmp(name, "gsensor")) //do not open gsensor here
284 continue;
285 LOGI("open %s\n",de->d_name);
286 }
287 ev_fds[ev_count].fd = fd;
288 ev_fds[ev_count].events = POLLIN;
289 evs[ev_count].fd = &ev_fds[ev_count];
290
291 /* Load virtualkeys if there are any */
292 vk_init(&evs[ev_count]);
293
294 ev_count++;
295 if(ev_count == MAX_DEVICES) break;
296 }
297 }
298
299 return 0;
300 }
301
ev_exit(void)302 void ev_exit(void)
303 {
304 while (ev_count-- > 0) {
305 if (evs[ev_count].vk_count) {
306 free(evs[ev_count].vks);
307 evs[ev_count].vk_count = 0;
308 }
309 close(ev_fds[ev_count].fd);
310 }
311 }
312
vk_inside_display(__s32 value,struct input_absinfo * info,int screen_size)313 static int vk_inside_display(__s32 value, struct input_absinfo *info, int screen_size)
314 {
315 int screen_pos;
316
317 if (info->minimum == info->maximum)
318 return 0;
319
320 screen_pos = (value - info->minimum) * (screen_size - 1) / (info->maximum - info->minimum);
321 return (screen_pos >= 0 && screen_pos < screen_size);
322 }
323
vk_tp_to_screen(struct position * p,int * x,int * y)324 static int vk_tp_to_screen(struct position *p, int *x, int *y)
325 {
326 if (p->xi.minimum == p->xi.maximum || p->yi.minimum == p->yi.maximum)
327 {
328 // In this case, we assume the screen dimensions are the same.
329 *x = p->x;
330 *y = p->y;
331 return 0;
332 }
333
334 #ifdef _EVENT_LOGGING
335 LOGI("EV: p->x=%d x-range=%d,%d fb-width=%d\n", p->x, p->xi.minimum, p->xi.maximum, gr_fb_width());
336 #endif
337
338 #ifndef RECOVERY_TOUCHSCREEN_SWAP_XY
339 int fb_width = gr_fb_width();
340 int fb_height = gr_fb_height();
341 #else
342 // We need to swap the scaling sizes, too
343 int fb_width = gr_fb_height();
344 int fb_height = gr_fb_width();
345 #endif
346
347 *x = (p->x - p->xi.minimum) * (fb_width - 1) / (p->xi.maximum - p->xi.minimum);
348 *y = (p->y - p->yi.minimum) * (fb_height - 1) / (p->yi.maximum - p->yi.minimum);
349
350 if (*x >= 0 && *x < fb_width &&
351 *y >= 0 && *y < fb_height)
352 {
353 return 0;
354 }
355
356 return 1;
357 }
358
359 /* Translate a virtual key in to a real key event, if needed */
360 /* Returns non-zero when the event should be consumed */
vk_modify(struct ev * e,struct input_event * ev)361 static int vk_modify(struct ev *e, struct input_event *ev)
362 {
363 static int downX = -1, downY = -1;
364 static int discard = 0;
365 static int lastWasSynReport = 0;
366 static int touchReleaseOnNextSynReport = 0;
367 int i;
368 int x, y;
369
370 // This is used to ditch useless event handlers, like an accelerometer
371 if (e->ignored) return 1;
372
373 if (ev->type == EV_REL && ev->code == REL_Z)
374 {
375 // This appears to be an accelerometer or another strange input device. It's not the touchscreen.
376 #ifdef _EVENT_LOGGING
377 LOGI("EV: Device disabled due to non-touchscreen messages.\n");
378 #endif
379 e->ignored = 1;
380 return 1;
381 }
382
383 #ifdef _EVENT_LOGGING
384 LOGI("EV: %s => type: %x code: %x value: %d\n", e->deviceName, ev->type, ev->code, ev->value);
385 #endif
386
387 // Handle keyboard events, value of 1 indicates key down, 0 indicates key up
388 if (ev->type == EV_KEY) {
389 return 0;
390 }
391
392 if (ev->type == EV_ABS) {
393 switch (ev->code) {
394
395 case ABS_X: //00
396 e->p.synced |= 0x01;
397 e->p.x = ev->value;
398 #ifdef _EVENT_LOGGING
399 LOGI("EV: %s => EV_ABS ABS_X %d\n", e->deviceName, ev->value);
400 #endif
401 break;
402
403 case ABS_Y: //01
404 e->p.synced |= 0x02;
405 e->p.y = ev->value;
406 #ifdef _EVENT_LOGGING
407 LOGI("EV: %s => EV_ABS ABS_Y %d\n", e->deviceName, ev->value);
408 #endif
409 break;
410
411 case ABS_MT_POSITION: //2a
412 e->mt_p.synced = 0x03;
413 if (ev->value == (1 << 31))
414 {
415 e->mt_p.x = 0;
416 e->mt_p.y = 0;
417 lastWasSynReport = 1;
418 }
419 else
420 {
421 lastWasSynReport = 0;
422 e->mt_p.x = (ev->value & 0x7FFF0000) >> 16;
423 e->mt_p.y = (ev->value & 0xFFFF);
424 }
425 break;
426
427 case ABS_MT_TOUCH_MAJOR: //30
428 if (ev->value == 0)
429 {
430 // We're in a touch release, although some devices will still send positions as well
431 e->mt_p.x = 0;
432 e->mt_p.y = 0;
433 touchReleaseOnNextSynReport = 1;
434 }
435 #ifdef _EVENT_LOGGING
436 LOGI("EV: %s => EV_ABS ABS_MT_TOUCH_MAJOR %d\n", e->deviceName, ev->value);
437 #endif
438 break;
439
440 case ABS_MT_PRESSURE: //3a
441 if (ev->value == 0)
442 {
443 // We're in a touch release, although some devices will still send positions as well
444 e->mt_p.x = 0;
445 e->mt_p.y = 0;
446 touchReleaseOnNextSynReport = 1;
447 }
448 #ifdef _EVENT_LOGGING
449 LOGI("EV: %s => EV_ABS ABS_MT_PRESSURE %d\n", e->deviceName, ev->value);
450 #endif
451 break;
452
453 case ABS_MT_POSITION_X: //35
454 e->mt_p.synced |= 0x01;
455 e->mt_p.x = ev->value;
456 #ifdef _EVENT_LOGGING
457 LOGI("EV: %s => EV_ABS ABS_MT_POSITION_X %d\n", e->deviceName, ev->value);
458 #endif
459 break;
460
461 case ABS_MT_POSITION_Y: //36
462 e->mt_p.synced |= 0x02;
463 e->mt_p.y = ev->value;
464 #ifdef _EVENT_LOGGING
465 LOGI("EV: %s => EV_ABS ABS_MT_POSITION_Y %d\n", e->deviceName, ev->value);
466 #endif
467 break;
468
469 #ifdef _EVENT_LOGGING
470 // All of these items are strictly for logging purposes only. Return 1 because they don't need to be handled.
471 case ABS_MT_TOUCH_MINOR: //31
472 LOGI("EV: %s => EV_ABS ABS_MT_TOUCH_MINOR %d\n", e->deviceName, ev->value);
473 return 1;
474 break;
475
476 case ABS_MT_WIDTH_MAJOR: //32
477 LOGI("EV: %s => EV_ABS ABS_MT_WIDTH_MAJOR %d\n", e->deviceName, ev->value);
478 return 1;
479 break;
480
481 case ABS_MT_WIDTH_MINOR: //33
482 LOGI("EV: %s => EV_ABS ABS_MT_WIDTH_MINOR %d\n", e->deviceName, ev->value);
483 return 1;
484 break;
485
486 case ABS_MT_ORIENTATION: //34
487 LOGI("EV: %s => EV_ABS ABS_MT_ORIENTATION %d\n", e->deviceName, ev->value);
488 return 1;
489 break;
490
491 case ABS_MT_TOOL_TYPE: //37
492 LOGI("EV: %s => EV_ABS ABS_MT_TOOL_TYPE %d\n", e->deviceName, ev->value);
493 return 1;
494 break;
495
496 case ABS_MT_BLOB_ID: //38
497 LOGI("EV: %s => EV_ABS ABS_MT_BLOB_ID %d\n", e->deviceName, ev->value);
498 return 1;
499 break;
500
501 case ABS_MT_TRACKING_ID: //39
502 LOGI("EV: %s => EV_ABS ABS_MT_TRACKING_ID %d\n", e->deviceName, ev->value);
503 return 1;
504 break;
505
506 case ABS_MT_DISTANCE: //3b
507 LOGI("EV: %s => EV_ABS ABS_MT_DISTANCE %d\n", e->deviceName, ev->value);
508 return 1;
509 break;
510 #endif
511
512 default:
513 // This is an unhandled message, just skip it
514 return 1;
515 }
516
517 if (ev->code != ABS_MT_POSITION)
518 {
519 lastWasSynReport = 0;
520 return 1;
521 }
522 }
523
524 // Check if we should ignore the message
525 if (ev->code != ABS_MT_POSITION && (ev->type != EV_SYN || (ev->code != SYN_REPORT && ev->code != SYN_MT_REPORT)))
526 {
527 lastWasSynReport = 0;
528 return 0;
529 }
530
531 #ifdef _EVENT_LOGGING
532 if (ev->type == EV_SYN && ev->code == SYN_REPORT) LOGI("EV: %s => EV_SYN SYN_REPORT\n", e->deviceName);
533 if (ev->type == EV_SYN && ev->code == SYN_MT_REPORT) LOGI("EV: %s => EV_SYN SYN_MT_REPORT\n", e->deviceName);
534 #endif
535
536 // Discard the MT versions
537 if (ev->code == SYN_MT_REPORT) return 0;
538
539 if (lastWasSynReport == 1 || touchReleaseOnNextSynReport == 1)
540 {
541 // Reset the value
542 touchReleaseOnNextSynReport = 0;
543
544 // We are a finger-up state
545 if (!discard)
546 {
547 // Report the key up
548 ev->type = EV_ABS;
549 ev->code = 0;
550 ev->value = (downX << 16) | downY;
551 }
552 downX = -1;
553 downY = -1;
554 if (discard)
555 {
556 discard = 0;
557 return 1;
558 }
559 return 0;
560 }
561 lastWasSynReport = 1;
562
563 // Retrieve where the x,y position is
564 if (e->p.synced & 0x03)
565 {
566 vk_tp_to_screen(&e->p, &x, &y);
567 }
568 else if (e->mt_p.synced & 0x03)
569 {
570 vk_tp_to_screen(&e->mt_p, &x, &y);
571 }
572 else
573 {
574 // We don't have useful information to convey
575 return 1;
576 }
577
578 #ifdef RECOVERY_TOUCHSCREEN_SWAP_XY
579 x ^= y;
580 y ^= x;
581 x ^= y;
582 #endif
583 #ifdef RECOVERY_TOUCHSCREEN_FLIP_X
584 x = gr_fb_width() - x;
585 #endif
586 #ifdef RECOVERY_TOUCHSCREEN_FLIP_Y
587 y = gr_fb_height() - y;
588 #endif
589
590 #ifdef _EVENT_LOGGING
591 LOGI("EV: x: %d y: %d\n", x, y);
592 #endif
593
594 // Clear the current sync states
595 e->p.synced = e->mt_p.synced = 0;
596
597 // If we have nothing useful to report, skip it
598 if (x == -1 || y == -1) return 1;
599
600 // On first touch, see if we're at a virtual key
601 if (downX == -1)
602 {
603 // Attempt mapping to virtual key
604 for (i = 0; i < e->vk_count; ++i)
605 {
606 int xd = ABS(e->vks[i].centerx - x);
607 int yd = ABS(e->vks[i].centery - y);
608
609 if (xd < e->vks[i].width/2 && yd < e->vks[i].height/2)
610 {
611 ev->type = EV_KEY;
612 ev->code = e->vks[i].scancode;
613 ev->value = 1;
614
615 vibrate(VIBRATOR_TIME_MS);
616
617 // Mark that all further movement until lift is discard,
618 // and make sure we don't come back into this area
619 discard = 1;
620 downX = 0;
621 return 0;
622 }
623 }
624 }
625
626 // If we were originally a button press, discard this event
627 if (discard)
628 {
629 return 1;
630 }
631
632 // Record where we started the touch for deciding if this is a key or a scroll
633 downX = x;
634 downY = y;
635
636 ev->type = EV_ABS;
637 ev->code = 1;
638 ev->value = (x << 16) | y;
639 return 0;
640 }
641
ev_get(struct input_event * ev,unsigned dont_wait)642 int ev_get(struct input_event *ev, unsigned dont_wait)
643 {
644 int r;
645 unsigned n;
646
647 do {
648 r = poll(ev_fds, ev_count, dont_wait ? 0 : -1);
649
650 if(r > 0) {
651 for(n = 0; n < ev_count; n++) {
652 if(ev_fds[n].revents & POLLIN) {
653 r = read(ev_fds[n].fd, ev, sizeof(*ev));
654 if(r == sizeof(*ev)) {
655 if (!vk_modify(&evs[n], ev))
656 return 0;
657 }
658 }
659 }
660 }
661 } while(dont_wait == 0);
662
663 return -1;
664 }
665