protected virtual Point GetCoordinate(short linkCollection, Screen currentScr, IntPtr pRawDataPacket) { int physicalX = 0; int physicalY = 0; HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, linkCollection, NativeMethods.XCoordinateId, ref physicalX, _hPreparsedData.DangerousGetHandle(), pRawDataPacket, _dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, linkCollection, NativeMethods.YCoordinateId, ref physicalY, _hPreparsedData.DangerousGetHandle(), pRawDataPacket, _dwSizHid); int x, y; if (_isAxisCorresponds) { x = physicalX * currentScr.Bounds.Width / _physicalMax.X; y = physicalY * currentScr.Bounds.Height / _physicalMax.Y; } else { x = physicalY * currentScr.Bounds.Width / _physicalMax.Y; y = physicalX * currentScr.Bounds.Height / _physicalMax.X; } x = _xAxisDirection ? x : currentScr.Bounds.Width - x; y = _yAxisDirection ? y : currentScr.Bounds.Height - y; return(new Point(x + currentScr.Bounds.X, y + currentScr.Bounds.Y)); }
public virtual int GetContactId(short nodeIndex, IntPtr pRawDataPacket) { int contactIdentifier = 0; HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, NativeMethods.ContactIdentifierId, ref contactIdentifier, _hPreparsedData.DangerousGetHandle(), pRawDataPacket, _dwSizHid); return(contactIdentifier); }
public virtual HidNativeApi.HIDP_LINK_COLLECTION_NODE[] GetLinkCollectionNodes() { int linkCount = 0; HidNativeApi.HidP_GetLinkCollectionNodes(null, ref linkCount, _hPreparsedData.DangerousGetHandle()); HidNativeApi.HIDP_LINK_COLLECTION_NODE[] lcn = new HidNativeApi.HIDP_LINK_COLLECTION_NODE[linkCount]; HidNativeApi.HidP_GetLinkCollectionNodes(lcn, ref linkCount, _hPreparsedData.DangerousGetHandle()); return(lcn); }
private static ushort[] GetButtonList(IntPtr pPreparsedData, IntPtr pRawData, short nodeIndex, int rawDateSize) { int usageLength = 0; HidNativeApi.HidP_GetUsages(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, null, ref usageLength, pPreparsedData, pRawData, rawDateSize); var usageList = new ushort[usageLength]; HidNativeApi.HidP_GetUsages(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, usageList, ref usageLength, pPreparsedData, pRawData, rawDateSize); return(usageList); }
public virtual int GetContactCount() { int contactCount = 0; if (HidNativeApi.HIDP_STATUS_SUCCESS != HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, 0, NativeMethods.ContactCountId, ref contactCount, _hPreparsedData.DangerousGetHandle(), _pRawData, _dwSizHid)) { throw new ApplicationException(Common.Localization.LocalizationProvider.Instance.GetTextValue("Messages.ContactCountError")); } return(contactCount); }
public void GetPhysicalMax(int collectionCount) { short valueCapsLength = (short)(collectionCount > 0 ? collectionCount : 1); HidNativeApi.HidP_Value_Caps[] hvc = new HidNativeApi.HidP_Value_Caps[valueCapsLength]; HidNativeApi.HidP_GetSpecificValueCaps(HidReportType.Input, NativeMethods.GenericDesktopPage, 0, NativeMethods.XCoordinateId, hvc, ref valueCapsLength, _hPreparsedData.DangerousGetHandle()); _physicalMax.X = hvc[0].PhysicalMax != 0 ? hvc[0].PhysicalMax : hvc[0].LogicalMax; HidNativeApi.HidP_GetSpecificValueCaps(HidReportType.Input, NativeMethods.GenericDesktopPage, 0, NativeMethods.YCoordinateId, hvc, ref valueCapsLength, _hPreparsedData.DangerousGetHandle()); _physicalMax.Y = hvc[0].PhysicalMax != 0 ? hvc[0].PhysicalMax : hvc[0].LogicalMax; }
private Point GetPhysicalMax(int collectionCount, IntPtr pPreparsedData) { short valueCapsLength = (short)collectionCount; Point p = new Point(); HidNativeApi.HidP_Value_Caps[] hvc = new HidNativeApi.HidP_Value_Caps[valueCapsLength]; HidNativeApi.HidP_GetSpecificValueCaps(HidReportType.Input, NativeMethods.GenericDesktopPage, 0, NativeMethods.XCoordinateId, hvc, ref valueCapsLength, pPreparsedData); p.X = hvc[0].PhysicalMax != 0 ? hvc[0].PhysicalMax : hvc[0].LogicalMax; HidNativeApi.HidP_GetSpecificValueCaps(HidReportType.Input, NativeMethods.GenericDesktopPage, 0, NativeMethods.YCoordinateId, hvc, ref valueCapsLength, pPreparsedData); p.Y = hvc[0].PhysicalMax != 0 ? hvc[0].PhysicalMax : hvc[0].LogicalMax; return(p); }
private void GetPhysicalMax(NativeMethods.RAWINPUT rawInput, IntPtr pPreparsedData) { short valueCapsLength = 1; Point p = new Point(); HidNativeApi.HidP_Value_Caps[] hvc = new HidNativeApi.HidP_Value_Caps[valueCapsLength]; HidNativeApi.HidP_GetSpecificValueCaps(HidReportType.Input, NativeMethods.GenericDesktopPage, 1, NativeMethods.XCoordinateId, hvc, ref valueCapsLength, pPreparsedData); p.X = hvc[0].PhysicalMax != 0 ? hvc[0].PhysicalMax : hvc[0].LogicalMax; HidNativeApi.HidP_GetSpecificValueCaps(HidReportType.Input, NativeMethods.GenericDesktopPage, 1, NativeMethods.YCoordinateId, hvc, ref valueCapsLength, pPreparsedData); p.Y = hvc[0].PhysicalMax != 0 ? hvc[0].PhysicalMax : hvc[0].LogicalMax; _touchScreenPhysicalMax[rawInput.header.hDevice] = p; }
protected override Point GetCoordinate(short linkCollection, Screen currentScr, IntPtr pRawDataPacket) { int physicalX = 0; int physicalY = 0; HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, linkCollection, NativeMethods.XCoordinateId, ref physicalX, _hPreparsedData.DangerousGetHandle(), pRawDataPacket, _dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, linkCollection, NativeMethods.YCoordinateId, ref physicalY, _hPreparsedData.DangerousGetHandle(), pRawDataPacket, _dwSizHid); int x, y; x = physicalX * currentScr.Bounds.Width / _physicalMax.X; y = physicalY * currentScr.Bounds.Height / _physicalMax.Y; return(new Point(x + currentScr.Bounds.X, y + currentScr.Bounds.Y)); }
/// <summary> /// Processes WM_INPUT messages to retrieve information about any /// touch events that occur. /// </summary> /// <param name="LParam">The WM_INPUT message to process.</param> private void ProcessInputCommand(IntPtr LParam) { uint dwSize = 0; // First call to GetRawInputData sets the value of dwSize // dwSize can then be used to allocate the appropriate amount of memore, // storing the pointer in "buffer". NativeMethods.GetRawInputData(LParam, NativeMethods.RID_INPUT, IntPtr.Zero, ref dwSize, (uint)Marshal.SizeOf(typeof(NativeMethods.RAWINPUTHEADER))); IntPtr buffer = Marshal.AllocHGlobal((int)dwSize); IntPtr pPreparsedData = IntPtr.Zero; try { // Check that buffer points to something, and if so, // call GetRawInputData again to fill the allocated memory // with information about the input if (buffer != IntPtr.Zero && NativeMethods.GetRawInputData(LParam, NativeMethods.RID_INPUT, buffer, ref dwSize, (uint)Marshal.SizeOf(typeof(NativeMethods.RAWINPUTHEADER))) == dwSize) { NativeMethods.RAWINPUT raw = (NativeMethods.RAWINPUT)Marshal.PtrToStructure(buffer, typeof(NativeMethods.RAWINPUT)); if (!_touchScreenPhysicalMax.ContainsKey(raw.header.hDevice)) { return; } GetCurrentScreenOrientation(); uint pcbSize = 0; NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, IntPtr.Zero, ref pcbSize); pPreparsedData = Marshal.AllocHGlobal((int)pcbSize); NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, pPreparsedData, ref pcbSize); if (_touchScreenPhysicalMax[raw.header.hDevice].Equals(Point.Empty)) { GetPhysicalMax(raw, pPreparsedData); return; } int contactCount = 0; IntPtr pRawData = new IntPtr(buffer.ToInt64() + (raw.header.dwSize - raw.hid.dwSizHid * raw.hid.dwCount)); HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.TouchScreenUsagePage, 0, NativeMethods.ContactCountId, ref contactCount, pPreparsedData, pRawData, raw.hid.dwSizHid); int linkCount = 0; HidNativeApi.HidP_GetLinkCollectionNodes(null, ref linkCount, pPreparsedData); HidNativeApi.HIDP_LINK_COLLECTION_NODE[] lcn = new HidNativeApi.HIDP_LINK_COLLECTION_NODE[linkCount]; HidNativeApi.HidP_GetLinkCollectionNodes(lcn, ref linkCount, pPreparsedData); if (contactCount != 0) { _requiringContactCount = contactCount; _outputTouchs = new List <RawTouchData>(contactCount); } if (_requiringContactCount == 0) { return; } int contactIdentifier = 0; int physicalX = 0; int physicalY = 0; int screenWidth = Screen.PrimaryScreen.Bounds.Width; int screenHeight = Screen.PrimaryScreen.Bounds.Height; for (int dwIndex = 0; dwIndex < raw.hid.dwCount; dwIndex++) { for (short nodeIndex = 1; nodeIndex <= lcn[0].NumberOfChildren; nodeIndex++) { IntPtr pRawDataPacket = new IntPtr(pRawData.ToInt64() + dwIndex * raw.hid.dwSizHid); HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.TouchScreenUsagePage, nodeIndex, NativeMethods.ContactIdentifierId, ref contactIdentifier, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.XCoordinateId, ref physicalX, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.YCoordinateId, ref physicalY, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); int usageLength = 0; HidNativeApi.HidP_GetUsages(HidReportType.Input, NativeMethods.TouchScreenUsagePage, nodeIndex, null, ref usageLength, pPreparsedData, pRawData, raw.hid.dwSizHid); HidNativeApi.HIDP_DATA[] hd = new HidNativeApi.HIDP_DATA[usageLength]; HidNativeApi.HidP_GetUsages(HidReportType.Input, NativeMethods.TouchScreenUsagePage, nodeIndex, hd, ref usageLength, pPreparsedData, pRawData, raw.hid.dwSizHid); int x, y; if (_isAxisCorresponds) { x = physicalX * screenWidth / _touchScreenPhysicalMax[raw.header.hDevice].X; y = physicalY * screenHeight / _touchScreenPhysicalMax[raw.header.hDevice].Y; } else { x = physicalY * screenWidth / _touchScreenPhysicalMax[raw.header.hDevice].Y; y = physicalX * screenHeight / _touchScreenPhysicalMax[raw.header.hDevice].X; } x = _xAxisDirection ? x : screenWidth - x; y = _yAxisDirection ? y : screenHeight - y; bool tip = hd.Length != 0 && hd[0].DataIndex == NativeMethods.TipId; _outputTouchs.Add(new RawTouchData(tip, contactIdentifier, new Point(x, y))); if (--_requiringContactCount == 0) { break; } } if (_requiringContactCount == 0) { break; } } if (_requiringContactCount == 0 && PointsIntercepted != null) { PointsIntercepted(this, new RawPointsDataMessageEventArgs(_outputTouchs)); } } else { throw new ApplicationException("GetRawInputData does not return correct size !\n."); } } finally { Marshal.FreeHGlobal(pPreparsedData); Marshal.FreeHGlobal(buffer); } }
/// <summary> /// Processes WM_INPUT messages to retrieve information about any /// touch events that occur. /// </summary> /// <param name="LParam">The WM_INPUT message to process.</param> private void ProcessInputCommand(IntPtr LParam) { uint dwSize = 0; // First call to GetRawInputData sets the value of dwSize // dwSize can then be used to allocate the appropriate amount of memore, // storing the pointer in "buffer". NativeMethods.GetRawInputData(LParam, NativeMethods.RID_INPUT, IntPtr.Zero, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))); IntPtr buffer = Marshal.AllocHGlobal((int)dwSize); try { // Check that buffer points to something, and if so, // call GetRawInputData again to fill the allocated memory // with information about the input if (buffer == IntPtr.Zero || NativeMethods.GetRawInputData(LParam, NativeMethods.RID_INPUT, buffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize) { throw new ApplicationException("GetRawInputData does not return correct size !\n."); } RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(buffer, typeof(RAWINPUT)); ushort usage; if (!_validDevices.TryGetValue(raw.header.hDevice, out usage)) { return; } if (usage == NativeMethods.TouchScreenUsage) { if (_sourceDevice == Devices.None) { _currentScr = Screen.FromPoint(Cursor.Position); if (_currentScr == null) { return; } _sourceDevice = Devices.TouchScreen; GetCurrentScreenOrientation(); } else if (_sourceDevice != Devices.TouchScreen) { return; } uint pcbSize = 0; NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, IntPtr.Zero, ref pcbSize); IntPtr pPreparsedData = Marshal.AllocHGlobal((int)pcbSize); using (new SafeUnmanagedMemoryHandle(pPreparsedData)) { NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, pPreparsedData, ref pcbSize); int contactCount = 0; IntPtr pRawData = new IntPtr(buffer.ToInt64() + (raw.header.dwSize - raw.hid.dwSizHid * raw.hid.dwCount)); HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, 0, NativeMethods.ContactCountId, ref contactCount, pPreparsedData, pRawData, raw.hid.dwSizHid); int linkCount = 0; HidNativeApi.HidP_GetLinkCollectionNodes(null, ref linkCount, pPreparsedData); HidNativeApi.HIDP_LINK_COLLECTION_NODE[] lcn = new HidNativeApi.HIDP_LINK_COLLECTION_NODE[linkCount]; HidNativeApi.HidP_GetLinkCollectionNodes(lcn, ref linkCount, pPreparsedData); if (_physicalMax.IsEmpty) { _physicalMax = GetPhysicalMax(linkCount, pPreparsedData); } if (contactCount != 0) { _requiringContactCount = contactCount; _outputTouchs = new List <RawData>(contactCount); } if (_requiringContactCount == 0) { return; } int contactIdentifier = 0; int physicalX = 0; int physicalY = 0; for (int dwIndex = 0; dwIndex < raw.hid.dwCount; dwIndex++) { for (short nodeIndex = 1; nodeIndex <= lcn[0].NumberOfChildren; nodeIndex++) { IntPtr pRawDataPacket = new IntPtr(pRawData.ToInt64() + dwIndex * raw.hid.dwSizHid); HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, NativeMethods.ContactIdentifierId, ref contactIdentifier, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.XCoordinateId, ref physicalX, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.YCoordinateId, ref physicalY, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); int usageLength = 0; HidNativeApi.HidP_GetUsages(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, null, ref usageLength, pPreparsedData, pRawData, raw.hid.dwSizHid); HidNativeApi.HIDP_DATA[] hd = new HidNativeApi.HIDP_DATA[usageLength]; HidNativeApi.HidP_GetUsages(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, hd, ref usageLength, pPreparsedData, pRawData, raw.hid.dwSizHid); int x, y; if (_isAxisCorresponds) { x = physicalX * _currentScr.Bounds.Width / _physicalMax.X; y = physicalY * _currentScr.Bounds.Height / _physicalMax.Y; } else { x = physicalY * _currentScr.Bounds.Width / _physicalMax.Y; y = physicalX * _currentScr.Bounds.Height / _physicalMax.X; } x = _xAxisDirection ? x : _currentScr.Bounds.Width - x; y = _yAxisDirection ? y : _currentScr.Bounds.Height - y; bool tip = hd.Length != 0 && hd[0].DataIndex == NativeMethods.TipId; _outputTouchs.Add(new RawData(tip, contactIdentifier, new Point(x + _currentScr.Bounds.X, y + _currentScr.Bounds.Y))); if (--_requiringContactCount == 0) { break; } } if (_requiringContactCount == 0) { break; } } } } else if (usage == NativeMethods.TouchPadUsage) { if (_sourceDevice == Devices.None) { _currentScr = Screen.FromPoint(Cursor.Position); if (_currentScr == null) { return; } _sourceDevice = Devices.TouchPad; } else if (_sourceDevice != Devices.TouchPad) { return; } uint pcbSize = 0; NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, IntPtr.Zero, ref pcbSize); IntPtr pPreparsedData = Marshal.AllocHGlobal((int)pcbSize); using (new SafeUnmanagedMemoryHandle(pPreparsedData)) { NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, pPreparsedData, ref pcbSize); int contactCount = 0; IntPtr pRawData = new IntPtr(buffer.ToInt64() + (raw.header.dwSize - raw.hid.dwSizHid * raw.hid.dwCount)); HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, 0, NativeMethods.ContactCountId, ref contactCount, pPreparsedData, pRawData, raw.hid.dwSizHid); int linkCount = 0; HidNativeApi.HidP_GetLinkCollectionNodes(null, ref linkCount, pPreparsedData); HidNativeApi.HIDP_LINK_COLLECTION_NODE[] lcn = new HidNativeApi.HIDP_LINK_COLLECTION_NODE[linkCount]; HidNativeApi.HidP_GetLinkCollectionNodes(lcn, ref linkCount, pPreparsedData); if (_physicalMax.IsEmpty) { _physicalMax = GetPhysicalMax(linkCount, pPreparsedData); } if (contactCount != 0) { _requiringContactCount = contactCount; _outputTouchs = new List <RawData>(contactCount); } if (_requiringContactCount == 0) { return; } int contactIdentifier = 0; int physicalX = 0; int physicalY = 0; for (int dwIndex = 0; dwIndex < raw.hid.dwCount; dwIndex++) { for (short nodeIndex = 1; nodeIndex <= lcn[0].NumberOfChildren; nodeIndex++) { IntPtr pRawDataPacket = new IntPtr(pRawData.ToInt64() + dwIndex * raw.hid.dwSizHid); HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, NativeMethods.ContactIdentifierId, ref contactIdentifier, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.XCoordinateId, ref physicalX, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.YCoordinateId, ref physicalY, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); int usageLength = 0; HidNativeApi.HidP_GetUsages(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, null, ref usageLength, pPreparsedData, pRawData, raw.hid.dwSizHid); HidNativeApi.HIDP_DATA[] hd = new HidNativeApi.HIDP_DATA[usageLength]; HidNativeApi.HidP_GetUsages(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, hd, ref usageLength, pPreparsedData, pRawData, raw.hid.dwSizHid); int x, y; x = physicalX * _currentScr.Bounds.Width / _physicalMax.X; y = physicalY * _currentScr.Bounds.Height / _physicalMax.Y; bool tip = hd.Length != 0 && hd[0].DataIndex == NativeMethods.TipId; _outputTouchs.Add(new RawData(tip, contactIdentifier, new Point(x + _currentScr.Bounds.X, y + _currentScr.Bounds.Y))); if (--_requiringContactCount == 0) { break; } } if (_requiringContactCount == 0) { break; } } } } if (_requiringContactCount == 0 && PointsIntercepted != null) { PointsIntercepted(this, new RawPointsDataMessageEventArgs(_outputTouchs, _sourceDevice)); if (_outputTouchs.TrueForAll(rd => !rd.Tip)) { _sourceDevice = Devices.None; _physicalMax = Point.Empty; } } } finally { Marshal.FreeHGlobal(buffer); } }
/// <summary> /// Processes WM_INPUT messages to retrieve information about any /// touch events that occur. /// </summary> /// <param name="LParam">The WM_INPUT message to process.</param> private void ProcessInputCommand(IntPtr LParam) { uint dwSize = 0; // First call to GetRawInputData sets the value of dwSize // dwSize can then be used to allocate the appropriate amount of memore, // storing the pointer in "buffer". NativeMethods.GetRawInputData(LParam, NativeMethods.RID_INPUT, IntPtr.Zero, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))); IntPtr buffer = Marshal.AllocHGlobal((int)dwSize); try { // Check that buffer points to something, and if so, // call GetRawInputData again to fill the allocated memory // with information about the input if (buffer == IntPtr.Zero || NativeMethods.GetRawInputData(LParam, NativeMethods.RID_INPUT, buffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER))) != dwSize) { throw new ApplicationException("GetRawInputData does not return correct size !\n."); } RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(buffer, typeof(RAWINPUT)); ushort usage; if (!_validDevices.TryGetValue(raw.header.hDevice, out usage)) { if (ValidateDevice(raw.header.hDevice, out usage)) { _validDevices.Add(raw.header.hDevice, usage); } } if (usage == 0) { return; } if (usage == NativeMethods.PenUsage) { if (_ignoreTouchInputWhenUsingPen) { _penLastActivity = Environment.TickCount; } else { _penLastActivity = null; } if (_penGestureButton == 0) { return; } switch (_sourceDevice) { case Devices.TouchScreen: case Devices.None: case Devices.Pen: break; default: return; } uint pcbSize = 0; NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, IntPtr.Zero, ref pcbSize); IntPtr pPreparsedData = Marshal.AllocHGlobal((int)pcbSize); using (new SafeUnmanagedMemoryHandle(pPreparsedData)) { NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, pPreparsedData, ref pcbSize); IntPtr pRawData = new IntPtr(buffer.ToInt64() + (raw.header.dwSize - raw.hid.dwSizHid * raw.hid.dwCount)); ushort[] usageList = GetButtonList(pPreparsedData, pRawData, 0, raw.hid.dwSizHid); DeviceStates state = DeviceStates.None; foreach (var u in usageList) { switch (u) { case NativeMethods.TipId: state |= DeviceStates.Tip; break; case NativeMethods.InRangeId: state |= DeviceStates.InRange; break; case NativeMethods.BarrelButtonId: state |= DeviceStates.RightClickButton; break; case NativeMethods.InvertId: state |= DeviceStates.Invert; break; case NativeMethods.EraserId: state |= DeviceStates.Eraser; break; default: break; } } if (_sourceDevice == Devices.None || _sourceDevice == Devices.TouchScreen) { if ((state & _penGestureButton) != 0) { _currentScr = Screen.FromPoint(Cursor.Position); if (_currentScr == null) { return; } _sourceDevice = Devices.Pen; GetCurrentScreenOrientation(); } else { return; } } else if (_sourceDevice == Devices.Pen) { if ((state & _penGestureButton) == 0 || (state & DeviceStates.InRange) == 0) { state = DeviceStates.None; } } if (_physicalMax.IsEmpty) { _physicalMax = GetPhysicalMax(1, pPreparsedData); } int physicalX = 0; int physicalY = 0; HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, 0, NativeMethods.XCoordinateId, ref physicalX, pPreparsedData, pRawData, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, 0, NativeMethods.YCoordinateId, ref physicalY, pPreparsedData, pRawData, raw.hid.dwSizHid); int x, y; if (_isAxisCorresponds) { x = physicalX * _currentScr.Bounds.Width / _physicalMax.X; y = physicalY * _currentScr.Bounds.Height / _physicalMax.Y; } else { x = physicalY * _currentScr.Bounds.Width / _physicalMax.Y; y = physicalX * _currentScr.Bounds.Height / _physicalMax.X; } x = _xAxisDirection ? x : _currentScr.Bounds.Width - x; y = _yAxisDirection ? y : _currentScr.Bounds.Height - y; _outputTouchs = new List <RawData>(1); _outputTouchs.Add(new RawData(state, 0, new Point(x + _currentScr.Bounds.X, y + _currentScr.Bounds.Y))); } } else if (usage == NativeMethods.TouchScreenUsage) { if (_penLastActivity != null && Environment.TickCount - _penLastActivity < 100) { return; } if (_sourceDevice == Devices.None) { _currentScr = Screen.FromPoint(Cursor.Position); if (_currentScr == null) { return; } _sourceDevice = Devices.TouchScreen; GetCurrentScreenOrientation(); } else if (_sourceDevice != Devices.TouchScreen) { return; } uint pcbSize = 0; NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, IntPtr.Zero, ref pcbSize); IntPtr pPreparsedData = Marshal.AllocHGlobal((int)pcbSize); using (new SafeUnmanagedMemoryHandle(pPreparsedData)) { NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, pPreparsedData, ref pcbSize); int contactCount = 0; IntPtr pRawData = new IntPtr(buffer.ToInt64() + (raw.header.dwSize - raw.hid.dwSizHid * raw.hid.dwCount)); if (HidNativeApi.HIDP_STATUS_SUCCESS != HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, 0, NativeMethods.ContactCountId, ref contactCount, pPreparsedData, pRawData, raw.hid.dwSizHid)) { throw new ApplicationException(LocalizationProvider.Instance.GetTextValue("Messages.ContactCountError")); } int linkCount = 0; HidNativeApi.HidP_GetLinkCollectionNodes(null, ref linkCount, pPreparsedData); HidNativeApi.HIDP_LINK_COLLECTION_NODE[] lcn = new HidNativeApi.HIDP_LINK_COLLECTION_NODE[linkCount]; HidNativeApi.HidP_GetLinkCollectionNodes(lcn, ref linkCount, pPreparsedData); if (_physicalMax.IsEmpty) { _physicalMax = GetPhysicalMax(linkCount, pPreparsedData); } if (contactCount != 0) { _requiringContactCount = contactCount; _outputTouchs = new List <RawData>(contactCount); } if (_requiringContactCount == 0) { return; } int contactIdentifier = 0; int physicalX = 0; int physicalY = 0; for (int dwIndex = 0; dwIndex < raw.hid.dwCount; dwIndex++) { for (short nodeIndex = 1; nodeIndex <= lcn[0].NumberOfChildren; nodeIndex++) { IntPtr pRawDataPacket = new IntPtr(pRawData.ToInt64() + dwIndex * raw.hid.dwSizHid); HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, NativeMethods.ContactIdentifierId, ref contactIdentifier, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.XCoordinateId, ref physicalX, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.YCoordinateId, ref physicalY, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); ushort[] usageList = GetButtonList(pPreparsedData, pRawData, nodeIndex, raw.hid.dwSizHid); int x, y; if (_isAxisCorresponds) { x = physicalX * _currentScr.Bounds.Width / _physicalMax.X; y = physicalY * _currentScr.Bounds.Height / _physicalMax.Y; } else { x = physicalY * _currentScr.Bounds.Width / _physicalMax.Y; y = physicalX * _currentScr.Bounds.Height / _physicalMax.X; } x = _xAxisDirection ? x : _currentScr.Bounds.Width - x; y = _yAxisDirection ? y : _currentScr.Bounds.Height - y; bool tip = usageList.Length != 0 && usageList[0] == NativeMethods.TipId; _outputTouchs.Add(new RawData(tip ? DeviceStates.Tip : DeviceStates.None, contactIdentifier, new Point(x + _currentScr.Bounds.X, y + _currentScr.Bounds.Y))); if (--_requiringContactCount == 0) { break; } } if (_requiringContactCount == 0) { break; } } } } else if (usage == NativeMethods.TouchPadUsage) { if (_sourceDevice == Devices.None) { _currentScr = Screen.FromPoint(Cursor.Position); if (_currentScr == null) { return; } _sourceDevice = Devices.TouchPad; } else if (_sourceDevice != Devices.TouchPad) { return; } uint pcbSize = 0; NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, IntPtr.Zero, ref pcbSize); IntPtr pPreparsedData = Marshal.AllocHGlobal((int)pcbSize); using (new SafeUnmanagedMemoryHandle(pPreparsedData)) { NativeMethods.GetRawInputDeviceInfo(raw.header.hDevice, NativeMethods.RIDI_PREPARSEDDATA, pPreparsedData, ref pcbSize); int contactCount = 0; IntPtr pRawData = new IntPtr(buffer.ToInt64() + (raw.header.dwSize - raw.hid.dwSizHid * raw.hid.dwCount)); if (HidNativeApi.HIDP_STATUS_SUCCESS != HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, 0, NativeMethods.ContactCountId, ref contactCount, pPreparsedData, pRawData, raw.hid.dwSizHid)) { throw new ApplicationException(LocalizationProvider.Instance.GetTextValue("Messages.ContactCountError")); } int linkCount = 0; HidNativeApi.HidP_GetLinkCollectionNodes(null, ref linkCount, pPreparsedData); HidNativeApi.HIDP_LINK_COLLECTION_NODE[] lcn = new HidNativeApi.HIDP_LINK_COLLECTION_NODE[linkCount]; HidNativeApi.HidP_GetLinkCollectionNodes(lcn, ref linkCount, pPreparsedData); if (_physicalMax.IsEmpty) { _physicalMax = GetPhysicalMax(linkCount, pPreparsedData); } if (contactCount != 0) { _requiringContactCount = contactCount; _outputTouchs = new List <RawData>(contactCount); } if (_requiringContactCount == 0) { return; } int contactIdentifier = 0; int physicalX = 0; int physicalY = 0; for (int dwIndex = 0; dwIndex < raw.hid.dwCount; dwIndex++) { for (short nodeIndex = 1; nodeIndex <= lcn[0].NumberOfChildren; nodeIndex++) { IntPtr pRawDataPacket = new IntPtr(pRawData.ToInt64() + dwIndex * raw.hid.dwSizHid); HidNativeApi.HidP_GetUsageValue(HidReportType.Input, NativeMethods.DigitizerUsagePage, nodeIndex, NativeMethods.ContactIdentifierId, ref contactIdentifier, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.XCoordinateId, ref physicalX, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); HidNativeApi.HidP_GetScaledUsageValue(HidReportType.Input, NativeMethods.GenericDesktopPage, nodeIndex, NativeMethods.YCoordinateId, ref physicalY, pPreparsedData, pRawDataPacket, raw.hid.dwSizHid); ushort[] usageList = GetButtonList(pPreparsedData, pRawData, nodeIndex, raw.hid.dwSizHid); int x, y; x = physicalX * _currentScr.Bounds.Width / _physicalMax.X; y = physicalY * _currentScr.Bounds.Height / _physicalMax.Y; bool tip = usageList.Length != 0 && usageList[0] == NativeMethods.TipId; _outputTouchs.Add(new RawData(tip ? DeviceStates.Tip : DeviceStates.None, contactIdentifier, new Point(x + _currentScr.Bounds.X, y + _currentScr.Bounds.Y))); if (--_requiringContactCount == 0) { break; } } if (_requiringContactCount == 0) { break; } } } } if (_requiringContactCount == 0 && PointsIntercepted != null) { PointsIntercepted(this, new RawPointsDataMessageEventArgs(_outputTouchs, _sourceDevice)); if (_outputTouchs.TrueForAll(rd => rd.State == DeviceStates.None)) { _sourceDevice = Devices.None; _physicalMax = Point.Empty; } } } finally { Marshal.FreeHGlobal(buffer); } }