📄 usb-hid.c
字号:
s->dx -= dx; s->dy -= dy; s->dz -= 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] = dx; buf[2] = dy; l = 3; if (len >= 4) { buf[3] = dz; l = 4; } return l;}static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len){ int dz, b, l; if (!s->mouse_grabbed) { qemu_add_mouse_event_handler(usb_tablet_event, s, 1); 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, int pid, uint8_t devep, uint8_t *data, int len){ USBMouseState *s = (USBMouseState *)dev; int ret = 0; switch(pid) { case USB_TOKEN_IN: if (devep == 1) { if (s->kind == USB_MOUSE) ret = usb_mouse_poll(s, data, len); else if (s->kind == USB_TABLET) ret = usb_tablet_poll(s, data, len); } else { goto fail; } break; case USB_TOKEN_OUT: default: fail: ret = USB_RET_STALL; break; } return ret;}USBDevice *usb_tablet_init(void){ USBMouseState *s; 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->kind = USB_TABLET; return (USBDevice *)s;}USBDevice *usb_mouse_init(void){ USBMouseState *s; 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->kind = USB_MOUSE; return (USBDevice *)s;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -