Exemple #1
0
        internal RawStylusInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            PenContext penContext,
            RawStylusActions actions,
            int tabletDeviceId,
            int stylusDeviceId,
            int[] data)
            : base(inputSource, InputType.Stylus, mode, timestamp)
        {
            // Validate parameters
            if (!RawStylusActionsHelper.IsValid(actions))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, "actions"));
            }
            if (data == null && actions != RawStylusActions.InRange)
            {
                throw new ArgumentNullException("data");
            }

            _penContext     = new SecurityCriticalDataClass <PenContext>(penContext);
            _actions        = actions;
            _tabletDeviceId = tabletDeviceId;
            _stylusDeviceId = stylusDeviceId;
            _data           = data;
            _isSynchronize  = false;
        }
        /// <summary>
        ///     Constructs an instance of the RawStylusInputReport class.
        /// </summary>
        /// <param name="mode">
        ///     The mode in which the input is being provided.
        /// </param>
        /// <param name="timestamp">
        ///     The time when the input occurred.
        /// </param>
        /// <param name="inputSource">
        ///     The PresentationSource over which the stylus moved.
        /// <param name="actions">
        ///     The set of actions being reported.
        /// </param>
        ///  /// </param>
        /// <param name="stylusPointDescGenerator">
        ///     Function to generate the stylus point description.
        /// </param>
        /// <param name="tabletDeviceId">
        ///     Tablet device id.
        /// </param>
        /// <param name="stylusDeviceId">
        ///     Stylus device id.
        /// </param>
        /// <param name="data">
        ///     Raw stylus data.
        /// </param>
        internal RawStylusInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            RawStylusActions actions,
            Func <StylusPointDescription> stylusPointDescGenerator,
            int tabletDeviceId,
            int stylusDeviceId,
            int[] data)
            : base(inputSource, InputType.Stylus, mode, timestamp)
        {
            // Validate parameters
            if (!RawStylusActionsHelper.IsValid(actions))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, nameof(actions)));
            }
            if (data == null && actions != RawStylusActions.InRange)
            {
                throw new ArgumentNullException(nameof(data));
            }

            _actions = actions;
            _stylusPointDescGenerator = stylusPointDescGenerator;
            _data           = data;
            _isSynchronize  = false;
            _tabletDeviceId = tabletDeviceId;
            _stylusDeviceId = stylusDeviceId;
        }
Exemple #3
0
        internal RawStylusInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            RawStylusActions actions,
            StylusPointDescription mousePointDescription,
            int[] mouseData)
            : base(inputSource, InputType.Stylus, mode, timestamp)
        {
            // Validate parameters
            if (!RawStylusActionsHelper.IsValid(actions))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, "actions"));
            }
            if (mouseData == null)
            {
                throw new ArgumentNullException("mouseData");
            }

            _penContext            = new SecurityCriticalDataClass <PenContext>(null);
            _actions               = actions;
            _tabletDeviceId        = 0;
            _stylusDeviceId        = 0;
            _data                  = mouseData;
            _isSynchronize         = false;
            _mousePointDescription = mousePointDescription;
            _isMouseInput          = true;
        }
        /// <summary>
        ///     Constructs an instance of the RawStylusInputReport class.
        /// </summary>
        /// <param name="mode">
        ///     The mode in which the input is being provided.
        /// </param>
        /// <param name="timestamp">
        ///     The time when the input occurred.
        /// </param>
        /// <param name="inputSource">
        ///     The PresentationSource over which the stylus moved.
        /// </param>
        /// <param name="penContext">
        ///     The PenContext.
        /// </param>
        /// <param name="actions">
        ///     The set of actions being reported.
        /// </param>
        /// <param name="tabletDeviceId">
        ///     Tablet device id.
        /// </param>
        /// <param name="stylusDeviceId">
        ///     Stylus device id.
        /// </param>
        /// <param name="data">
        ///     Raw stylus data.
        /// </param>
        internal RawStylusInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            PenContext penContext,
            RawStylusActions actions,
            int tabletDeviceId,
            int stylusDeviceId,
            int[] data)
            : this(mode, timestamp, inputSource, actions, () => { return(penContext.StylusPointDescription); }, tabletDeviceId, stylusDeviceId, data)
        {
            // Validate parameters
            if (!RawStylusActionsHelper.IsValid(actions))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, nameof(actions)));
            }
            if (data == null && actions != RawStylusActions.InRange)
            {
                throw new ArgumentNullException(nameof(data));
            }

            _actions        = actions;
            _data           = data;
            _isSynchronize  = false;
            _tabletDeviceId = tabletDeviceId;
            _stylusDeviceId = stylusDeviceId;
            PenContext      = penContext;
        }
        internal RawStylusInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            PenContext penContext,
            RawStylusActions actions,
            int tabletDeviceId,
            int stylusDeviceId,
            int[] data)
            : base(inputSource, InputType.Stylus, mode, timestamp)
        {
            // Validate parameters
            if (!RawStylusActionsHelper.IsValid(actions))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, "actions"));
            }
            if (data == null && actions != RawStylusActions.InRange)
            {
                throw new ArgumentNullException("data");
            }

            _penContext     = new SecurityCriticalDataClass<PenContext>(penContext);
            _actions        = actions;
            _tabletDeviceId = tabletDeviceId;
            _stylusDeviceId = stylusDeviceId;
            _data           = data;
            _isSynchronize  = false;
        }
