public override void InjectPointer(PointerData[] pointerData)
        {
            if (pointerData.Length > 256)
            {
                throw new ArgumentOutOfRangeException(paramName: string.Format(format: "The maximum number of simultaneous touch points is {0}.", arg0: 256U));
            }
            if (Log.OutImplementation != null)
            {
                foreach (var pointerData1 in pointerData)
                {
                    Log.Out(msg: "Inject Pointer: {0}", (object)pointerData1.ToString());
                }
            }
            var pointerTypeInfo = new PointerTypeInfo[pointerData.Length];

            for (var index = 0; index < pointerData.Length; ++index)
            {
                pointerTypeInfo[index] = TransformPointer(pointerData: pointerData[index], inputType: POINTER_INPUT_TYPE.TOUCH);
            }
            if (!InternalNativeMethods.InjectPointerInput(device: this.device, pointerTypeInfo: pointerTypeInfo, count: (uint)pointerTypeInfo.Length))
            {
                throw new Win32Exception(error: Marshal.GetLastWin32Error());
            }
        }
        protected PointerTypeInfo TransformPointer(
            PointerData pointerData,
            POINTER_INPUT_TYPE inputType)
        {
            var pointerTypeInfo = new PointerTypeInfo();

            pointerTypeInfo.type = inputType;
            var pointerInfo = new PointerInfo();

            pointerInfo.pointerType   = inputType;
            pointerInfo.pointerId     = pointerData.pointerId;
            pointerInfo.pointerFlags  = pointerData.flags;
            pointerInfo.pixelLocation = pointerData.location;
            switch (inputType)
            {
            case POINTER_INPUT_TYPE.TOUCH:
                pointerTypeInfo.data.touchInfo.pointerInfo = pointerInfo;
                pointerTypeInfo.data.touchInfo.touchMask   = TOUCH_MASK.NONE;
                pointerTypeInfo.data.touchInfo.touchFlags  = (TOUCH_FLAGS)pointerData.pressedButton;
                if (pointerData.width.HasValue && pointerData.height.HasValue)
                {
                    pointerTypeInfo.data.touchInfo.contact = new Rect {
                        left   = pointerTypeInfo.data.touchInfo.pointerInfo.pixelLocation.X - pointerData.width.Value / 2,
                        right  = pointerTypeInfo.data.touchInfo.pointerInfo.pixelLocation.X + pointerData.width.Value / 2,
                        top    = pointerTypeInfo.data.touchInfo.pointerInfo.pixelLocation.Y - pointerData.height.Value / 2,
                        bottom = pointerTypeInfo.data.touchInfo.pointerInfo.pixelLocation.Y + pointerData.height.Value / 2
                    };
                    pointerTypeInfo.data.touchInfo.touchMask |= TOUCH_MASK.CONTACTAREA;
                }

                if (pointerData.pressure.HasValue)
                {
                    pointerTypeInfo.data.touchInfo.pressure   = pointerData.pressure.Value;
                    pointerTypeInfo.data.touchInfo.touchMask |= TOUCH_MASK.PRESSURE;
                }

                if (pointerData.twist.HasValue)
                {
                    pointerTypeInfo.data.touchInfo.orientation = pointerData.twist.Value;
                    pointerTypeInfo.data.touchInfo.touchMask  |= TOUCH_MASK.ORIENTATION;
                }

                break;

            case POINTER_INPUT_TYPE.PEN:
                pointerTypeInfo.data.penInfo.pointerInfo = pointerInfo;
                pointerTypeInfo.data.penInfo.penMask     = PEN_MASK.NONE;
                pointerTypeInfo.data.penInfo.penFlags    = (PEN_FLAGS)pointerData.pressedButton;
                if (pointerData.tiltX.HasValue)
                {
                    pointerTypeInfo.data.penInfo.tiltX    = pointerData.tiltX.Value;
                    pointerTypeInfo.data.penInfo.penMask |= PEN_MASK.TILT_X;
                }

                if (pointerData.tiltY.HasValue)
                {
                    pointerTypeInfo.data.penInfo.tiltY    = pointerData.tiltY.Value;
                    pointerTypeInfo.data.penInfo.penMask |= PEN_MASK.TILT_Y;
                }

                if (pointerData.pressure.HasValue)
                {
                    pointerTypeInfo.data.penInfo.pressure = pointerData.pressure.Value;
                    pointerTypeInfo.data.penInfo.penMask |= PEN_MASK.PRESSURE;
                }

                if (pointerData.twist.HasValue)
                {
                    pointerTypeInfo.data.penInfo.rotation = pointerData.twist.Value;
                    pointerTypeInfo.data.penInfo.penMask |= PEN_MASK.ROTATION;
                }

                break;

            default:
                pointerTypeInfo.data.touchInfo.pointerInfo = pointerInfo;
                pointerTypeInfo.data.touchInfo.touchMask   = TOUCH_MASK.NONE;
                break;
            }

            return(pointerTypeInfo);
        }