blob: 1f07f5aa42ad20a469a206c5fa66b2c6a23d2a29 [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
Steve Kondik6ec5bc82017-06-15 01:31:51 -070035ANDROID_SINGLETON_STATIC_INSTANCE(InputDevice)
36
Steve Kondik107d2e52017-06-13 17:34:56 -070037static const struct UInputOptions {
38 int cmd;
39 int bit;
40} kOptions[] = {
41 {UI_SET_EVBIT, EV_KEY},
Steve Kondik6ec5bc82017-06-15 01:31:51 -070042 {UI_SET_EVBIT, EV_REL},
Steve Kondik107d2e52017-06-13 17:34:56 -070043 {UI_SET_EVBIT, EV_ABS},
44 {UI_SET_EVBIT, EV_SYN},
45 {UI_SET_ABSBIT, ABS_X},
46 {UI_SET_ABSBIT, ABS_Y},
Steve Kondik6ec5bc82017-06-15 01:31:51 -070047 {UI_SET_RELBIT, REL_WHEEL},
Steve Kondik107d2e52017-06-13 17:34:56 -070048 {UI_SET_PROPBIT, INPUT_PROP_DIRECT},
49};
50
Steve Kondik107d2e52017-06-13 17:34:56 -070051status_t InputDevice::start(uint32_t width, uint32_t height) {
Steve Kondik6ec5bc82017-06-15 01:31:51 -070052 Mutex::Autolock _l(mLock);
53
Steve Kondik107d2e52017-06-13 17:34:56 -070054 status_t err = OK;
Steve Kondik107d2e52017-06-13 17:34:56 -070055
56 struct input_id id = {
57 BUS_VIRTUAL, /* Bus type */
58 1, /* Vendor */
59 1, /* Product */
Steve Kondik6ec5bc82017-06-15 01:31:51 -070060 4, /* Version */
Steve Kondik107d2e52017-06-13 17:34:56 -070061 };
62
Steve Kondik6ec5bc82017-06-15 01:31:51 -070063 if (mFD >= 0) {
Steve Kondik107d2e52017-06-13 17:34:56 -070064 ALOGE("Input device already open!");
65 return NO_INIT;
66 }
67
Steve Kondik6ec5bc82017-06-15 01:31:51 -070068 mFD = open(UINPUT_DEVICE, O_WRONLY | O_NONBLOCK);
69 if (mFD < 0) {
70 ALOGE("Failed to open %s: err=%d", UINPUT_DEVICE, mFD);
Steve Kondik107d2e52017-06-13 17:34:56 -070071 return NO_INIT;
72 }
73
74 unsigned int idx = 0;
75 for (idx = 0; idx < sizeof(kOptions) / sizeof(kOptions[0]); idx++) {
Steve Kondik6ec5bc82017-06-15 01:31:51 -070076 if (ioctl(mFD, kOptions[idx].cmd, kOptions[idx].bit) < 0) {
Steve Kondik107d2e52017-06-13 17:34:56 -070077 ALOGE("uinput ioctl failed: %d %d", kOptions[idx].cmd, kOptions[idx].bit);
78 goto err_ioctl;
79 }
80 }
81
82 for (idx = 0; idx < KEY_MAX; idx++) {
Steve Kondik6ec5bc82017-06-15 01:31:51 -070083 if (ioctl(mFD, UI_SET_KEYBIT, idx) < 0) {
Steve Kondik107d2e52017-06-13 17:34:56 -070084 ALOGE("UI_SET_KEYBIT failed");
85 goto err_ioctl;
86 }
87 }
88
Steve Kondik6ec5bc82017-06-15 01:31:51 -070089 memset(&mUserDev, 0, sizeof(mUserDev));
90 strncpy(mUserDev.name, "VNC-RemoteInput", UINPUT_MAX_NAME_SIZE);
Steve Kondik107d2e52017-06-13 17:34:56 -070091
Steve Kondik6ec5bc82017-06-15 01:31:51 -070092 mUserDev.id = id;
Steve Kondik107d2e52017-06-13 17:34:56 -070093
Steve Kondik6ec5bc82017-06-15 01:31:51 -070094 mUserDev.absmin[ABS_X] = 0;
95 mUserDev.absmax[ABS_X] = width;
96 mUserDev.absmin[ABS_Y] = 0;
97 mUserDev.absmax[ABS_Y] = height;
Steve Kondik107d2e52017-06-13 17:34:56 -070098
Steve Kondik6ec5bc82017-06-15 01:31:51 -070099 if (write(mFD, &mUserDev, sizeof(mUserDev)) != sizeof(mUserDev)) {
Steve Kondik107d2e52017-06-13 17:34:56 -0700100 ALOGE("Failed to configure uinput device");
101 goto err_ioctl;
102 }
103
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700104 if (ioctl(mFD, UI_DEV_CREATE) == -1) {
Steve Kondik107d2e52017-06-13 17:34:56 -0700105 ALOGE("UI_DEV_CREATE failed");
106 goto err_ioctl;
107 }
108
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700109 ALOGD("Virtual input device created successfully (%dx%d)", width, height);
110 return NO_ERROR;
Steve Kondik107d2e52017-06-13 17:34:56 -0700111
112err_ioctl:
113 int prev_errno = errno;
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700114 ::close(mFD);
Steve Kondik107d2e52017-06-13 17:34:56 -0700115 errno = prev_errno;
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700116 mFD = -1;
Steve Kondik107d2e52017-06-13 17:34:56 -0700117 return NO_INIT;
118}
119
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700120status_t InputDevice::reconfigure(uint32_t width, uint32_t height) {
121 stop();
122 return start(width, height);
123}
124
Steve Kondik107d2e52017-06-13 17:34:56 -0700125status_t InputDevice::stop() {
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700126 Mutex::Autolock _l(mLock);
127 if (mFD < 0) {
Steve Kondik107d2e52017-06-13 17:34:56 -0700128 return OK;
129 }
130
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700131 ioctl(mFD, UI_DEV_DESTROY);
132 close(mFD);
133 mFD = -1;
Steve Kondik107d2e52017-06-13 17:34:56 -0700134
135 return OK;
136}
137
138status_t InputDevice::inject(uint16_t type, uint16_t code, int32_t value) {
139 struct input_event event;
140 memset(&event, 0, sizeof(event));
141 gettimeofday(&event.time, 0); /* This should not be able to fail ever.. */
142 event.type = type;
143 event.code = code;
144 event.value = value;
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700145 if (write(mFD, &event, sizeof(event)) != sizeof(event)) return BAD_VALUE;
Steve Kondik107d2e52017-06-13 17:34:56 -0700146 return OK;
147}
148
149status_t InputDevice::injectSyn(uint16_t type, uint16_t code, int32_t value) {
150 if (inject(type, code, value) != OK) {
151 return BAD_VALUE;
152 }
153 return inject(EV_SYN, SYN_REPORT, 0);
154}
155
156status_t InputDevice::movePointer(int32_t x, int32_t y) {
157 if (inject(EV_REL, REL_X, x) != OK) {
158 return BAD_VALUE;
159 }
160 return injectSyn(EV_REL, REL_Y, y);
161}
162
163status_t InputDevice::setPointer(int32_t x, int32_t y) {
164 if (inject(EV_ABS, ABS_X, x) != OK) {
165 return BAD_VALUE;
166 }
167 return injectSyn(EV_ABS, ABS_Y, y);
168}
169
170status_t InputDevice::press(uint16_t code) {
171 return inject(EV_KEY, code, 1);
172}
173
174status_t InputDevice::release(uint16_t code) {
175 return inject(EV_KEY, code, 0);
176}
177
178status_t InputDevice::click(uint16_t code) {
179 if (press(code) != OK) {
180 return BAD_VALUE;
181 }
182 return release(code);
183}
184
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700185void InputDevice::onKeyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl) {
186 InputDevice::getInstance().keyEvent(down, key, cl);
187}
188
Steve Kondik107d2e52017-06-13 17:34:56 -0700189void InputDevice::keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl) {
190 int code;
191 int sh = 0;
192 int alt = 0;
193
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700194 if (mFD < 0) return;
195
196 Mutex::Autolock _l(mLock);
Steve Kondik107d2e52017-06-13 17:34:56 -0700197
198 if ((code = keysym2scancode(key, cl, &sh, &alt))) {
199 int ret = 0;
200
201 if (key && down) {
202 if (sh) press(42); // left shift
203 if (alt) press(56); // left alt
204
205 inject(EV_SYN, SYN_REPORT, 0);
206
207 ret = press(code);
208 if (ret != 0) {
209 ALOGE("Error: %d (%s)\n", errno, strerror(errno));
210 }
211
212 inject(EV_SYN, SYN_REPORT, 0);
213
214 ret = release(code);
215 if (ret != 0) {
216 ALOGE("Error: %d (%s)\n", errno, strerror(errno));
217 }
218
219 inject(EV_SYN, SYN_REPORT, 0);
220
221 if (alt) release(56); // left alt
222 if (sh) release(42); // left shift
223
224 inject(EV_SYN, SYN_REPORT, 0);
225 }
226 }
227}
228
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700229void InputDevice::onPointerEvent(int buttonMask, int x, int y, rfbClientPtr cl) {
230 InputDevice::getInstance().pointerEvent(buttonMask, x, y, cl);
231}
232
Steve Kondik107d2e52017-06-13 17:34:56 -0700233void InputDevice::pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl) {
234 static int leftClicked = 0, rightClicked = 0, middleClicked = 0;
235 (void)cl;
236
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700237 if (mFD < 0) return;
238
239 ALOGV("pointerEvent: buttonMask=%x x=%d y=%d", buttonMask, x, y);
240
241 Mutex::Autolock _l(mLock);
Steve Kondik107d2e52017-06-13 17:34:56 -0700242
243 if ((buttonMask & 1) && leftClicked) { // left btn clicked and moving
244 static int i = 0;
245 i = i + 1;
246
247 if (i % 10 == 1) // some tweak to not report every move event
248 {
249 inject(EV_ABS, ABS_X, x);
250 inject(EV_ABS, ABS_Y, y);
251 inject(EV_SYN, SYN_REPORT, 0);
252 }
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700253 } else if (buttonMask & 1) { // left btn clicked
Steve Kondik107d2e52017-06-13 17:34:56 -0700254 leftClicked = 1;
255
256 inject(EV_ABS, ABS_X, x);
257 inject(EV_ABS, ABS_Y, y);
258 inject(EV_KEY, BTN_TOUCH, 1);
259 inject(EV_SYN, SYN_REPORT, 0);
260 } else if (leftClicked) // left btn released
261 {
262 leftClicked = 0;
263 inject(EV_ABS, ABS_X, x);
264 inject(EV_ABS, ABS_Y, y);
265 inject(EV_KEY, BTN_TOUCH, 0);
266 inject(EV_SYN, SYN_REPORT, 0);
267 }
268
269 if (buttonMask & 4) // right btn clicked
270 {
271 rightClicked = 1;
272 press(158); // back key
273 inject(EV_SYN, SYN_REPORT, 0);
274 } else if (rightClicked) // right button released
275 {
276 rightClicked = 0;
277 release(158);
278 inject(EV_SYN, SYN_REPORT, 0);
279 }
280
281 if (buttonMask & 2) // mid btn clicked
282 {
283 middleClicked = 1;
284 press(KEY_END);
285 inject(EV_SYN, SYN_REPORT, 0);
286 } else if (middleClicked) // mid btn released
287 {
288 middleClicked = 0;
289 release(KEY_END);
290 inject(EV_SYN, SYN_REPORT, 0);
291 }
Steve Kondik6ec5bc82017-06-15 01:31:51 -0700292
293 if (buttonMask & 8) {
294 inject(EV_REL, REL_WHEEL, 1);
295 }
296
297 if (buttonMask & 0x10) {
298 inject(EV_REL, REL_WHEEL, -1);
299 }
Steve Kondik107d2e52017-06-13 17:34:56 -0700300}
301
302// 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
303static const int qwerty[] = {30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, 50,
304 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44};
305// ,!,",#,$,%,&,',(,),*,+,,,-,.,/
306static const int spec1[] = {57, 2, 40, 4, 5, 6, 8, 40, 10, 11, 9, 13, 51, 12, 52, 52};
307static const int spec1sh[] = {0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1};
308// :,;,<,=,>,?,@
309static const int spec2[] = {39, 39, 227, 13, 228, 53, 3};
310static const int spec2sh[] = {1, 0, 1, 1, 1, 1, 1};
311// [,\,],^,_,`
312static const int spec3[] = {26, 43, 27, 7, 12, 399};
313static const int spec3sh[] = {0, 0, 0, 1, 1, 0};
314// {,|,},~
315static const int spec4[] = {26, 43, 27, 215, 14};
316static const int spec4sh[] = {1, 1, 1, 1, 0};
317
318int InputDevice::keysym2scancode(rfbKeySym c, rfbClientPtr cl, int* sh, int* alt) {
319 int real = 1;
320 if ('a' <= c && c <= 'z') return qwerty[c - 'a'];
321 if ('A' <= c && c <= 'Z') {
322 (*sh) = 1;
323 return qwerty[c - 'A'];
324 }
325 if ('1' <= c && c <= '9') return c - '1' + 2;
326 if (c == '0') return 11;
327 if (32 <= c && c <= 47) {
328 (*sh) = spec1sh[c - 32];
329 return spec1[c - 32];
330 }
331 if (58 <= c && c <= 64) {
332 (*sh) = spec2sh[c - 58];
333 return spec2[c - 58];
334 }
335 if (91 <= c && c <= 96) {
336 (*sh) = spec3sh[c - 91];
337 return spec3[c - 91];
338 }
339 if (123 <= c && c <= 127) {
340 (*sh) = spec4sh[c - 123];
341 return spec4[c - 123];
342 }
343 switch (c) {
344 case 0xff08:
345 return 14; // backspace
346 case 0xff09:
347 return 15; // tab
348 case 1:
349 (*alt) = 1;
350 return 34; // ctrl+a
351 case 3:
352 (*alt) = 1;
353 return 46; // ctrl+c
354 case 4:
355 (*alt) = 1;
356 return 32; // ctrl+d
357 case 18:
358 (*alt) = 1;
359 return 31; // ctrl+r
360 case 0xff0D:
361 return 28; // enter
362 case 0xff1B:
363 return 158; // esc -> back
364 case 0xFF51:
365 return 105; // left -> DPAD_LEFT
366 case 0xFF53:
367 return 106; // right -> DPAD_RIGHT
368 case 0xFF54:
369 return 108; // down -> DPAD_DOWN
370 case 0xFF52:
371 return 103; // up -> DPAD_UP
372 // case 360:
373 // return 232;// end -> DPAD_CENTER (ball click)
374 case 0xff50:
375 return KEY_HOME; // home
376 case 0xFFC8:
377 rfbShutdownServer(cl->screen, TRUE);
378 return 0; // F11 disconnect
379 case 0xffff:
380 return 158; // del -> back
381 case 0xff55:
382 return 229; // PgUp -> menu
383 case 0xffcf:
384 return 127; // F2 -> search
385 case 0xffe3:
386 return 127; // left ctrl -> search
387 case 0xff56:
388 return 61; // PgUp -> call
389 case 0xff57:
390 return 107; // End -> endcall
391 case 0xffc2:
392 return 211; // F5 -> focus
393 case 0xffc3:
394 return 212; // F6 -> camera
395 case 0xffc4:
396 return 150; // F7 -> explorer
397 case 0xffc5:
398 return 155; // F8 -> envelope
399
400 case 50081:
401 case 225:
402 (*alt) = 1;
403 if (real) return 48; // a with acute
404 return 30; // a with acute -> a with ring above
405
406 case 50049:
407 case 193:
408 (*sh) = 1;
409 (*alt) = 1;
410 if (real) return 48; // A with acute
411 return 30; // A with acute -> a with ring above
412
413 case 50089:
414 case 233:
415 (*alt) = 1;
416 return 18; // e with acute
417
418 case 50057:
419 case 201:
420 (*sh) = 1;
421 (*alt) = 1;
422 return 18; // E with acute
423
424 case 50093:
425 case 0xffbf:
426 (*alt) = 1;
427 if (real) return 36; // i with acute
428 return 23; // i with acute -> i with grave
429
430 case 50061:
431 case 205:
432 (*sh) = 1;
433 (*alt) = 1;
434 if (real) return 36; // I with acute
435 return 23; // I with acute -> i with grave
436
437 case 50099:
438 case 243:
439 (*alt) = 1;
440 if (real) return 16; // o with acute
441 return 24; // o with acute -> o with grave
442
443 case 50067:
444 case 211:
445 (*sh) = 1;
446 (*alt) = 1;
447 if (real) return 16; // O with acute
448 return 24; // O with acute -> o with grave
449
450 case 50102:
451 case 246:
452 (*alt) = 1;
453 return 25; // o with diaeresis
454
455 case 50070:
456 case 214:
457 (*sh) = 1;
458 (*alt) = 1;
459 return 25; // O with diaeresis
460
461 case 50577:
462 case 245:
463 (*alt) = 1;
464 if (real) return 19; // Hungarian o
465 return 25; // Hungarian o -> o with diaeresis
466
467 case 50576:
468 case 213:
469 (*sh) = 1;
470 (*alt) = 1;
471 if (real) return 19; // Hungarian O
472 return 25; // Hungarian O -> O with diaeresis
473
474 case 50106:
475 // case 0xffbe:
476 // (*alt)=1;
477 // if (real)
478 // return 17; //u with acute
479 // return 22; //u with acute -> u with grave
480 case 50074:
481 case 218:
482 (*sh) = 1;
483 (*alt) = 1;
484 if (real) return 17; // U with acute
485 return 22; // U with acute -> u with grave
486 case 50108:
487 case 252:
488 (*alt) = 1;
489 return 47; // u with diaeresis
490
491 case 50076:
492 case 220:
493 (*sh) = 1;
494 (*alt) = 1;
495 return 47; // U with diaeresis
496
497 case 50609:
498 case 251:
499 (*alt) = 1;
500 if (real) return 45; // Hungarian u
501 return 47; // Hungarian u -> u with diaeresis
502
503 case 50608:
504 case 219:
505 (*sh) = 1;
506 (*alt) = 1;
507 if (real) return 45; // Hungarian U
508 return 47; // Hungarian U -> U with diaeresis
509 }
510 return 0;
511}