Exemple #6
0
 internal static bool IsValid(RawStylusActions action)
 {
     if (action < RawStylusActions.None || action > MaxActions)
     {
         return(false);
     }
     return(true);
 }
 internal static bool IsValid(RawStylusActions action)
 {
     if (action < RawStylusActions.None || action > MaxActions)
     { 
         return false;
     } 
     return true; 
 }
Exemple #8
0
        internal static RoutedEvent GetPreviewEventFromRawStylusActions(RawStylusActions actions)
        {
            RoutedEvent previewEvent = null;

            switch (actions)
            {
            case RawStylusActions.Down:
            {
                previewEvent = Stylus.PreviewStylusDownEvent;
            }
            break;

            case RawStylusActions.Up:
            {
                previewEvent = Stylus.PreviewStylusUpEvent;
            }
            break;

            case RawStylusActions.Move:
            {
                previewEvent = Stylus.PreviewStylusMoveEvent;
            }
            break;

            case RawStylusActions.InAirMove:
            {
                previewEvent = Stylus.PreviewStylusInAirMoveEvent;
            }
            break;

            case RawStylusActions.InRange:
            {
                previewEvent = Stylus.PreviewStylusInRangeEvent;
            }
            break;

            case RawStylusActions.OutOfRange:
            {
                previewEvent = Stylus.PreviewStylusOutOfRangeEvent;
            }
            break;

            case RawStylusActions.SystemGesture:
            {
                previewEvent = Stylus.PreviewStylusSystemGestureEvent;
            }
            break;
            }

            return(previewEvent);
        }
Exemple #9
0
        /////////////////////////////////////////////////////////////////////

        void ProcessInput(
            RawStylusActions actions,
            PenContext penContext,
            int tabletDeviceId,
            int stylusPointerId,
            int[] data, int timestamp)
        {
            // (all events but SystemEvent go thru here)
            _stylusLogic.ProcessInput(
                actions,
                penContext,
                tabletDeviceId,
                stylusPointerId,
                data,
                timestamp,
                _inputSource.Value);
        }
Exemple #10
0
        /////////////////////////////////////////////////////////////////////
        // (on app Dispatcher)
        internal void FireCustomData(object callbackData,
                                     RawStylusActions action,
                                     bool targetVerified)
        {
            // Only fire if plugin is enabled and hooked up to plugincollection.
            if (__enabled && _pic != null)
            {
                switch (action)
                {
                case RawStylusActions.Down:
                    OnStylusDownProcessed(callbackData, targetVerified);
                    break;

                case RawStylusActions.Move:
                    OnStylusMoveProcessed(callbackData, targetVerified);
                    break;

                case RawStylusActions.Up:
                    OnStylusUpProcessed(callbackData, targetVerified);
                    break;
                }
            }
        }
