xref: /OK3568_Linux_fs/external/rk_pcba_test/pcba_minui/minui/events.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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