2
0

input-linux.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /*
  2. * This work is licensed under the terms of the GNU GPL, version 2 or
  3. * (at your option) any later version. See the COPYING file in the
  4. * top-level directory.
  5. */
  6. #include "qemu/osdep.h"
  7. #include "qapi/error.h"
  8. #include "qemu/config-file.h"
  9. #include "qemu/main-loop.h"
  10. #include "qemu/module.h"
  11. #include "qemu/sockets.h"
  12. #include "ui/input.h"
  13. #include "qom/object_interfaces.h"
  14. #include "sysemu/iothread.h"
  15. #include "block/aio.h"
  16. #include <sys/ioctl.h>
  17. #include "standard-headers/linux/input.h"
  18. #include "qom/object.h"
  19. static bool linux_is_button(unsigned int lnx)
  20. {
  21. if (lnx < 0x100) {
  22. return false;
  23. }
  24. if (lnx >= 0x160 && lnx < 0x2c0) {
  25. return false;
  26. }
  27. return true;
  28. }
  29. #define TYPE_INPUT_LINUX "input-linux"
  30. OBJECT_DECLARE_SIMPLE_TYPE(InputLinux,
  31. INPUT_LINUX)
  32. struct InputLinux {
  33. Object parent;
  34. char *evdev;
  35. int fd;
  36. bool repeat;
  37. bool grab_request;
  38. bool grab_active;
  39. bool grab_all;
  40. bool keydown[KEY_CNT];
  41. int keycount;
  42. int wheel;
  43. bool initialized;
  44. bool has_rel_x;
  45. bool has_abs_x;
  46. int num_keys;
  47. int num_btns;
  48. int abs_x_min;
  49. int abs_x_max;
  50. int abs_y_min;
  51. int abs_y_max;
  52. struct input_event event;
  53. int read_offset;
  54. enum GrabToggleKeys grab_toggle;
  55. QTAILQ_ENTRY(InputLinux) next;
  56. };
  57. static QTAILQ_HEAD(, InputLinux) inputs = QTAILQ_HEAD_INITIALIZER(inputs);
  58. static void input_linux_toggle_grab(InputLinux *il)
  59. {
  60. intptr_t request = !il->grab_active;
  61. InputLinux *item;
  62. int rc;
  63. rc = ioctl(il->fd, EVIOCGRAB, request);
  64. if (rc < 0) {
  65. return;
  66. }
  67. il->grab_active = !il->grab_active;
  68. if (!il->grab_all) {
  69. return;
  70. }
  71. QTAILQ_FOREACH(item, &inputs, next) {
  72. if (item == il || item->grab_all) {
  73. /* avoid endless loops */
  74. continue;
  75. }
  76. if (item->grab_active != il->grab_active) {
  77. input_linux_toggle_grab(item);
  78. }
  79. }
  80. }
  81. static bool input_linux_check_toggle(InputLinux *il)
  82. {
  83. switch (il->grab_toggle) {
  84. case GRAB_TOGGLE_KEYS_CTRL_CTRL:
  85. return il->keydown[KEY_LEFTCTRL] &&
  86. il->keydown[KEY_RIGHTCTRL];
  87. case GRAB_TOGGLE_KEYS_ALT_ALT:
  88. return il->keydown[KEY_LEFTALT] &&
  89. il->keydown[KEY_RIGHTALT];
  90. case GRAB_TOGGLE_KEYS_SHIFT_SHIFT:
  91. return il->keydown[KEY_LEFTSHIFT] &&
  92. il->keydown[KEY_RIGHTSHIFT];
  93. case GRAB_TOGGLE_KEYS_META_META:
  94. return il->keydown[KEY_LEFTMETA] &&
  95. il->keydown[KEY_RIGHTMETA];
  96. case GRAB_TOGGLE_KEYS_SCROLLLOCK:
  97. return il->keydown[KEY_SCROLLLOCK];
  98. case GRAB_TOGGLE_KEYS_CTRL_SCROLLLOCK:
  99. return (il->keydown[KEY_LEFTCTRL] ||
  100. il->keydown[KEY_RIGHTCTRL]) &&
  101. il->keydown[KEY_SCROLLLOCK];
  102. case GRAB_TOGGLE_KEYS__MAX:
  103. /* avoid gcc error */
  104. break;
  105. }
  106. return false;
  107. }
  108. static bool input_linux_should_skip(InputLinux *il,
  109. struct input_event *event)
  110. {
  111. return (il->grab_toggle == GRAB_TOGGLE_KEYS_SCROLLLOCK ||
  112. il->grab_toggle == GRAB_TOGGLE_KEYS_CTRL_SCROLLLOCK) &&
  113. event->code == KEY_SCROLLLOCK;
  114. }
  115. static void input_linux_handle_keyboard(InputLinux *il,
  116. struct input_event *event)
  117. {
  118. if (event->type == EV_KEY) {
  119. if (event->value > 2 || (event->value > 1 && !il->repeat)) {
  120. /*
  121. * ignore autorepeat + unknown key events
  122. * 0 == up, 1 == down, 2 == autorepeat, other == undefined
  123. */
  124. return;
  125. }
  126. if (event->code >= KEY_CNT) {
  127. /*
  128. * Should not happen. But better safe than sorry,
  129. * and we make Coverity happy too.
  130. */
  131. return;
  132. }
  133. /* keep track of key state */
  134. if (!il->keydown[event->code] && event->value) {
  135. il->keydown[event->code] = true;
  136. il->keycount++;
  137. }
  138. if (il->keydown[event->code] && !event->value) {
  139. il->keydown[event->code] = false;
  140. il->keycount--;
  141. }
  142. /* send event to guest when grab is active */
  143. if (il->grab_active && !input_linux_should_skip(il, event)) {
  144. int qcode = qemu_input_linux_to_qcode(event->code);
  145. qemu_input_event_send_key_qcode(NULL, qcode, event->value);
  146. }
  147. /* hotkey -> record switch request ... */
  148. if (input_linux_check_toggle(il)) {
  149. il->grab_request = true;
  150. }
  151. /*
  152. * ... and do the switch when all keys are lifted, so we
  153. * confuse neither guest nor host with keys which seem to
  154. * be stuck due to missing key-up events.
  155. */
  156. if (il->grab_request && !il->keycount) {
  157. il->grab_request = false;
  158. input_linux_toggle_grab(il);
  159. }
  160. }
  161. }
  162. static void input_linux_event_mouse_button(int button)
  163. {
  164. qemu_input_queue_btn(NULL, button, true);
  165. qemu_input_event_sync();
  166. qemu_input_queue_btn(NULL, button, false);
  167. qemu_input_event_sync();
  168. }
  169. static void input_linux_handle_mouse(InputLinux *il, struct input_event *event)
  170. {
  171. if (!il->grab_active) {
  172. return;
  173. }
  174. switch (event->type) {
  175. case EV_KEY:
  176. switch (event->code) {
  177. case BTN_LEFT:
  178. qemu_input_queue_btn(NULL, INPUT_BUTTON_LEFT, event->value);
  179. break;
  180. case BTN_RIGHT:
  181. qemu_input_queue_btn(NULL, INPUT_BUTTON_RIGHT, event->value);
  182. break;
  183. case BTN_MIDDLE:
  184. qemu_input_queue_btn(NULL, INPUT_BUTTON_MIDDLE, event->value);
  185. break;
  186. case BTN_GEAR_UP:
  187. qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_UP, event->value);
  188. break;
  189. case BTN_GEAR_DOWN:
  190. qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_DOWN,
  191. event->value);
  192. break;
  193. case BTN_SIDE:
  194. qemu_input_queue_btn(NULL, INPUT_BUTTON_SIDE, event->value);
  195. break;
  196. case BTN_EXTRA:
  197. qemu_input_queue_btn(NULL, INPUT_BUTTON_EXTRA, event->value);
  198. break;
  199. };
  200. break;
  201. case EV_REL:
  202. switch (event->code) {
  203. case REL_X:
  204. qemu_input_queue_rel(NULL, INPUT_AXIS_X, event->value);
  205. break;
  206. case REL_Y:
  207. qemu_input_queue_rel(NULL, INPUT_AXIS_Y, event->value);
  208. break;
  209. case REL_WHEEL:
  210. il->wheel = event->value;
  211. break;
  212. }
  213. break;
  214. case EV_ABS:
  215. switch (event->code) {
  216. case ABS_X:
  217. qemu_input_queue_abs(NULL, INPUT_AXIS_X, event->value,
  218. il->abs_x_min, il->abs_x_max);
  219. break;
  220. case ABS_Y:
  221. qemu_input_queue_abs(NULL, INPUT_AXIS_Y, event->value,
  222. il->abs_y_min, il->abs_y_max);
  223. break;
  224. }
  225. break;
  226. case EV_SYN:
  227. qemu_input_event_sync();
  228. if (il->wheel != 0) {
  229. input_linux_event_mouse_button((il->wheel > 0)
  230. ? INPUT_BUTTON_WHEEL_UP
  231. : INPUT_BUTTON_WHEEL_DOWN);
  232. il->wheel = 0;
  233. }
  234. break;
  235. }
  236. }
  237. static void input_linux_event(void *opaque)
  238. {
  239. InputLinux *il = opaque;
  240. int rc;
  241. int read_size;
  242. uint8_t *p = (uint8_t *)&il->event;
  243. for (;;) {
  244. read_size = sizeof(il->event) - il->read_offset;
  245. rc = read(il->fd, &p[il->read_offset], read_size);
  246. if (rc != read_size) {
  247. if (rc < 0 && errno != EAGAIN) {
  248. fprintf(stderr, "%s: read: %s\n", __func__, strerror(errno));
  249. qemu_set_fd_handler(il->fd, NULL, NULL, NULL);
  250. close(il->fd);
  251. } else if (rc > 0) {
  252. il->read_offset += rc;
  253. }
  254. break;
  255. }
  256. il->read_offset = 0;
  257. if (il->num_keys) {
  258. input_linux_handle_keyboard(il, &il->event);
  259. }
  260. if ((il->has_rel_x || il->has_abs_x) && il->num_btns) {
  261. input_linux_handle_mouse(il, &il->event);
  262. }
  263. }
  264. }
  265. static void input_linux_complete(UserCreatable *uc, Error **errp)
  266. {
  267. InputLinux *il = INPUT_LINUX(uc);
  268. uint8_t evtmap, relmap, absmap;
  269. uint8_t keymap[KEY_CNT / 8], keystate[KEY_CNT / 8];
  270. unsigned int i;
  271. int rc, ver;
  272. struct input_absinfo absinfo;
  273. if (!il->evdev) {
  274. error_setg(errp, "no input device specified");
  275. return;
  276. }
  277. il->fd = open(il->evdev, O_RDWR);
  278. if (il->fd < 0) {
  279. error_setg_file_open(errp, errno, il->evdev);
  280. return;
  281. }
  282. qemu_set_nonblock(il->fd);
  283. rc = ioctl(il->fd, EVIOCGVERSION, &ver);
  284. if (rc < 0) {
  285. error_setg(errp, "%s: is not an evdev device", il->evdev);
  286. goto err_close;
  287. }
  288. rc = ioctl(il->fd, EVIOCGBIT(0, sizeof(evtmap)), &evtmap);
  289. if (rc < 0) {
  290. goto err_read_event_bits;
  291. }
  292. if (evtmap & (1 << EV_REL)) {
  293. relmap = 0;
  294. rc = ioctl(il->fd, EVIOCGBIT(EV_REL, sizeof(relmap)), &relmap);
  295. if (rc < 0) {
  296. goto err_read_event_bits;
  297. }
  298. if (relmap & (1 << REL_X)) {
  299. il->has_rel_x = true;
  300. }
  301. }
  302. if (evtmap & (1 << EV_ABS)) {
  303. absmap = 0;
  304. rc = ioctl(il->fd, EVIOCGBIT(EV_ABS, sizeof(absmap)), &absmap);
  305. if (rc < 0) {
  306. goto err_read_event_bits;
  307. }
  308. if (absmap & (1 << ABS_X)) {
  309. il->has_abs_x = true;
  310. rc = ioctl(il->fd, EVIOCGABS(ABS_X), &absinfo);
  311. if (rc < 0) {
  312. error_setg(errp, "%s: failed to get get absolute X value",
  313. il->evdev);
  314. goto err_close;
  315. }
  316. il->abs_x_min = absinfo.minimum;
  317. il->abs_x_max = absinfo.maximum;
  318. rc = ioctl(il->fd, EVIOCGABS(ABS_Y), &absinfo);
  319. if (rc < 0) {
  320. error_setg(errp, "%s: failed to get get absolute Y value",
  321. il->evdev);
  322. goto err_close;
  323. }
  324. il->abs_y_min = absinfo.minimum;
  325. il->abs_y_max = absinfo.maximum;
  326. }
  327. }
  328. if (evtmap & (1 << EV_KEY)) {
  329. memset(keymap, 0, sizeof(keymap));
  330. rc = ioctl(il->fd, EVIOCGBIT(EV_KEY, sizeof(keymap)), keymap);
  331. if (rc < 0) {
  332. goto err_read_event_bits;
  333. }
  334. rc = ioctl(il->fd, EVIOCGKEY(sizeof(keystate)), keystate);
  335. if (rc < 0) {
  336. error_setg(errp, "%s: failed to get global key state", il->evdev);
  337. goto err_close;
  338. }
  339. for (i = 0; i < KEY_CNT; i++) {
  340. if (keymap[i / 8] & (1 << (i % 8))) {
  341. if (linux_is_button(i)) {
  342. il->num_btns++;
  343. } else {
  344. il->num_keys++;
  345. }
  346. if (keystate[i / 8] & (1 << (i % 8))) {
  347. il->keydown[i] = true;
  348. il->keycount++;
  349. }
  350. }
  351. }
  352. }
  353. qemu_set_fd_handler(il->fd, input_linux_event, NULL, il);
  354. if (il->keycount) {
  355. /* delay grab until all keys are released */
  356. il->grab_request = true;
  357. } else {
  358. input_linux_toggle_grab(il);
  359. }
  360. QTAILQ_INSERT_TAIL(&inputs, il, next);
  361. il->initialized = true;
  362. return;
  363. err_read_event_bits:
  364. error_setg(errp, "%s: failed to read event bits", il->evdev);
  365. err_close:
  366. close(il->fd);
  367. return;
  368. }
  369. static void input_linux_instance_finalize(Object *obj)
  370. {
  371. InputLinux *il = INPUT_LINUX(obj);
  372. if (il->initialized) {
  373. QTAILQ_REMOVE(&inputs, il, next);
  374. qemu_set_fd_handler(il->fd, NULL, NULL, NULL);
  375. close(il->fd);
  376. }
  377. g_free(il->evdev);
  378. }
  379. static char *input_linux_get_evdev(Object *obj, Error **errp)
  380. {
  381. InputLinux *il = INPUT_LINUX(obj);
  382. return g_strdup(il->evdev);
  383. }
  384. static void input_linux_set_evdev(Object *obj, const char *value,
  385. Error **errp)
  386. {
  387. InputLinux *il = INPUT_LINUX(obj);
  388. if (il->evdev) {
  389. error_setg(errp, "evdev property already set");
  390. return;
  391. }
  392. il->evdev = g_strdup(value);
  393. }
  394. static bool input_linux_get_grab_all(Object *obj, Error **errp)
  395. {
  396. InputLinux *il = INPUT_LINUX(obj);
  397. return il->grab_all;
  398. }
  399. static void input_linux_set_grab_all(Object *obj, bool value,
  400. Error **errp)
  401. {
  402. InputLinux *il = INPUT_LINUX(obj);
  403. il->grab_all = value;
  404. }
  405. static bool input_linux_get_repeat(Object *obj, Error **errp)
  406. {
  407. InputLinux *il = INPUT_LINUX(obj);
  408. return il->repeat;
  409. }
  410. static void input_linux_set_repeat(Object *obj, bool value,
  411. Error **errp)
  412. {
  413. InputLinux *il = INPUT_LINUX(obj);
  414. il->repeat = value;
  415. }
  416. static int input_linux_get_grab_toggle(Object *obj, Error **errp)
  417. {
  418. InputLinux *il = INPUT_LINUX(obj);
  419. return il->grab_toggle;
  420. }
  421. static void input_linux_set_grab_toggle(Object *obj, int value,
  422. Error **errp)
  423. {
  424. InputLinux *il = INPUT_LINUX(obj);
  425. il->grab_toggle = value;
  426. }
  427. static void input_linux_instance_init(Object *obj)
  428. {
  429. }
  430. static void input_linux_class_init(ObjectClass *oc, void *data)
  431. {
  432. UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
  433. ucc->complete = input_linux_complete;
  434. object_class_property_add_str(oc, "evdev",
  435. input_linux_get_evdev,
  436. input_linux_set_evdev);
  437. object_class_property_add_bool(oc, "grab_all",
  438. input_linux_get_grab_all,
  439. input_linux_set_grab_all);
  440. object_class_property_add_bool(oc, "repeat",
  441. input_linux_get_repeat,
  442. input_linux_set_repeat);
  443. object_class_property_add_enum(oc, "grab-toggle", "GrabToggleKeys",
  444. &GrabToggleKeys_lookup,
  445. input_linux_get_grab_toggle,
  446. input_linux_set_grab_toggle);
  447. }
  448. static const TypeInfo input_linux_info = {
  449. .name = TYPE_INPUT_LINUX,
  450. .parent = TYPE_OBJECT,
  451. .class_init = input_linux_class_init,
  452. .instance_size = sizeof(InputLinux),
  453. .instance_init = input_linux_instance_init,
  454. .instance_finalize = input_linux_instance_finalize,
  455. .interfaces = (InterfaceInfo[]) {
  456. { TYPE_USER_CREATABLE },
  457. { }
  458. }
  459. };
  460. static void register_types(void)
  461. {
  462. type_register_static(&input_linux_info);
  463. }
  464. type_init(register_types);