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