📄 usb-hid.c
字号:
if (!s->mouse_grabbed) { s->eh_entry = qemu_add_mouse_event_handler(usb_tablet_event, s, 1, "QEMU USB Tablet"); s->mouse_grabbed = 1; } dz = int_clamp(s->dz, -128, 127); s->dz -= dz; /* Appears we have to invert the wheel direction */ dz = 0 - dz; b = 0; if (s->buttons_state & MOUSE_EVENT_LBUTTON) b |= 0x01; if (s->buttons_state & MOUSE_EVENT_RBUTTON) b |= 0x02; if (s->buttons_state & MOUSE_EVENT_MBUTTON) b |= 0x04; buf[0] = b; buf[1] = s->x & 0xff; buf[2] = s->x >> 8; buf[3] = s->y & 0xff; buf[4] = s->y >> 8; buf[5] = dz; l = 6; return l;}static void usb_mouse_handle_reset(USBDevice *dev){ USBMouseState *s = (USBMouseState *)dev; s->dx = 0; s->dy = 0; s->dz = 0; s->x = 0; s->y = 0; s->buttons_state = 0;}static int usb_mouse_handle_control(USBDevice *dev, int request, int value, int index, int length, uint8_t *data){ USBMouseState *s = (USBMouseState *)dev; int ret = 0; switch(request) { case DeviceRequest | USB_REQ_GET_STATUS: data[0] = (1 << USB_DEVICE_SELF_POWERED) | (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP); data[1] = 0x00; ret = 2; break; case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: if (value == USB_DEVICE_REMOTE_WAKEUP) { dev->remote_wakeup = 0; } else { goto fail; } ret = 0; break; case DeviceOutRequest | USB_REQ_SET_FEATURE: if (value == USB_DEVICE_REMOTE_WAKEUP) { dev->remote_wakeup = 1; } else { goto fail; } ret = 0; break; case DeviceOutRequest | USB_REQ_SET_ADDRESS: dev->addr = value; ret = 0; break; case DeviceRequest | USB_REQ_GET_DESCRIPTOR: switch(value >> 8) { case USB_DT_DEVICE: memcpy(data, qemu_mouse_dev_descriptor, sizeof(qemu_mouse_dev_descriptor)); ret = sizeof(qemu_mouse_dev_descriptor); break; case USB_DT_CONFIG: if (s->kind == USB_MOUSE) { memcpy(data, qemu_mouse_config_descriptor, sizeof(qemu_mouse_config_descriptor)); ret = sizeof(qemu_mouse_config_descriptor); } else if (s->kind == USB_TABLET) { memcpy(data, qemu_tablet_config_descriptor, sizeof(qemu_tablet_config_descriptor)); ret = sizeof(qemu_tablet_config_descriptor); } break; case USB_DT_STRING: switch(value & 0xff) { case 0: /* language ids */ data[0] = 4; data[1] = 3; data[2] = 0x09; data[3] = 0x04; ret = 4; break; case 1: /* serial number */ ret = set_usb_string(data, "1"); break; case 2: /* product description */ if (s->kind == USB_MOUSE) ret = set_usb_string(data, "QEMU USB Mouse"); else if (s->kind == USB_TABLET) ret = set_usb_string(data, "QEMU USB Tablet"); break; case 3: /* vendor description */ ret = set_usb_string(data, "QEMU " QEMU_VERSION); break; case 4: ret = set_usb_string(data, "HID Mouse"); break; case 5: ret = set_usb_string(data, "Endpoint1 Interrupt Pipe"); break; default: goto fail; } break; default: goto fail; } break; case DeviceRequest | USB_REQ_GET_CONFIGURATION: data[0] = 1; ret = 1; break; case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: ret = 0; break; case DeviceRequest | USB_REQ_GET_INTERFACE: data[0] = 0; ret = 1; break; case DeviceOutRequest | USB_REQ_SET_INTERFACE: ret = 0; break; /* hid specific requests */ case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: switch(value >> 8) { case 0x22: if (s->kind == USB_MOUSE) { memcpy(data, qemu_mouse_hid_report_descriptor, sizeof(qemu_mouse_hid_report_descriptor)); ret = sizeof(qemu_mouse_hid_report_descriptor); } else if (s->kind == USB_TABLET) { memcpy(data, qemu_tablet_hid_report_descriptor, sizeof(qemu_tablet_hid_report_descriptor)); ret = sizeof(qemu_tablet_hid_report_descriptor); } break; default: goto fail; } break; case GET_REPORT: if (s->kind == USB_MOUSE) ret = usb_mouse_poll(s, data, length); else if (s->kind == USB_TABLET) ret = usb_tablet_poll(s, data, length); break; case SET_IDLE: ret = 0; break; default: fail: ret = USB_RET_STALL; break; } return ret;}static int usb_mouse_handle_data(USBDevice *dev, USBPacket *p){ USBMouseState *s = (USBMouseState *)dev; int ret = 0; switch(p->pid) { case USB_TOKEN_IN: if (p->devep == 1) { if (s->kind == USB_MOUSE) ret = usb_mouse_poll(s, p->data, p->len); else if (s->kind == USB_TABLET) ret = usb_tablet_poll(s, p->data, p->len); if (!s->status_changed) { ret = USB_RET_NAK; } else { if (head != tail) { s->buttons_state = head->button_state; head = head->next; } else { s->status_changed = 0; } } } else { goto fail; } break; case USB_TOKEN_OUT: default: fail: ret = USB_RET_STALL; break; } return ret;}static void usb_mouse_handle_destroy(USBDevice *dev){ USBMouseState *s = (USBMouseState *)dev; qemu_remove_mouse_event_handler(s->eh_entry); qemu_free(s);}void usb_mouse_save(QEMUFile *f, void *opaque){ USBMouseState *s = (USBMouseState*)opaque; qemu_put_be32s(f, &s->dx); qemu_put_be32s(f, &s->dy); qemu_put_be32s(f, &s->dz); qemu_put_be32s(f, &s->buttons_state); qemu_put_be32s(f, &s->x); qemu_put_be32s(f, &s->y); qemu_put_be32s(f, &s->kind); qemu_put_be32s(f, &s->mouse_grabbed); qemu_put_be32s(f, &s->status_changed);}int usb_mouse_load(QEMUFile *f, void *opaque, int version_id){ USBMouseState *s = (USBMouseState*)opaque; if (version_id != 1) return -EINVAL; qemu_get_be32s(f, &s->dx); qemu_get_be32s(f, &s->dy); qemu_get_be32s(f, &s->dz); qemu_get_be32s(f, &s->buttons_state); qemu_get_be32s(f, &s->x); qemu_get_be32s(f, &s->y); qemu_get_be32s(f, &s->kind); qemu_get_be32s(f, &s->mouse_grabbed); qemu_get_be32s(f, &s->status_changed); if ( s->kind == USB_TABLET) { fprintf(logfile, "usb_mouse_load:add usb_tablet_event.\n"); qemu_add_mouse_event_handler(usb_tablet_event, s, 1, "QEMU USB Tablet"); } else if ( s->kind == USB_MOUSE) { fprintf(logfile, "usb_mouse_load:add usb_mouse_event.\n"); qemu_add_mouse_event_handler(usb_mouse_event, s, 0, "QEMU USB MOUSE"); } return 0;}USBDevice *usb_tablet_init(void){ USBMouseState *s; int i; for (i = 0; i < 19; i++) { mousequeue[i].button_state = 0; mousequeue[i].next = &(mousequeue[i + 1]); } mousequeue[i].button_state = 0; mousequeue[i].next = mousequeue; s = qemu_mallocz(sizeof(USBMouseState)); if (!s) return NULL; s->dev.speed = USB_SPEED_FULL; s->dev.handle_packet = usb_generic_handle_packet; s->dev.handle_reset = usb_mouse_handle_reset; s->dev.handle_control = usb_mouse_handle_control; s->dev.handle_data = usb_mouse_handle_data; s->dev.handle_destroy = usb_mouse_handle_destroy; s->kind = USB_TABLET; s->status_changed = 0; pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet"); register_savevm("USB tablet dev", 0, 1, usb_mouse_save, usb_mouse_load, s); return (USBDevice *)s;}USBDevice *usb_mouse_init(void){ USBMouseState *s; int i; for (i = 0; i < 19; i++) { mousequeue[i].button_state = 0; mousequeue[i].next = &(mousequeue[i + 1]); } mousequeue[i].button_state = 0; mousequeue[i].next = mousequeue; s = qemu_mallocz(sizeof(USBMouseState)); if (!s) return NULL; s->dev.speed = USB_SPEED_FULL; s->dev.handle_packet = usb_generic_handle_packet; s->dev.handle_reset = usb_mouse_handle_reset; s->dev.handle_control = usb_mouse_handle_control; s->dev.handle_data = usb_mouse_handle_data; s->dev.handle_destroy = usb_mouse_handle_destroy; s->kind = USB_MOUSE; s->status_changed = 0; pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse"); register_savevm("USB mouse dev", 0, 1, usb_mouse_save, usb_mouse_load, s); return (USBDevice *)s;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -