Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
        /// <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);
            }
        }
Exemplo n.º 4
0
        /// <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);
            }
        }
Exemplo n.º 5
0
        /// <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);
            }
        }