/// <summary>
        ///     Analyzes stylus input and determines if a SystemGesture should be generated.
        /// </summary>
        /// <param name="stylusInputReport">The latest stylus input report.</param>
        /// <returns>The SystemGesture to generate, null otherwise.</returns>
        internal SystemGesture?GenerateStaticGesture(RawStylusInputReport stylusInputReport)
        {
            switch (stylusInputReport.Actions)
            {
            case RawStylusActions.Down:
                OnTouchDown(stylusInputReport);
                return(null);

            case RawStylusActions.Up:
                return(OnTouchUp(stylusInputReport));


            case RawStylusActions.SystemGesture:
                OnSystemGesture((RawStylusSystemGestureInputReport)stylusInputReport);
                return(null);

            /*
             * case RawStylusActions.Move:
             * case RawStylusActions.Activate:
             * case RawStylusActions.Deactivate:
             * case RawStylusActions.OutOfRange:
             * return null;
             */

            default:
                return(null);
            }
        }
        /// <summary> 
        ///     Analyzes stylus input and determines if a SystemGesture should be generated.
        /// </summary> 
        /// <param name="stylusInputReport">The latest stylus input report.</param> 
        /// <returns>The SystemGesture to generate, null otherwise.</returns>
        internal SystemGesture? GenerateStaticGesture(RawStylusInputReport stylusInputReport) 
        {
            switch (stylusInputReport.Actions)
            {
                case RawStylusActions.Down: 
                    OnTouchDown(stylusInputReport);
                    return null; 
 
                case RawStylusActions.Up:
                    return OnTouchUp(stylusInputReport); 


                case RawStylusActions.SystemGesture:
                    OnSystemGesture((RawStylusSystemGestureInputReport)stylusInputReport); 
                    return null;
 
                    /* 
                case RawStylusActions.Move:
                case RawStylusActions.Activate: 
                case RawStylusActions.Deactivate:
                case RawStylusActions.OutOfRange:
                    return null;
                     */ 

                default: 
                    return null; 
            }
        } 
        private SystemGesture? OnTouchUp(RawStylusInputReport stylusInputReport)
        { 
            switch (_currentState)
            {
                case State.TwoFingersDown:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId)) 
                    {
                        // One of the two fingers released 
                        _firstUpTime = Environment.TickCount; 
                        _currentState = State.OneFingerInStaticGesture;
                    } 
                    break;

                case State.OneFingerDown:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId)) 
                    {
                        // The single finger that was down was released 
                        _currentState = State.Idle; 
                    }
                    break; 

                case State.OneFingerInStaticGesture:
                    // The last of two fingers released
                    _currentState = State.Idle; 

                    // Check the times and see if a TwoFingerTap or Rollover should be generated. 
                    // TwoFingerTap is more constrained than Rollover, so check it first. 
                    if (IsTwoFingerTap())
                    { 
                        return SystemGesture.TwoFingerTap;
                    }
#if ROLLOVER_IMPLEMENTED
                    else if (IsRollover()) 
                    {
                        return SystemGesture.Rollover; 
                    } 
#endif
                    break; 

                case State.TwoFingersInWisptisGesture:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                    { 
                        // One of the two fingers released.
                        _currentState = State.OneFingerInWisptisGesture; 
                    } 
                    break;
 
                case State.OneFingerInWisptisGesture:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                    {
                        // The last finger released 
                        _currentState = State.Idle;
                    } 
                    break; 

            } 

            return null;
        }
Example #4
0
        internal StylusPlugInCollection InvokeStylusPluginCollectionForMouse(RawStylusInputReport inputReport, IInputElement directlyOver, StylusPlugInCollection currentPlugInCollection)
        {
            StylusPlugInCollection newPlugInCollection = null;

            // lock to make sure only one event is processed at a time and no changes to state can
            // be made until we finish routing this event.
            lock (__rtiLock)
            {
                //Debug.Assert(inputReport.Actions == RawStylusActions.Down ||
                //             inputReport.Actions == RawStylusActions.Up ||
                //             inputReport.Actions == RawStylusActions.Move);

                // Find new target plugin collection
                if (directlyOver != null)
                {
                    UIElement uiElement = InputElement.GetContainingUIElement(directlyOver as DependencyObject) as UIElement;
                    if (uiElement != null)
                    {
                        newPlugInCollection = FindPlugInCollection(uiElement);
                    }
                }

                // Fire Leave event to old pluginCollection if we need to.
                if (currentPlugInCollection != null && currentPlugInCollection != newPlugInCollection)
                {
                    // NOTE: input report points for mouse are in avalon measured units and not device!
                    RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, currentPlugInCollection.ViewToElement, currentPlugInCollection);

                    currentPlugInCollection.FireEnterLeave(false, tempRawStylusInput, true);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                }
                if (newPlugInCollection != null)
                {
                    // NOTE: input report points for mouse are in avalon measured units and not device!
                    RawStylusInput rawStylusInput = new RawStylusInput(inputReport, newPlugInCollection.ViewToElement, newPlugInCollection);
                    inputReport.RawStylusInput = rawStylusInput;

                    if (newPlugInCollection != currentPlugInCollection)
                    {
                        newPlugInCollection.FireEnterLeave(true, rawStylusInput, true);
                    }

                    // We are on the pen thread, just call directly.
                    newPlugInCollection.FireRawStylusInput(rawStylusInput);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;

                    // Fire custom data events (always confirmed for mouse)
                    foreach (RawStylusInputCustomData customData in rawStylusInput.CustomDataList)
                    {
                        customData.Owner.FireCustomData(customData.Data, inputReport.Actions, true);
                    }
                }
            }
            return(newPlugInCollection);
        }
        private SystemGesture?OnTouchUp(RawStylusInputReport stylusInputReport)
        {
            switch (_currentState)
            {
            case State.TwoFingersDown:
                if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                {
                    // One of the two fingers released
                    _firstUpTime  = Environment.TickCount;
                    _currentState = State.OneFingerInStaticGesture;
                }
                break;

            case State.OneFingerDown:
                if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                {
                    // The single finger that was down was released
                    _currentState = State.Idle;
                }
                break;

            case State.OneFingerInStaticGesture:
                // The last of two fingers released
                _currentState = State.Idle;

                // Check the times and see if a TwoFingerTap or Rollover should be generated.
                // TwoFingerTap is more constrained than Rollover, so check it first.
                if (IsTwoFingerTap())
                {
                    return(SystemGesture.TwoFingerTap);
                }
#if ROLLOVER_IMPLEMENTED
                else if (IsRollover())
                {
                    return(SystemGesture.Rollover);
                }
#endif
                break;

            case State.TwoFingersInWisptisGesture:
                if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                {
                    // One of the two fingers released.
                    _currentState = State.OneFingerInWisptisGesture;
                }
                break;

            case State.OneFingerInWisptisGesture:
                if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                {
                    // The last finger released
                    _currentState = State.Idle;
                }
                break;
            }

            return(null);
        }
