internal StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote) { StagingAreaInputItem item = new StagingAreaInputItem(false); item.Reset(input, promote); return(PushInput(item)); }
/// <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)); }
/// <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)); }
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); }
// 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(); } } }
// 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(); } } }
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); }
internal override void Reset(StagingAreaInputItem input, InputManager inputManager) { _canceled = false; base.Reset(input, inputManager); }
internal StagingAreaInputItem PushMarker() { StagingAreaInputItem item = new StagingAreaInputItem(true); return(PushInput(item)); }
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); }
internal StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote) { StagingAreaInputItem item = new StagingAreaInputItem(false); item.Reset(input, promote); return PushInput(item); }
internal NotifyInputEventArgs (InputManager inputManager, StagingAreaInputItem stagingItem) { this.inputManager = inputManager; this.stagingItem = stagingItem; }
public StagingAreaInputItem PushInput (StagingAreaInputItem input) { throw new NotImplementedException (); }
internal ProcessInputEventArgs (InputManager inputManager, StagingAreaInputItem stagingItem) : base (inputManager, stagingItem) { }
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); }
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; }
public StagingAreaInputItem PushInput(StagingAreaInputItem input) { if(!_allowAccessToStagingArea) { throw new InvalidOperationException(SR.Get(SRID.NotAllowedToAccessStagingArea)); } return this.UnsecureInputManager.PushInput(input); }
public StagingAreaInputItem PushInput (InputEventArgs input, StagingAreaInputItem promote) { throw new NotImplementedException (); }
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); } } } } } }
internal ProcessInputEventArgs(InputManager inputManager, StagingAreaInputItem stagingItem) : base(inputManager, stagingItem) { }
public StagingAreaInputItem PushInput(StagingAreaInputItem input) { throw new NotImplementedException(); }
internal StagingAreaInputItem PushInput(StagingAreaInputItem inputItem) { _stagingArea.Push(inputItem); return inputItem; }
public StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote) { throw new NotImplementedException(); }
internal StagingAreaInputItem PushMarker() { StagingAreaInputItem item = new StagingAreaInputItem(true); return PushInput(item); }
// Helper to access the StylusDevice property. private StylusDevice GetStylusDevice(StagingAreaInputItem stagingItem) { return stagingItem.GetData(_tagStylusDevice) as StylusDevice; }
internal virtual void Reset(StagingAreaInputItem input, InputManager inputManager) { _input = input; _inputManager = inputManager; }
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); } }
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); } } }
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); }
public StagingAreaInputItem PushInput(InputEventArgs input, StagingAreaInputItem promote) { return(default(StagingAreaInputItem)); }
internal override void Reset(StagingAreaInputItem input, InputManager inputManager) { _allowAccessToStagingArea = true; base.Reset(input, inputManager); }
public StagingAreaInputItem PushInput(StagingAreaInputItem input) { return(default(StagingAreaInputItem)); }
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); } }