blob: df3cbd613cbdd381c7a1b1aa6c4bc10e1c92b501 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/**
2 * @file evdev.c
3 *
4 */
5
6/*********************
7 * INCLUDES
8 *********************/
9#include "evdev.h"
10#if USE_EVDEV != 0
11
12#include <stdio.h>
13#include <unistd.h>
14#include <fcntl.h>
15#include <linux/input.h>
16
17/*********************
18 * DEFINES
19 *********************/
20
21/**********************
22 * TYPEDEFS
23 **********************/
24
25/**********************
26 * STATIC PROTOTYPES
27 **********************/
28int map(int x, int in_min, int in_max, int out_min, int out_max);
29
30/**********************
31 * STATIC VARIABLES
32 **********************/
33int evdev_fd;
34int evdev_root_x;
35int evdev_root_y;
36int evdev_button;
37
38int evdev_key_val;
39
40/**********************
41 * MACROS
42 **********************/
43
44/**********************
45 * GLOBAL FUNCTIONS
46 **********************/
47
48/**
49 * Initialize the evdev interface
50 */
51void evdev_init(void)
52{
53 evdev_fd = open(EVDEV_NAME, O_RDWR | O_NOCTTY | O_NDELAY);
54 if(evdev_fd == -1) {
55 perror("unable open evdev interface:");
56 return;
57 }
58
59 fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);
60
61 evdev_root_x = 0;
62 evdev_root_y = 0;
63 evdev_key_val = 0;
64 evdev_button = LV_INDEV_STATE_REL;
65}
66/**
67 * reconfigure the device file for evdev
68 * @param dev_name set the evdev device filename
69 * @return true: the device file set complete
70 * false: the device file doesn't exist current system
71 */
72bool evdev_set_file(char* dev_name)
73{
74 if(evdev_fd != -1) {
75 close(evdev_fd);
76 }
77 evdev_fd = open(dev_name, O_RDWR | O_NOCTTY | O_NDELAY);
78
79 if(evdev_fd == -1) {
80 perror("unable open evdev interface:");
81 return false;
82 }
83
84 fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);
85
86 evdev_root_x = 0;
87 evdev_root_y = 0;
88 evdev_key_val = 0;
89 evdev_button = LV_INDEV_STATE_REL;
90
91 return true;
92}
93/**
94 * Get the current position and state of the evdev
95 * @param data store the evdev data here
96 * @return false: because the points are not buffered, so no more data to be read
97 */
98bool evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
99{
100 struct input_event in;
101
102 while(read(evdev_fd, &in, sizeof(struct input_event)) > 0) {
103 if(in.type == EV_REL) {
104 if(in.code == REL_X)
105 #if EVDEV_SWAP_AXES
106 evdev_root_y += in.value;
107 #else
108 evdev_root_x += in.value;
109 #endif
110 else if(in.code == REL_Y)
111 #if EVDEV_SWAP_AXES
112 evdev_root_x += in.value;
113 #else
114 evdev_root_y += in.value;
115 #endif
116 } else if(in.type == EV_ABS) {
117 if(in.code == ABS_X)
118 #if EVDEV_SWAP_AXES
119 evdev_root_y = in.value;
120 #else
121 evdev_root_x = in.value;
122 #endif
123 else if(in.code == ABS_Y)
124 #if EVDEV_SWAP_AXES
125 evdev_root_x = in.value;
126 #else
127 evdev_root_y = in.value;
128 #endif
129 else if(in.code == ABS_MT_POSITION_X)
130 #if EVDEV_SWAP_AXES
131 evdev_root_y = in.value;
132 #else
133 evdev_root_x = in.value;
134 #endif
135 else if(in.code == ABS_MT_POSITION_Y)
136 #if EVDEV_SWAP_AXES
137 evdev_root_x = in.value;
138 #else
139 evdev_root_y = in.value;
140 #endif
141 } else if(in.type == EV_KEY) {
142 if(in.code == BTN_MOUSE || in.code == BTN_TOUCH) {
143 if(in.value == 0)
144 evdev_button = LV_INDEV_STATE_REL;
145 else if(in.value == 1)
146 evdev_button = LV_INDEV_STATE_PR;
147 } else if(drv->type == LV_INDEV_TYPE_KEYPAD) {
148 data->state = (in.value) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
149 switch(in.code) {
150 case KEY_BACKSPACE:
151 data->key = LV_KEY_BACKSPACE;
152 break;
153 case KEY_ENTER:
154 data->key = LV_KEY_ENTER;
155 break;
156 case KEY_UP:
157 data->key = LV_KEY_UP;
158 break;
159 case KEY_LEFT:
160 data->key = LV_KEY_PREV;
161 break;
162 case KEY_RIGHT:
163 data->key = LV_KEY_NEXT;
164 break;
165 case KEY_DOWN:
166 data->key = LV_KEY_DOWN;
167 break;
168 default:
169 data->key = 0;
170 break;
171 }
172 evdev_key_val = data->key;
173 evdev_button = data->state;
174 return false;
175 }
176 }
177 }
178
179 if(drv->type == LV_INDEV_TYPE_KEYPAD) {
180 /* No data retrieved */
181 data->key = evdev_key_val;
182 data->state = evdev_button;
183 return false;
184 }
185 if(drv->type != LV_INDEV_TYPE_POINTER)
186 return false;
187 /*Store the collected data*/
188
189#if EVDEV_CALIBRATE
190 data->point.x = map(evdev_root_x, EVDEV_HOR_MIN, EVDEV_HOR_MAX, 0, lv_disp_get_hor_res(drv->disp));
191 data->point.y = map(evdev_root_y, EVDEV_VER_MIN, EVDEV_VER_MAX, 0, lv_disp_get_ver_res(drv->disp));
192#else
193 data->point.x = evdev_root_x;
194 data->point.y = evdev_root_y;
195#endif
196
197 data->state = evdev_button;
198
199 if(data->point.x < 0)
200 data->point.x = 0;
201 if(data->point.y < 0)
202 data->point.y = 0;
203 if(data->point.x >= lv_disp_get_hor_res(drv->disp))
204 data->point.x = lv_disp_get_hor_res(drv->disp) - 1;
205 if(data->point.y >= lv_disp_get_ver_res(drv->disp))
206 data->point.y = lv_disp_get_ver_res(drv->disp) - 1;
207
208 return false;
209}
210
211/**********************
212 * STATIC FUNCTIONS
213 **********************/
214int map(int x, int in_min, int in_max, int out_min, int out_max)
215{
216 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
217}
218
219#endif