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