blob: e74204ee6800b9969c521512f7860daa8434a180 [file] [log] [blame]
Steve Kondik107d2e52017-06-13 17:34:56 -07001#define LOG_TAG "VNC-InputDevice"
2#include <utils/Log.h>
3
4#include "InputDevice.h"
5
6#include <fcntl.h>
7#include <stdio.h>
8
9#include <sys/ioctl.h>
10
11#include <linux/input.h>
12#include <linux/uinput.h>
13
14#include <rfb/keysym.h>
15
16using namespace android;
17
18static const struct UInputOptions {
19 int cmd;
20 int bit;
21} kOptions[] = {
22 {UI_SET_EVBIT, EV_KEY},
23 {UI_SET_EVBIT, EV_REP},
24 {UI_SET_EVBIT, EV_ABS},
25 {UI_SET_EVBIT, EV_SYN},
26 {UI_SET_ABSBIT, ABS_X},
27 {UI_SET_ABSBIT, ABS_Y},
28 {UI_SET_PROPBIT, INPUT_PROP_DIRECT},
29};
30
31int InputDevice::sFD = -1;
32
33status_t InputDevice::start(uint32_t width, uint32_t height) {
34 status_t err = OK;
35 struct uinput_user_dev user_dev;
36
37 struct input_id id = {
38 BUS_VIRTUAL, /* Bus type */
39 1, /* Vendor */
40 1, /* Product */
41 1, /* Version */
42 };
43
44 if (sFD >= 0) {
45 ALOGE("Input device already open!");
46 return NO_INIT;
47 }
48
49 sFD = open(UINPUT_DEVICE, O_WRONLY | O_NONBLOCK);
50 if (sFD < 0) {
51 ALOGE("Failed to open %s: err=%d", UINPUT_DEVICE, sFD);
52 return NO_INIT;
53 }
54
55 unsigned int idx = 0;
56 for (idx = 0; idx < sizeof(kOptions) / sizeof(kOptions[0]); idx++) {
57 if (ioctl(sFD, kOptions[idx].cmd, kOptions[idx].bit) < 0) {
58 ALOGE("uinput ioctl failed: %d %d", kOptions[idx].cmd, kOptions[idx].bit);
59 goto err_ioctl;
60 }
61 }
62
63 for (idx = 0; idx < KEY_MAX; idx++) {
64 if (ioctl(sFD, UI_SET_KEYBIT, idx) < 0) {
65 ALOGE("UI_SET_KEYBIT failed");
66 goto err_ioctl;
67 }
68 }
69
70 memset(&user_dev, 0, sizeof(user_dev));
71 strncpy(user_dev.name, "VNC", UINPUT_MAX_NAME_SIZE);
72
73 user_dev.id = id;
74
75 user_dev.absmin[ABS_X] = 0;
76 user_dev.absmax[ABS_X] = width;
77 user_dev.absmin[ABS_Y] = 0;
78 user_dev.absmax[ABS_Y] = height;
79
80 if (write(sFD, &user_dev, sizeof(user_dev)) != sizeof(user_dev)) {
81 ALOGE("Failed to configure uinput device");
82 goto err_ioctl;
83 }
84
85 if (ioctl(sFD, UI_DEV_CREATE) == -1) {
86 ALOGE("UI_DEV_CREATE failed");
87 goto err_ioctl;
88 }
89
90 return OK;
91
92err_ioctl:
93 int prev_errno = errno;
94 ::close(sFD);
95 errno = prev_errno;
96 sFD = -1;
97 return NO_INIT;
98}
99
100status_t InputDevice::stop() {
101 if (sFD < 0) {
102 return OK;
103 }
104
105 sleep(2);
106
107 ioctl(sFD, UI_DEV_DESTROY);
108 close(sFD);
109 sFD = -1;
110
111 return OK;
112}
113
114status_t InputDevice::inject(uint16_t type, uint16_t code, int32_t value) {
115 struct input_event event;
116 memset(&event, 0, sizeof(event));
117 gettimeofday(&event.time, 0); /* This should not be able to fail ever.. */
118 event.type = type;
119 event.code = code;
120 event.value = value;
121 if (write(sFD, &event, sizeof(event)) != sizeof(event)) return BAD_VALUE;
122 return OK;
123}
124
125status_t InputDevice::injectSyn(uint16_t type, uint16_t code, int32_t value) {
126 if (inject(type, code, value) != OK) {
127 return BAD_VALUE;
128 }
129 return inject(EV_SYN, SYN_REPORT, 0);
130}
131
132status_t InputDevice::movePointer(int32_t x, int32_t y) {
133 if (inject(EV_REL, REL_X, x) != OK) {
134 return BAD_VALUE;
135 }
136 return injectSyn(EV_REL, REL_Y, y);
137}
138
139status_t InputDevice::setPointer(int32_t x, int32_t y) {
140 if (inject(EV_ABS, ABS_X, x) != OK) {
141 return BAD_VALUE;
142 }
143 return injectSyn(EV_ABS, ABS_Y, y);
144}
145
146status_t InputDevice::press(uint16_t code) {
147 return inject(EV_KEY, code, 1);
148}
149
150status_t InputDevice::release(uint16_t code) {
151 return inject(EV_KEY, code, 0);
152}
153
154status_t InputDevice::click(uint16_t code) {
155 if (press(code) != OK) {
156 return BAD_VALUE;
157 }
158 return release(code);
159}
160
161void InputDevice::keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl) {
162 int code;
163 int sh = 0;
164 int alt = 0;
165
166 if (sFD < 0) return;
167
168 if ((code = keysym2scancode(key, cl, &sh, &alt))) {
169 int ret = 0;
170
171 if (key && down) {
172 if (sh) press(42); // left shift
173 if (alt) press(56); // left alt
174
175 inject(EV_SYN, SYN_REPORT, 0);
176
177 ret = press(code);
178 if (ret != 0) {
179 ALOGE("Error: %d (%s)\n", errno, strerror(errno));
180 }
181
182 inject(EV_SYN, SYN_REPORT, 0);
183
184 ret = release(code);
185 if (ret != 0) {
186 ALOGE("Error: %d (%s)\n", errno, strerror(errno));
187 }
188
189 inject(EV_SYN, SYN_REPORT, 0);
190
191 if (alt) release(56); // left alt
192 if (sh) release(42); // left shift
193
194 inject(EV_SYN, SYN_REPORT, 0);
195 }
196 }
197}
198
199void InputDevice::pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl) {
200 static int leftClicked = 0, rightClicked = 0, middleClicked = 0;
201 (void)cl;
202
203 if (sFD < 0) return;
204
205 if ((buttonMask & 1) && leftClicked) { // left btn clicked and moving
206 static int i = 0;
207 i = i + 1;
208
209 if (i % 10 == 1) // some tweak to not report every move event
210 {
211 inject(EV_ABS, ABS_X, x);
212 inject(EV_ABS, ABS_Y, y);
213 inject(EV_SYN, SYN_REPORT, 0);
214 }
215 } else if (buttonMask & 1) // left btn clicked
216 {
217 leftClicked = 1;
218
219 inject(EV_ABS, ABS_X, x);
220 inject(EV_ABS, ABS_Y, y);
221 inject(EV_KEY, BTN_TOUCH, 1);
222 inject(EV_SYN, SYN_REPORT, 0);
223 } else if (leftClicked) // left btn released
224 {
225 leftClicked = 0;
226 inject(EV_ABS, ABS_X, x);
227 inject(EV_ABS, ABS_Y, y);
228 inject(EV_KEY, BTN_TOUCH, 0);
229 inject(EV_SYN, SYN_REPORT, 0);
230 }
231
232 if (buttonMask & 4) // right btn clicked
233 {
234 rightClicked = 1;
235 press(158); // back key
236 inject(EV_SYN, SYN_REPORT, 0);
237 } else if (rightClicked) // right button released
238 {
239 rightClicked = 0;
240 release(158);
241 inject(EV_SYN, SYN_REPORT, 0);
242 }
243
244 if (buttonMask & 2) // mid btn clicked
245 {
246 middleClicked = 1;
247 press(KEY_END);
248 inject(EV_SYN, SYN_REPORT, 0);
249 } else if (middleClicked) // mid btn released
250 {
251 middleClicked = 0;
252 release(KEY_END);
253 inject(EV_SYN, SYN_REPORT, 0);
254 }
255}
256
257// q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,z,x,c,v,b,n,m
258static const int qwerty[] = {30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50,
259 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44};
260// ,!,",#,$,%,&,',(,),*,+,,,-,.,/
261static const int spec1[] = {57, 2, 40, 4, 5, 6, 8, 40, 10, 11, 9, 13, 51, 12, 52, 52};
262static const int spec1sh[] = {0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1};
263// :,;,<,=,>,?,@
264static const int spec2[] = {39, 39, 227, 13, 228, 53, 3};
265static const int spec2sh[] = {1, 0, 1, 1, 1, 1, 1};
266// [,\,],^,_,`
267static const int spec3[] = {26, 43, 27, 7, 12, 399};
268static const int spec3sh[] = {0, 0, 0, 1, 1, 0};
269// {,|,},~
270static const int spec4[] = {26, 43, 27, 215, 14};
271static const int spec4sh[] = {1, 1, 1, 1, 0};
272
273int InputDevice::keysym2scancode(rfbKeySym c, rfbClientPtr cl, int* sh, int* alt) {
274 int real = 1;
275 if ('a' <= c && c <= 'z') return qwerty[c - 'a'];
276 if ('A' <= c && c <= 'Z') {
277 (*sh) = 1;
278 return qwerty[c - 'A'];
279 }
280 if ('1' <= c && c <= '9') return c - '1' + 2;
281 if (c == '0') return 11;
282 if (32 <= c && c <= 47) {
283 (*sh) = spec1sh[c - 32];
284 return spec1[c - 32];
285 }
286 if (58 <= c && c <= 64) {
287 (*sh) = spec2sh[c - 58];
288 return spec2[c - 58];
289 }
290 if (91 <= c && c <= 96) {
291 (*sh) = spec3sh[c - 91];
292 return spec3[c - 91];
293 }
294 if (123 <= c && c <= 127) {
295 (*sh) = spec4sh[c - 123];
296 return spec4[c - 123];
297 }
298 switch (c) {
299 case 0xff08:
300 return 14; // backspace
301 case 0xff09:
302 return 15; // tab
303 case 1:
304 (*alt) = 1;
305 return 34; // ctrl+a
306 case 3:
307 (*alt) = 1;
308 return 46; // ctrl+c
309 case 4:
310 (*alt) = 1;
311 return 32; // ctrl+d
312 case 18:
313 (*alt) = 1;
314 return 31; // ctrl+r
315 case 0xff0D:
316 return 28; // enter
317 case 0xff1B:
318 return 158; // esc -> back
319 case 0xFF51:
320 return 105; // left -> DPAD_LEFT
321 case 0xFF53:
322 return 106; // right -> DPAD_RIGHT
323 case 0xFF54:
324 return 108; // down -> DPAD_DOWN
325 case 0xFF52:
326 return 103; // up -> DPAD_UP
327 // case 360:
328 // return 232;// end -> DPAD_CENTER (ball click)
329 case 0xff50:
330 return KEY_HOME; // home
331 case 0xFFC8:
332 rfbShutdownServer(cl->screen, TRUE);
333 return 0; // F11 disconnect
334 case 0xffff:
335 return 158; // del -> back
336 case 0xff55:
337 return 229; // PgUp -> menu
338 case 0xffcf:
339 return 127; // F2 -> search
340 case 0xffe3:
341 return 127; // left ctrl -> search
342 case 0xff56:
343 return 61; // PgUp -> call
344 case 0xff57:
345 return 107; // End -> endcall
346 case 0xffc2:
347 return 211; // F5 -> focus
348 case 0xffc3:
349 return 212; // F6 -> camera
350 case 0xffc4:
351 return 150; // F7 -> explorer
352 case 0xffc5:
353 return 155; // F8 -> envelope
354
355 case 50081:
356 case 225:
357 (*alt) = 1;
358 if (real) return 48; // a with acute
359 return 30; // a with acute -> a with ring above
360
361 case 50049:
362 case 193:
363 (*sh) = 1;
364 (*alt) = 1;
365 if (real) return 48; // A with acute
366 return 30; // A with acute -> a with ring above
367
368 case 50089:
369 case 233:
370 (*alt) = 1;
371 return 18; // e with acute
372
373 case 50057:
374 case 201:
375 (*sh) = 1;
376 (*alt) = 1;
377 return 18; // E with acute
378
379 case 50093:
380 case 0xffbf:
381 (*alt) = 1;
382 if (real) return 36; // i with acute
383 return 23; // i with acute -> i with grave
384
385 case 50061:
386 case 205:
387 (*sh) = 1;
388 (*alt) = 1;
389 if (real) return 36; // I with acute
390 return 23; // I with acute -> i with grave
391
392 case 50099:
393 case 243:
394 (*alt) = 1;
395 if (real) return 16; // o with acute
396 return 24; // o with acute -> o with grave
397
398 case 50067:
399 case 211:
400 (*sh) = 1;
401 (*alt) = 1;
402 if (real) return 16; // O with acute
403 return 24; // O with acute -> o with grave
404
405 case 50102:
406 case 246:
407 (*alt) = 1;
408 return 25; // o with diaeresis
409
410 case 50070:
411 case 214:
412 (*sh) = 1;
413 (*alt) = 1;
414 return 25; // O with diaeresis
415
416 case 50577:
417 case 245:
418 (*alt) = 1;
419 if (real) return 19; // Hungarian o
420 return 25; // Hungarian o -> o with diaeresis
421
422 case 50576:
423 case 213:
424 (*sh) = 1;
425 (*alt) = 1;
426 if (real) return 19; // Hungarian O
427 return 25; // Hungarian O -> O with diaeresis
428
429 case 50106:
430 // case 0xffbe:
431 // (*alt)=1;
432 // if (real)
433 // return 17; //u with acute
434 // return 22; //u with acute -> u with grave
435 case 50074:
436 case 218:
437 (*sh) = 1;
438 (*alt) = 1;
439 if (real) return 17; // U with acute
440 return 22; // U with acute -> u with grave
441 case 50108:
442 case 252:
443 (*alt) = 1;
444 return 47; // u with diaeresis
445
446 case 50076:
447 case 220:
448 (*sh) = 1;
449 (*alt) = 1;
450 return 47; // U with diaeresis
451
452 case 50609:
453 case 251:
454 (*alt) = 1;
455 if (real) return 45; // Hungarian u
456 return 47; // Hungarian u -> u with diaeresis
457
458 case 50608:
459 case 219:
460 (*sh) = 1;
461 (*alt) = 1;
462 if (real) return 45; // Hungarian U
463 return 47; // Hungarian U -> U with diaeresis
464 }
465 return 0;
466}