Example #6
0
        internal SystemGesture?GenerateStaticGesture(RawStylusInputReport stylusInputReport)
        {
            if (_multiTouchSystemGestureLogic != null)
            {
                return(_multiTouchSystemGestureLogic.GenerateStaticGesture(stylusInputReport));
            }

            return(null);
        }
Example #7
0
        internal Point GetLastTabletPoint(RawStylusInputReport stylusInputReport)
        {
            var lastPoint = stylusInputReport.GetLastTabletPoint();

            if (!_tabletToView.HasValue)
            {
                //
                _tabletToView = InputManager.Current.StylusLogic.GetTabletToViewTransform(this);
            }

            return(_tabletToView.Value.Transform(lastPoint));
        }
Example #8
0
        internal StylusPlugInCollection TargetPlugInCollection(RawStylusInputReport inputReport)
        {
            // Caller must make call to this routine inside of lock(__rtiLock)!
            StylusPlugInCollection pic = null;

            // We should only be called when not on the application thread!
            System.Diagnostics.Debug.Assert(!inputReport.StylusDevice.CheckAccess());

            WispStylusDevice stylusDevice = inputReport.StylusDevice.As <WispStylusDevice>();

            // We're on the pen thread so can't touch visual tree.  Use capturedPlugIn (if capture on) or cached rects.
            bool elementHasCapture = false;

            pic = stylusDevice.GetCapturedPlugInCollection(ref elementHasCapture);
            int pointLength = inputReport.PenContext.StylusPointDescription.GetInputArrayLengthPerPoint();

            // Make sure that the captured Plugin Collection is still in the list.  CaptureChanges are
            // deferred so there is a window where the stylus device is not updated yet.  This protects us
            // from using a bogus plugin collecton for an element that is in an invalid state.
            if (elementHasCapture && !_plugInCollectionList.Contains(pic))
            {
                elementHasCapture = false;  // force true hittesting to be done!
            }

            if (!elementHasCapture && inputReport.Data != null && inputReport.Data.Length >= pointLength)
            {
                int[] data = inputReport.Data;
                System.Diagnostics.Debug.Assert(data.Length % pointLength == 0);
                Point ptTablet = new Point(data[data.Length - pointLength], data[data.Length - pointLength + 1]);
                // Note: the StylusLogic data inside DeviceUnitsFromMeasurUnits is protected by __rtiLock.
                ptTablet   = ptTablet * stylusDevice.TabletDevice.TabletDeviceImpl.TabletToScreen;
                ptTablet.X = (int)Math.Round(ptTablet.X);                        // Make sure we snap to whole window pixels.
                ptTablet.Y = (int)Math.Round(ptTablet.Y);
                ptTablet   = _stylusLogic.MeasureUnitsFromDeviceUnits(ptTablet); // change to measured units now.

                pic = HittestPlugInCollection(ptTablet);                         // Use cached rectangles for UIElements.
            }
            return(pic);
        }
        private void OnTouchDown(RawStylusInputReport stylusInputReport)
        {
            switch (_currentState) 
            {
                case State.Idle: 
                    // The first finger came down 
                    Reset(); // Clear old settings
                    _firstStylusDeviceId = stylusInputReport.StylusDeviceId; 
                    _currentState = State.OneFingerDown;
                    _firstDownTime = Environment.TickCount;
                    break;
 
                case State.OneFingerDown:
                    // The second finger came down 
                    Debug.Assert(_firstStylusDeviceId != null && _firstStylusDeviceId != stylusInputReport.StylusDeviceId); 
                    Debug.Assert(_secondStylusDeviceId == null);
                    _secondStylusDeviceId = stylusInputReport.StylusDeviceId; 
                    _currentState = State.TwoFingersDown;
                    break;

                    // Ignoring fingers beyond two 
            }
        } 
        private void OnTouchDown(RawStylusInputReport stylusInputReport)
        {
            switch (_currentState)
            {
            case State.Idle:
                // The first finger came down
                Reset();     // Clear old settings
                _firstStylusDeviceId = stylusInputReport.StylusDeviceId;
                _currentState        = State.OneFingerDown;
                _firstDownTime       = Environment.TickCount;
                break;

            case State.OneFingerDown:
                // The second finger came down
                Debug.Assert(_firstStylusDeviceId != null && _firstStylusDeviceId != stylusInputReport.StylusDeviceId);
                Debug.Assert(_secondStylusDeviceId == null);
                _secondStylusDeviceId = stylusInputReport.StylusDeviceId;
                _currentState         = State.TwoFingersDown;
                break;

                // Ignoring fingers beyond two
            }
        }
