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