Пример #1
0
        internal StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote)
        {
            StagingAreaInputItem item = new StagingAreaInputItem(false);

            item.Reset(input, promote);

            return(PushInput(item));
        }
Пример #2
0
        /// <summary>
        ///     Pushes an input event onto the top of the staging area.
        /// </summary>
        /// <param name="input">
        ///     The input event to place on the staging area.  This may not
        ///     be null, and may not already exist in the staging area.
        /// </param>
        /// <returns>
        ///     The specified staging area input item.
        /// </returns>
        public StagingAreaInputItem PushInput(StagingAreaInputItem input)
        {
            if (!_allowAccessToStagingArea)
            {
                throw new InvalidOperationException(SR.Get(SRID.NotAllowedToAccessStagingArea));
            }

            return(this.UnsecureInputManager.PushInput(input));
        }
Пример #3
0
        /// <summary>
        ///     Pushes an input event onto the top of the staging area.
        /// </summary>
        /// <param name="input">
        ///     The input event to place on the staging area.  This may not
        ///     be null, and may not already exist in the staging area.
        /// </param>
        /// <param name="promote">
        ///     An existing staging area item to promote the state from.
        /// </param>
        /// <returns>
        ///     The staging area input item that wraps the specified input.
        /// </returns>
        public StagingAreaInputItem PushInput(InputEventArgs input,
                                              StagingAreaInputItem promote) // Note: this should be a bool, and always use the InputItem available on these args.
        {
            if (!_allowAccessToStagingArea)
            {
                throw new InvalidOperationException(SR.Get(SRID.NotAllowedToAccessStagingArea));
            }

            return(this.UnsecureInputManager.PushInput(input, promote));
        }
Пример #4
0
        public StagingAreaInputItem PushInput(InputEventArgs input,
                                              StagingAreaInputItem promote) // Note: this should be a bool, and always use the InputItem available on these args. 
        {
            if(!_allowAccessToStagingArea)
            {
                throw new InvalidOperationException(SR.Get(SRID.NotAllowedToAccessStagingArea)); 
            }
 
            return this.UnsecureInputManager.PushInput(input, promote); 
        }
Пример #5
0
        // For performace reasons, we try to reuse these event args.
        // Allow an existing item to be promoted by keeping the existing dictionary.
        internal void Reset(InputEventArgs input, StagingAreaInputItem promote)
        {
            _input = input;

            if (promote != null && promote._dictionary != null)
            {
                _dictionary = (Hashtable)promote._dictionary.Clone();
            }
            else
            {
                if (_dictionary != null)
                {
                    _dictionary.Clear();
                }
                else
                {
                    _dictionary = new Hashtable();
                }
            }
        }
Пример #6
0
        // For performace reasons, we try to reuse these event args.
        // Allow an existing item to be promoted by keeping the existing dictionary. 
        internal void Reset(InputEventArgs input, StagingAreaInputItem promote) 
        {
            _input = input; 

            if(promote != null && promote._dictionary != null)
            {
                // 
                _dictionary = (Hashtable) promote._dictionary.Clone();
            } 
            else 
            {
                if(_dictionary != null) 
                {
                    _dictionary.Clear();
                }
                else 
                {
                    _dictionary = new Hashtable(); 
                } 
            }
        } 
Пример #7
0
        public bool ProcessInput(InputEventArgs input)
        {
            StagingAreaInputItem stagingItem = new StagingAreaInputItem(input);

            PreProcessInputEventArgs preProcessArgs = new PreProcessInputEventArgs(this, stagingItem);

            if (PreProcessInput != null)
            {
                PreProcessInput(this, preProcessArgs);
            }

            NotifyInputEventArgs notifyArgs = new NotifyInputEventArgs(this, stagingItem);

            if (PreNotifyInput != null)
            {
                PreNotifyInput(this, notifyArgs);
            }

#if notyet
            if (!preProcessArgs.Canceled)
            {
                /* XXX route the event */;
            }
#endif

            if (PostNotifyInput != null)
            {
                PostNotifyInput(this, notifyArgs);
            }

            if (PostProcessInput != null)
            {
                ProcessInputEventArgs processArgs = new ProcessInputEventArgs(this, stagingItem);
                PostProcessInput(this, processArgs);
            }

            return(true);
        }
Пример #8
0
 internal override void Reset(StagingAreaInputItem input, InputManager inputManager)
 {
     _canceled = false;
     base.Reset(input, inputManager);
 }
Пример #9
0
        internal StagingAreaInputItem PushMarker()
        {
            StagingAreaInputItem item = new StagingAreaInputItem(true);

            return(PushInput(item));
        }
Пример #10
0
 internal StagingAreaInputItem PushInput(StagingAreaInputItem inputItem)
 {
     _stagingArea.Push(inputItem);
     return(inputItem);
 }
 private bool IsPointerButtonEventItem(StagingAreaInputItem stagingItem)
 {
     return stagingItem != null && (stagingItem.Input as MouseButtonEventArgs != null || stagingItem.Input as StylusButtonEventArgs != null);
 }
Пример #12
0
        internal StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote)
        {
            StagingAreaInputItem item = new StagingAreaInputItem(false);
            item.Reset(input, promote);

            return PushInput(item);
        }
Пример #13
0
		internal NotifyInputEventArgs (InputManager inputManager,
					       StagingAreaInputItem stagingItem)
		{
			this.inputManager = inputManager;
			this.stagingItem = stagingItem;
		}
Пример #14
0
		public StagingAreaInputItem PushInput (StagingAreaInputItem input)
		{
			throw new NotImplementedException ();
		}
Пример #15
0
		internal ProcessInputEventArgs (InputManager inputManager,
						StagingAreaInputItem stagingItem)
			: base (inputManager, stagingItem)
		{
		}
Пример #16
0
 internal NotifyInputEventArgs(InputManager inputManager,
                               StagingAreaInputItem stagingItem)
 {
     this.inputManager = inputManager;
     this.stagingItem  = stagingItem;
 }
 public StagingAreaInputItem PushInput(StagingAreaInputItem input)
 {
   return default(StagingAreaInputItem);
 }
 public StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote)
 {
   return default(StagingAreaInputItem);
 }
Пример #19
0
		public bool ProcessInput (InputEventArgs input)
		{
			StagingAreaInputItem stagingItem = new StagingAreaInputItem (input);

			PreProcessInputEventArgs preProcessArgs = new PreProcessInputEventArgs(this, stagingItem);
			if (PreProcessInput != null)
				PreProcessInput (this, preProcessArgs);

			NotifyInputEventArgs notifyArgs = new NotifyInputEventArgs(this, stagingItem);
			if (PreNotifyInput != null)
				PreNotifyInput (this, notifyArgs);

#if notyet
			if (!preProcessArgs.Canceled)
				/* XXX route the event */;
#endif

			if (PostNotifyInput != null)
				PostNotifyInput (this, notifyArgs);

			if (PostProcessInput != null) {
				ProcessInputEventArgs processArgs = new ProcessInputEventArgs (this, stagingItem);
				PostProcessInput (this, processArgs);
			}

			return true;
		}
Пример #20
0
        public StagingAreaInputItem PushInput(StagingAreaInputItem input)
        {
            if(!_allowAccessToStagingArea) 
            {
                throw new InvalidOperationException(SR.Get(SRID.NotAllowedToAccessStagingArea)); 
            } 

            return this.UnsecureInputManager.PushInput(input); 
        }
Пример #21
0
		public StagingAreaInputItem PushInput (InputEventArgs input, StagingAreaInputItem promote)
		{
			throw new NotImplementedException ();
		}