Example #11
0
        void CallPlugInsForMouse(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 == null || _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.Value.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; 
                    }

                    // NTRAID:WINDOWSOS#1536432-2006/03/15-WAYNEZEN,
                    // Take the presentation source which is associated to the directly over element. 
                    source = PresentationSource.CriticalFromVisual(directlyOverVisual);
 
                } 

                PenContexts penContexts = GetPenContextsFromHwnd(source); 

                if ((penContexts != null) &&
                    (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, 
                                                                GetMousePointDescription,
                                                                data);

                    // Avoid re-entrancy due to lock() being used. 
                    using (Dispatcher.DisableProcessing())
                    { 
                        // Call plugins (does enter/leave and FireCustomData as well) 
                        _activeMousePlugInCollection = penContexts.InvokeStylusPluginCollectionForMouse(inputReport, directlyOver, _activeMousePlugInCollection);
                    } 
                }
            }
        }
Example #12
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);
        } 
Example #13
0
        internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport)
        {
            // Find PenContexts object for this inputReport.
            StylusPlugInCollection pic = null;

            // lock to make sure only one event is processed at a time and no changes to state can
            // be made until we finish routing this event.
            lock (__rtiLock)
            {
                switch (inputReport.Actions)
                {
                case RawStylusActions.Down:
                case RawStylusActions.Move:
                case RawStylusActions.Up:
                    // Figure out current target plugincollection.
                    pic = TargetPlugInCollection(inputReport);
                    break;

                default:
                    return;     // Nothing to do unless one of the above events
                }

                WispStylusDevice stylusDevice = inputReport.StylusDevice.As <WispStylusDevice>();

                StylusPlugInCollection currentPic = stylusDevice.CurrentNonVerifiedTarget;

                // Fire Leave event if we need to.
                if (currentPic != null && currentPic != pic)
                {
                    // Create new RawStylusInput to send
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
                    transformTabletToView.Children.Add(currentPic.ViewToElement);                                                              // Make it relative to the element.
                    transformTabletToView.Freeze();                                                                                            // Must be frozen for multi-threaded access.

                    RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, transformTabletToView, currentPic);

                    currentPic.FireEnterLeave(false, tempRawStylusInput, false);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                    stylusDevice.CurrentNonVerifiedTarget = null;
                }

                if (pic != null)
                {
                    // NOTE: PenContext info will not change (it gets rebuilt instead so keeping ref is fine)
                    //    The transformTabletToView matrix and plugincollection rects though can change based
                    //    off of layout events which is why we need to lock this.
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
                    transformTabletToView.Children.Add(pic.ViewToElement);                                                                     // Make it relative to the element.
                    transformTabletToView.Freeze();                                                                                            // Must be frozen for multi-threaded access.

                    RawStylusInput rawStylusInput = new RawStylusInput(inputReport, transformTabletToView, pic);
                    inputReport.RawStylusInput = rawStylusInput;

                    if (pic != currentPic)
                    {
                        stylusDevice.CurrentNonVerifiedTarget = pic;
                        pic.FireEnterLeave(true, rawStylusInput, false);
                    }

                    // We are on the pen thread, just call directly.
                    pic.FireRawStylusInput(rawStylusInput);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                }
            } // lock(__rtiLock)
        }
Example #14
0
        private void GenerateInRange(RawStylusInputReport rawStylusInputReport)
        {
            StylusDevice stylusDevice = rawStylusInputReport.StylusDevice;
 
            RawStylusInputReport inputReport =
                new RawStylusInputReport(rawStylusInputReport.Mode, 
                                         rawStylusInputReport.Timestamp, 
                                         rawStylusInputReport.InputSource,
                                         rawStylusInputReport.PenContext, 
                                         RawStylusActions.InRange,
                                         stylusDevice.TabletDevice.Id,
                                         stylusDevice.Id,
                                         rawStylusInputReport.Data); 

            InputReportEventArgs input = new InputReportEventArgs(stylusDevice, inputReport); 
            input.RoutedEvent=InputManager.PreviewInputReportEvent; 
            _inputManager.Value.ProcessInput(input);
        } 
Example #15
0
 internal abstract void UpdateEventStylusPoints(RawStylusInputReport report, bool resetIfNoOverride);
