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