Пример #22
0
        private void PromoteMainToMouse(StagingAreaInputItem stagingItem)
        { 
            if(!stagingItem.Input.Handled) 
            {
                StylusEventArgs stylusArgs = stagingItem.Input as StylusEventArgs; 
                if (stylusArgs != null)
                {
                    StylusDevice stylusDevice = stylusArgs.StylusDevice;
 
                    // We only want to promote to mouse when we actually have real stylus input.
                    if (stylusDevice != null) 
                    { 
                        Debug.Assert(ShouldPromoteToMouse(stylusDevice) && stylusDevice.TouchDevice.PromotingToOther);
 
                        if (IgnoreGestureToMousePromotion(stylusArgs as StylusSystemGestureEventArgs, stylusDevice.TouchDevice))
                        {
                            return;
                        } 

                        RawMouseActions actions = stylusDevice.GetMouseActionsFromStylusEventAndPlaybackCachedDown(stagingItem.Input.RoutedEvent, stylusArgs); 
 
                        if (actions != RawMouseActions.None)
                        { 
                            PresentationSource mouseInputSource = stylusDevice.GetMousePresentationSource();

                            if (mouseInputSource != null)
                            { 
                                Point pt = PointUtil.ScreenToClient(stylusDevice.LastMouseScreenPoint, mouseInputSource);
 
                                // 
                                // use the dispatcher as a way of coalescing mouse *move* messages
                                // BUT don't flood the dispatcher with delegates if we're already 
                                // waiting for a callback
                                //
                                if ((actions & RawMouseActions.AbsoluteMove) != 0)
                                { 
                                    if (actions == _lastRawMouseAction && _waitingForDelegate)
                                    { 
                                        return; // We don't need to process this one. 
                                    }
                                    else 
                                    {
                                        //set the waiting bit so we won't enter here again
                                        //until we get the callback
                                        _waitingForDelegate = true; 

                                        Dispatcher.BeginInvoke(DispatcherPriority.Input, 
                                        (DispatcherOperationCallback)delegate(object unused) 
                                        {
                                            //reset our flags here in the callback. 
                                            _waitingForDelegate = false;
                                            return null;
                                        },
                                        null); 
                                    }
                                } 
 
                                // See if we need to set the Mouse Activate flag.
                                if (_inputManager.Value.PrimaryMouseDevice.CriticalActiveSource != mouseInputSource) 
                                {
                                    actions |= RawMouseActions.Activate;
                                }
 
                                _lastRawMouseAction = actions;
 
                                RawMouseInputReport mouseInputReport = new RawMouseInputReport( 
                                                                            InputMode.Foreground, stylusArgs.Timestamp, mouseInputSource,
                                                                            actions, (int)pt.X, (int)pt.Y, 0, IntPtr.Zero); 

                                InputReportEventArgs inputReportArgs = new InputReportEventArgs(stylusDevice, mouseInputReport);
                                inputReportArgs.RoutedEvent=InputManager.PreviewInputReportEvent;
                                _inputManager.Value.ProcessInput(inputReportArgs); 
                            }
                        } 
                    } 
                }
            } 
        }
Пример #23
0
 internal ProcessInputEventArgs(InputManager inputManager,
                                StagingAreaInputItem stagingItem)
     : base(inputManager, stagingItem)
 {
 }
Пример #24
0
 internal override void Reset(StagingAreaInputItem input, InputManager inputManager)
 {
     _canceled = false;
     base.Reset(input, inputManager);
 }
Пример #25
0
 public StagingAreaInputItem PushInput(StagingAreaInputItem input)
 {
     throw new NotImplementedException();
 }
Пример #26
0
 internal StagingAreaInputItem PushInput(StagingAreaInputItem inputItem)
 {
     _stagingArea.Push(inputItem);
     return inputItem;
 }
Пример #27
0
 public StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote)
 {
     throw new NotImplementedException();
 }
Пример #28
0
        internal StagingAreaInputItem PushMarker()
        {
            StagingAreaInputItem item = new StagingAreaInputItem(true);

            return PushInput(item);
        }
Пример #29
0
 // Helper to access the StylusDevice property.
 private StylusDevice GetStylusDevice(StagingAreaInputItem stagingItem)
 {
     return stagingItem.GetData(_tagStylusDevice) as StylusDevice;
 }
Пример #30
0
 internal virtual void Reset(StagingAreaInputItem input, InputManager inputManager)
 {
     _input        = input;
     _inputManager = inputManager;
 }
Пример #31
0
 private void PromoteMainMoveToTouch(StylusDevice stylusDevice, StagingAreaInputItem stagingItem) 
 { 
     StylusTouchDevice touchDevice = stylusDevice.TouchDevice;
     bool shouldPromoteToMouse = ShouldPromoteToMouse(stylusDevice); 
     if (touchDevice.IsActive)
     {
         if (!touchDevice.OnMove() && shouldPromoteToMouse)
         { 
             if (touchDevice.PromotingToManipulation)
             { 
                 IList<StagingAreaInputItem> storedStagingItems = touchDevice.StoredStagingAreaItems; 
                 int stagingItemCount = storedStagingItems.Count;
                 if (stagingItemCount > 0 && 
                     storedStagingItems[stagingItemCount - 1].Input.RoutedEvent == Stylus.StylusMoveEvent)
                 {
                     storedStagingItems[stagingItemCount - 1] = stagingItem;
                 } 
                 else
                 { 
                     touchDevice.StoredStagingAreaItems.Add(stagingItem); 
                 }
             } 
             else if (touchDevice.PromotingToOther)
             {
                 PromoteMainToMouse(stagingItem);
             } 
         }
     } 
     else if (shouldPromoteToMouse) 
     {
         PromoteMainToMouse(stagingItem); 
     }
 }