Exemple #11
0
        internal void ProcessInput(
                            RawStylusActions actions,
                            PenContext penContext, 
                            int tabletDeviceId,
                            int stylusDeviceId, 
                            int[] data, 
                            int timestamp,
                            PresentationSource inputSource) 
        {
            RawStylusInputReport inputReport =
                new RawStylusInputReport(InputMode.Foreground,
                                         timestamp, 
                                         inputSource,
                                         penContext, 
                                         actions, 
                                         tabletDeviceId,
                                         stylusDeviceId, 
                                         data);

            ProcessInputReport(inputReport);
        } 
        /// <summary>
        /// Processes the latest WM_POINTER message and forwards it to the WPF input stack.
        /// </summary>
        /// <param name="pointerId">The id of the pointer message</param>
        /// <param name="action">The stylus action being done</param>
        /// <param name="timestamp">The time (in ticks) the message arrived</param>
        /// <returns>True if successfully processed (handled), false otherwise</returns>
        private bool ProcessMessage(uint pointerId, RawStylusActions action, int timestamp)
        {
            bool handled = false;

            // Acquire all pointer data needed
            PointerData data = new PointerData(pointerId);

            // Only process touch or pen messages, do not process mouse or touchpad
            if (data.IsValid &&
                (data.Info.pointerType == UnsafeNativeMethods.POINTER_INPUT_TYPE.PT_TOUCH ||
                 data.Info.pointerType == UnsafeNativeMethods.POINTER_INPUT_TYPE.PT_PEN))
            {
                uint cursorId = 0;

                if (UnsafeNativeMethods.GetPointerCursorId(pointerId, ref cursorId))
                {
                    IntPtr deviceId = data.Info.sourceDevice;

                    // If we cannot acquire the latest tablet and stylus then wait for the
                    // next message.
                    if (!UpdateCurrentTabletAndStylus(deviceId, cursorId))
                    {
                        return(false);
                    }

                    // Convert move to InAirMove if applicable
                    if (action == RawStylusActions.Move &&
                        (!data.Info.pointerFlags.HasFlag(UnsafeNativeMethods.POINTER_FLAGS.POINTER_FLAG_INCONTACT) &&
                         data.Info.pointerFlags.HasFlag(UnsafeNativeMethods.POINTER_FLAGS.POINTER_FLAG_INRANGE)))
                    {
                        action = RawStylusActions.InAirMove;
                    }

                    // Generate a raw input to send to the input manager to start the event chain in PointerLogic
                    RawStylusInputReport rsir =
                        new RawStylusInputReport(
                            InputMode.Foreground,
                            timestamp,
                            _source.Value,
                            action,
                            () => { return(_currentTabletDevice.StylusPointDescription); },
                            _currentTabletDevice.Id,
                            _currentStylusDevice.Id,
                            GenerateRawStylusData(data, _currentTabletDevice))
                    {
                        StylusDevice = _currentStylusDevice.StylusDevice,
                    };

                    // Send the input report to the stylus plugins if we're not doing a drag and the window
                    // is currently enabled.
                    if (!_pointerLogic.Value.InDragDrop && IsWindowEnabled)
                    {
                        PointerStylusPlugInManager manager;

                        if (_pointerLogic.Value.PlugInManagers.TryGetValue(_source.Value, out manager))
                        {
                            manager.InvokeStylusPluginCollection(rsir);
                        }
                    }

                    // Update the data in the stylus device with the latest pointer data
                    _currentStylusDevice.Update(this, _source.Value, data, rsir);

                    // Call the StylusDevice to process and fire any interactions that
                    // might have resulted from the input.  If the originating inputs
                    // have been handled, we don't want to generate any gestures.
                    _currentStylusDevice.UpdateInteractions(rsir);

                    InputReportEventArgs irea = new InputReportEventArgs(_currentStylusDevice.StylusDevice, rsir)
                    {
                        RoutedEvent = InputManager.PreviewInputReportEvent,
                    };

                    // Now send the input report
                    InputManager.UnsecureCurrent.ProcessInput(irea);

                    // If this is not a primary pointer input, we don't want to
                    // allow it to go to DefWindowProc, so we should handle it.
                    // This ensures that primary pointer to mouse promotions
                    // will occur in multi-touch scenarios.
                    // We don't use the results of the input processing here as doing
                    // so could possibly cause some messages of a pointer chain as
                    // being handled, and some as being unhandled.  This results in
                    // undefined behavior in the WM_POINTER stack.
                    // <see cref="https://msdn.microsoft.com/en-us/library/windows/desktop/hh454923(v=vs.85).aspx"/>
                    handled = !_currentStylusDevice.IsPrimary;
                }
            }

            return(handled);
        }
        /// <summary>
        /// Used in order to allow StylusPlugins to affect mouse inputs as well as touch.
        /// </summary>
        internal static void InvokePlugInsForMouse(ProcessInputEventArgs e)
        {
            if (!e.StagingItem.Input.Handled)
            {
                // if we see a preview mouse event that is not generated by a stylus
                // then send on to plugin
                if ((e.StagingItem.Input.RoutedEvent != Mouse.PreviewMouseDownEvent) &&
                    (e.StagingItem.Input.RoutedEvent != Mouse.PreviewMouseUpEvent) &&
                    (e.StagingItem.Input.RoutedEvent != Mouse.PreviewMouseMoveEvent) &&
                    (e.StagingItem.Input.RoutedEvent != InputManager.InputReportEvent))
                {
                    return;
                }

                // record the mouse capture for later reference..
                MouseDevice        mouseDevice;
                PresentationSource source;
                bool             leftButtonDown;
                bool             rightButtonDown;
                RawStylusActions stylusActions = RawStylusActions.None;
                int timestamp;

                // See if we need to deal sending a leave due to this PresentationSource being Deactivated
                // If not then we just return and do nothing.
                if (e.StagingItem.Input.RoutedEvent == InputManager.InputReportEvent)
                {
                    if (_activeMousePlugInCollection?.Element == null)
                    {
                        return;
                    }

                    InputReportEventArgs input = e.StagingItem.Input as InputReportEventArgs;

                    if (input.Report.Type != InputType.Mouse)
                    {
                        return;
                    }

                    RawMouseInputReport mouseInputReport = (RawMouseInputReport)input.Report;

                    if ((mouseInputReport.Actions & RawMouseActions.Deactivate) != RawMouseActions.Deactivate)
                    {
                        return;
                    }

                    mouseDevice = InputManager.UnsecureCurrent.PrimaryMouseDevice;

                    // Mouse set directly over to null when truly deactivating.
                    if (mouseDevice == null || mouseDevice.DirectlyOver != null)
                    {
                        return;
                    }

                    leftButtonDown  = mouseDevice.LeftButton == MouseButtonState.Pressed;
                    rightButtonDown = mouseDevice.RightButton == MouseButtonState.Pressed;
                    timestamp       = mouseInputReport.Timestamp;

                    // Get presentationsource from element.
                    source = PresentationSource.CriticalFromVisual(_activeMousePlugInCollection.Element as Visual);
                }
                else
                {
                    MouseEventArgs mouseEventArgs = e.StagingItem.Input as MouseEventArgs;
                    mouseDevice     = mouseEventArgs.MouseDevice;
                    leftButtonDown  = mouseDevice.LeftButton == MouseButtonState.Pressed;
                    rightButtonDown = mouseDevice.RightButton == MouseButtonState.Pressed;

                    // Only look at mouse input reports that truly come from a mouse (and is not an up or deactivate) and it
                    // must be pressed state if a move (we don't fire stylus inair moves currently)
                    if (mouseEventArgs.StylusDevice != null &&
                        e.StagingItem.Input.RoutedEvent != Mouse.PreviewMouseUpEvent)
                    {
                        return;
                    }

                    if (e.StagingItem.Input.RoutedEvent == Mouse.PreviewMouseMoveEvent)
                    {
                        if (!leftButtonDown)
                        {
                            return;
                        }
                        stylusActions = RawStylusActions.Move;
                    }
                    if (e.StagingItem.Input.RoutedEvent == Mouse.PreviewMouseDownEvent)
                    {
                        MouseButtonEventArgs mouseButtonEventArgs = mouseEventArgs as MouseButtonEventArgs;
                        if (mouseButtonEventArgs.ChangedButton != MouseButton.Left)
                        {
                            return;
                        }
                        stylusActions = RawStylusActions.Down;
                    }
                    if (e.StagingItem.Input.RoutedEvent == Mouse.PreviewMouseUpEvent)
                    {
                        MouseButtonEventArgs mouseButtonEventArgs = mouseEventArgs as MouseButtonEventArgs;
                        if (mouseButtonEventArgs.ChangedButton != MouseButton.Left)
                        {
                            return;
                        }
                        stylusActions = RawStylusActions.Up;
                    }
                    timestamp = mouseEventArgs.Timestamp;

                    Visual directlyOverVisual = mouseDevice.DirectlyOver as Visual;
                    if (directlyOverVisual == null)
                    {
                        return;
                    }

                    //
                    // Take the presentation source which is associated to the directly over element.
                    source = PresentationSource.CriticalFromVisual(directlyOverVisual);
                }

                if ((source != null) &&
                    (source.CompositionTarget != null) &&
                    !source.CompositionTarget.IsDisposed)
                {
                    IInputElement directlyOver = mouseDevice.DirectlyOver;
                    int           packetStatus = (leftButtonDown ? 1 : 0) | (rightButtonDown ? 9 : 0); // pen tip down == 1, barrel = 8
                    Point         ptClient     = mouseDevice.GetPosition(source.RootVisual as IInputElement);
                    ptClient = source.CompositionTarget.TransformToDevice.Transform(ptClient);

                    int   buttons = (leftButtonDown ? 1 : 0) | (rightButtonDown ? 3 : 0);
                    int[] data    = { (int)ptClient.X, (int)ptClient.Y, packetStatus, buttons };
                    RawStylusInputReport inputReport = new RawStylusInputReport(
                        InputMode.Foreground,
                        timestamp,
                        source,
                        stylusActions,
                        () => { return(MousePointDescription); },
                        0, 0,
                        data);

                    PointerStylusPlugInManager manager =
                        StylusLogic.GetCurrentStylusLogicAs <PointerLogic>()?.GetManagerForSource(source);

                    // Avoid re-entrancy due to lock() being used.
                    using (Dispatcher.CurrentDispatcher.DisableProcessing())
                    {
                        // Call plugins (does enter/leave and FireCustomData as well)
                        _activeMousePlugInCollection = manager?.InvokeStylusPluginCollectionForMouse(inputReport, directlyOver, _activeMousePlugInCollection);
                    }
                }
            }
        }
 /////////////////////////////////////////////////////////////////////
 // (on app Dispatcher)
 internal void FireCustomData(object callbackData, 
                                                     RawStylusActions action,
                                                     bool targetVerified)
 {
     // Only fire if plugin is enabled and hooked up to plugincollection.
     if (__enabled && _pic != null)
     {
         switch (action)
         {
             case RawStylusActions.Down:
                 OnStylusDownProcessed(callbackData, targetVerified);
                 break;
             case RawStylusActions.Move:
                 OnStylusMoveProcessed(callbackData, targetVerified);
                 break;
             case RawStylusActions.Up:
                 OnStylusUpProcessed(callbackData, targetVerified);
                 break;
         }
     }
 }
