Changeset 47571 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Aug 7, 2013 9:49:33 AM (11 years ago)
- Location:
- trunk/src/VBox/Devices/Input
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Input/DevPS2.cpp
r47259 r47571 1391 1391 1392 1392 /** 1393 * @interface_method_impl{PDMIMOUSEPORT, pfnPutEventM T}1394 */ 1395 static DECLCALLBACK(int) kbdMousePutEventM T(PPDMIMOUSEPORT pInterface,1396 uint32_t x, uint32_t y,1397 uint32_t cContact,1398 uint32_t fContact)1393 * @interface_method_impl{PDMIMOUSEPORT, pfnPutEventMultiTouch} 1394 */ 1395 static DECLCALLBACK(int) kbdMousePutEventMultiTouch(PPDMIMOUSEPORT pInterface, 1396 uint8_t cContacts, 1397 const uint64_t *pau64Contacts, 1398 uint32_t u32ScanTime) 1399 1399 { 1400 1400 AssertFailedReturn(VERR_NOT_SUPPORTED); 1401 NOREF(pInterface); NOREF( x); NOREF(y); NOREF(cContact); NOREF(fContact);1401 NOREF(pInterface); NOREF(cContacts); NOREF(pau64Contacts); NOREF(u32ScanTime); 1402 1402 } 1403 1403 … … 1568 1568 pThis->Mouse.IPort.pfnPutEvent = kbdMousePutEvent; 1569 1569 pThis->Mouse.IPort.pfnPutEventAbs = kbdMousePutEventAbs; 1570 pThis->Mouse.IPort.pfnPutEventM T = kbdMousePutEventMT;1570 pThis->Mouse.IPort.pfnPutEventMultiTouch = kbdMousePutEventMultiTouch; 1571 1571 1572 1572 /* -
trunk/src/VBox/Devices/Input/DrvMouseQueue.cpp
r47360 r47571 61 61 * Event type for @a DRVMOUSEQUEUEITEM 62 62 */ 63 enum EVENTTYPE { RELATIVE, ABSOLUTE , MULTITOUCH};63 enum EVENTTYPE { RELATIVE, ABSOLUTE }; 64 64 65 65 /** … … 90 90 int32_t dw; 91 91 } Absolute; 92 struct93 {94 uint32_t fContact;95 uint32_t x;96 uint32_t y;97 uint32_t cContact;98 } MultiTouch;99 92 } u; 100 93 } DRVMOUSEQUEUEITEM, *PDRVMOUSEQUEUEITEM; … … 181 174 182 175 183 /** 184 * @interface_method_impl{PDMIMOUSEPORT,pfnPutEventMT} 185 */ 186 static DECLCALLBACK(int) drvMouseQueuePutEventMT(PPDMIMOUSEPORT pInterface, 187 uint32_t x, uint32_t y, 188 uint32_t cContact, 189 uint32_t fContact) 190 { 191 PDRVMOUSEQUEUE pDrv = IMOUSEPORT_2_DRVMOUSEQUEUE(pInterface); 192 if (pDrv->fInactive) 193 return VINF_SUCCESS; 194 195 PDRVMOUSEQUEUEITEM pItem = (PDRVMOUSEQUEUEITEM)PDMQueueAlloc(pDrv->pQueue); 196 if (pItem) 197 { 198 RT_ZERO(pItem->u.padding); 199 pItem->enmType = MULTITOUCH; 200 pItem->u.MultiTouch.x = x; 201 pItem->u.MultiTouch.y = y; 202 pItem->u.MultiTouch.cContact = cContact; 203 pItem->u.MultiTouch.fContact = fContact; 204 PDMQueueInsert(pDrv->pQueue, &pItem->Core); 205 return VINF_SUCCESS; 206 } 207 return VERR_PDM_NO_QUEUE_ITEMS; 208 } 209 176 static DECLCALLBACK(int) drvMouseQueuePutEventMultiTouch(PPDMIMOUSEPORT pInterface, 177 uint8_t cContacts, 178 const uint64_t *pau64Contacts, 179 uint32_t u32ScanTime) 180 { 181 PDRVMOUSEQUEUE pThis = IMOUSEPORT_2_DRVMOUSEQUEUE(pInterface); 182 return pThis->pUpPort->pfnPutEventMultiTouch(pThis->pUpPort, cContacts, pau64Contacts, u32ScanTime); 183 } 210 184 211 185 /* -=-=-=-=- IConnector -=-=-=-=- */ … … 260 234 pItem->u.Absolute.dw, 261 235 pItem->u.Absolute.fButtons); 262 else if (pItem->enmType == MULTITOUCH)263 rc = pThis->pUpPort->pfnPutEventMT(pThis->pUpPort,264 pItem->u.MultiTouch.x,265 pItem->u.MultiTouch.y,266 pItem->u.MultiTouch.cContact,267 pItem->u.MultiTouch.fContact);268 236 else 269 237 return false; … … 366 334 pDrv->IPort.pfnPutEvent = drvMouseQueuePutEvent; 367 335 pDrv->IPort.pfnPutEventAbs = drvMouseQueuePutEventAbs; 368 pDrv->IPort.pfnPutEventM T = drvMouseQueuePutEventMT;336 pDrv->IPort.pfnPutEventMultiTouch = drvMouseQueuePutEventMultiTouch; 369 337 370 338 /* -
trunk/src/VBox/Devices/Input/UsbMouse.cpp
r47468 r47571 139 139 uint32_t fButtons; 140 140 } Absolute; 141 struct142 {143 uint32_t fContact;144 uint32_t x;145 uint32_t y;146 uint32_t cContact;147 } MultiTouch;148 141 } u; 149 142 } USBHIDM_ACCUM, *PUSBHIDM_ACCUM; 143 144 #define MT_CONTACTS_PER_REPORT 5 145 146 #define MT_CONTACT_MAX_COUNT 10 147 148 #define MT_CONTACT_F_IN_CONTACT 0x01 149 #define MT_CONTACT_F_IN_RANGE 0x02 150 151 #define MT_CONTACT_S_ACTIVE 0x01 /* Contact must be reported to the guest. */ 152 #define MT_CONTACT_S_CANCELLED 0x02 /* Contact loss must be reported to the guest. */ 153 #define MT_CONTACT_S_REUSED 0x04 /* Report contact loss for the oldId and then new contact for the id. */ 154 #define MT_CONTACT_S_DIRTY 0x08 /* Temporary flag used to track already processed elements. */ 155 156 typedef struct MTCONTACT 157 { 158 uint16_t x; 159 uint16_t y; 160 uint8_t id; 161 uint8_t flags; 162 uint8_t status; 163 uint8_t oldId; /* Valid only if MT_CONTACT_S_REUSED is set. */ 164 } MTCONTACT; 150 165 151 166 … … 211 226 } Lun0; 212 227 228 MTCONTACT aCurrentContactState[MT_CONTACT_MAX_COUNT]; 229 MTCONTACT aReportingContactState[MT_CONTACT_MAX_COUNT]; 230 uint32_t u32LastTouchScanTime; 231 bool fTouchReporting; 213 232 } USBHID; 214 233 /** Pointer to the USB HID instance data. */ 215 234 typedef USBHID *PUSBHID; 216 235 236 #pragma pack(1) 217 237 /** 218 238 * The USB HID report structure for relative device. … … 238 258 239 259 /** 240 * The USB HID report structure for the multi-touch device. 241 */ 242 243 typedef struct USBHIDMT_REPORT 244 { 245 uint8_t idReport; 246 uint8_t fContact; 247 uint16_t x; 248 uint16_t y; 249 uint8_t cContact; 250 } USBHIDMT_REPORT, *PUSBHIDMT_REPORT; 251 252 /** 253 * The combined USB HID report union for relative, absolute and multi-touch 260 * The combined USB HID report union for relative and absolute 254 261 * devices. 255 262 */ … … 258 265 USBHIDM_REPORT m; 259 266 USBHIDT_REPORT t; 260 USBHIDMT_REPORT mt;261 267 } USBHIDTM_REPORT, *PUSBHIDTM_REPORT; 268 269 /** 270 * The USB HID report structure for the multi-touch device. 271 */ 272 typedef struct USBHIDMT_REPORT 273 { 274 uint8_t idReport; 275 uint8_t cContacts; 276 struct 277 { 278 uint8_t fContact; 279 uint8_t cContact; 280 uint16_t x; 281 uint16_t y; 282 } aContacts[MT_CONTACTS_PER_REPORT]; 283 uint32_t u32ScanTime; 284 } USBHIDMT_REPORT, *PUSBHIDMT_REPORT; 285 #pragma pack() 262 286 263 287 /******************************************************************************* … … 303 327 /* .bmAttributes = */ 3 /* interrupt */, 304 328 /* .wMaxPacketSize = */ 6, 329 /* .bInterval = */ 10, 330 }, 331 /* .pvMore = */ NULL, 332 /* .pvClass = */ NULL, 333 /* .cbClass = */ 0 334 }, 335 }; 336 337 static const VUSBDESCENDPOINTEX g_aUsbHidMTEndpointDescs[] = 338 { 339 { 340 { 341 /* .bLength = */ sizeof(VUSBDESCENDPOINT), 342 /* .bDescriptorType = */ VUSB_DT_ENDPOINT, 343 /* .bEndpointAddress = */ 0x81 /* ep=1, in */, 344 /* .bmAttributes = */ 3 /* interrupt */, 345 /* .wMaxPacketSize = */ 64, 305 346 /* .bInterval = */ 10, 306 347 }, … … 384 425 }; 385 426 427 /* 428 * Multi-touch device implementation based on "Windows Pointer Device Data Delivery Protocol" 429 * specification. 430 */ 431 432 #define REPORTID_TOUCH_POINTER 1 433 #define REPORTID_TOUCH_EVENT 2 434 #define REPORTID_TOUCH_MAX_COUNT 3 435 #define REPORTID_TOUCH_QABLOB 4 436 #define REPORTID_TOUCH_DEVCONFIG 5 437 386 438 static const uint8_t g_UsbHidMTReportDesc[] = 387 439 { 388 /* Usage Page */ 0x05, 0x0D, /* Digitisers */ 389 /* Usage */ 0x09, 0x04, /* Touch Screen */ 390 /* Collection */ 0xA1, 0x01, /* Application */ 391 /* Report ID */ 0x85, REPORTID_MOUSE, 392 /* Usage */ 0x09, 0x22, /* Finger */ 393 /* Collection */ 0xA1, 0x00, /* Physical */ 394 /* Usage */ 0x09, 0x42, /* Tip Switch */ 395 /* Usage */ 0x09, 0x32, /* In Range */ 396 /* Logical Minimum */ 0x15, 0x00, /* 0 */ 397 /* Logical Maximum */ 0x25, 0x01, /* 1 */ 398 /* Report Count */ 0x95, 0x02, /* 2 */ 399 /* Report Size */ 0x75, 0x01, /* 1 */ 400 /* Input */ 0x81, 0x02, /* Data, Value, Absolute, Bit field */ 401 /* Report Count */ 0x95, 0x06, /* 6 (padding bits) */ 402 /* Input */ 0x81, 0x03, /* Constant, Value, Absolute, Bit field */ 403 /* Usage Page */ 0x05, 0x01, /* Generic Desktop */ 404 /* Usage */ 0x09, 0x30, /* X */ 405 /* Usage */ 0x09, 0x31, /* Y */ 406 /* Logical Minimum */ 0x15, 0x00, /* 0 */ 407 /* Logical Maximum */ 0x26, 0xFF,0x7F,/* 0x7fff */ 408 /* Physical Minimum */ 0x35, 0x00, /* 0 */ 409 /* Physical Maximum */ 0x46, 0xFF,0x7F,/* 0x7fff */ 410 /* Report Size */ 0x75, 0x10, /* 16 */ 411 /* Report Count */ 0x95, 0x02, /* 2 */ 412 /* Input */ 0x81, 0x02, /* Data, Value, Absolute, Bit field */ 413 /* Usage Page */ 0x05, 0x0D, /* Digitisers */ 414 /* Usage */ 0x09, 0x51, /* Contact Identifier */ 415 /* Report Count */ 0x95, 0x01, /* 1 */ 416 /* Report Size */ 0x75, 0x08, /* 8 */ 417 /* Input */ 0x81, 0x02, /* Data, Value, Absolute, Bit field */ 418 /* End Collection */ 0xC0, 419 /* Report ID */ 0x85, REPORTID_MAX_COUNT, 420 /* Usage */ 0x09, 0x55, /* Contact Count Maximum */ 421 /* Report Count */ 0x95, 0x01, /* 1 */ 422 /* Logical Maximum */ 0x25, 0x40, /* 64 */ 423 /* Feature */ 0xB1, 0x03, /* Constant, Value, Absolute, Bit field */ 424 /* End Collection */ 0xC0 440 /* Usage Page (Digitizer) */ 0x05, 0x0D, 441 /* Usage (Touch Screen) */ 0x09, 0x04, 442 /* Collection (Application) */ 0xA1, 0x01, 443 /* Report ID */ 0x85, REPORTID_TOUCH_EVENT, 444 /* Usage Page (Digitizer) */ 0x05, 0x0D, 445 /* Usage (Contact count) */ 0x09, 0x54, 446 /* Report Size (8) */ 0x75, 0x08, 447 /* Logical Minimum (0) */ 0x15, 0x00, 448 /* Logical Maximum (12) */ 0x25, 0x0C, 449 /* Report Count (1) */ 0x95, 0x01, 450 /* Input (Var) */ 0x81, 0x02, 451 452 /* MT_CONTACTS_PER_REPORT structs u8TipSwitch, u8ContactIdentifier, u16X, u16Y */ 453 /* 1 of 5 */ 454 /* Usage (Finger) */ 0x09, 0x22, 455 /* Collection (Logical) */ 0xA1, 0x02, 456 /* Usage (Tip Switch) */ 0x09, 0x42, 457 /* Logical Minimum (0) */ 0x15, 0x00, 458 /* Logical Maximum (1) */ 0x25, 0x01, 459 /* Report Size (1) */ 0x75, 0x01, 460 /* Report Count (1) */ 0x95, 0x01, 461 /* Input (Var) */ 0x81, 0x02, 462 463 /* Usage (In Range) */ 0x09, 0x32, 464 /* Logical Minimum (0) */ 0x15, 0x00, 465 /* Logical Maximum (1) */ 0x25, 0x01, 466 /* Report Size (1) */ 0x75, 0x01, 467 /* Report Count (1) */ 0x95, 0x01, 468 /* Input (Var) */ 0x81, 0x02, 469 470 /* Report Count (6) */ 0x95, 0x06, 471 /* Input (Cnst,Var) */ 0x81, 0x03, 472 473 /* Report Size (8) */ 0x75, 0x08, 474 /* Usage (Contact identifier) */ 0x09, 0x51, 475 /* Report Count (1) */ 0x95, 0x01, 476 /* Logical Minimum (0) */ 0x15, 0x00, 477 /* Logical Maximum (32) */ 0x25, 0x20, 478 /* Input (Var) */ 0x81, 0x02, 479 480 /* Usage Page (Generic Desktop) */ 0x05, 0x01, 481 /* Logical Maximum (32K) */ 0x26, 0xFF, 0x7F, 482 /* Report Size (16) */ 0x75, 0x10, 483 /* Usage (X) */ 0x09, 0x30, 484 /* Input (Var) */ 0x81, 0x02, 485 486 /* Usage (Y) */ 0x09, 0x31, 487 /* Input (Var) */ 0x81, 0x02, 488 /* End Collection */ 0xC0, 489 /* 2 of 5 */ 490 /* Usage Page (Digitizer) */ 0x05, 0x0D, 491 /* Usage (Finger) */ 0x09, 0x22, 492 /* Collection (Logical) */ 0xA1, 0x02, 493 /* Usage (Tip Switch) */ 0x09, 0x42, 494 /* Logical Minimum (0) */ 0x15, 0x00, 495 /* Logical Maximum (1) */ 0x25, 0x01, 496 /* Report Size (1) */ 0x75, 0x01, 497 /* Report Count (1) */ 0x95, 0x01, 498 /* Input (Var) */ 0x81, 0x02, 499 /* Usage (In Range) */ 0x09, 0x32, 500 /* Logical Minimum (0) */ 0x15, 0x00, 501 /* Logical Maximum (1) */ 0x25, 0x01, 502 /* Report Size (1) */ 0x75, 0x01, 503 /* Report Count (1) */ 0x95, 0x01, 504 /* Input (Var) */ 0x81, 0x02, 505 /* Report Count (6) */ 0x95, 0x06, 506 /* Input (Cnst,Var) */ 0x81, 0x03, 507 /* Report Size (8) */ 0x75, 0x08, 508 /* Usage (Contact identifier) */ 0x09, 0x51, 509 /* Report Count (1) */ 0x95, 0x01, 510 /* Logical Minimum (0) */ 0x15, 0x00, 511 /* Logical Maximum (32) */ 0x25, 0x20, 512 /* Input (Var) */ 0x81, 0x02, 513 /* Usage Page (Generic Desktop) */ 0x05, 0x01, 514 /* Logical Maximum (32K) */ 0x26, 0xFF, 0x7F, 515 /* Report Size (16) */ 0x75, 0x10, 516 /* Usage (X) */ 0x09, 0x30, 517 /* Input (Var) */ 0x81, 0x02, 518 /* Usage (Y) */ 0x09, 0x31, 519 /* Input (Var) */ 0x81, 0x02, 520 /* End Collection */ 0xC0, 521 /* 3 of 5 */ 522 /* Usage Page (Digitizer) */ 0x05, 0x0D, 523 /* Usage (Finger) */ 0x09, 0x22, 524 /* Collection (Logical) */ 0xA1, 0x02, 525 /* Usage (Tip Switch) */ 0x09, 0x42, 526 /* Logical Minimum (0) */ 0x15, 0x00, 527 /* Logical Maximum (1) */ 0x25, 0x01, 528 /* Report Size (1) */ 0x75, 0x01, 529 /* Report Count (1) */ 0x95, 0x01, 530 /* Input (Var) */ 0x81, 0x02, 531 /* Usage (In Range) */ 0x09, 0x32, 532 /* Logical Minimum (0) */ 0x15, 0x00, 533 /* Logical Maximum (1) */ 0x25, 0x01, 534 /* Report Size (1) */ 0x75, 0x01, 535 /* Report Count (1) */ 0x95, 0x01, 536 /* Input (Var) */ 0x81, 0x02, 537 /* Report Count (6) */ 0x95, 0x06, 538 /* Input (Cnst,Var) */ 0x81, 0x03, 539 /* Report Size (8) */ 0x75, 0x08, 540 /* Usage (Contact identifier) */ 0x09, 0x51, 541 /* Report Count (1) */ 0x95, 0x01, 542 /* Logical Minimum (0) */ 0x15, 0x00, 543 /* Logical Maximum (32) */ 0x25, 0x20, 544 /* Input (Var) */ 0x81, 0x02, 545 /* Usage Page (Generic Desktop) */ 0x05, 0x01, 546 /* Logical Maximum (32K) */ 0x26, 0xFF, 0x7F, 547 /* Report Size (16) */ 0x75, 0x10, 548 /* Usage (X) */ 0x09, 0x30, 549 /* Input (Var) */ 0x81, 0x02, 550 /* Usage (Y) */ 0x09, 0x31, 551 /* Input (Var) */ 0x81, 0x02, 552 /* End Collection */ 0xC0, 553 /* 4 of 5 */ 554 /* Usage Page (Digitizer) */ 0x05, 0x0D, 555 /* Usage (Finger) */ 0x09, 0x22, 556 /* Collection (Logical) */ 0xA1, 0x02, 557 /* Usage (Tip Switch) */ 0x09, 0x42, 558 /* Logical Minimum (0) */ 0x15, 0x00, 559 /* Logical Maximum (1) */ 0x25, 0x01, 560 /* Report Size (1) */ 0x75, 0x01, 561 /* Report Count (1) */ 0x95, 0x01, 562 /* Input (Var) */ 0x81, 0x02, 563 /* Usage (In Range) */ 0x09, 0x32, 564 /* Logical Minimum (0) */ 0x15, 0x00, 565 /* Logical Maximum (1) */ 0x25, 0x01, 566 /* Report Size (1) */ 0x75, 0x01, 567 /* Report Count (1) */ 0x95, 0x01, 568 /* Input (Var) */ 0x81, 0x02, 569 /* Report Count (6) */ 0x95, 0x06, 570 /* Input (Cnst,Var) */ 0x81, 0x03, 571 /* Report Size (8) */ 0x75, 0x08, 572 /* Usage (Contact identifier) */ 0x09, 0x51, 573 /* Report Count (1) */ 0x95, 0x01, 574 /* Logical Minimum (0) */ 0x15, 0x00, 575 /* Logical Maximum (32) */ 0x25, 0x20, 576 /* Input (Var) */ 0x81, 0x02, 577 /* Usage Page (Generic Desktop) */ 0x05, 0x01, 578 /* Logical Maximum (32K) */ 0x26, 0xFF, 0x7F, 579 /* Report Size (16) */ 0x75, 0x10, 580 /* Usage (X) */ 0x09, 0x30, 581 /* Input (Var) */ 0x81, 0x02, 582 /* Usage (Y) */ 0x09, 0x31, 583 /* Input (Var) */ 0x81, 0x02, 584 /* End Collection */ 0xC0, 585 /* 5 of 5 */ 586 /* Usage Page (Digitizer) */ 0x05, 0x0D, 587 /* Usage (Finger) */ 0x09, 0x22, 588 /* Collection (Logical) */ 0xA1, 0x02, 589 /* Usage (Tip Switch) */ 0x09, 0x42, 590 /* Logical Minimum (0) */ 0x15, 0x00, 591 /* Logical Maximum (1) */ 0x25, 0x01, 592 /* Report Size (1) */ 0x75, 0x01, 593 /* Report Count (1) */ 0x95, 0x01, 594 /* Input (Var) */ 0x81, 0x02, 595 /* Usage (In Range) */ 0x09, 0x32, 596 /* Logical Minimum (0) */ 0x15, 0x00, 597 /* Logical Maximum (1) */ 0x25, 0x01, 598 /* Report Size (1) */ 0x75, 0x01, 599 /* Report Count (1) */ 0x95, 0x01, 600 /* Input (Var) */ 0x81, 0x02, 601 /* Report Count (6) */ 0x95, 0x06, 602 /* Input (Cnst,Var) */ 0x81, 0x03, 603 /* Report Size (8) */ 0x75, 0x08, 604 /* Usage (Contact identifier) */ 0x09, 0x51, 605 /* Report Count (1) */ 0x95, 0x01, 606 /* Logical Minimum (0) */ 0x15, 0x00, 607 /* Logical Maximum (32) */ 0x25, 0x20, 608 /* Input (Var) */ 0x81, 0x02, 609 /* Usage Page (Generic Desktop) */ 0x05, 0x01, 610 /* Logical Maximum (32K) */ 0x26, 0xFF, 0x7F, 611 /* Report Size (16) */ 0x75, 0x10, 612 /* Usage (X) */ 0x09, 0x30, 613 /* Input (Var) */ 0x81, 0x02, 614 /* Usage (Y) */ 0x09, 0x31, 615 /* Input (Var) */ 0x81, 0x02, 616 /* End Collection */ 0xC0, 617 618 /* Note: "Scan time" usage is required for all touch devices (in 100microseconds units). */ 619 /* Usage Page (Digitizer) */ 0x05, 0x0D, 620 /* Logical Minimum (0) */ 0x17, 0x00, 0x00, 0x00, 0x00, 621 /* Logical Maximum (2147483647) */ 0x27, 0xFF, 0xFF, 0xFF, 0x7F, 622 /* Report Size (32) */ 0x75, 0x20, 623 /* Report Count (1) */ 0x95, 0x01, 624 /* Unit Exponent (0) */ 0x55, 0x00, 625 /* Unit (None) */ 0x65, 0x00, 626 /* Usage (Scan time) */ 0x09, 0x56, 627 /* Input (Var) */ 0x81, 0x02, 628 629 /* Report ID */ 0x85, REPORTID_TOUCH_MAX_COUNT, 630 /* Usage (Contact count maximum) */ 0x09, 0x55, 631 /* Usage (Device identifier) */ 0x09, 0x53, 632 /* Report Size (8) */ 0x75, 0x08, 633 /* Report Count (2) */ 0x95, 0x02, 634 /* Logical Maximum (255) */ 0x26, 0xFF, 0x00, 635 /* Feature (Var) */ 0xB1, 0x02, 636 637 /* Usage Page (Vendor-Defined 1) */ 0x06, 0x00, 0xFF, 638 /* Usage (QA blob) */ 0x09, 0xC5, 639 /* Report ID */ 0x85, REPORTID_TOUCH_QABLOB, 640 /* Logical Minimum (0) */ 0x15, 0x00, 641 /* Logical Maximum (255) */ 0x26, 0xFF, 0x00, 642 /* Report Size (8) */ 0x75, 0x08, 643 /* Report Count (256) */ 0x96, 0x00, 0x01, 644 /* Feature (Var) */ 0xB1, 0x02, 645 /* End Collection */ 0xC0, 646 647 /* Note: the pointer report is required by specification: 648 * "The report descriptor for a multiple input device must include at least 649 * one top-level collection for the primary device and a separate top-level 650 * collection for the mouse." 651 */ 652 /* Usage Page (Generic Desktop) */ 0x05, 0x01, 653 /* Usage (Pointer) */ 0x09, 0x01, 654 /* Collection (Application) */ 0xA1, 0x01, 655 /* Report ID */ 0x85, REPORTID_TOUCH_POINTER, 656 /* Usage (Pointer) */ 0x09, 0x01, 657 /* Collection (Logical) */ 0xA1, 0x02, 658 /* Usage Page (Button) */ 0x05, 0x09, 659 /* Usage Minimum (Button 1) */ 0x19, 0x01, 660 /* Usage Maximum (Button 2) */ 0x29, 0x02, 661 /* Logical Minimum (0) */ 0x15, 0x00, 662 /* Logical Maximum (1) */ 0x25, 0x01, 663 /* Report Count (2) */ 0x95, 0x02, 664 /* Report Size (1) */ 0x75, 0x01, 665 /* Input (Var) */ 0x81, 0x02, 666 /* Report Count (1) */ 0x95, 0x01, 667 /* Report Size (6) */ 0x75, 0x06, 668 /* Input (Cnst,Ary,Abs) */ 0x81, 0x01, 669 /* Usage Page (Generic Desktop) */ 0x05, 0x01, 670 /* Usage (X) */ 0x09, 0x30, 671 /* Usage (Y) */ 0x09, 0x31, 672 /* Logical Minimum (0) */ 0x16, 0x00, 0x00, 673 /* Logical Maximum (32K) */ 0x26, 0xFF, 0x7F, 674 /* Physical Minimum (0) */ 0x36, 0x00, 0x00, 675 /* Physical Maximum (32K) */ 0x46, 0xFF, 0x7F, 676 /* Unit (None) */ 0x66, 0x00, 0x00, 677 /* Report Size (16) */ 0x75, 0x10, 678 /* Report Count (2) */ 0x95, 0x02, 679 /* Input (Var) */ 0x81, 0x02, 680 /* End Collection */ 0xC0, 681 /* End Collection */ 0xC0, 682 683 /* Usage Page (Digitizer) */ 0x05, 0x0D, 684 /* Usage (Device configuration) */ 0x09, 0x0E, 685 /* Collection (Application) */ 0xA1, 0x01, 686 /* Report ID */ 0x85, REPORTID_TOUCH_DEVCONFIG, 687 /* Usage (Device settings) */ 0x09, 0x23, 688 /* Collection (Logical) */ 0xA1, 0x02, 689 /* Usage (Device mode) */ 0x09, 0x52, 690 /* Usage (Device identifier) */ 0x09, 0x53, 691 /* Logical Minimum (0) */ 0x15, 0x00, 692 /* Logical Maximum (10) */ 0x25, 0x0A, 693 /* Report Size (8) */ 0x75, 0x08, 694 /* Report Count (2) */ 0x95, 0x02, 695 /* Feature (Var) */ 0xB1, 0x02, 696 /* End Collection */ 0xC0, 697 /* End Collection */ 0xC0 425 698 }; 426 699 … … 455 728 /* .bLength = */ 0x09, 456 729 /* .bDescriptorType = */ 0x21, /* HID */ 457 /* .bcdHID = */ 0x10, 0x0 1, /* 1.1 */730 /* .bcdHID = */ 0x10, 0x02, /* 2.1 */ 458 731 /* .bCountryCode = */ 0, 459 732 /* .bNumDescriptors = */ 1, 460 733 /* .bDescriptorType = */ 0x22, /* Report */ 461 /* .wDescriptorLength = */ sizeof(g_UsbHidMTReportDesc), 0x00734 /* .wDescriptorLength = */ RT_LO_U8(sizeof(g_UsbHidMTReportDesc)), RT_HI_U8(sizeof(g_UsbHidMTReportDesc)) 462 735 }; 463 736 … … 520 793 /* .pvClass = */ &g_UsbHidMTIfHidDesc, 521 794 /* .cbClass = */ sizeof(g_UsbHidMTIfHidDesc), 522 &g_aUsbHid TEndpointDescs[0],795 &g_aUsbHidMTEndpointDescs[0], 523 796 /* .pIAD = */ NULL, 524 797 /* .cbIAD = */ 0 … … 740 1013 PVUSBURB pCur = pQueue->pHead; 741 1014 if (pCur == pUrb) 1015 { 742 1016 pQueue->pHead = pUrb->Dev.pNext; 1017 if (!pUrb->Dev.pNext) 1018 pQueue->ppTail = &pQueue->pHead; 1019 } 743 1020 else 744 1021 { … … 754 1031 if (!pCur) 755 1032 return false; 756 } 757 if (!pUrb->Dev.pNext) 758 pQueue->ppTail = &pQueue->pHead; 1033 if (!pUrb->Dev.pNext) 1034 pQueue->ppTail = &pCur->Dev.pNext; 1035 } 1036 pUrb->Dev.pNext = NULL; 759 1037 return true; 760 1038 } … … 919 1197 pReport->m.fButtons, cbCopy)); 920 1198 break; 921 case USBHIDMODE_MULTI_TOUCH:922 pReport->mt.idReport = REPORTID_MOUSE;923 pReport->mt.cContact = pAccumulated->u.MultiTouch.cContact;924 pReport->mt.x = pAccumulated->u.MultiTouch.x;925 pReport->mt.y = pAccumulated->u.MultiTouch.y;926 pReport->mt.fContact = pAccumulated->u.MultiTouch.fContact;927 928 cbCopy = sizeof(pReport->mt);929 LogRel3(("Multi-touch event, x=%u, y=%u, cContact=%u, fContact=%02x, report size %d\n",930 (unsigned)pReport->mt.x, (unsigned)pReport->mt.y,931 (unsigned)pReport->mt.cContact, (unsigned)pReport->mt.fContact,932 cbCopy));933 break;934 1199 } 935 1200 … … 940 1205 } 941 1206 1207 DECLINLINE(MTCONTACT *) usbHidFindMTContact(MTCONTACT *paContacts, size_t cContacts, 1208 uint8_t u8Mask, uint8_t u8Value) 1209 { 1210 size_t i; 1211 for (i = 0; i < cContacts; i++) 1212 { 1213 if ((paContacts[i].status & u8Mask) == u8Value) 1214 { 1215 return &paContacts[i]; 1216 } 1217 } 1218 1219 return NULL; 1220 } 1221 1222 static int usbHidSendMultiTouchReport(PUSBHID pThis, PVUSBURB pUrb) 1223 { 1224 uint8_t i; 1225 MTCONTACT *pRepContact; 1226 MTCONTACT *pCurContact; 1227 1228 /* Number of contacts to be reported. In hybrid mode the first report contains 1229 * total number of contacts and subsequent reports contain 0. 1230 */ 1231 uint8_t cContacts = 0; 1232 1233 Assert(pThis->fHasPendingChanges); 1234 1235 if (!pThis->fTouchReporting) 1236 { 1237 pThis->fTouchReporting = true; 1238 1239 /* Update the reporting state with the new current state. 1240 * Also mark all active contacts in reporting state as dirty, 1241 * that is they must be reported to the guest. 1242 */ 1243 for (i = 0; i < MT_CONTACT_MAX_COUNT; i++) 1244 { 1245 pRepContact = &pThis->aReportingContactState[i]; 1246 pCurContact = &pThis->aCurrentContactState[i]; 1247 1248 if (pCurContact->status & MT_CONTACT_S_ACTIVE) 1249 { 1250 if (pCurContact->status & MT_CONTACT_S_REUSED) 1251 { 1252 pCurContact->status &= ~MT_CONTACT_S_REUSED; 1253 1254 /* Keep x,y. Will report lost contact at this point. */ 1255 pRepContact->id = pCurContact->oldId; 1256 pRepContact->flags = 0; 1257 pRepContact->status = MT_CONTACT_S_REUSED; 1258 } 1259 else if (pThis->aCurrentContactState[i].status & MT_CONTACT_S_CANCELLED) 1260 { 1261 pCurContact->status &= ~(MT_CONTACT_S_CANCELLED | MT_CONTACT_S_ACTIVE); 1262 1263 /* Keep x,y. Will report lost contact at this point. */ 1264 pRepContact->id = pCurContact->id; 1265 pRepContact->flags = 0; 1266 pRepContact->status = 0; 1267 } 1268 else 1269 { 1270 if (pCurContact->flags == 0) 1271 { 1272 pCurContact->status &= ~MT_CONTACT_S_ACTIVE; /* Contact disapeared. */ 1273 } 1274 1275 pRepContact->x = pCurContact->x; 1276 pRepContact->y = pCurContact->y; 1277 pRepContact->id = pCurContact->id; 1278 pRepContact->flags = pCurContact->flags; 1279 pRepContact->status = 0; 1280 } 1281 1282 cContacts++; 1283 1284 pRepContact->status |= MT_CONTACT_S_DIRTY; 1285 } 1286 else 1287 { 1288 pRepContact->status = 0; 1289 } 1290 } 1291 } 1292 1293 /* Report current state. */ 1294 USBHIDMT_REPORT *p = (USBHIDMT_REPORT *)&pUrb->abData[0]; 1295 RT_ZERO(*p); 1296 1297 p->idReport = REPORTID_TOUCH_EVENT; 1298 p->cContacts = cContacts; 1299 1300 uint8_t iReportedContact; 1301 for (iReportedContact = 0; iReportedContact < MT_CONTACTS_PER_REPORT; iReportedContact++) 1302 { 1303 /* Find the next not reported contact. */ 1304 pRepContact = usbHidFindMTContact(pThis->aReportingContactState, RT_ELEMENTS(pThis->aReportingContactState), 1305 MT_CONTACT_S_DIRTY, MT_CONTACT_S_DIRTY); 1306 1307 if (!pRepContact) 1308 { 1309 LogRel3(("usbHid: no more touch contacts to report\n")); 1310 break; 1311 } 1312 1313 if (pRepContact->status & MT_CONTACT_S_REUSED) 1314 { 1315 /* Do not clear DIRTY flag for contacts which were reused. 1316 * Because two reports must be generated: 1317 * one for old contact off, and the second for new contact on. 1318 */ 1319 pRepContact->status &= ~MT_CONTACT_S_REUSED; 1320 } 1321 else 1322 { 1323 pRepContact->status &= ~MT_CONTACT_S_DIRTY; 1324 } 1325 1326 p->aContacts[iReportedContact].fContact = pRepContact->flags; 1327 p->aContacts[iReportedContact].cContact = pRepContact->id; 1328 p->aContacts[iReportedContact].x = pRepContact->x >> pThis->u8CoordShift; 1329 p->aContacts[iReportedContact].y = pRepContact->y >> pThis->u8CoordShift; 1330 } 1331 1332 p->u32ScanTime = pThis->u32LastTouchScanTime * 10; 1333 1334 Assert(iReportedContact > 0); 1335 1336 /* Reset TouchReporting if all contacts reported. */ 1337 pRepContact = usbHidFindMTContact(pThis->aReportingContactState, RT_ELEMENTS(pThis->aReportingContactState), 1338 MT_CONTACT_S_DIRTY, MT_CONTACT_S_DIRTY); 1339 1340 if (!pRepContact) 1341 { 1342 LogRel3(("usbHid: all touch contacts reported\n")); 1343 pThis->fTouchReporting = false; 1344 pThis->fHasPendingChanges = false; 1345 } 1346 else 1347 { 1348 pThis->fHasPendingChanges = true; 1349 } 1350 1351 LogRel3(("usbHid: reporting touch contact:\n%.*Rhxd\n", sizeof(USBHIDMT_REPORT), p)); 1352 return usbHidCompleteOk(pThis, pUrb, sizeof(USBHIDMT_REPORT)); 1353 } 1354 942 1355 /** 943 1356 * Sends a state report to the host if there is a pending URB. … … 946 1359 { 947 1360 PVUSBURB pUrb = usbHidQueueRemoveHead(&pThis->ToHostQueue); 1361 1362 if (pThis->enmMode == USBHIDMODE_MULTI_TOUCH) 1363 { 1364 /* This device uses a different reporting method and fHasPendingChanges maintenance. */ 1365 if (pUrb) 1366 return usbHidSendMultiTouchReport(pThis, pUrb); 1367 return VINF_SUCCESS; 1368 } 948 1369 949 1370 if (pUrb) … … 1030 1451 1031 1452 /** 1032 * @interface_method_impl{PDMIMOUSEPORT,pfnPutEventMT} 1033 */ 1034 static DECLCALLBACK(int) usbHidMousePutEventMT(PPDMIMOUSEPORT pInterface, 1035 uint32_t x, uint32_t y, 1036 uint32_t cContact, 1037 uint32_t fContact) 1038 { 1453 * @interface_method_impl{PDMIMOUSEPORT,pfnPutEventMultiTouch} 1454 */ 1455 static DECLCALLBACK(int) usbHidMousePutEventMultiTouch(PPDMIMOUSEPORT pInterface, 1456 uint8_t cContacts, 1457 const uint64_t *pau64Contacts, 1458 uint32_t u32ScanTime) 1459 { 1460 uint8_t i; 1461 uint8_t j; 1462 1463 /* Make a copy of new contacts */ 1464 MTCONTACT *paNewContacts = (MTCONTACT *)RTMemTmpAlloc(sizeof(MTCONTACT) * cContacts); 1465 if (!paNewContacts) 1466 return VERR_NO_MEMORY; 1467 1468 for (i = 0; i < cContacts; i++) 1469 { 1470 paNewContacts[i].x = RT_LO_U16(RT_LO_U32(pau64Contacts[i])); 1471 paNewContacts[i].y = RT_HI_U16(RT_LO_U32(pau64Contacts[i])); 1472 paNewContacts[i].id = RT_BYTE1(RT_HI_U32(pau64Contacts[i])); 1473 paNewContacts[i].flags = RT_BYTE2(RT_HI_U32(pau64Contacts[i])) & (MT_CONTACT_F_IN_CONTACT | MT_CONTACT_F_IN_RANGE); 1474 paNewContacts[i].status = MT_CONTACT_S_DIRTY; 1475 paNewContacts[i].oldId = 0; /* Not used. */ 1476 } 1477 1039 1478 PUSBHID pThis = RT_FROM_MEMBER(pInterface, USBHID, Lun0.IPort); 1040 if (pThis->fHasPendingChanges) 1041 return VERR_TRY_AGAIN; 1479 MTCONTACT *pCurContact = NULL; 1480 MTCONTACT *pNewContact = NULL; 1481 1042 1482 RTCritSectEnter(&pThis->CritSect); 1043 1483 1044 1484 Assert(pThis->enmMode == USBHIDMODE_MULTI_TOUCH); 1045 1485 1046 /* Accumulate movement - the events from the front end may arrive 1047 * at a much higher rate than USB can handle. Probably not a real issue 1048 * when only the Z axis is relative (X/Y movement isn't technically 1049 * accumulated and only the last value is used). 1486 /* Maintain a state of all current contacts. 1487 * Intr URBs will be completed according to the state. 1050 1488 */ 1051 pThis->PtrDelta.u.MultiTouch.fContact = fContact; 1052 pThis->PtrDelta.u.MultiTouch.x = x >> pThis->u8CoordShift; 1053 pThis->PtrDelta.u.MultiTouch.y = y >> pThis->u8CoordShift; 1054 pThis->PtrDelta.u.MultiTouch.cContact = cContact; 1489 1490 /* Mark all existing contacts as dirty. */ 1491 for (i = 0; i < RT_ELEMENTS(pThis->aCurrentContactState); i++) 1492 pThis->aCurrentContactState[i].status |= MT_CONTACT_S_DIRTY; 1493 1494 /* Update existing contacts and mark new contacts. */ 1495 for (i = 0; i < cContacts; i++) 1496 { 1497 pNewContact = &paNewContacts[i]; 1498 1499 /* Find existing contact with the same id. */ 1500 pCurContact = NULL; 1501 for (j = 0; j < RT_ELEMENTS(pThis->aCurrentContactState); j++) 1502 { 1503 if ( (pThis->aCurrentContactState[j].status & MT_CONTACT_S_ACTIVE) != 0 1504 && pThis->aCurrentContactState[j].id == pNewContact->id) 1505 { 1506 pCurContact = &pThis->aCurrentContactState[j]; 1507 break; 1508 } 1509 } 1510 1511 if (pCurContact) 1512 { 1513 pNewContact->status &= ~MT_CONTACT_S_DIRTY; 1514 1515 pCurContact->x = pNewContact->x; 1516 pCurContact->y = pNewContact->y; 1517 if (pCurContact->flags == 0) /* Contact disappeared already. */ 1518 { 1519 if ((pCurContact->status & MT_CONTACT_S_REUSED) == 0) 1520 { 1521 pCurContact->status |= MT_CONTACT_S_REUSED; /* Report to the guest that the contact not in touch. */ 1522 pCurContact->oldId = pCurContact->id; 1523 } 1524 } 1525 pCurContact->flags = pNewContact->flags; 1526 pCurContact->status &= ~MT_CONTACT_S_DIRTY; 1527 } 1528 } 1529 1530 /* Append new contacts (the dirty one in the paNewContacts). */ 1531 for (i = 0; i < cContacts; i++) 1532 { 1533 pNewContact = &paNewContacts[i]; 1534 1535 if (pNewContact->status & MT_CONTACT_S_DIRTY) 1536 { 1537 /* It is a new contact, copy is to one of not ACTIVE or not updated existing contacts. */ 1538 pCurContact = usbHidFindMTContact(pThis->aCurrentContactState, RT_ELEMENTS(pThis->aCurrentContactState), 1539 MT_CONTACT_S_ACTIVE, 0); 1540 1541 if (pCurContact) 1542 { 1543 *pCurContact = *pNewContact; 1544 pCurContact->status = MT_CONTACT_S_ACTIVE; /* Reset status. */ 1545 } 1546 else 1547 { 1548 /* Dirty existing contacts can be reused. */ 1549 pCurContact = usbHidFindMTContact(pThis->aCurrentContactState, RT_ELEMENTS(pThis->aCurrentContactState), 1550 MT_CONTACT_S_ACTIVE | MT_CONTACT_S_DIRTY, 1551 MT_CONTACT_S_ACTIVE | MT_CONTACT_S_DIRTY); 1552 1553 if (pCurContact) 1554 { 1555 pCurContact->x = pNewContact->x; 1556 pCurContact->y = pNewContact->y; 1557 if ((pCurContact->status & MT_CONTACT_S_REUSED) == 0) 1558 { 1559 pCurContact->status |= MT_CONTACT_S_REUSED; /* Report to the guest that the contact not in touch. */ 1560 pCurContact->oldId = pCurContact->id; 1561 } 1562 pCurContact->flags = pNewContact->flags; 1563 pCurContact->status &= ~MT_CONTACT_S_DIRTY; 1564 } 1565 else 1566 { 1567 LogRel3(("usbHid: dropped new contact: %d,%d id %d flags %RX8 status %RX8 oldId %d\n", 1568 pNewContact->x, 1569 pNewContact->y, 1570 pNewContact->id, 1571 pNewContact->flags, 1572 pNewContact->status, 1573 pNewContact->oldId 1574 )); 1575 } 1576 } 1577 } 1578 } 1579 1580 /* Mark still dirty existing contacts as cancelled, because a new set of contacts does not include them. */ 1581 for (i = 0; i < RT_ELEMENTS(pThis->aCurrentContactState); i++) 1582 { 1583 pCurContact = &pThis->aCurrentContactState[i]; 1584 if (pCurContact->status & MT_CONTACT_S_DIRTY) 1585 { 1586 pCurContact->status |= MT_CONTACT_S_CANCELLED; 1587 pCurContact->status &= ~MT_CONTACT_S_DIRTY; 1588 } 1589 } 1590 1591 pThis->u32LastTouchScanTime = u32ScanTime; 1592 1593 LogRel3(("usbHid: scanTime (ms): %d\n", pThis->u32LastTouchScanTime)); 1594 for (i = 0; i < RT_ELEMENTS(pThis->aCurrentContactState); i++) 1595 { 1596 LogRel3(("usbHid: contact state[%d]: %d,%d id %d flags %RX8 status %RX8 oldId %d\n", 1597 i, 1598 pThis->aCurrentContactState[i].x, 1599 pThis->aCurrentContactState[i].y, 1600 pThis->aCurrentContactState[i].id, 1601 pThis->aCurrentContactState[i].flags, 1602 pThis->aCurrentContactState[i].status, 1603 pThis->aCurrentContactState[i].oldId 1604 )); 1605 } 1606 1607 pThis->fHasPendingChanges = true; 1055 1608 1056 1609 /* Send a report if possible. */ … … 1058 1611 1059 1612 RTCritSectLeave(&pThis->CritSect); 1613 1614 RTMemTmpFree(paNewContacts); 1060 1615 return VINF_SUCCESS; 1061 1616 } … … 1067 1622 { 1068 1623 PUSBHID pThis = PDMINS_2_DATA(pUsbIns, PUSBHID); 1069 LogRelFlow(("usbHidUrbReap/#%u: cMillies=%u\n", pUsbIns->iInstance, cMillies));1070 1624 1071 1625 RTCritSectEnter(&pThis->CritSect); … … 1157 1711 case USBHIDREQSTATE_READY: 1158 1712 usbHidQueueAddTail(&pThis->ToHostQueue, pUrb); 1713 LogRelFlow(("usbHidHandleIntrDevToHost: Added %p:%s to the queue\n", 1714 pUrb, pUrb->pszDesc)); 1159 1715 /* If a report is pending, send it right away. */ 1160 1716 if (pThis->fHasPendingChanges) 1161 1717 usbHidSendReport(pThis); 1162 LogRelFlow(("usbHidHandleIntrDevToHost: Added %p:%s to the queue\n",1163 pUrb, pUrb->pszDesc));1164 1718 return VINF_SUCCESS; 1165 1719 … … 1174 1728 } 1175 1729 1730 #define GET_REPORT 0x01 1731 #define GET_IDLE 0x02 1732 #define GET_PROTOCOL 0x03 1733 #define SET_REPORT 0x09 1734 #define SET_IDLE 0x0A 1735 #define SET_PROTOCOL 0x0B 1736 1737 static uint8_t sau8QASampleBlob[256] = 1738 { 1739 0xfc, 0x28, 0xfe, 0x84, 0x40, 0xcb, 0x9a, 0x87, 1740 0x0d, 0xbe, 0x57, 0x3c, 0xb6, 0x70, 0x09, 0x88, 1741 0x07, 0x97, 0x2d, 0x2b, 0xe3, 0x38, 0x34, 0xb6, 1742 0x6c, 0xed, 0xb0, 0xf7, 0xe5, 0x9c, 0xf6, 0xc2, 1743 0x2e, 0x84, 0x1b, 0xe8, 0xb4, 0x51, 0x78, 0x43, 1744 0x1f, 0x28, 0x4b, 0x7c, 0x2d, 0x53, 0xaf, 0xfc, 1745 0x47, 0x70, 0x1b, 0x59, 0x6f, 0x74, 0x43, 0xc4, 1746 0xf3, 0x47, 0x18, 0x53, 0x1a, 0xa2, 0xa1, 0x71, 1747 0xc7, 0x95, 0x0e, 0x31, 0x55, 0x21, 0xd3, 0xb5, 1748 0x1e, 0xe9, 0x0c, 0xba, 0xec, 0xb8, 0x89, 0x19, 1749 0x3e, 0xb3, 0xaf, 0x75, 0x81, 0x9d, 0x53, 0xb9, 1750 0x41, 0x57, 0xf4, 0x6d, 0x39, 0x25, 0x29, 0x7c, 1751 0x87, 0xd9, 0xb4, 0x98, 0x45, 0x7d, 0xa7, 0x26, 1752 0x9c, 0x65, 0x3b, 0x85, 0x68, 0x89, 0xd7, 0x3b, 1753 0xbd, 0xff, 0x14, 0x67, 0xf2, 0x2b, 0xf0, 0x2a, 1754 0x41, 0x54, 0xf0, 0xfd, 0x2c, 0x66, 0x7c, 0xf8, 1755 0xc0, 0x8f, 0x33, 0x13, 0x03, 0xf1, 0xd3, 0xc1, 1756 0x0b, 0x89, 0xd9, 0x1b, 0x62, 0xcd, 0x51, 0xb7, 1757 0x80, 0xb8, 0xaf, 0x3a, 0x10, 0xc1, 0x8a, 0x5b, 1758 0xe8, 0x8a, 0x56, 0xf0, 0x8c, 0xaa, 0xfa, 0x35, 1759 0xe9, 0x42, 0xc4, 0xd8, 0x55, 0xc3, 0x38, 0xcc, 1760 0x2b, 0x53, 0x5c, 0x69, 0x52, 0xd5, 0xc8, 0x73, 1761 0x02, 0x38, 0x7c, 0x73, 0xb6, 0x41, 0xe7, 0xff, 1762 0x05, 0xd8, 0x2b, 0x79, 0x9a, 0xe2, 0x34, 0x60, 1763 0x8f, 0xa3, 0x32, 0x1f, 0x09, 0x78, 0x62, 0xbc, 1764 0x80, 0xe3, 0x0f, 0xbd, 0x65, 0x20, 0x08, 0x13, 1765 0xc1, 0xe2, 0xee, 0x53, 0x2d, 0x86, 0x7e, 0xa7, 1766 0x5a, 0xc5, 0xd3, 0x7d, 0x98, 0xbe, 0x31, 0x48, 1767 0x1f, 0xfb, 0xda, 0xaf, 0xa2, 0xa8, 0x6a, 0x89, 1768 0xd6, 0xbf, 0xf2, 0xd3, 0x32, 0x2a, 0x9a, 0xe4, 1769 0xcf, 0x17, 0xb7, 0xb8, 0xf4, 0xe1, 0x33, 0x08, 1770 0x24, 0x8b, 0xc4, 0x43, 0xa5, 0xe5, 0x24, 0xc2 1771 }; 1772 1773 static int usbHidRequestClass(PUSBHID pThis, PUSBHIDEP pEp, PVUSBURB pUrb) 1774 { 1775 PVUSBSETUP pSetup = (PVUSBSETUP)&pUrb->abData[0]; 1776 1777 if (pThis->enmMode != USBHIDMODE_MULTI_TOUCH) 1778 { 1779 LogRelFlow(("usbHid: bmRequestType=%#x bRequest=%#x wValue=%#x wIndex=%#x wLength=%#x\n", 1780 pSetup->bmRequestType, pSetup->bRequest, pSetup->wValue, 1781 pSetup->wIndex, pSetup->wLength)); 1782 return usbHidCompleteStall(pThis, pEp, pUrb, "Unsupported class req"); 1783 } 1784 1785 int rc = VINF_SUCCESS; 1786 1787 switch (pSetup->bRequest) 1788 { 1789 case SET_REPORT: 1790 case GET_REPORT: 1791 { 1792 uint8_t u8ReportType = RT_HI_U8(pSetup->wValue); 1793 uint8_t u8ReportID = RT_LO_U8(pSetup->wValue); 1794 LogRelFlow(("usbHid: %s: type %d, ID %d, data\n%.*Rhxd\n", 1795 pSetup->bRequest == GET_REPORT? "GET_REPORT": "SET_REPORT", 1796 u8ReportType, u8ReportID, 1797 pUrb->cbData - sizeof(VUSBSETUP), &pUrb->abData[sizeof(VUSBSETUP)])); 1798 uint32_t cbData = 0; 1799 if (pSetup->bRequest == GET_REPORT) 1800 { 1801 if (u8ReportType == 3 && u8ReportID == REPORTID_TOUCH_MAX_COUNT) 1802 { 1803 pUrb->abData[sizeof(VUSBSETUP) + 0] = REPORTID_TOUCH_MAX_COUNT; 1804 pUrb->abData[sizeof(VUSBSETUP) + 1] = MT_CONTACT_MAX_COUNT; /* Contact count maximum. */ 1805 pUrb->abData[sizeof(VUSBSETUP) + 2] = 0; /* Device identifier */ 1806 cbData = 3; 1807 } 1808 else if (u8ReportType == 3 && u8ReportID == REPORTID_TOUCH_QABLOB) 1809 { 1810 uint32_t cbLeft = pUrb->cbData; 1811 pUrb->abData[sizeof(VUSBSETUP) + 0] = REPORTID_TOUCH_QABLOB; /* Report Id. */ 1812 memcpy(&pUrb->abData[sizeof(VUSBSETUP) + 1], 1813 sau8QASampleBlob, sizeof(sau8QASampleBlob)); 1814 cbData = sizeof(sau8QASampleBlob) + 1; 1815 } 1816 } 1817 1818 rc = usbHidCompleteOk(pThis, pUrb, sizeof(VUSBSETUP) + cbData); 1819 } break; 1820 default: 1821 { 1822 LogRelFlow(("usbHid: bmRequestType=%#x bRequest=%#x wValue=%#x wIndex=%#x wLength=%#x\n", 1823 pSetup->bmRequestType, pSetup->bRequest, pSetup->wValue, 1824 pSetup->wIndex, pSetup->wLength)); 1825 rc = usbHidCompleteStall(pThis, pEp, pUrb, "Unsupported class req MT"); 1826 } 1827 } 1828 1829 return rc; 1830 } 1176 1831 1177 1832 /** … … 1363 2018 usbHidCompleteStall(pThis, pEp, pUrb, "TODO: standard request stuff"); 1364 2019 } 2020 else if ((pSetup->bmRequestType & VUSB_REQ_MASK) == VUSB_REQ_CLASS) 2021 { 2022 /* Only VUSB_TO_INTERFACE is allowed. */ 2023 if ((pSetup->bmRequestType & VUSB_RECIP_MASK) == VUSB_TO_INTERFACE) 2024 { 2025 return usbHidRequestClass(pThis, pEp, pUrb); 2026 } 2027 2028 LogRelFlow(("usbHid: invalid recipient of class req: bmRequestType=%#x bRequest=%#x wValue=%#x wIndex=%#x wLength=%#x\n", 2029 pSetup->bmRequestType, pSetup->bRequest, pSetup->wValue, 2030 pSetup->wIndex, pSetup->wLength)); 2031 return usbHidCompleteStall(pThis, pEp, pUrb, "Invalid recip"); 2032 } 1365 2033 else 1366 2034 { … … 1582 2250 pThis->Lun0.IPort.pfnPutEvent = usbHidMousePutEvent; 1583 2251 pThis->Lun0.IPort.pfnPutEventAbs = usbHidMousePutEventAbs; 1584 pThis->Lun0.IPort.pfnPutEventM T = usbHidMousePutEventMT;2252 pThis->Lun0.IPort.pfnPutEventMultiTouch = usbHidMousePutEventMultiTouch; 1585 2253 1586 2254 /* -
trunk/src/VBox/Devices/Input/testcase/tstUsbMouse.cpp
r47422 r47571 247 247 } 248 248 249 249 #if 0 250 /** @todo PDM interface was updated. This is not working anymore. */ 250 251 static void testSendPositionMT(RTTEST hTest) 251 252 { … … 296 297 g_UsbHidMou.pfnDestruct(pThis); 297 298 } 298 299 #endif 299 300 300 301 int main() … … 322 323 testSendPositionRel(hTest); 323 324 testSendPositionAbs(hTest); 324 testSendPositionMT(hTest);325 /* testSendPositionMT(hTest); */ 325 326 return RTTestSummaryAndDestroy(hTest); 326 327 }
Note:
See TracChangeset
for help on using the changeset viewer.