Changeset 43605 in vbox
- Timestamp:
- Oct 10, 2012 5:54:15 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Input/UsbMouse.cpp
r43561 r43605 147 147 * is set. */ 148 148 RTSEMEVENT hEvtDoneQueue; 149 149 150 /** Someone is waiting on the done queue. */ 150 151 bool fHaveDoneQueueWaiter; 151 152 /** If device has pending changes. */ 153 bool fHasPendingChanges; 152 154 /** Is this an absolute pointing device (tablet)? Relative (mouse) otherwise. */ 153 155 bool isAbsolute; 154 155 156 /** Tablet coordinate shift factor for old and broken operating systems. */ 156 157 uint8_t u8CoordShift; … … 201 202 uint16_t cy; 202 203 } USBHIDT_REPORT, *PUSBHIDT_REPORT; 204 205 /** 206 * The combined USB HID report union for relative and absolute device. 207 */ 208 typedef union USBHIDTM_REPORT 209 { 210 USBHIDT_REPORT t; 211 USBHIDM_REPORT m; 212 } USBHIDTM_REPORT, *PUSBHIDTM_REPORT; 203 213 204 214 /******************************************************************************* … … 669 679 */ 670 680 pThis->enmState = USBHIDREQSTATE_READY; 681 pThis->fHasPendingChanges = false; 671 682 672 683 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aEps); i++) … … 691 702 } 692 703 704 static int8_t clamp_i8(int32_t val) 705 { 706 if (val > 127) { 707 val = 127; 708 } else if (val < -127) { 709 val = -127; 710 } 711 return val; 712 } 713 714 /** 715 * Create a USB HID report report based on the currently accumulated data. 716 */ 717 static size_t usbHidFillReport(PUSBHIDTM_REPORT pReport, PUSBHIDM_ACCUM pAccumulated, bool isAbsolute) 718 { 719 size_t cbCopy; 720 721 if (isAbsolute) 722 { 723 pReport->t.btn = pAccumulated->btn; 724 pReport->t.cx = pAccumulated->dX; 725 pReport->t.cy = pAccumulated->dY; 726 pReport->t.dz = clamp_i8(pAccumulated->dZ); 727 728 cbCopy = sizeof(pReport->t); 729 // LogRel(("Abs movement, X=%d, Y=%d, dZ=%d, btn=%02x, report size %d\n", pReport->t.cx, pReport->t.cy, pReport->t.dz, pReport->t.btn, cbCopy)); 730 } 731 else 732 { 733 pReport->m.btn = pAccumulated->btn; 734 pReport->m.dx = clamp_i8(pAccumulated->dX); 735 pReport->m.dy = clamp_i8(pAccumulated->dY); 736 pReport->m.dz = clamp_i8(pAccumulated->dZ); 737 738 cbCopy = sizeof(pReport->m); 739 // LogRel(("Rel movement, dX=%d, dY=%d, dZ=%d, btn=%02x, report size %d\n", pReport->m.dx, pReport->m.dy, pReport->m.dz, pReport->m.btn, cbCopy)); 740 } 741 742 /* Clear the accumulated movement. */ 743 RT_ZERO(*pAccumulated); 744 745 return cbCopy; 746 } 747 748 /** 749 * Sends a state report to the host if there is a pending URB. 750 */ 751 static int usbHidSendReport(PUSBHID pThis) 752 { 753 PVUSBURB pUrb = usbHidQueueRemoveHead(&pThis->ToHostQueue); 754 755 if (pUrb) 756 { 757 PUSBHIDTM_REPORT pReport = (PUSBHIDTM_REPORT)&pUrb->abData[0]; 758 size_t cbCopy; 759 760 cbCopy = usbHidFillReport(pReport, &pThis->PtrDelta, pThis->isAbsolute); 761 pThis->fHasPendingChanges = false; 762 return usbHidCompleteOk(pThis, pUrb, cbCopy); 763 } 764 else 765 { 766 Log2(("No available URB for USB mouse\n")); 767 pThis->fHasPendingChanges = true; 768 } 769 return VINF_EOF; 770 } 693 771 694 772 /** … … 701 779 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUSEPORT, &pThis->Lun0.IPort); 702 780 return NULL; 703 }704 705 static int8_t clamp_i8(int32_t val)706 {707 if (val > 127) {708 val = 127;709 } else if (val < -127) {710 val = -127;711 }712 return val;713 781 } 714 782 … … 727 795 { 728 796 PUSBHID pThis = RT_FROM_MEMBER(pInterface, USBHID, Lun0.IPort); 729 // int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY); 730 // AssertReleaseRC(rc); 731 732 /* If we aren't in the expected mode, switch. This should only really need to be done once. */ 733 // if (pThis->isAbsolute) 734 // pThis->Lun0.pDrv->pfnAbsModeChange(pThis->Lun0.pDrv, pThis->isAbsolute); 797 RTCritSectEnter(&pThis->CritSect); 735 798 736 799 /* Accumulate movement - the events from the front end may arrive … … 742 805 pThis->PtrDelta.dZ -= i32DeltaZ; /* Inverted! */ 743 806 744 /* Check if there's a URB waiting. If so, send a report. 745 */ 746 PVUSBURB pUrb = usbHidQueueRemoveHead(&pThis->ToHostQueue); 747 if (pUrb) 748 { 749 size_t cbCopy; 750 USBHIDM_REPORT report; 751 752 //@todo: fix/extend 753 report.btn = pThis->PtrDelta.btn; 754 report.dx = clamp_i8(pThis->PtrDelta.dX); 755 report.dy = clamp_i8(pThis->PtrDelta.dY); 756 report.dz = clamp_i8(pThis->PtrDelta.dZ); 757 758 cbCopy = sizeof(report); 759 memcpy(&pUrb->abData[0], &report, cbCopy); 760 761 /* Clear the accumulated movement. */ 762 pThis->PtrDelta.dX = pThis->PtrDelta.dY = pThis->PtrDelta.dZ = 0; 763 764 /* Complete the URB. */ 765 usbHidCompleteOk(pThis, pUrb, cbCopy); 766 // LogRel(("Rel movement, dX=%d, dY=%d, dZ=%d, btn=%02x, report size %d\n", report.dx, report.dy, report.dz, report.btn, cbCopy)); 767 } 768 769 // PDMCritSectLeave(&pThis->CritSect); 807 /* Send a report if possible. */ 808 usbHidSendReport(pThis); 809 810 RTCritSectLeave(&pThis->CritSect); 770 811 return VINF_SUCCESS; 771 812 } … … 785 826 { 786 827 PUSBHID pThis = RT_FROM_MEMBER(pInterface, USBHID, Lun0.IPort); 787 // int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY); 788 // AssertReleaseRC(rc); 828 RTCritSectEnter(&pThis->CritSect); 789 829 790 830 Assert(pThis->isAbsolute); … … 792 832 /* Accumulate movement - the events from the front end may arrive 793 833 * at a much higher rate than USB can handle. Probably not a real issue 794 * when only the Z axis is relative. 834 * when only the Z axis is relative (X/Y movement isn't technically 835 * accumulated and only the last value is used). 795 836 */ 796 837 pThis->PtrDelta.btn = fButtonStates; 838 pThis->PtrDelta.dX = u32X >> pThis->u8CoordShift; 839 pThis->PtrDelta.dY = u32Y >> pThis->u8CoordShift; 797 840 pThis->PtrDelta.dZ -= i32DeltaZ; /* Inverted! */ 798 841 799 /* Check if there's a URB waiting. If so, send a report. 800 */ 801 PVUSBURB pUrb = usbHidQueueRemoveHead(&pThis->ToHostQueue); 802 if (pUrb) 803 { 804 size_t cbCopy; 805 USBHIDT_REPORT report; 806 807 report.btn = pThis->PtrDelta.btn; 808 report.cx = u32X >> pThis->u8CoordShift; 809 report.cy = u32Y >> pThis->u8CoordShift; 810 report.dz = clamp_i8(pThis->PtrDelta.dZ); 811 812 cbCopy = sizeof(report); 813 memcpy(&pUrb->abData[0], &report, cbCopy); 814 815 /* Clear the accumulated movement. */ 816 pThis->PtrDelta.dZ = 0; 817 818 /* Complete the URB. */ 819 usbHidCompleteOk(pThis, pUrb, cbCopy); 820 // LogRel(("Abs movement, X=%d, Y=%d, dZ=%d, btn=%02x, report size %d\n", report.cx, report.cy, report.dz, report.btn, cbCopy)); 821 } 822 823 // PDMCritSectLeave(&pThis->CritSect); 842 /* Send a report if possible. */ 843 usbHidSendReport(pThis); 844 845 RTCritSectLeave(&pThis->CritSect); 824 846 return VINF_SUCCESS; 825 847 } … … 919 941 case USBHIDREQSTATE_READY: 920 942 usbHidQueueAddTail(&pThis->ToHostQueue, pUrb); 943 /* If a report is pending, send it right away. */ 944 if (pThis->fHasPendingChanges) 945 usbHidSendReport(pThis); 921 946 LogFlow(("usbHidHandleIntrDevToHost: Added %p:%s to the queue\n", pUrb, pUrb->pszDesc)); 922 947 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.