pikeyd165 – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /**** uinput.c *****************************/ |
2 | /* M. Moller 2013-01-16 */ |
||
3 | /* Universal RPi GPIO keyboard daemon */ |
||
4 | /*******************************************/ |
||
5 | |||
6 | /* |
||
7 | Copyright (C) 2013 Michael Moller. |
||
8 | This file is part of the Universal Raspberry Pi GPIO keyboard daemon. |
||
9 | |||
10 | This is free software; you can redistribute it and/or |
||
11 | modify it under the terms of the GNU Lesser General Public |
||
12 | License as published by the Free Software Foundation; either |
||
13 | version 2.1 of the License, or (at your option) any later version. |
||
14 | |||
15 | The software is distributed in the hope that it will be useful, |
||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
18 | Lesser General Public License for more details. |
||
19 | |||
20 | You should have received a copy of the GNU Lesser General Public |
||
21 | License along with the GNU C Library; if not, write to the Free |
||
22 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
||
23 | 02111-1307 USA. |
||
24 | */ |
||
25 | |||
26 | #include <stdio.h> |
||
27 | #include <stdlib.h> |
||
28 | #include <string.h> |
||
29 | #include <unistd.h> |
||
30 | #include <fcntl.h> |
||
31 | #include <errno.h> |
||
32 | #include <linux/input.h> |
||
33 | #include <linux/uinput.h> |
||
34 | #include "config.h" |
||
35 | #include "daemon.h" |
||
36 | #include "time.h" |
||
37 | #include "uinput.h" |
||
38 | #include <stdbool.h> |
||
39 | |||
40 | int sendKey(int key, int value); |
||
41 | int sendRel(int devm, int dx, int dy); |
||
42 | static int sendSync(int); |
||
43 | |||
44 | static struct input_event uidev_ev; |
||
45 | static int uidev_fd_key; |
||
46 | int uidev_fd_mouse1; |
||
47 | int uidev_fd_mouse2; |
||
48 | |||
49 | |||
50 | |||
51 | #define die(str, args...) do { \ |
||
52 | perror(str); \ |
||
53 | return(EXIT_FAILURE); \ |
||
54 | } while(0) |
||
55 | |||
56 | int init_uinput(bool skip_mouse_init) |
||
57 | { |
||
58 | int fd; |
||
59 | struct uinput_user_dev uidev; |
||
60 | int i; |
||
61 | |||
62 | fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); |
||
63 | if(fd < 0) |
||
64 | die("/dev/uinput"); |
||
65 | |||
66 | if(ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0) |
||
67 | die("error: ioctl"); |
||
68 | |||
69 | if(ioctl(fd, UI_SET_EVBIT, EV_REP) < 0) |
||
70 | die("error: ioctl"); |
||
71 | |||
72 | |||
73 | //alter code (mouse im keydevice) |
||
74 | #if 0 |
||
75 | if( skip_mouse_init == false) { |
||
76 | if(ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) < 0) |
||
77 | die("error: ioctl"); |
||
78 | |||
79 | if(ioctl(fd, UI_SET_EVBIT, EV_REL) < 0) |
||
80 | die("error: ioctl"); |
||
81 | if(ioctl(fd, UI_SET_RELBIT, REL_X) < 0) |
||
82 | die("error: ioctl"); |
||
83 | if(ioctl(fd, UI_SET_RELBIT, REL_Y) < 0) |
||
84 | die("error: ioctl"); |
||
85 | } |
||
86 | #endif |
||
87 | |||
88 | /* don't forget to add all the keys! */ |
||
89 | for(i=0; i<256; i++){ |
||
90 | if(ioctl(fd, UI_SET_KEYBIT, i) < 0) |
||
91 | die("error: ioctl"); |
||
92 | } |
||
93 | |||
94 | memset(&uidev, 0, sizeof(uidev)); |
||
95 | snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-sample0"); |
||
96 | uidev.id.bustype = BUS_USB; |
||
97 | uidev.id.vendor = 0x1; |
||
98 | uidev.id.product = 0x1; |
||
99 | uidev.id.version = 1; |
||
100 | |||
101 | if(write(fd, &uidev, sizeof(uidev)) < 0) |
||
102 | die("error: write"); |
||
103 | |||
104 | if(ioctl(fd, UI_DEV_CREATE) < 0) |
||
105 | die("error: ioctl"); |
||
106 | |||
107 | uidev_fd_key = fd; |
||
108 | |||
109 | |||
110 | |||
111 | |||
112 | |||
113 | /******************mouses******************/ |
||
114 | |||
115 | if( skip_mouse_init == false) { |
||
116 | |||
117 | printf("Mouse/Trackball enabled\n"); |
||
118 | |||
119 | //mouse 1 |
||
120 | fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); |
||
121 | if(fd < 0) |
||
122 | die("/dev/uinput"); |
||
123 | |||
124 | |||
125 | // if(ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) < 0) |
||
126 | // die("error: ioctl"); |
||
127 | |||
128 | if(ioctl(fd, UI_SET_EVBIT, EV_REL) < 0) |
||
129 | die("error: ioctl"); |
||
130 | if(ioctl(fd, UI_SET_RELBIT, REL_X) < 0) |
||
131 | die("error: ioctl"); |
||
132 | if(ioctl(fd, UI_SET_RELBIT, REL_Y) < 0) |
||
133 | die("error: ioctl"); |
||
134 | |||
135 | memset(&uidev, 0, sizeof(uidev)); |
||
136 | snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-sample1"); |
||
137 | uidev.id.bustype = BUS_USB; |
||
138 | uidev.id.vendor = 0x1; |
||
139 | uidev.id.product = 0x1; |
||
140 | uidev.id.version = 1; |
||
141 | |||
142 | if(write(fd, &uidev, sizeof(uidev)) < 0) |
||
143 | die("error: write"); |
||
144 | |||
145 | if(ioctl(fd, UI_DEV_CREATE) < 0) |
||
146 | die("error: ioctl"); |
||
147 | |||
148 | uidev_fd_mouse1 = fd; |
||
149 | |||
150 | //mouse 2 |
||
151 | fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK); |
||
152 | if(fd < 0) |
||
153 | die("/dev/uinput"); |
||
154 | |||
155 | // if(ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) < 0) |
||
156 | // die("error: ioctl"); |
||
157 | |||
158 | if(ioctl(fd, UI_SET_EVBIT, EV_REL) < 0) |
||
159 | die("error: ioctl"); |
||
160 | if(ioctl(fd, UI_SET_RELBIT, REL_X) < 0) |
||
161 | die("error: ioctl"); |
||
162 | if(ioctl(fd, UI_SET_RELBIT, REL_Y) < 0) |
||
163 | die("error: ioctl"); |
||
164 | |||
165 | memset(&uidev, 0, sizeof(uidev)); |
||
166 | snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-sample2"); |
||
167 | uidev.id.bustype = BUS_USB; |
||
168 | uidev.id.vendor = 0x1; |
||
169 | uidev.id.product = 0x1; |
||
170 | uidev.id.version = 1; |
||
171 | |||
172 | if(write(fd, &uidev, sizeof(uidev)) < 0) |
||
173 | die("error: write"); |
||
174 | |||
175 | if(ioctl(fd, UI_DEV_CREATE) < 0) |
||
176 | die("error: ioctl"); |
||
177 | |||
178 | uidev_fd_mouse2 = fd; |
||
179 | |||
180 | |||
181 | |||
182 | } |
||
183 | /******************mouses******************/ |
||
184 | |||
185 | |||
186 | |||
187 | |||
188 | |||
189 | |||
190 | |||
191 | |||
192 | |||
193 | return 0; |
||
194 | } |
||
195 | |||
196 | int test_uinput(void) |
||
197 | { |
||
198 | int dx, dy; |
||
199 | int i,k; |
||
200 | |||
201 | srand(time(NULL)); |
||
202 | |||
203 | while(1) { |
||
204 | switch(rand() % 4) { |
||
205 | case 0: |
||
206 | dx = -10; |
||
207 | dy = -1; |
||
208 | break; |
||
209 | case 1: |
||
210 | dx = 10; |
||
211 | dy = 1; |
||
212 | break; |
||
213 | case 2: |
||
214 | dx = -1; |
||
215 | dy = 10; |
||
216 | break; |
||
217 | case 3: |
||
218 | dx = 1; |
||
219 | dy = -10; |
||
220 | break; |
||
221 | } |
||
222 | |||
223 | k = send_gpio_keys(21, 1); |
||
224 | sendKey(k, 0); |
||
225 | |||
226 | for(i = 0; i < 20; i++) { |
||
227 | //sendKey(KEY_D, 1); |
||
228 | //sendKey(KEY_D, 0); |
||
229 | sendRel(uidev_fd_mouse1,dx, dy); |
||
230 | |||
231 | usleep(15000); |
||
232 | } |
||
233 | |||
234 | sleep(10); |
||
235 | } |
||
236 | } |
||
237 | |||
238 | int close_uinput(bool skip_mouse_init) |
||
239 | { |
||
240 | sleep(2); |
||
241 | |||
242 | if(ioctl(uidev_fd_key, UI_DEV_DESTROY) < 0) |
||
243 | die("error: ioctl"); |
||
244 | |||
245 | close(uidev_fd_key); |
||
246 | |||
247 | |||
248 | /******************mouses******************/ |
||
249 | if( skip_mouse_init == false) { |
||
250 | |||
251 | if(ioctl(uidev_fd_mouse1, UI_DEV_DESTROY) < 0) |
||
252 | die("error: ioctl"); |
||
253 | |||
254 | close(uidev_fd_mouse1); |
||
255 | |||
256 | |||
257 | if(ioctl(uidev_fd_mouse2, UI_DEV_DESTROY) < 0) |
||
258 | die("error: ioctl"); |
||
259 | |||
260 | close(uidev_fd_mouse2); |
||
261 | } |
||
262 | |||
263 | |||
264 | /******************mouses******************/ |
||
265 | |||
266 | |||
267 | |||
268 | return 0; |
||
269 | } |
||
270 | |||
271 | int sendKey(int key, int value) |
||
272 | { |
||
273 | memset(&uidev_ev, 0, sizeof(struct input_event)); |
||
274 | gettimeofday(&uidev_ev.time, NULL); |
||
275 | uidev_ev.type = EV_KEY; |
||
276 | uidev_ev.code = key; |
||
277 | |||
278 | //CM sanity fix |
||
279 | if(value!=0) |
||
280 | value=1; |
||
281 | |||
282 | uidev_ev.value = value; |
||
283 | if(write(uidev_fd_key, &uidev_ev, sizeof(struct input_event)) < 0) |
||
284 | die("error: write"); |
||
285 | |||
286 | sendSync(uidev_fd_key); |
||
287 | |||
288 | return 0; |
||
289 | } |
||
290 | |||
291 | int sendRel(int devm,int dx, int dy) |
||
292 | { |
||
293 | //printf("dx: %i dy: %i\n",dx,dy); |
||
294 | |||
295 | memset(&uidev_ev, 0, sizeof(struct input_event)); |
||
296 | uidev_ev.type = EV_REL; |
||
297 | uidev_ev.code = REL_X; |
||
298 | uidev_ev.value = dx; |
||
299 | if(write(devm, &uidev_ev, sizeof(struct input_event)) < 0) |
||
300 | die("error: write"); |
||
301 | |||
302 | memset(&uidev_ev, 0, sizeof(struct input_event)); |
||
303 | uidev_ev.type = EV_REL; |
||
304 | uidev_ev.code = REL_Y; |
||
305 | uidev_ev.value = dy; |
||
306 | if(write(devm, &uidev_ev, sizeof(struct input_event)) < 0) |
||
307 | die("error: write"); |
||
308 | |||
309 | sendSync(devm); |
||
310 | |||
311 | return 0; |
||
312 | } |
||
313 | |||
314 | static int sendSync(int devm) |
||
315 | { |
||
316 | //memset(&uidev_ev, 0, sizeof(struct input_event)); |
||
317 | uidev_ev.type = EV_SYN; |
||
318 | uidev_ev.code = SYN_REPORT; |
||
319 | uidev_ev.value = 0; |
||
320 | if(write(devm, &uidev_ev, sizeof(struct input_event)) < 0) |
||
321 | die("error: sendSync - write"); |
||
322 | |||
323 | return 0; |
||
324 | } |
||
325 | |||
326 | int send_gpio_keys(int gpio, int value) |
||
327 | { |
||
328 | int k; |
||
329 | restart_keys(); |
||
330 | while( got_more_keys(gpio) ){ |
||
331 | k = get_next_key(gpio); |
||
332 | sendKey(k, value); |
||
333 | if(value && got_more_keys(gpio)){ |
||
334 | /* release the current key, so the next one can be pressed */ |
||
335 | sendKey(k, 0); |
||
336 | } |
||
337 | } |
||
338 | return k; |
||
339 | } |