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