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); }
/// <summary> /// </summary> internal StylusPlugInCollection InvokeStylusPluginCollectionForMouse(RawStylusInputReport inputReport, IInputElement directlyOver, StylusPlugInCollection currentPlugInCollection) { StylusPlugInCollection newPlugInCollection = null; // 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.CurrentStylusLogic.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); } // (Comment not applicable until RTI back in) We are on the RTI thread, just call directly. newPlugInCollection.FireRawStylusInput(rawStylusInput); // Indicate we've used a stylus plugin StylusLogic.CurrentStylusLogic.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); }
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) }
/// <summary> /// Verifies that the call to the stylus plugin on the RTI thread was valid against the current visual tree. /// If this verification fails, we will rebuild and resend the raw input and custom data in order to inform /// the target collections of the error and fix it. /// </summary> /// <remarks> /// This is a remnant of verifying hits to the collections based on the UI thread calling this /// after the real time input thread has previously called a collection. This is due to the RTI thread /// not being 100% synchronous with the visual tree in terms of hitting the collections. This is sort of /// redundant right now, but needs to be here when we re-implement the RTI. /// </remarks> internal 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. } PointerLogic pointerLogic = StylusLogic.GetCurrentStylusLogicAs <PointerLogic>(); 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 = FindPlugInCollection(newTarget); } // Make sure any lock() calls do not reenter on us. using (Dispatcher.CurrentDispatcher.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: (This applies when RTI is back in) 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(rawStylusInputReport.StylusDevice.As <PointerStylusDevice>().GetTabletToElementTransform(null)); // 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; } PointerStylusDevice stylusDevice = rawStylusInputReport.StylusDevice.As <PointerStylusDevice>(); // Now fire the confirmed enter/leave events as necessary. StylusPlugInCollection currentTarget = 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(stylusDevice.GetTabletToElementTransform(null)); // 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); // Indicate we've used a stylus plugin pointerLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed; } // Update the verified target. 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); // Indicate we've used a stylus plugin pointerLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed; } // 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.As <PointerStylusDevice>().UpdateEventStylusPoints(rawStylusInputReport, true); } } }