Пример #32
0
 private void PromoteMainDownToTouch(StylusDevice stylusDevice, StagingAreaInputItem stagingItem) 
 { 
     StylusTouchDevice touchDevice = stylusDevice.TouchDevice;
     if (touchDevice.IsActive) 
     {
         // Deactivate and end the previous cycle if already active
         touchDevice.OnDeactivate();
     } 
     touchDevice.OnActivate();
     bool shouldPromoteToMouse = ShouldPromoteToMouse(stylusDevice); 
     if (!touchDevice.OnDown() && shouldPromoteToMouse) 
     {
         if (touchDevice.PromotingToManipulation) 
         {
             touchDevice.StoredStagingAreaItems.Add(stagingItem);
         }
         else if (touchDevice.PromotingToOther) 
         {
             PromoteMainToMouse(stagingItem); 
         } 
     }
 } 
Пример #33
0
 internal virtual void Reset(StagingAreaInputItem input, InputManager inputManager)
 {
     _input = input;
     _inputManager = inputManager;
 }
Пример #34
0
        private bool ProcessStagingArea()
        {
            bool handled = false;

            // For performance reasons, try to reuse the input event args.
            // If we are reentrered, we have to start over with fresh event
            // args, so we clear the member variables before continuing.
            // Also, we cannot simply make an single instance of the
            // PreProcessedInputEventArgs and cast it to NotifyInputEventArgs
            // or ProcessInputEventArgs because a malicious user could upcast
            // the object and call inappropriate methods.
            NotifyInputEventArgs     notifyInputEventArgs     = (_notifyInputEventArgs != null) ? _notifyInputEventArgs : new NotifyInputEventArgs();
            ProcessInputEventArgs    processInputEventArgs    = (_processInputEventArgs != null) ? _processInputEventArgs : new ProcessInputEventArgs();
            PreProcessInputEventArgs preProcessInputEventArgs = (_preProcessInputEventArgs != null) ? _preProcessInputEventArgs : new PreProcessInputEventArgs();

            _notifyInputEventArgs     = null;
            _processInputEventArgs    = null;
            _preProcessInputEventArgs = null;

            // Because we can be reentered, we can't just enumerate over the
            // staging area - that could throw an exception if the queue
            // changes underneath us.  Instead, just loop until we find a
            // frame marker or until the staging area is empty.
            StagingAreaInputItem item = null;

            while ((item = PopInput()) != null)
            {
                // If we found a marker, we have reached the end of a
                // "section" of the staging area.  We just return from
                // the synchronous processing of the staging area.
                // If a dispatcher frame has been pushed by someone, this
                // will not return to the original ProcessInput.  Instead
                // it will unwind to the dispatcher and since we have
                // already pushed a work item to continue processing the
                // input, it will simply call back into us to do more
                // processing.  At which point we will continue to drain
                // the staging area.  This could cause strage behavior,
                // but it is deemed more acceptable than stalling input
                // processing.

                // In the future, in ordre to
                // make sure we all agree on this.  We could also
                // just delay the rest of the staging area until
                // the dispatcher frame finishes.  Unfortunately,
                // this means one could receive an input event for
                // something that happened a long time ago.
                if (item.IsMarker)
                {
                    break;
                }

                // Pre-Process the input.  This could modify the staging
                // area, and it could cancel the processing of this
                // input event.
                //
                // Because we use multi-cast delegates, we always have to
                // create a new multi-cast delegate when we add or remove
                // a handler.  This means we can just call the current
                // multi-cast delegate instance, and it is safe to iterate
                // over, even if we get reentered.
                if (_preProcessInput != null)
                {
                    preProcessInputEventArgs.Reset(item, this);

                    // Invoke the handlers in reverse order so that handlers that
                    // users add are invoked before handlers in the system.
                    Delegate[] handlers = _preProcessInput.GetInvocationList();
                    for (int i = (handlers.Length - 1); i >= 0; i--)
                    {
                        PreProcessInputEventHandler handler = (PreProcessInputEventHandler)handlers[i];
                        handler(this, preProcessInputEventArgs);
                    }
                }

                if (!preProcessInputEventArgs.Canceled)
                {
                    // Pre-Notify the input.
                    //
                    // Because we use multi-cast delegates, we always have to
                    // create a new multi-cast delegate when we add or remove
                    // a handler.  This means we can just call the current
                    // multi-cast delegate instance, and it is safe to iterate
                    // over, even if we get reentered.
                    if (_preNotifyInput != null)
                    {
                        notifyInputEventArgs.Reset(item, this);

                        // Invoke the handlers in reverse order so that handlers that
                        // users add are invoked before handlers in the system.
                        Delegate[] handlers = _preNotifyInput.GetInvocationList();
                        for (int i = (handlers.Length - 1); i >= 0; i--)
                        {
                            NotifyInputEventHandler handler = (NotifyInputEventHandler)handlers[i];
                            handler(this, notifyInputEventArgs);
                        }
                    }

                    // Raise the input event being processed.
                    InputEventArgs input = item.Input;

                    // Some input events are explicitly associated with
                    // an element.  Those that are not are associated with
                    // the target of the input device for this event.
                    DependencyObject eventSource = input.Source as DependencyObject;
                    if (eventSource == null || !InputElement.IsValid(eventSource as IInputElement))
                    {
                        if (input.Device != null)
                        {
                            eventSource = input.Device.Target as DependencyObject;
                        }
                    }

                    // During synchronized input processing, event should be discarded if not listening for this input type.
                    if (_isSynchronizedInput &&
                        SynchronizedInputHelper.IsMappedEvent(input) &&
                        Array.IndexOf(SynchronizedInputEvents, input.RoutedEvent) < 0 &&
                        Array.IndexOf(PairedSynchronizedInputEvents, input.RoutedEvent) < 0)
                    {
                        if (!SynchronizedInputHelper.ShouldContinueListening(input))
                        {
                            // Discard the event
                            _synchronizedInputState = SynchronizedInputStates.Discarded;
                            SynchronizedInputHelper.RaiseAutomationEvents();
                            CancelSynchronizedInput();
                        }
                        else
                        {
                            _synchronizedInputAsyncClearOperation = Dispatcher.BeginInvoke((Action) delegate
                            {
                                // Discard the event
                                _synchronizedInputState = SynchronizedInputStates.Discarded;
                                SynchronizedInputHelper.RaiseAutomationEvents();
                                CancelSynchronizedInput();
                            },
                                                                                           DispatcherPriority.Background);
                        }
                    }
                    else
                    {
                        if (eventSource != null)
                        {
                            if (InputElement.IsUIElement(eventSource))
                            {
                                UIElement e = (UIElement)eventSource;

                                e.RaiseEvent(input, true); // Call the "trusted" flavor of RaiseEvent.
                            }
                            else if (InputElement.IsContentElement(eventSource))
                            {
                                ContentElement ce = (ContentElement)eventSource;

                                ce.RaiseEvent(input, true);// Call the "trusted" flavor of RaiseEvent.
                            }
                            else if (InputElement.IsUIElement3D(eventSource))
                            {
                                UIElement3D e3D = (UIElement3D)eventSource;

                                e3D.RaiseEvent(input, true); // Call the "trusted" flavor of RaiseEvent
                            }

                            // If synchronized input raise appropriate automation event.

                            if (_isSynchronizedInput && SynchronizedInputHelper.IsListening(_listeningElement, input))
                            {
                                if (!SynchronizedInputHelper.ShouldContinueListening(input))
                                {
                                    SynchronizedInputHelper.RaiseAutomationEvents();
                                    CancelSynchronizedInput();
                                }
                                else
                                {
                                    _synchronizedInputAsyncClearOperation = Dispatcher.BeginInvoke((Action) delegate
                                    {
                                        SynchronizedInputHelper.RaiseAutomationEvents();
                                        CancelSynchronizedInput();
                                    },
                                                                                                   DispatcherPriority.Background);
                                }
                            }
                        }
                    }

                    // Post-Notify the input.
                    //
                    // Because we use multi-cast delegates, we always have to
                    // create a new multi-cast delegate when we add or remove
                    // a handler.  This means we can just call the current
                    // multi-cast delegate instance, and it is safe to iterate
                    // over, even if we get reentered.
                    if (_postNotifyInput != null)
                    {
                        notifyInputEventArgs.Reset(item, this);

                        // Invoke the handlers in reverse order so that handlers that
                        // users add are invoked before handlers in the system.
                        Delegate[] handlers = _postNotifyInput.GetInvocationList();
                        for (int i = (handlers.Length - 1); i >= 0; i--)
                        {
                            NotifyInputEventHandler handler = (NotifyInputEventHandler)handlers[i];
                            handler(this, notifyInputEventArgs);
                        }
                    }

                    // Post-Process the input.  This could modify the staging
                    // area.
                    //
                    // Because we use multi-cast delegates, we always have to
                    // create a new multi-cast delegate when we add or remove
                    // a handler.  This means we can just call the current
                    // multi-cast delegate instance, and it is safe to iterate
                    // over, even if we get reentered.
                    if (_postProcessInput != null)
                    {
                        processInputEventArgs.Reset(item, this);

                        RaiseProcessInputEventHandlers(_postProcessInput, processInputEventArgs);

                        // PreviewInputReport --> InputReport
                        if (item.Input.RoutedEvent == InputManager.PreviewInputReportEvent)
                        {
                            if (!item.Input.Handled)
                            {
                                InputReportEventArgs previewInputReport = (InputReportEventArgs)item.Input;

                                InputReportEventArgs inputReport = new InputReportEventArgs(previewInputReport.Device, previewInputReport.Report);
                                inputReport.RoutedEvent = InputManager.InputReportEvent;
                                PushInput(inputReport, item);
                            }
                        }
                    }

                    if (input.Handled)
                    {
                        handled = true;
                    }
                }
            }

            // Store our input event args so that we can use them again, and
            // avoid having to allocate more.
            _notifyInputEventArgs     = notifyInputEventArgs;
            _processInputEventArgs    = processInputEventArgs;
            _preProcessInputEventArgs = preProcessInputEventArgs;

            // Make sure to throw away the contents of the event args so
            // we don't keep refs around to things we don't mean to.
            _notifyInputEventArgs.Reset(null, null);
            _processInputEventArgs.Reset(null, null);
            _preProcessInputEventArgs.Reset(null, null);

            return(handled);
        }
