Changeset 26682 in vbox for trunk/src/VBox/Devices/Input
- Timestamp:
- Feb 22, 2010 4:42:55 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Input/UsbMouse.cpp
r26495 r26682 32 32 * @{ */ 33 33 #define USBHID_STR_ID_MANUFACTURER 1 34 #define USBHID_STR_ID_PRODUCT 2 34 #define USBHID_STR_ID_PRODUCT_M 2 35 #define USBHID_STR_ID_PRODUCT_T 3 35 36 /** @} */ 36 37 … … 44 45 #define VBOX_USB_VENDOR 0x80EE 45 46 #define USBHID_PID_MOUSE 0x0020 47 #define USBHID_PID_TABLET 0x0021 46 48 /** @} */ 47 49 … … 142 144 bool fHaveDoneQueueWaiter; 143 145 146 /** Is this an absolute pointing device (tablet)? Relative (mouse) otherwise. */ 147 bool isAbsolute; 148 144 149 /** 145 150 * Mouse port - LUN#0. … … 166 171 167 172 /** 168 * The USB HID report structure .173 * The USB HID report structure for relative device. 169 174 */ 170 175 typedef struct USBHIDM_REPORT … … 176 181 } USBHIDM_REPORT, *PUSBHIDM_REPORT; 177 182 183 /** 184 * The USB HID report structure for relative device. 185 */ 186 187 typedef struct USBHIDT_REPORT 188 { 189 uint16_t cx; 190 uint16_t cy; 191 int8_t dz; 192 uint8_t btn; 193 } USBHIDT_REPORT, *PUSBHIDT_REPORT; 194 178 195 /******************************************************************************* 179 196 * Global Variables * … … 182 199 { 183 200 { USBHID_STR_ID_MANUFACTURER, "VirtualBox" }, 184 { USBHID_STR_ID_PRODUCT, "USB Mouse" }, 201 { USBHID_STR_ID_PRODUCT_M, "USB Mouse" }, 202 { USBHID_STR_ID_PRODUCT_T, "USB Tablet" }, 185 203 }; 186 204 … … 190 208 }; 191 209 192 static const VUSBDESCENDPOINTEX g_aUsbHid EndpointDescs[] =210 static const VUSBDESCENDPOINTEX g_aUsbHidMEndpointDescs[] = 193 211 { 194 212 { … … 207 225 }; 208 226 209 /* HID report descriptor. */ 210 static const uint8_t g_UsbHidReportDesc[] = 227 static const VUSBDESCENDPOINTEX g_aUsbHidTEndpointDescs[] = 228 { 229 { 230 { 231 /* .bLength = */ sizeof(VUSBDESCENDPOINT), 232 /* .bDescriptorType = */ VUSB_DT_ENDPOINT, 233 /* .bEndpointAddress = */ 0x81 /* ep=1, in */, 234 /* .bmAttributes = */ 3 /* interrupt */, 235 /* .wMaxPacketSize = */ 6, 236 /* .bInterval = */ 10, 237 }, 238 /* .pvMore = */ NULL, 239 /* .pvClass = */ NULL, 240 /* .cbClass = */ 0 241 }, 242 }; 243 244 /* HID report descriptor (mouse). */ 245 static const uint8_t g_UsbHidMReportDesc[] = 211 246 { 212 247 /* Usage Page */ 0x05, 0x01, /* Generic Desktop */ … … 239 274 }; 240 275 276 /* HID report descriptor (tablet). */ 277 static const uint8_t g_UsbHidTReportDesc[] = 278 { 279 /* Usage Page */ 0x05, 0x01, /* Generic Desktop */ 280 /* Usage */ 0x09, 0x02, /* Mouse */ 281 /* Collection */ 0xA1, 0x01, /* Application */ 282 /* Usage */ 0x09, 0x01, /* Pointer */ 283 /* Collection */ 0xA1, 0x00, /* Physical */ 284 /* Usage Page */ 0x05, 0x01, /* Generic Desktop */ 285 /* Usage */ 0x09, 0x30, /* X */ 286 /* Usage */ 0x09, 0x31, /* Y */ 287 /* Logical Minimum */ 0x15, 0x00, /* 0 */ 288 /* Logical Maximum */ 0x26, 0xFF,0x7F,/* 0x7fff */ 289 /* Physical Minimum */ 0x35, 0x00, /* 0 */ 290 /* Physical Maximum */ 0x46, 0xFF,0x7F,/* 0x7fff */ 291 /* Report Size */ 0x75, 0x10, /* 16 */ 292 /* Report Count */ 0x95, 0x02, /* 2 */ 293 /* Input */ 0x81, 0x02, /* Data, Value, Absolute, Bit field */ 294 /* Usage Page */ 0x05, 0x01, /* Generic Desktop */ 295 /* Usage */ 0x09, 0x38, /* Z (wheel) */ 296 /* Logical Minimum */ 0x15, 0x81, /* -127 */ 297 /* Logical Maximum */ 0x25, 0x7F, /* +127 */ 298 /* Report Size */ 0x75, 0x08, /* 8 */ 299 /* Report Count */ 0x95, 0x01, /* 1 */ 300 /* Input */ 0x81, 0x06, /* Data, Value, Relative, Bit field */ 301 /* Usage Page */ 0x05, 0x09, /* Button */ 302 /* Usage Minimum */ 0x19, 0x01, /* Button 1 */ 303 /* Usage Maximum */ 0x29, 0x03, /* Button 3 */ 304 /* Logical Minimum */ 0x15, 0x00, /* 0 */ 305 /* Logical Maximum */ 0x25, 0x01, /* 1 */ 306 /* Report Count */ 0x95, 0x03, /* 3 */ 307 /* Report Size */ 0x75, 0x01, /* 1 */ 308 /* Input */ 0x81, 0x02, /* Data, Value, Absolute, Bit field */ 309 /* Report Count */ 0x95, 0x01, /* 1 */ 310 /* Report Size */ 0x75, 0x05, /* 5 (padding bits) */ 311 /* Input */ 0x81, 0x03, /* Constant, Value, Absolute, Bit field */ 312 /* End Collection */ 0xC0, 313 /* End Collection */ 0xC0, 314 }; 315 241 316 /* Additional HID class interface descriptor. */ 242 static const uint8_t g_UsbHid IfHidDesc[] =317 static const uint8_t g_UsbHidMIfHidDesc[] = 243 318 { 244 319 /* .bLength = */ 0x09, … … 248 323 /* .bNumDescriptors = */ 1, 249 324 /* .bDescriptorType = */ 0x22, /* Report */ 250 /* .wDescriptorLength = */ sizeof(g_UsbHidReportDesc), 0x00 251 }; 252 253 static const VUSBDESCINTERFACEEX g_UsbHidInterfaceDesc = 325 /* .wDescriptorLength = */ sizeof(g_UsbHidMReportDesc), 0x00 326 }; 327 328 /* Additional HID class interface descriptor. */ 329 static const uint8_t g_UsbHidTIfHidDesc[] = 330 { 331 /* .bLength = */ 0x09, 332 /* .bDescriptorType = */ 0x21, /* HID */ 333 /* .bcdHID = */ 0x10, 0x01, /* 1.1 */ 334 /* .bCountryCode = */ 0, 335 /* .bNumDescriptors = */ 1, 336 /* .bDescriptorType = */ 0x22, /* Report */ 337 /* .wDescriptorLength = */ sizeof(g_UsbHidTReportDesc), 0x00 338 }; 339 340 static const VUSBDESCINTERFACEEX g_UsbHidMInterfaceDesc = 254 341 { 255 342 { … … 265 352 }, 266 353 /* .pvMore = */ NULL, 267 /* .pvClass = */ &g_UsbHidIfHidDesc, 268 /* .cbClass = */ sizeof(g_UsbHidIfHidDesc), 269 &g_aUsbHidEndpointDescs[0] 270 }; 271 272 static const VUSBINTERFACE g_aUsbHidInterfaces[] = 273 { 274 { &g_UsbHidInterfaceDesc, /* .cSettings = */ 1 }, 275 }; 276 277 static const VUSBDESCCONFIGEX g_UsbHidConfigDesc = 354 /* .pvClass = */ &g_UsbHidMIfHidDesc, 355 /* .cbClass = */ sizeof(g_UsbHidMIfHidDesc), 356 &g_aUsbHidMEndpointDescs[0] 357 }; 358 359 static const VUSBDESCINTERFACEEX g_UsbHidTInterfaceDesc = 360 { 361 { 362 /* .bLength = */ sizeof(VUSBDESCINTERFACE), 363 /* .bDescriptorType = */ VUSB_DT_INTERFACE, 364 /* .bInterfaceNumber = */ 0, 365 /* .bAlternateSetting = */ 0, 366 /* .bNumEndpoints = */ 1, 367 /* .bInterfaceClass = */ 3 /* HID */, 368 /* .bInterfaceSubClass = */ 1 /* Boot Interface */, 369 /* .bInterfaceProtocol = */ 2 /* Mouse */, 370 /* .iInterface = */ 0 371 }, 372 /* .pvMore = */ NULL, 373 /* .pvClass = */ &g_UsbHidTIfHidDesc, 374 /* .cbClass = */ sizeof(g_UsbHidTIfHidDesc), 375 &g_aUsbHidTEndpointDescs[0] 376 }; 377 378 static const VUSBINTERFACE g_aUsbHidMInterfaces[] = 379 { 380 { &g_UsbHidMInterfaceDesc, /* .cSettings = */ 1 }, 381 }; 382 383 static const VUSBINTERFACE g_aUsbHidTInterfaces[] = 384 { 385 { &g_UsbHidTInterfaceDesc, /* .cSettings = */ 1 }, 386 }; 387 388 static const VUSBDESCCONFIGEX g_UsbHidMConfigDesc = 278 389 { 279 390 { … … 281 392 /* .bDescriptorType = */ VUSB_DT_CONFIG, 282 393 /* .wTotalLength = */ 0 /* recalculated on read */, 283 /* .bNumInterfaces = */ RT_ELEMENTS(g_aUsbHid Interfaces),394 /* .bNumInterfaces = */ RT_ELEMENTS(g_aUsbHidMInterfaces), 284 395 /* .bConfigurationValue =*/ 1, 285 396 /* .iConfiguration = */ 0, … … 288 399 }, 289 400 NULL, 290 &g_aUsbHidInterfaces[0] 291 }; 292 293 static const VUSBDESCDEVICE g_UsbHidDeviceDesc = 294 { 295 /* .bLength = */ sizeof(g_UsbHidDeviceDesc), 401 &g_aUsbHidMInterfaces[0] 402 }; 403 404 static const VUSBDESCCONFIGEX g_UsbHidTConfigDesc = 405 { 406 { 407 /* .bLength = */ sizeof(VUSBDESCCONFIG), 408 /* .bDescriptorType = */ VUSB_DT_CONFIG, 409 /* .wTotalLength = */ 0 /* recalculated on read */, 410 /* .bNumInterfaces = */ RT_ELEMENTS(g_aUsbHidTInterfaces), 411 /* .bConfigurationValue =*/ 1, 412 /* .iConfiguration = */ 0, 413 /* .bmAttributes = */ RT_BIT(7), 414 /* .MaxPower = */ 50 /* 100mA */ 415 }, 416 NULL, 417 &g_aUsbHidTInterfaces[0] 418 }; 419 420 static const VUSBDESCDEVICE g_UsbHidMDeviceDesc = 421 { 422 /* .bLength = */ sizeof(g_UsbHidMDeviceDesc), 296 423 /* .bDescriptorType = */ VUSB_DT_DEVICE, 297 424 /* .bcdUsb = */ 0x110, /* 1.1 */ … … 304 431 /* .bcdDevice = */ 0x0100, /* 1.0 */ 305 432 /* .iManufacturer = */ USBHID_STR_ID_MANUFACTURER, 306 /* .iProduct = */ USBHID_STR_ID_PRODUCT ,433 /* .iProduct = */ USBHID_STR_ID_PRODUCT_M, 307 434 /* .iSerialNumber = */ 0, 308 435 /* .bNumConfigurations = */ 1 309 436 }; 310 437 311 static const PDMUSBDESCCACHE g_UsbHidDescCache = 312 { 313 /* .pDevice = */ &g_UsbHidDeviceDesc, 314 /* .paConfigs = */ &g_UsbHidConfigDesc, 438 static const VUSBDESCDEVICE g_UsbHidTDeviceDesc = 439 { 440 /* .bLength = */ sizeof(g_UsbHidTDeviceDesc), 441 /* .bDescriptorType = */ VUSB_DT_DEVICE, 442 /* .bcdUsb = */ 0x110, /* 1.1 */ 443 /* .bDeviceClass = */ 0 /* Class specified in the interface desc. */, 444 /* .bDeviceSubClass = */ 0 /* Subclass specified in the interface desc. */, 445 /* .bDeviceProtocol = */ 0 /* Protocol specified in the interface desc. */, 446 /* .bMaxPacketSize0 = */ 8, 447 /* .idVendor = */ VBOX_USB_VENDOR, 448 /* .idProduct = */ USBHID_PID_TABLET, 449 /* .bcdDevice = */ 0x0100, /* 1.0 */ 450 /* .iManufacturer = */ USBHID_STR_ID_MANUFACTURER, 451 /* .iProduct = */ USBHID_STR_ID_PRODUCT_T, 452 /* .iSerialNumber = */ 0, 453 /* .bNumConfigurations = */ 1 454 }; 455 456 static const PDMUSBDESCCACHE g_UsbHidMDescCache = 457 { 458 /* .pDevice = */ &g_UsbHidMDeviceDesc, 459 /* .paConfigs = */ &g_UsbHidMConfigDesc, 460 /* .paLanguages = */ g_aUsbHidLanguages, 461 /* .cLanguages = */ RT_ELEMENTS(g_aUsbHidLanguages), 462 /* .fUseCachedDescriptors = */ true, 463 /* .fUseCachedStringsDescriptors = */ true 464 }; 465 466 static const PDMUSBDESCCACHE g_UsbHidTDescCache = 467 { 468 /* .pDevice = */ &g_UsbHidTDeviceDesc, 469 /* .paConfigs = */ &g_UsbHidTConfigDesc, 315 470 /* .paLanguages = */ g_aUsbHidLanguages, 316 471 /* .cLanguages = */ RT_ELEMENTS(g_aUsbHidLanguages), … … 542 697 543 698 /** 544 * Mouse event handler.699 * Relative mouse event handler. 545 700 * 546 701 * @returns VBox status code. … … 558 713 // AssertReleaseRC(rc); 559 714 715 /* If we aren't in the expected mode, switch. This should only really need to be done once. */ 716 // if (pThis->isAbsolute) 717 // pThis->Lun0.pDrv->pfnAbsModeChange(pThis->Lun0.pDrv, pThis->isAbsolute); 718 560 719 /* Accumulate movement - the events from the front end may arrive 561 720 * at a much higher rate than USB can handle. … … 571 730 if (pUrb) 572 731 { 732 size_t cbCopy; 573 733 USBHIDM_REPORT report; 574 size_t cbCopy;575 734 576 735 //@todo: fix/extend … … 582 741 cbCopy = sizeof(report); 583 742 memcpy(&pUrb->abData[0], &report, cbCopy); 584 usbHidCompleteOk(pThis, pUrb, cbCopy);585 743 586 744 /* Clear the accumulated movement. */ 587 745 pThis->PtrDelta.dX = pThis->PtrDelta.dY = pThis->PtrDelta.dZ = 0; 746 747 /* Complete the URB. */ 748 usbHidCompleteOk(pThis, pUrb, cbCopy); 749 // LogRel(("Rel movement, dX=%d, dY=%d, dZ=%d, btn=%02x, report size %d\n", report.dx, report.dy, report.dz, report.btn, cbCopy)); 750 } 751 752 // PDMCritSectLeave(&pThis->CritSect); 753 return VINF_SUCCESS; 754 } 755 756 /** 757 * Absolute mouse event handler. 758 * 759 * @returns VBox status code. 760 * @param pInterface Pointer to the mouse port interface (KBDState::Mouse.iPort). 761 * @param u32X The X coordinate. 762 * @param u32Y The Y coordinate. 763 * @param i32DeltaZ The Z delta. 764 * @param i32DeltaW The W delta. 765 * @param fButtonStates The button states. 766 */ 767 static DECLCALLBACK(int) usbHidMousePutEventAbs(PPDMIMOUSEPORT pInterface, uint32_t u32X, uint32_t u32Y, int32_t i32DeltaZ, int32_t i32DeltaW, uint32_t fButtonStates) 768 { 769 PUSBHID pThis = RT_FROM_MEMBER(pInterface, USBHID, Lun0.IPort); 770 // int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY); 771 // AssertReleaseRC(rc); 772 773 Assert(pThis->isAbsolute); 774 775 /* Accumulate movement - the events from the front end may arrive 776 * at a much higher rate than USB can handle. Probably not a real issue 777 * when only the Z axis is relative. 778 */ 779 pThis->PtrDelta.btn = fButtonStates; 780 pThis->PtrDelta.dZ -= i32DeltaZ; /* Inverted! */ 781 782 /* Check if there's a URB waiting. If so, send a report. 783 */ 784 PVUSBURB pUrb = usbHidQueueRemoveHead(&pThis->ToHostQueue); 785 if (pUrb) 786 { 787 size_t cbCopy; 788 USBHIDT_REPORT report; 789 790 report.btn = pThis->PtrDelta.btn; 791 report.cx = u32X / 2; 792 report.cy = u32Y / 2; 793 report.dz = clamp_i8(pThis->PtrDelta.dZ); 794 795 cbCopy = sizeof(report); 796 memcpy(&pUrb->abData[0], &report, cbCopy); 797 798 /* Clear the accumulated movement. */ 799 pThis->PtrDelta.dZ = 0; 800 801 /* Complete the URB. */ 802 usbHidCompleteOk(pThis, pUrb, cbCopy); 803 // LogRel(("Abs movement, X=%d, Y=%d, dZ=%d, btn=%02x, report size %d\n", report.cx, report.cy, report.dz, report.btn, cbCopy)); 588 804 } 589 805 … … 734 950 { 735 951 case DT_IF_HID_REPORT: 736 uint32_t cbCopy; 737 952 uint32_t cbCopy; 953 uint32_t cbDesc; 954 const uint8_t *pDesc; 955 956 if (pThis->isAbsolute) 957 { 958 cbDesc = sizeof(g_UsbHidTReportDesc); 959 pDesc = (const uint8_t *)&g_UsbHidTReportDesc; 960 } 961 else 962 { 963 cbDesc = sizeof(g_UsbHidMReportDesc); 964 pDesc = (const uint8_t *)&g_UsbHidMReportDesc; 965 } 738 966 /* Returned data is written after the setup message. */ 739 967 cbCopy = pUrb->cbData - sizeof(*pSetup); 740 cbCopy = RT_MIN(cbCopy, sizeof(g_UsbHidReportDesc));968 cbCopy = RT_MIN(cbCopy, cbDesc); 741 969 Log(("usbHid: GET_DESCRIPTOR DT_IF_HID_REPORT wValue=%#x wIndex=%#x cbCopy=%#x\n", pSetup->wValue, pSetup->wIndex, cbCopy)); 742 memcpy(&pUrb->abData[sizeof(*pSetup)], &g_UsbHidReportDesc, cbCopy);970 memcpy(&pUrb->abData[sizeof(*pSetup)], pDesc, cbCopy); 743 971 return usbHidCompleteOk(pThis, pUrb, cbCopy + sizeof(*pSetup)); 744 972 default: … … 871 1099 pThis->bConfigurationValue = bConfigurationValue; 872 1100 1101 /* 1102 * Set received event type to absolute or relative. 1103 */ 1104 pThis->Lun0.pDrv->pfnAbsModeChange(pThis->Lun0.pDrv, pThis->isAbsolute); 1105 873 1106 RTCritSectLeave(&pThis->CritSect); 874 1107 return VINF_SUCCESS; … … 883 1116 PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID); 884 1117 LogFlow(("usbHidUsbGetDescriptorCache/#%u:\n", pUsbIns->iInstance)); 885 return &g_UsbHidDescCache; 1118 if (pThis->isAbsolute) { 1119 return &g_UsbHidTDescCache; 1120 } else { 1121 return &g_UsbHidMDescCache; 1122 } 886 1123 } 887 1124 … … 952 1189 * Validate and read the configuration. 953 1190 */ 954 rc = CFGMR3ValidateConfig(pCfg, "/", " ", "", "UsbHid", iInstance);1191 rc = CFGMR3ValidateConfig(pCfg, "/", "Absolute", "Config", "UsbHid", iInstance); 955 1192 if (RT_FAILURE(rc)) 956 1193 return rc; 957 1194 rc = CFGMR3QueryBoolDef(pCfg, "Absolute", &pThis->isAbsolute, false); 1195 if (RT_FAILURE(rc)) 1196 return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, N_("HID failed to query settings")); 1197 958 1198 pThis->Lun0.IBase.pfnQueryInterface = usbHidMouseQueryInterface; 959 1199 pThis->Lun0.IPort.pfnPutEvent = usbHidMousePutEvent; 1200 pThis->Lun0.IPort.pfnPutEventAbs = usbHidMousePutEventAbs; 960 1201 961 1202 /* … … 965 1206 if (RT_FAILURE(rc)) 966 1207 return PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, N_("HID failed to attach mouse driver")); 1208 1209 pThis->Lun0.pDrv = PDMIBASE_QUERY_INTERFACE(pThis->Lun0.pDrvBase, PDMIMOUSECONNECTOR); 1210 if (!pThis->Lun0.pDrv) 1211 return PDMUsbHlpVMSetError(pUsbIns, VERR_PDM_MISSING_INTERFACE, RT_SRC_POS, N_("HID failed to query mouse interface")); 967 1212 968 1213 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.