xref: /OK3568_Linux_fs/app/lvgl_demo/hal/evdev.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /**
2  * @file evdev.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "evdev.h"
10 #if USE_EVDEV != 0 || USE_BSD_EVDEV
11 
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #if USE_BSD_EVDEV
16 #include <dev/evdev/input.h>
17 #else
18 #include <linux/input.h>
19 #endif
20 #include <dirent.h>
21 
22 #include "main.h"
23 /*********************
24  *      DEFINES
25  *********************/
26 
27 /**********************
28  *      TYPEDEFS
29  **********************/
30 
31 /**********************
32  *  STATIC PROTOTYPES
33  **********************/
34 int map(int x, int in_min, int in_max, int out_min, int out_max);
35 
36 /**********************
37  *  STATIC VARIABLES
38  **********************/
39 int evdev_fd;
40 int evdev_root_x;
41 int evdev_root_y;
42 int evdev_button;
43 
44 int evdev_key_val;
45 
46 int evdev_rot;
47 /**********************
48  *      MACROS
49  **********************/
50 
51 /**********************
52  *   GLOBAL FUNCTIONS
53  **********************/
54 
55 #define TP_NAME_LEN (32)
56 static char tp_event[TP_NAME_LEN] = EVDEV_NAME;
57 /**
58  * Get touchscreen device event no
59  */
evdev_get_tp_event(void)60 void evdev_get_tp_event(void)
61 {
62     int fd = 0, len = 0;
63     int i = 0, input_dev_num = 0;
64     DIR *pDir;
65     struct dirent* ent = NULL;
66     char file_name[TP_NAME_LEN];
67     char tp_name[TP_NAME_LEN];
68     char *path = "/sys/class/input";
69 
70     if ((pDir = opendir(path)) == NULL) {
71         printf("%s: open %s filed\n", __func__, path);
72         return;
73     }
74 
75     while ((ent = readdir(pDir)) != NULL) {
76         if (strstr(ent->d_name, "input"))
77             input_dev_num++;
78 //            printf("%s: %s input deveices %d\n",
79 //                   __func__,
80 //                   ent->d_name,
81 //                   input_dev_num);
82     }
83     closedir(pDir);
84 
85     for (i = 0; i < input_dev_num; i++) {
86         sprintf(file_name, "/sys/class/input/input%d/name", i);
87         fd = open(file_name, O_RDONLY);
88         if (fd == -1) {
89             printf("%s: open %s failed\n", __func__, file_name);
90             return;
91         }
92 
93         len = read(fd, tp_name, TP_NAME_LEN);
94         if (len <= 0) {
95             printf("%s: read %s failed\n", __func__, file_name);
96             close(fd);
97             return;
98         }
99 
100         if (len >= TP_NAME_LEN)
101             len = TP_NAME_LEN - 1;
102 
103         tp_name[len] = '\0';
104 
105         if (strstr(tp_name, "ts")) {
106             sprintf(tp_event, "/dev/input/event%d", i);
107             printf("%s: %s = %s%s\n", __func__, file_name, tp_name, tp_event);
108         }
109 
110         close(fd);
111     }
112 }
113 
114 /**
115  * Initialize the evdev interface
116  */
evdev_init(int rot)117 void evdev_init(int rot)
118 {
119     evdev_rot = rot;
120     evdev_get_tp_event();
121 #if USE_BSD_EVDEV
122     evdev_fd = open(tp_event, O_RDWR | O_NOCTTY);
123 #else
124     evdev_fd = open(tp_event, O_RDWR | O_NOCTTY | O_NDELAY);
125 #endif
126     if(evdev_fd == -1) {
127         perror("unable open evdev interface:");
128         return;
129     }
130 
131 #if USE_BSD_EVDEV
132     fcntl(evdev_fd, F_SETFL, O_NONBLOCK);
133 #else
134     fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);
135 #endif
136 
137     evdev_root_x = 0;
138     evdev_root_y = 0;
139     evdev_key_val = 0;
140     evdev_button = LV_INDEV_STATE_REL;
141 }
142 /**
143  * reconfigure the device file for evdev
144  * @param dev_name set the evdev device filename
145  * @return true: the device file set complete
146  *         false: the device file doesn't exist current system
147  */
evdev_set_file(char * dev_name)148 bool evdev_set_file(char* dev_name)
149 {
150      if(evdev_fd != -1) {
151         close(evdev_fd);
152      }
153 #if USE_BSD_EVDEV
154      evdev_fd = open(dev_name, O_RDWR | O_NOCTTY);
155 #else
156      evdev_fd = open(dev_name, O_RDWR | O_NOCTTY | O_NDELAY);
157 #endif
158 
159      if(evdev_fd == -1) {
160         perror("unable open evdev interface:");
161         return false;
162      }
163 
164 #if USE_BSD_EVDEV
165      fcntl(evdev_fd, F_SETFL, O_NONBLOCK);
166 #else
167      fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);
168 #endif
169 
170      evdev_root_x = 0;
171      evdev_root_y = 0;
172      evdev_key_val = 0;
173      evdev_button = LV_INDEV_STATE_REL;
174 
175      return true;
176 }
177 /**
178  * Get the current position and state of the evdev
179  * @param data store the evdev data here
180  * @return false: because the points are not buffered, so no more data to be read
181  */
evdev_read(lv_indev_drv_t * drv,lv_indev_data_t * data)182 void evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
183 {
184     struct input_event in;
185     int tmp;
186 
187     while(read(evdev_fd, &in, sizeof(struct input_event)) > 0) {
188         if(in.type == EV_REL) {
189             if(in.code == REL_X)
190 #if EVDEV_SWAP_AXES
191                 evdev_root_y += in.value;
192 #else
193                 evdev_root_x += in.value;
194 #endif
195             else if(in.code == REL_Y)
196 #if EVDEV_SWAP_AXES
197                 evdev_root_x += in.value;
198 #else
199                 evdev_root_y += in.value;
200 #endif
201         } else if(in.type == EV_ABS) {
202             if(in.code == ABS_X)
203 #if EVDEV_SWAP_AXES
204                 evdev_root_y = in.value;
205 #else
206                 evdev_root_x = in.value;
207 #endif
208             else if(in.code == ABS_Y)
209 #if EVDEV_SWAP_AXES
210                 evdev_root_x = in.value;
211 #else
212                 evdev_root_y = in.value;
213 #endif
214             else if(in.code == ABS_MT_POSITION_X)
215 #if EVDEV_SWAP_AXES
216                 evdev_root_y = in.value;
217 #else
218                 evdev_root_x = in.value;
219 #endif
220             else if(in.code == ABS_MT_POSITION_Y)
221 #if EVDEV_SWAP_AXES
222                 evdev_root_x = in.value;
223 #else
224                 evdev_root_y = in.value;
225 #endif
226             else if(in.code == ABS_MT_TRACKING_ID)
227                 if(in.value == -1)
228                     evdev_button = LV_INDEV_STATE_REL;
229                 else if(in.value == 0)
230                     evdev_button = LV_INDEV_STATE_PR;
231         } else if(in.type == EV_KEY) {
232             if(in.code == BTN_MOUSE || in.code == BTN_TOUCH) {
233                 if(in.value == 0)
234                     evdev_button = LV_INDEV_STATE_REL;
235                 else if(in.value == 1)
236                     evdev_button = LV_INDEV_STATE_PR;
237             } else if(drv->type == LV_INDEV_TYPE_KEYPAD) {
238                 data->state = (in.value) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
239                 switch(in.code) {
240                 case KEY_BACKSPACE:
241                     data->key = LV_KEY_BACKSPACE;
242                     break;
243                 case KEY_ENTER:
244                     data->key = LV_KEY_ENTER;
245                     break;
246                 case KEY_UP:
247                     data->key = LV_KEY_UP;
248                     break;
249                 case KEY_LEFT:
250                     data->key = LV_KEY_PREV;
251                     break;
252                 case KEY_RIGHT:
253                     data->key = LV_KEY_NEXT;
254                     break;
255                 case KEY_DOWN:
256                     data->key = LV_KEY_DOWN;
257                     break;
258                 default:
259                     data->key = 0;
260                     break;
261                 }
262                 evdev_key_val = data->key;
263                 evdev_button = data->state;
264                 return ;
265             }
266         }
267     }
268 
269     if(drv->type == LV_INDEV_TYPE_KEYPAD) {
270         /* No data retrieved */
271         data->key = evdev_key_val;
272         data->state = evdev_button;
273         return ;
274     }
275     if(drv->type != LV_INDEV_TYPE_POINTER)
276         return ;
277     /*Store the collected data*/
278 
279 #if EVDEV_CALIBRATE
280     if (app_disp_rotation() == LV_DISP_ROT_90 ||
281         app_disp_rotation() == LV_DISP_ROT_270) {
282         data->point.x = map(evdev_root_x, EVDEV_HOR_MIN, EVDEV_HOR_MAX,
283                             0, drv->disp->driver->ver_res);
284         data->point.y = map(evdev_root_y, EVDEV_VER_MIN, EVDEV_VER_MAX,
285                             0, drv->disp->driver->hor_res);
286     } else {
287         data->point.x = map(evdev_root_x, EVDEV_HOR_MIN, EVDEV_HOR_MAX,
288                             0, drv->disp->driver->hor_res);
289         data->point.y = map(evdev_root_y, EVDEV_VER_MIN, EVDEV_VER_MAX,
290                             0, drv->disp->driver->ver_res);
291     }
292 #else
293     data->point.x = evdev_root_x;
294     data->point.y = evdev_root_y;
295 #endif
296 
297     data->state = evdev_button;
298 
299     switch (evdev_rot)
300     {
301     case 0:
302     default:
303         break;
304     case 90:
305         tmp = data->point.x;
306         data->point.x = data->point.y;
307         data->point.y = drv->disp->driver->ver_res - tmp;
308         break;
309     case 180:
310         tmp = data->point.x;
311         data->point.x = drv->disp->driver->hor_res - data->point.y;
312         data->point.y = drv->disp->driver->ver_res - tmp;
313         break;
314     case 270:
315         tmp = data->point.x;
316         data->point.x = drv->disp->driver->hor_res - data->point.y;
317         data->point.y = tmp;
318         break;
319     }
320 
321     if (data->point.x < 0)
322       data->point.x = 0;
323     if (data->point.y < 0)
324       data->point.y = 0;
325     if (data->point.x >= drv->disp->driver->hor_res)
326         data->point.x = drv->disp->driver->hor_res - 1;
327     if (data->point.y >= drv->disp->driver->ver_res)
328         data->point.y = drv->disp->driver->ver_res - 1;
329 
330     return ;
331 }
332 
333 /**********************
334  *   STATIC FUNCTIONS
335  **********************/
map(int x,int in_min,int in_max,int out_min,int out_max)336 int map(int x, int in_min, int in_max, int out_min, int out_max)
337 {
338     return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
339 }
340 
341 #endif
342