Пример #35
0
 public StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote)
 {
     return(default(StagingAreaInputItem));
 }
Пример #36
0
 internal override void Reset(StagingAreaInputItem input, InputManager inputManager)
 {
     _allowAccessToStagingArea = true;
     base.Reset(input, inputManager);
 }
Пример #37
0
 public StagingAreaInputItem PushInput(StagingAreaInputItem input)
 {
     return(default(StagingAreaInputItem));
 }
Пример #38
0
 internal override void Reset(StagingAreaInputItem input, InputManager inputManager) 
 {
     _allowAccessToStagingArea = true; 
     base.Reset(input, inputManager);
 }
Пример #39
0
        private void PromoteMainUpToTouch(StylusDevice stylusDevice, StagingAreaInputItem stagingItem)
        { 
            StylusTouchDevice touchDevice = stylusDevice.TouchDevice;
            bool shouldPromoteToMouse = ShouldPromoteToMouse(stylusDevice);
            if (touchDevice.IsActive)
            { 
                touchDevice.OnUp();
 
                // Promote Up to Mouse if mouse left/right button is 
                // pressed, even if TouchUp event is handled. This is such
                // that we dont leave mouse in an inconsistent pressed state. 
                if (shouldPromoteToMouse && touchDevice.PromotingToOther &&
                    (_mouseLeftButtonState == MouseButtonState.Pressed ||
                    _mouseRightButtonState == MouseButtonState.Pressed))
                { 
                    PromoteMainToMouse(stagingItem);
                } 
 
                // PromoteMainToMouse is an outbound call that may have pumped messages.
                // Since the world may have changed, verify that the device is still active. 
                if (touchDevice.IsActive)
                {
                    touchDevice.OnDeactivate();
                } 
            }
            else if (shouldPromoteToMouse) 
            { 
                PromoteMainToMouse(stagingItem);
            } 
        }