Example #16
0
 internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport)
 { 
     if (inputReport.StylusDevice != null) 
     {
         inputReport.PenContext.Contexts.InvokeStylusPluginCollection(inputReport); 
     }
 }
        public void Synchronize()
        {
            // Simulate a stylus move (if we are current stylus, inrange, visuals still valid to update
            // and has moved).
            if (InRange && _inputSource != null && _inputSource.Value != null &&
                _inputSource.Value.CompositionTarget != null && !_inputSource.Value.CompositionTarget.IsDisposed)
            {
                Point ptDevice = PointUtil.ScreenToClient(_lastScreenLocation, _inputSource.Value);
                
                // GlobalHitTest always returns an IInputElement, so we are sure to have one.
                IInputElement stylusOver = GlobalHitTest(_inputSource.Value, ptDevice);
                bool fOffsetChanged = false;

                if (_stylusOver == stylusOver)
                {
                    Point ptOffset = GetPosition(stylusOver);
                    fOffsetChanged = MS.Internal.DoubleUtil.AreClose(ptOffset.X, _rawElementRelativePosition.X) == false || MS.Internal.DoubleUtil.AreClose(ptOffset.Y, _rawElementRelativePosition.Y) == false;
                }

                if(fOffsetChanged || _stylusOver != stylusOver)
                {
                    int timeStamp = Environment.TickCount;
                    PenContext penContext = _stylusLogic.GetStylusPenContextForHwnd(_inputSource.Value,TabletDevice.Id);

                    if (_eventStylusPoints != null &&
                        _eventStylusPoints.Count > 0 &&
                        StylusPointDescription.AreCompatible(penContext.StylusPointDescription, _eventStylusPoints.Description))
                    {

                        StylusPoint stylusPoint = _eventStylusPoints[_eventStylusPoints.Count - 1];
                        int[] data = stylusPoint.GetPacketData();

                        // get back to the correct coordinate system
                        Matrix m = TabletDevice.TabletToScreen;
                        m.Invert();
                        Point ptTablet = ptDevice * m;

                        data[0] = (int)ptTablet.X;
                        data[1] = (int)ptTablet.Y;

                        RawStylusInputReport report = new RawStylusInputReport(InputMode.Foreground,
                                                                             timeStamp,
                                                                             _inputSource.Value,
                                                                             penContext,
                                                                             InAir?RawStylusActions.InAirMove:RawStylusActions.Move,
                                                                             TabletDevice.Id,
                                                                             Id,
                                                                             data);


                        report.Synchronized = true;

                        InputReportEventArgs inputReportEventArgs = new InputReportEventArgs(this, report);
                        inputReportEventArgs.RoutedEvent=InputManager.PreviewInputReportEvent;

                        _stylusLogic.InputManagerProcessInputEventArgs(inputReportEventArgs);
                    }
                }
            }
        }
Example #18
0
        bool IsValidStylusAction(RawStylusInputReport rawStylusInputReport) 
        {
            bool allowEvent = true; 
            StylusDevice stylusDevice = rawStylusInputReport.StylusDevice; 

            // See if we have the correct PenContext we are receiving input from.  We can get two 
            // different PenContext objects actually sending us input simultaneously.  We lock onto the
            // the first one we see come in range and keep locked on that till we see it go out of range.
            // If we go out of range and have overlapping inrange from another PenContext we will
            // force that PenContext to be the current one by forcing a InRange stylus event. 

            // Now check for proper state of the device for the given Stylus event. 
            switch (rawStylusInputReport.Actions) 
            {
                case RawStylusActions.InRange: 
                    // only process inrange if currently out of range and the inputsource is not disposed.
                    allowEvent = !stylusDevice.InRange && !rawStylusInputReport.InputSource.IsDisposed;
                    break;
 
                case RawStylusActions.InAirMove:
                    if (!stylusDevice.InRange && !rawStylusInputReport.InputSource.IsDisposed) 
                    { 
                        // Force InRange if stylus is out of range.
                        Debug.Assert(stylusDevice.InAir); 
                        GenerateInRange(rawStylusInputReport);
                    }
                    else
                    { 
                        // If InAir and either inputSource matches current devices input source or
                        // the last down input source then it is OK to process and we can allow this. 
                        allowEvent = rawStylusInputReport.PenContext == stylusDevice.ActivePenContext; 
                    }
                    break; 

                case RawStylusActions.Down:
                    if (!stylusDevice.InRange)
                    { 
                        Debug.Assert(stylusDevice.InAir);
                        GenerateInRange(rawStylusInputReport); 
                    } 
                    else
                    { 
                        allowEvent = rawStylusInputReport.PenContext == stylusDevice.ActivePenContext;
                    }
                    break;
 
                case RawStylusActions.Move:
                    allowEvent = rawStylusInputReport.PenContext == stylusDevice.ActivePenContext; 
                    break; 

                case RawStylusActions.Up: 
                    allowEvent = rawStylusInputReport.PenContext == stylusDevice.ActivePenContext;
                    break;

                case RawStylusActions.SystemGesture: 
                    allowEvent = rawStylusInputReport.PenContext == stylusDevice.ActivePenContext;
 
                    if (allowEvent) 
                    {
                        RawStylusSystemGestureInputReport systemGestureReport = (RawStylusSystemGestureInputReport)rawStylusInputReport; 

                        // If we see a Tap gesture that is sent when we are not in the down state then
                        // ignore this (it's a double tap issue) since we will have generated one when
                        // we see the up. 
                        if (systemGestureReport.SystemGesture == SystemGesture.Tap && stylusDevice.InAir)
                        { 
                            allowEvent = false; 
                        }
                    } 
                    break;

                case RawStylusActions.OutOfRange:
                    allowEvent = rawStylusInputReport.PenContext == stylusDevice.ActivePenContext; 
                    break;
            } 
 
            return allowEvent;
        } 
 internal void UpdateEventStylusPoints(RawStylusInputReport report, bool resetIfNoOverride)
 {
     if (report.RawStylusInput != null && report.RawStylusInput.StylusPointsModified)
     {
         GeneralTransform transformToElement = report.RawStylusInput.Target.ViewToElement.Inverse;                
         //note that RawStylusInput.Target (of type StylusPluginCollection)
         //guarantees that ViewToElement is invertible
         Debug.Assert(transformToElement != null);
         
         _eventStylusPoints = report.RawStylusInput.GetStylusPoints(transformToElement);
     }
     else if (resetIfNoOverride)
     {
         _eventStylusPoints =
             new StylusPointCollection(report.StylusPointDescription,
                                       report.GetRawPacketData(),
                                       GetTabletToElementTransform(null),
                                       Matrix.Identity);
     }
 }
        internal Point GetLastTabletPoint(RawStylusInputReport stylusInputReport)
        {
            var lastPoint = stylusInputReport.GetLastTabletPoint();

            if (!_tabletToView.HasValue)
            {
                // 
                _tabletToView = InputManager.Current.StylusLogic.GetTabletToViewTransform(this);
            }

            return _tabletToView.Value.Transform(lastPoint);
        }
        internal SystemGesture? GenerateStaticGesture(RawStylusInputReport stylusInputReport)
        {
            if (_multiTouchSystemGestureLogic != null)
            {
                return _multiTouchSystemGestureLogic.GenerateStaticGesture(stylusInputReport);
            }

            return null;
        }