Exemple #15
0
        internal RawStylusInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            RawStylusActions actions,
            StylusPointDescription mousePointDescription,
            int[] mouseData)
            : base(inputSource, InputType.Stylus, mode, timestamp)
        {
            // Validate parameters
            if (!RawStylusActionsHelper.IsValid(actions))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, "actions"));
            }
            if (mouseData == null)
            {
                throw new ArgumentNullException("mouseData");
            }

            _penContext     = new SecurityCriticalDataClass<PenContext>(null);
            _actions        = actions;
            _tabletDeviceId = 0;
            _stylusDeviceId = 0;
            _data           = mouseData;
            _isSynchronize  = false;
            _mousePointDescription = mousePointDescription;
            _isMouseInput = true;
        }
Exemple #16
0
 void ProcessInput(
     RawStylusActions actions,
     PenContext penContext,
     int tabletDeviceId, 
     int stylusPointerId,
     int[] data, int timestamp)
 {
     // (all events but SystemEvent go thru here)
     _stylusLogic.ProcessInput(
                                 actions,
                                 penContext,
                                 tabletDeviceId,
                                 stylusPointerId,
                                 data, 
                                 timestamp,
                                 _inputSource.Value);
 }
Exemple #17
0
        ///////////////////////////////////////////////////////////////////// 

        RoutedEvent GetPreviewEventFromRawStylusActions(RawStylusActions actions) 
        { 
            if((actions & RawStylusActions.Down) != 0)
                return Stylus.PreviewStylusDownEvent; 
            if ((actions & RawStylusActions.Up) != 0)
                return Stylus.PreviewStylusUpEvent;
            if ((actions & RawStylusActions.Move) != 0)
                return Stylus.PreviewStylusMoveEvent; 
            if ((actions & RawStylusActions.InAirMove) != 0)
                return Stylus.PreviewStylusInAirMoveEvent; 
            if ((actions & RawStylusActions.InRange) != 0) 
                return Stylus.PreviewStylusInRangeEvent;
            if ((actions & RawStylusActions.OutOfRange) != 0) 
                return Stylus.PreviewStylusOutOfRangeEvent;
            if ((actions & RawStylusActions.SystemGesture) != 0)
                return Stylus.PreviewStylusSystemGestureEvent;
            return null; 
        }