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