Example #22
0
        private void VerifyStylusPlugInCollectionTarget(RawStylusInputReport rawStylusInputReport) 
        {
            switch (rawStylusInputReport.Actions)
            {
                case RawStylusActions.Down: 
                case RawStylusActions.Move:
                case RawStylusActions.Up: 
                    break; 
                default:
                    return; // do nothing if not Down, Move or Up. 
            }

            RawStylusInput originalRSI = rawStylusInputReport.RawStylusInput;
            // See if we have a plugin for the target of this input. 
            StylusPlugInCollection targetPIC = null;
            StylusPlugInCollection targetRtiPIC = (originalRSI != null) ? originalRSI.Target : null; 
            bool updateEventPoints = false; 

            // Make sure we use UIElement for target if non NULL and hit ContentElement. 
            UIElement newTarget = InputElement.GetContainingUIElement(rawStylusInputReport.StylusDevice.DirectlyOver as DependencyObject) as UIElement;
            if (newTarget != null)
            {
                targetPIC = rawStylusInputReport.PenContext.Contexts.FindPlugInCollection(newTarget); 
            }
 
            // Make sure any lock() calls do not reenter on us. 
            using(Dispatcher.DisableProcessing())
            { 
                // See if we hit the wrong PlugInCollection on the pen thread and clean things up if we did.
                if (targetRtiPIC != null && targetRtiPIC != targetPIC && originalRSI != null)
                {
                    // Fire custom data not confirmed events for both pre and post since bad target... 
                    foreach (RawStylusInputCustomData customData in originalRSI.CustomDataList)
                    { 
                        customData.Owner.FireCustomData(customData.Data, rawStylusInputReport.Actions, false); 
                    }
 
                    updateEventPoints = originalRSI.StylusPointsModified;

                    // Clear RawStylusInput data.
                    rawStylusInputReport.RawStylusInput = null; 
                }
 
                // See if we need to build up an RSI to send to the plugincollection (due to a mistarget). 
                bool sendRawStylusInput = false;
                if (targetPIC != null && rawStylusInputReport.RawStylusInput == null) 
                {
                    // NOTE: PenContext info will not change (it gets rebuilt instead so keeping ref is fine)
                    //    The transformTabletToView matrix and plugincollection rects though can change based
                    //    off of layout events which is why we need to lock this. 
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(new MatrixTransform(GetTabletToViewTransform(rawStylusInputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device) 
                    transformTabletToView.Children.Add(targetPIC.ViewToElement); // Make it relative to the element. 
                    transformTabletToView.Freeze();  // Must be frozen for multi-threaded access.
 
                    RawStylusInput rawStylusInput = new RawStylusInput(rawStylusInputReport, transformTabletToView, targetPIC);
                    rawStylusInputReport.RawStylusInput = rawStylusInput;
                    sendRawStylusInput = true;
                } 

                // Now fire the confirmed enter/leave events as necessary. 
                StylusPlugInCollection currentTarget = rawStylusInputReport.StylusDevice.CurrentVerifiedTarget; 
                if (targetPIC != currentTarget)
                { 
                    if (currentTarget != null)
                    {
                        // Fire leave event.  If we never had a plugin for this event then create a temp one.
                        if (originalRSI == null) 
                        {
                            GeneralTransformGroup transformTabletToView = new GeneralTransformGroup(); 
                            transformTabletToView.Children.Add(new MatrixTransform(GetTabletToViewTransform(rawStylusInputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device) 
                            transformTabletToView.Children.Add(currentTarget.ViewToElement); // Make it relative to the element.
                            transformTabletToView.Freeze();  // Must be frozen for multi-threaded access. 
                            originalRSI = new RawStylusInput(rawStylusInputReport, transformTabletToView, currentTarget);
                        }
                        currentTarget.FireEnterLeave(false, originalRSI, true);
                    } 

                    if (targetPIC != null) 
                    { 
                        // Fire Enter event
                        targetPIC.FireEnterLeave(true, rawStylusInputReport.RawStylusInput, true); 
                    }

                    // Update the verified target.
                    rawStylusInputReport.StylusDevice.CurrentVerifiedTarget = targetPIC; 
                }
 
 
                // Now fire RawStylusInput if needed to the right plugincollection.
                if (sendRawStylusInput) 
                {
                    // We are on the pen thread, just call directly.
                    targetPIC.FireRawStylusInput(rawStylusInputReport.RawStylusInput);
                    updateEventPoints = (updateEventPoints || rawStylusInputReport.RawStylusInput.StylusPointsModified); 
                }
 
                // Now fire PrePreviewCustomData events. 
                if (targetPIC != null)
                { 
                    // Send custom data pre event
                    foreach (RawStylusInputCustomData customData in rawStylusInputReport.RawStylusInput.CustomDataList)
                    {
                        customData.Owner.FireCustomData(customData.Data, rawStylusInputReport.Actions, true); 
                    }
                } 
 
                // VerifyRawTarget might resend to correct plugins or may have hit the wrong plugincollection.  The StylusPackets
                // may be overriden in those plugins so we need to call UpdateEventStylusPoints to update things. 
                if (updateEventPoints)
                {
                    rawStylusInputReport.StylusDevice.UpdateEventStylusPoints(rawStylusInputReport, true);
                } 
            }
        } 
Example #23
0
        private void GenerateGesture(RawStylusInputReport rawStylusInputReport, SystemGesture gesture) 
        {
            StylusDevice stylusDevice = rawStylusInputReport.StylusDevice; 
            System.Diagnostics.Debug.Assert(stylusDevice != null); 

            RawStylusSystemGestureInputReport inputReport = new RawStylusSystemGestureInputReport( 
                                                        InputMode.Foreground,
                                                        rawStylusInputReport.Timestamp,
                                                        rawStylusInputReport.InputSource,
                                                        rawStylusInputReport.PenContext, 
                                                        rawStylusInputReport.TabletDeviceId,
                                                        rawStylusInputReport.StylusDeviceId, 
                                                        gesture, 
                                                        0, // Gesture X location (only used for flicks)
                                                        0, // Gesture Y location (only used for flicks) 
                                                        0); // ButtonState (only used for flicks)
            inputReport.StylusDevice = stylusDevice;
            InputReportEventArgs input = new InputReportEventArgs(stylusDevice, inputReport);
            input.RoutedEvent=InputManager.PreviewInputReportEvent; 
            // Process this directly instead of doing a push. We want this event to get
            // to the user before the StylusUp and MouseUp event. 
            InputManagerProcessInputEventArgs(input); 
        }
        internal void UpdateState(RawStylusInputReport report)
        {
            Debug.Assert(report.TabletDeviceId == _tabletDevice.Id);
            Debug.Assert((report.Actions & RawStylusActions.None) == 0);

            _eventStylusPoints =
                new StylusPointCollection(  report.StylusPointDescription,
                                            report.GetRawPacketData(),
                                            GetTabletToElementTransform(null),
                                            Matrix.Identity);

            PresentationSource inputSource = DetermineValidSource(report.InputSource, _eventStylusPoints, report.PenContext.Contexts);
            
            // See if we need to remap the stylus data X and Y values to different presentation source.
            if (inputSource != null && inputSource != report.InputSource)
            {
                Point newWindowLocation = PointUtil.ClientToScreen(new Point(0, 0), inputSource);
                newWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(newWindowLocation);
                Point oldWindowLocation = _stylusLogic.MeasureUnitsFromDeviceUnits(report.PenContext.Contexts.DestroyedLocation);
                
                // Create translate matrix transform to shift coords to map points to new window location.
                MatrixTransform additionalTransform = new MatrixTransform(new Matrix(1, 0, 0, 1,
                                                            oldWindowLocation.X - newWindowLocation.X,
                                                            oldWindowLocation.Y - newWindowLocation.Y));
                _eventStylusPoints = _eventStylusPoints.Reformat(report.StylusPointDescription, additionalTransform);
            }

            _rawPosition = _eventStylusPoints[_eventStylusPoints.Count - 1];

            _inputSource = new SecurityCriticalDataClass<PresentationSource>(inputSource);

            if (inputSource != null)
            {
                // Update our screen position from this move.
                Point pt = _stylusLogic.DeviceUnitsFromMeasureUnits((Point)_rawPosition);
                _lastScreenLocation = PointUtil.ClientToScreen(pt, inputSource);
            }
            
            // If we are not blocked from updating the location we want to use for the 
            // promoted mouse location then update it.  We set this flag in the post process phase
            // of Stylus events (after they have fired).
            if (!_fBlockMouseMoveChanges)
            {
                _lastMouseScreenLocation = _lastScreenLocation;
            }

            if ((report.Actions & RawStylusActions.Down) != 0 ||
                 (report.Actions & RawStylusActions.Move) != 0)
            {
                _fInAir = false;

                // Keep the stylus down location for turning system gestures into mouse event
                if ((report.Actions & RawStylusActions.Down) != 0)
                {
                    _needToSendMouseDown = true;
                    // reset the gesture flag.  This is used to determine if we will need to fabricate a systemgesture tap on the 
                    // corresponding up event.
                    _fGestureWasFired = false;
                    _fDetectedDrag = false;
                    _seenHoldEnterGesture = false;

                    // Make sure our drag and move deltas are up to date.
                    TabletDevice.UpdateSizeDeltas(report.StylusPointDescription, _stylusLogic);
                }
                // See if we need to do our own Drag detection (on Stylus Move event)
                else if (inputSource != null && _fBlockMouseMoveChanges && _seenDoubleTapGesture && !_fGestureWasFired && !_fDetectedDrag)
                {
                    Size delta = TabletDevice.CancelSize;

                    // We use the first point of the packet data for Drag detection to try and
                    // filter out cases where the stylus skips when going down.
                    Point dragPosition =(Point)_eventStylusPoints[0];
                    dragPosition = _stylusLogic.DeviceUnitsFromMeasureUnits(dragPosition);
                    dragPosition = PointUtil.ClientToScreen(dragPosition, inputSource);

                    // See if we need to detect a Drag gesture.  If so do the calculation.
                    if ((Math.Abs(_lastMouseScreenLocation.X - dragPosition.X) > delta.Width) ||
                        (Math.Abs(_lastMouseScreenLocation.Y - dragPosition.Y) > delta.Height))
                    {
                        _fDetectedDrag = true;
                    }
                }
            }

            UpdateEventStylusPoints(report, false);

            if ((report.Actions & RawStylusActions.Up)        != 0 ||
                (report.Actions & RawStylusActions.InAirMove) != 0)
            {
                _fInAir = true;
                
                if ((report.Actions & RawStylusActions.Up) != 0)
                {
                    _sawMouseButton1Down = false; // reset this on Stylus Up.
                }
            }
        }
Example #25
0
        internal StylusPlugInCollection TargetPlugInCollection(RawStylusInputReport inputReport)
        {
            // Caller must make call to this routine inside of lock(__rtiLock)!
            StylusPlugInCollection pic = null;

            // We should only be called when not on the application thread!
            System.Diagnostics.Debug.Assert(!inputReport.StylusDevice.CheckAccess());

            // We're on the pen thread so can't touch visual tree.  Use capturedPlugIn (if capture on) or cached rects.
            bool elementHasCapture = false;
            pic = inputReport.StylusDevice.GetCapturedPlugInCollection(ref elementHasCapture);
            int pointLength = inputReport.PenContext.StylusPointDescription.GetInputArrayLengthPerPoint();
            // Make sure that the captured Plugin Collection is still in the list.  CaptureChanges are
            // deferred so there is a window where the stylus device is not updated yet.  This protects us
            // from using a bogus plugin collecton for an element that is in an invalid state.
            if (elementHasCapture && !_plugInCollectionList.Contains(pic))
            {
                elementHasCapture = false;  // force true hittesting to be done!
            }
            
            if (!elementHasCapture && inputReport.Data != null && inputReport.Data.Length >= pointLength)
            {
                int[] data = inputReport.Data;
                System.Diagnostics.Debug.Assert(data.Length % pointLength == 0);
                Point ptTablet = new Point(data[data.Length - pointLength], data[data.Length - pointLength + 1]);
                // Note: the StylusLogic data inside DeviceUnitsFromMeasurUnits is protected by __rtiLock.
                ptTablet = ptTablet * inputReport.StylusDevice.TabletDevice.TabletToScreen;
                ptTablet.X = (int)Math.Round(ptTablet.X); // Make sure we snap to whole window pixels.
                ptTablet.Y = (int)Math.Round(ptTablet.Y);
                ptTablet = _stylusLogic.MeasureUnitsFromDeviceUnits(ptTablet); // change to measured units now.

                pic = HittestPlugInCollection(ptTablet); // Use cached rectangles for UIElements.
            }
            return pic;
        }
Example #26
0
        internal StylusPlugInCollection InvokeStylusPluginCollectionForMouse(RawStylusInputReport inputReport, IInputElement directlyOver, StylusPlugInCollection currentPlugInCollection)
        {
            StylusPlugInCollection newPlugInCollection = null;

            // lock to make sure only one event is processed at a time and no changes to state can
            // be made until we finish routing this event.
            lock(__rtiLock)
            {
                //Debug.Assert(inputReport.Actions == RawStylusActions.Down || 
                //             inputReport.Actions == RawStylusActions.Up ||
                //             inputReport.Actions == RawStylusActions.Move);
                
                // Find new target plugin collection
                if (directlyOver != null)
                {
                    UIElement uiElement = InputElement.GetContainingUIElement(directlyOver as DependencyObject) as UIElement;
                    if (uiElement != null)
                    {
                        newPlugInCollection = FindPlugInCollection(uiElement);
                    }
                }                

                // Fire Leave event to old pluginCollection if we need to.
                if (currentPlugInCollection != null && currentPlugInCollection != newPlugInCollection)
                {
                    // NOTE: input report points for mouse are in avalon measured units and not device!
                    RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, currentPlugInCollection.ViewToElement, currentPlugInCollection);
                    
                    currentPlugInCollection.FireEnterLeave(false, tempRawStylusInput, true);
                }
                if (newPlugInCollection != null)
                {
                    // NOTE: input report points for mouse are in avalon measured units and not device!
                    RawStylusInput rawStylusInput = new RawStylusInput(inputReport, newPlugInCollection.ViewToElement, newPlugInCollection);
                    inputReport.RawStylusInput = rawStylusInput;

                    if (newPlugInCollection != currentPlugInCollection)
                    {
                        newPlugInCollection.FireEnterLeave(true, rawStylusInput, true);
                    }
                    
                    // We are on the pen thread, just call directly.
                    newPlugInCollection.FireRawStylusInput(rawStylusInput);

                    // Fire custom data events (always confirmed for mouse)
                    foreach (RawStylusInputCustomData customData in rawStylusInput.CustomDataList)
                    {
                        customData.Owner.FireCustomData(customData.Data, inputReport.Actions, true);
                    }
                }
            }
            return newPlugInCollection;
        }
Example #27
0
        void ProcessInputReport(RawStylusInputReport inputReport) 
        {
            // First, assign the StylusDevice (note it may still be null for new StylusDevice) 
            inputReport.StylusDevice = FindStylusDeviceWithLock(inputReport.StylusDeviceId);

            // Only call plugins if we are not in a drag drop operation and the HWND is enabled!
            if (!_inDragDrop || !inputReport.PenContext.Contexts.IsWindowDisabled) 
            {
                // Handle real time input (call StylusPlugIns) 
                InvokeStylusPluginCollection(inputReport); 
            }
 
            // ETW event indicating that a stylus input report was queued.
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordInput | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info, EventTrace.Event.StylusEventQueued, inputReport.StylusDeviceId);

            // Queue up new event. 
            lock(_stylusEventQueueLock)
            { 
                _queueStylusEvents.Enqueue(inputReport); 
            }
 
            // post the args into dispatcher queue
            Dispatcher.BeginInvoke(DispatcherPriority.Input, _dlgInputManagerProcessInput, null);
        }
Example #28
0
        internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport)
        {
            // Find PenContexts object for this inputReport.
            StylusPlugInCollection pic = null;

            // lock to make sure only one event is processed at a time and no changes to state can
            // be made until we finish routing this event.
            lock(__rtiLock)
            {
                switch (inputReport.Actions)
                {
                    case RawStylusActions.Down:
                    case RawStylusActions.Move:
                    case RawStylusActions.Up:
                         // Figure out current target plugincollection.
                        pic = TargetPlugInCollection(inputReport);
                        break;

                    default:
                        return; // Nothing to do unless one of the above events
                }

                StylusPlugInCollection currentPic = inputReport.StylusDevice.CurrentNonVerifiedTarget;
                
                // Fire Leave event if we need to.
                if (currentPic != null && currentPic != pic)
                {
                    // Create new RawStylusInput to send
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(inputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
                    transformTabletToView.Children.Add(currentPic.ViewToElement); // Make it relative to the element.
                    transformTabletToView.Freeze(); // Must be frozen for multi-threaded access.
                    
                    RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, transformTabletToView, currentPic);
                    
                    currentPic.FireEnterLeave(false, tempRawStylusInput, false);
                    inputReport.StylusDevice.CurrentNonVerifiedTarget = null;
                }

                if (pic != null)
                {
                    // NOTE: PenContext info will not change (it gets rebuilt instead so keeping ref is fine)
                    //    The transformTabletToView matrix and plugincollection rects though can change based 
                    //    off of layout events which is why we need to lock this.
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(inputReport.StylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
                    transformTabletToView.Children.Add(pic.ViewToElement); // Make it relative to the element.
                    transformTabletToView.Freeze();  // Must be frozen for multi-threaded access.
                    
                    RawStylusInput rawStylusInput = new RawStylusInput(inputReport, transformTabletToView, pic);
                    inputReport.RawStylusInput = rawStylusInput;

                    if (pic != currentPic)
                    {
                        inputReport.StylusDevice.CurrentNonVerifiedTarget = pic;
                        pic.FireEnterLeave(true, rawStylusInput, false);
                    }
                    
                    // We are on the pen thread, just call directly.
                    pic.FireRawStylusInput(rawStylusInput);
                }
            } // lock(__rtiLock)
        }
Example #29
0
 void PromoteRawToPreview(RawStylusInputReport report, ProcessInputEventArgs e)
 {
     RoutedEvent routedEvent = GetPreviewEventFromRawStylusActions(report.Actions); 
     if (routedEvent != null && report.StylusDevice != null && !report.StylusDevice.IgnoreStroke)
     { 
         StylusEventArgs args; 
         if (routedEvent != Stylus.PreviewStylusSystemGestureEvent)
         { 
             if (routedEvent == Stylus.PreviewStylusDownEvent)
             {
                 args = new StylusDownEventArgs(report.StylusDevice, report.Timestamp);
             } 
             else
             { 
                 args = new StylusEventArgs(report.StylusDevice, report.Timestamp); 
              }
         } 
         else
         {
             RawStylusSystemGestureInputReport reportSg = (RawStylusSystemGestureInputReport)report;
             args = new StylusSystemGestureEventArgs(report.StylusDevice, 
                                                     report.Timestamp,
                                                     reportSg.SystemGesture, 
                                                     reportSg.GestureX, 
                                                     reportSg.GestureY,
                                                     reportSg.ButtonState); 
         }
         args.InputReport = report;
         args.RoutedEvent= routedEvent;
         e.PushInput(args, e.StagingItem); 
     }
 }