Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Input / ManipulationDevice.cs / 1305600 / ManipulationDevice.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Windows; using System.Windows.Input; using System.Windows.Input.Manipulations; using System.Windows.Media; using System.Windows.Threading; using System.Security; using MS.Internal; using MS.Internal.PresentationCore; using MS.Utility; namespace System.Windows.Input { ////// Analyzes input events to be processed into manipulation and inertia events. /// internal sealed class ManipulationDevice : InputDevice { ////// Critical: Accesses PresentationSource.CriticalFromVisual. /// TreatAsSafe: Stored in Critical field and exposed in Critical property. /// Critical: Attaches to InputManager event handlers and stores a reference to the InputManager. /// TreatAsSafe: Does not expose the InputManager externally. /// ////// Created in AddManipulationDevice. /// [SecurityCritical, SecurityTreatAsSafe] private ManipulationDevice(UIElement element) : base() { _target = element; _activeSource = PresentationSource.CriticalFromVisual(element); _inputManager = InputManager.UnsecureCurrent; _inputManager.PostProcessInput += new ProcessInputEventHandler(PostProcessInput); _manipulationLogic = new ManipulationLogic(this); } ////// Critical: Detaches from InputManager event handlers. /// TreatAsSafe: Does not expose the InputManager externally. /// [SecurityCritical, SecurityTreatAsSafe] private void DetachManipulationDevice() { _inputManager.PostProcessInput -= new ProcessInputEventHandler(PostProcessInput); } ////// Returns the element that input from this device is sent to. /// public override IInputElement Target { get { return _target; } } ////// Returns the PresentationSource of Target. /// ////// SecurityCritical: Exposes a PresentationSource. /// PublicOK: There is a demand. /// public override PresentationSource ActiveSource { [SecurityCritical] get { SecurityHelper.DemandUIWindowPermission(); return _activeSource; } } ////// Returns a ManipulationDevice associated with the given UIElement. /// /// The target of the ManipulationDevice. ////// A ManipulationDevice associated with the element. /// If a device already exists for the element, a reference to that instance /// will be returned, otherwise a new instance will be created. /// ////// This function is thread-safe but should be called only on the /// same thread that 'element' is bound to, due to possibly calling /// the ManipulationDevice constructor. /// internal static ManipulationDevice AddManipulationDevice(UIElement element) { Debug.Assert(element != null, "element should be non-null."); element.VerifyAccess(); ManipulationDevice device = GetManipulationDevice(element); if (device == null) { if (_manipulationDevices == null) { _manipulationDevices = new Dictionary(2); } device = new ManipulationDevice(element); _manipulationDevices[element] = device; } return device; } /// /// Returns a ManipulationDevice associated with the given UIElement. /// /// The target of the ManipulationDevice. ////// A ManipulationDevice associated with the element. /// If a device does not already exists for the element, null is returned. /// internal static ManipulationDevice GetManipulationDevice(UIElement element) { Debug.Assert(element != null, "element should be non-null."); if (_manipulationDevices != null) { ManipulationDevice device; _manipulationDevices.TryGetValue(element, out device); return device; } return null; } ////// When a ManipulationDevice is no longer needed, remove it /// from the global list of devices. /// private void RemoveManipulationDevice() { _wasTicking = false; StopTicking(); DetachManipulationDevice(); _compensateForBoundaryFeedback = null; RemoveAllManipulators(); if (_manipulationDevices != null) { _manipulationDevices.Remove(_target); } } private void RemoveAllManipulators() { if (_manipulators != null) { for (int i = _manipulators.Count - 1; i >= 0; i--) { _manipulators[i].Updated -= OnManipulatorUpdated; } _manipulators.Clear(); } } internal void AddManipulator(IManipulator manipulator) { Debug.Assert(manipulator != null); VerifyAccess(); _manipulationEnded = false; if (_manipulators == null) { _manipulators = new List(2); } _manipulators.Add(manipulator); manipulator.Updated += OnManipulatorUpdated; // Adding a manipulator counts as an update OnManipulatorUpdated(manipulator, EventArgs.Empty); } internal void RemoveManipulator(IManipulator manipulator) { Debug.Assert(manipulator != null); VerifyAccess(); manipulator.Updated -= OnManipulatorUpdated; if (_manipulators != null) { _manipulators.Remove(manipulator); } // Removing a manipulator counts as an update OnManipulatorUpdated(manipulator, EventArgs.Empty); if (!_manipulationEnded) { if (_manipulators == null || _manipulators.Count == 0) { // cache the last removed manipulator _removedManipulator = manipulator; } // Call ReportFrame so that ManipulationInertiaStarting / ManipulationCompleted // gets called synchronously if needed ReportFrame(); _removedManipulator = null; } } /// /// Critical - Accesses _manipulationLogic. /// TreatAsSafe - OK to pass this information /// internal ManipulationModes ManipulationMode { [SecurityCritical, SecurityTreatAsSafe] get { return _manipulationLogic.ManipulationMode; } [SecurityCritical, SecurityTreatAsSafe] set { _manipulationLogic.ManipulationMode = value; } } ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - OK to pass this information /// internal ManipulationPivot ManipulationPivot { [SecurityCritical, SecurityTreatAsSafe] get { return _manipulationLogic.ManipulationPivot; } [SecurityCritical, SecurityTreatAsSafe] set { _manipulationLogic.ManipulationPivot = value; } } ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - OK to pass this information /// internal IInputElement ManipulationContainer { [SecurityCritical, SecurityTreatAsSafe] get { return _manipulationLogic.ManipulationContainer; } [SecurityCritical, SecurityTreatAsSafe] set { _manipulationLogic.ManipulationContainer = value; } } internal IEnumerableGetManipulatorsReadOnly() { if (_manipulators != null) { return new ReadOnlyCollection (_manipulators); } else { return new ReadOnlyCollection (new List (2)); } } internal void OnManipulatorUpdated(object sender, EventArgs e) { // After a period of inactivity, the ManipulationDevice will stop polling at the screen framerate // to stop wasting CPU usage. This notification will tell the device that activity is happening // so that it can know to poll. LastUpdatedTimestamp = ManipulationLogic.GetCurrentTimestamp(); ResumeAllTicking(); // Resumes the ticking of all the suspended devices on the thread StartTicking(); // Ensures that we continue ticking or restart ticking for this device } internal Point GetTransformedManipulatorPosition(Point point) { if (_compensateForBoundaryFeedback != null) { return _compensateForBoundaryFeedback(point); } return point; } /// /// Starts the ticking for all the ManipulationDevices /// on the thread only if they were ticking earlier. /// private static void ResumeAllTicking() { if (_manipulationDevices != null) { foreach (UIElement element in _manipulationDevices.Keys) { ManipulationDevice device = _manipulationDevices[element]; if (device != null && device._wasTicking) { device.StartTicking(); device._wasTicking = false; } } } } private void StartTicking() { if (!_ticking) { _ticking = true; CompositionTarget.Rendering += new EventHandler(OnRendering); SubscribeToLayoutUpdate(); } } private void StopTicking() { if (_ticking) { CompositionTarget.Rendering -= new EventHandler(OnRendering); _ticking = false; UnsubscribeFromLayoutUpdate(); } } [SecurityCritical, SecurityTreatAsSafe] private void SubscribeToLayoutUpdate() { _manipulationLogic.ContainerLayoutUpdated += OnContainerLayoutUpdated; } [SecurityCritical, SecurityTreatAsSafe] private void UnsubscribeFromLayoutUpdate() { _manipulationLogic.ContainerLayoutUpdated -= OnContainerLayoutUpdated; } private void OnContainerLayoutUpdated(object sender, EventArgs e) { ReportFrame(); } private void OnRendering(object sender, EventArgs e) { ReportFrame(); // If Manipulation didn't activate or becomes disabled, then stop ticking. // If we've exceeded the timeout without any manipulators updating, then stop ticking // to save energy. If a manipulator updates, we'll start ticking again. if (!IsManipulationActive || (ManipulationLogic.GetCurrentTimestamp() - LastUpdatedTimestamp) > ThrottleTimeout) { _wasTicking = _ticking; // ReportFrame could have stopped the ticking, hence take the latest value. StopTicking(); } } ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - Prods the logic object to do its work. Does not expose the object. /// [SecurityCritical, SecurityTreatAsSafe] private void ReportFrame() { if (!_manipulationEnded) { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordInput | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info, EventTrace.Event.ManipulationReportFrame, 0); _manipulationLogic.ReportFrame(_manipulators); } } ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - OK to report if manipulation is enabled. /// internal bool IsManipulationActive { [SecurityCritical, SecurityTreatAsSafe] get { return _manipulationLogic.IsManipulationActive; } } ////// Critical: This method can be used for input spoofing. /// [SecurityCritical] private void PostProcessInput(object sender, ProcessInputEventArgs e) { InputEventArgs inputEventArgs = e.StagingItem.Input; if (inputEventArgs.Device == this) { RoutedEvent routedEvent = inputEventArgs.RoutedEvent; if (routedEvent == Manipulation.ManipulationDeltaEvent) { ManipulationDeltaEventArgs deltaEventArgs = inputEventArgs as ManipulationDeltaEventArgs; if (deltaEventArgs != null) { // During deltas, see if panning feedback is needed on the window ManipulationDelta unusedManipulation = deltaEventArgs.UnusedManipulation; _manipulationLogic.RaiseBoundaryFeedback(unusedManipulation, deltaEventArgs.RequestedComplete); _manipulationLogic.PushEventsToDevice(); // If a Complete is requested, then pass it along to the manipulation processor if (deltaEventArgs.RequestedComplete) { _manipulationLogic.Complete(/* withInertia = */ deltaEventArgs.RequestedInertia); _manipulationLogic.PushEventsToDevice(); } else if (deltaEventArgs.RequestedCancel) { Debug.Assert(!deltaEventArgs.IsInertial); OnManipulationCancel(); } } } else if (routedEvent == Manipulation.ManipulationStartingEvent) { ManipulationStartingEventArgs startingEventArgs = inputEventArgs as ManipulationStartingEventArgs; if (startingEventArgs != null && startingEventArgs.RequestedCancel) { OnManipulationCancel(); } } else if (routedEvent == Manipulation.ManipulationStartedEvent) { ManipulationStartedEventArgs startedEventArgs = inputEventArgs as ManipulationStartedEventArgs; if (startedEventArgs != null) { if (startedEventArgs.RequestedComplete) { // If a Complete is requested, pass it along to the manipulation processor _manipulationLogic.Complete(/* withInertia = */ false); _manipulationLogic.PushEventsToDevice(); } else if (startedEventArgs.RequestedCancel) { OnManipulationCancel(); } else { // Start ticking to produce delta events ResumeAllTicking(); // Resumes the ticking of all the suspended devices on the thread StartTicking(); // Ensures that we continue ticking or restart ticking for this device } } } else if (routedEvent == Manipulation.ManipulationInertiaStartingEvent) { // Switching from using rendering for ticking to a timer at lower priority (handled by ManipulationLogic) StopTicking(); // Remove all the manipulators so that we dont re-start manipulations accidentally RemoveAllManipulators(); // Initialize inertia ManipulationInertiaStartingEventArgs inertiaEventArgs = inputEventArgs as ManipulationInertiaStartingEventArgs; if (inertiaEventArgs != null) { if (inertiaEventArgs.RequestedCancel) { OnManipulationCancel(); } else { _manipulationLogic.BeginInertia(inertiaEventArgs); } } } else if (routedEvent == Manipulation.ManipulationCompletedEvent) { _manipulationLogic.OnCompleted(); ManipulationCompletedEventArgs completedEventArgs = inputEventArgs as ManipulationCompletedEventArgs; if (completedEventArgs != null) { if (completedEventArgs.RequestedCancel) { Debug.Assert(!completedEventArgs.IsInertial); OnManipulationCancel(); } else if (!(completedEventArgs.IsInertial && _ticking)) { // Remove the manipulation device only if // another manipulation didnot start OnManipulationComplete(); } } } else if (routedEvent == Manipulation.ManipulationBoundaryFeedbackEvent) { ManipulationBoundaryFeedbackEventArgs boundaryEventArgs = inputEventArgs as ManipulationBoundaryFeedbackEventArgs; if (boundaryEventArgs != null) { _compensateForBoundaryFeedback = boundaryEventArgs.CompensateForBoundaryFeedback; } } } } ////// Critical: Calls IManipulator.ManipulationEnded which can /// potentially do mouse promotions. /// [SecurityCritical] private void OnManipulationCancel() { _manipulationEnded = true; if (_manipulators != null) { if (_removedManipulator != null) { Debug.Assert(_manipulators == null || _manipulators.Count == 0); // Report Manipulation Cancel to last removed manipulator _removedManipulator.ManipulationEnded(true); } else { // Report Manipulation Cancel to all the remaining manipulators Listmanipulators = new List (_manipulators); foreach (IManipulator manipulator in manipulators) { manipulator.ManipulationEnded(true); } } } RemoveManipulationDevice(); } /// /// Critical: Calls IManipulator.ManipulationEnded which can /// potentially do mouse promotions. /// [SecurityCritical] private void OnManipulationComplete() { _manipulationEnded = true; if (_manipulators != null) { // Report Manipulation Complete to all the remaining manipulators Listmanipulators = new List (_manipulators); foreach (IManipulator manipulator in manipulators) { manipulator.ManipulationEnded(false); } } RemoveManipulationDevice(); } /// /// Critical - Accesses _manipulationLogic. /// TreatAsSafe - Does not expose the object. /// [SecurityCritical, SecurityTreatAsSafe] internal void SetManipulationParameters(ManipulationParameters2D parameter) { _manipulationLogic.SetManipulationParameters(parameter); } ////// Completes the pending manipulation or inertia. /// ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - Does not expose the object. /// [SecurityCritical, SecurityTreatAsSafe] internal void CompleteManipulation(bool withInertia) { if (_manipulationLogic != null) { _manipulationLogic.Complete(withInertia); _manipulationLogic.PushEventsToDevice(); } } ////// Critical - Accesses _inputManager. /// [SecurityCritical] internal void ProcessManipulationInput(InputEventArgs e) { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordInput | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info, EventTrace.Event.ManipulationEventRaised, 0); _inputManager.ProcessInput(e); } ////// Critical: This data is not safe to expose as it holds refrence to PresentationSource. /// [SecurityCritical] private InputManager _inputManager; ////// Critical: Holds the the current manipulation state. Trusted to give manipulation events (and not spoofed input). /// [SecurityCritical] private ManipulationLogic _manipulationLogic; ////// PresentationSource is protected data. /// [SecurityCritical] private PresentationSource _activeSource; private UIElement _target; private List_manipulators; private bool _ticking; private bool _wasTicking; // boolean used to track suspended manipulation devices private Func _compensateForBoundaryFeedback; private bool _manipulationEnded = false; IManipulator _removedManipulator = null; [ThreadStatic] private static Int64 LastUpdatedTimestamp; private const Int64 ThrottleTimeout = TimeSpan.TicksPerSecond * 5; // 5 seconds (in 100ns units) of no activity will throttle down [ThreadStatic] private static Dictionary _manipulationDevices; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Windows; using System.Windows.Input; using System.Windows.Input.Manipulations; using System.Windows.Media; using System.Windows.Threading; using System.Security; using MS.Internal; using MS.Internal.PresentationCore; using MS.Utility; namespace System.Windows.Input { /// /// Analyzes input events to be processed into manipulation and inertia events. /// internal sealed class ManipulationDevice : InputDevice { ////// Critical: Accesses PresentationSource.CriticalFromVisual. /// TreatAsSafe: Stored in Critical field and exposed in Critical property. /// Critical: Attaches to InputManager event handlers and stores a reference to the InputManager. /// TreatAsSafe: Does not expose the InputManager externally. /// ////// Created in AddManipulationDevice. /// [SecurityCritical, SecurityTreatAsSafe] private ManipulationDevice(UIElement element) : base() { _target = element; _activeSource = PresentationSource.CriticalFromVisual(element); _inputManager = InputManager.UnsecureCurrent; _inputManager.PostProcessInput += new ProcessInputEventHandler(PostProcessInput); _manipulationLogic = new ManipulationLogic(this); } ////// Critical: Detaches from InputManager event handlers. /// TreatAsSafe: Does not expose the InputManager externally. /// [SecurityCritical, SecurityTreatAsSafe] private void DetachManipulationDevice() { _inputManager.PostProcessInput -= new ProcessInputEventHandler(PostProcessInput); } ////// Returns the element that input from this device is sent to. /// public override IInputElement Target { get { return _target; } } ////// Returns the PresentationSource of Target. /// ////// SecurityCritical: Exposes a PresentationSource. /// PublicOK: There is a demand. /// public override PresentationSource ActiveSource { [SecurityCritical] get { SecurityHelper.DemandUIWindowPermission(); return _activeSource; } } ////// Returns a ManipulationDevice associated with the given UIElement. /// /// The target of the ManipulationDevice. ////// A ManipulationDevice associated with the element. /// If a device already exists for the element, a reference to that instance /// will be returned, otherwise a new instance will be created. /// ////// This function is thread-safe but should be called only on the /// same thread that 'element' is bound to, due to possibly calling /// the ManipulationDevice constructor. /// internal static ManipulationDevice AddManipulationDevice(UIElement element) { Debug.Assert(element != null, "element should be non-null."); element.VerifyAccess(); ManipulationDevice device = GetManipulationDevice(element); if (device == null) { if (_manipulationDevices == null) { _manipulationDevices = new Dictionary(2); } device = new ManipulationDevice(element); _manipulationDevices[element] = device; } return device; } /// /// Returns a ManipulationDevice associated with the given UIElement. /// /// The target of the ManipulationDevice. ////// A ManipulationDevice associated with the element. /// If a device does not already exists for the element, null is returned. /// internal static ManipulationDevice GetManipulationDevice(UIElement element) { Debug.Assert(element != null, "element should be non-null."); if (_manipulationDevices != null) { ManipulationDevice device; _manipulationDevices.TryGetValue(element, out device); return device; } return null; } ////// When a ManipulationDevice is no longer needed, remove it /// from the global list of devices. /// private void RemoveManipulationDevice() { _wasTicking = false; StopTicking(); DetachManipulationDevice(); _compensateForBoundaryFeedback = null; RemoveAllManipulators(); if (_manipulationDevices != null) { _manipulationDevices.Remove(_target); } } private void RemoveAllManipulators() { if (_manipulators != null) { for (int i = _manipulators.Count - 1; i >= 0; i--) { _manipulators[i].Updated -= OnManipulatorUpdated; } _manipulators.Clear(); } } internal void AddManipulator(IManipulator manipulator) { Debug.Assert(manipulator != null); VerifyAccess(); _manipulationEnded = false; if (_manipulators == null) { _manipulators = new List(2); } _manipulators.Add(manipulator); manipulator.Updated += OnManipulatorUpdated; // Adding a manipulator counts as an update OnManipulatorUpdated(manipulator, EventArgs.Empty); } internal void RemoveManipulator(IManipulator manipulator) { Debug.Assert(manipulator != null); VerifyAccess(); manipulator.Updated -= OnManipulatorUpdated; if (_manipulators != null) { _manipulators.Remove(manipulator); } // Removing a manipulator counts as an update OnManipulatorUpdated(manipulator, EventArgs.Empty); if (!_manipulationEnded) { if (_manipulators == null || _manipulators.Count == 0) { // cache the last removed manipulator _removedManipulator = manipulator; } // Call ReportFrame so that ManipulationInertiaStarting / ManipulationCompleted // gets called synchronously if needed ReportFrame(); _removedManipulator = null; } } /// /// Critical - Accesses _manipulationLogic. /// TreatAsSafe - OK to pass this information /// internal ManipulationModes ManipulationMode { [SecurityCritical, SecurityTreatAsSafe] get { return _manipulationLogic.ManipulationMode; } [SecurityCritical, SecurityTreatAsSafe] set { _manipulationLogic.ManipulationMode = value; } } ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - OK to pass this information /// internal ManipulationPivot ManipulationPivot { [SecurityCritical, SecurityTreatAsSafe] get { return _manipulationLogic.ManipulationPivot; } [SecurityCritical, SecurityTreatAsSafe] set { _manipulationLogic.ManipulationPivot = value; } } ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - OK to pass this information /// internal IInputElement ManipulationContainer { [SecurityCritical, SecurityTreatAsSafe] get { return _manipulationLogic.ManipulationContainer; } [SecurityCritical, SecurityTreatAsSafe] set { _manipulationLogic.ManipulationContainer = value; } } internal IEnumerableGetManipulatorsReadOnly() { if (_manipulators != null) { return new ReadOnlyCollection (_manipulators); } else { return new ReadOnlyCollection (new List (2)); } } internal void OnManipulatorUpdated(object sender, EventArgs e) { // After a period of inactivity, the ManipulationDevice will stop polling at the screen framerate // to stop wasting CPU usage. This notification will tell the device that activity is happening // so that it can know to poll. LastUpdatedTimestamp = ManipulationLogic.GetCurrentTimestamp(); ResumeAllTicking(); // Resumes the ticking of all the suspended devices on the thread StartTicking(); // Ensures that we continue ticking or restart ticking for this device } internal Point GetTransformedManipulatorPosition(Point point) { if (_compensateForBoundaryFeedback != null) { return _compensateForBoundaryFeedback(point); } return point; } /// /// Starts the ticking for all the ManipulationDevices /// on the thread only if they were ticking earlier. /// private static void ResumeAllTicking() { if (_manipulationDevices != null) { foreach (UIElement element in _manipulationDevices.Keys) { ManipulationDevice device = _manipulationDevices[element]; if (device != null && device._wasTicking) { device.StartTicking(); device._wasTicking = false; } } } } private void StartTicking() { if (!_ticking) { _ticking = true; CompositionTarget.Rendering += new EventHandler(OnRendering); SubscribeToLayoutUpdate(); } } private void StopTicking() { if (_ticking) { CompositionTarget.Rendering -= new EventHandler(OnRendering); _ticking = false; UnsubscribeFromLayoutUpdate(); } } [SecurityCritical, SecurityTreatAsSafe] private void SubscribeToLayoutUpdate() { _manipulationLogic.ContainerLayoutUpdated += OnContainerLayoutUpdated; } [SecurityCritical, SecurityTreatAsSafe] private void UnsubscribeFromLayoutUpdate() { _manipulationLogic.ContainerLayoutUpdated -= OnContainerLayoutUpdated; } private void OnContainerLayoutUpdated(object sender, EventArgs e) { ReportFrame(); } private void OnRendering(object sender, EventArgs e) { ReportFrame(); // If Manipulation didn't activate or becomes disabled, then stop ticking. // If we've exceeded the timeout without any manipulators updating, then stop ticking // to save energy. If a manipulator updates, we'll start ticking again. if (!IsManipulationActive || (ManipulationLogic.GetCurrentTimestamp() - LastUpdatedTimestamp) > ThrottleTimeout) { _wasTicking = _ticking; // ReportFrame could have stopped the ticking, hence take the latest value. StopTicking(); } } ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - Prods the logic object to do its work. Does not expose the object. /// [SecurityCritical, SecurityTreatAsSafe] private void ReportFrame() { if (!_manipulationEnded) { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordInput | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info, EventTrace.Event.ManipulationReportFrame, 0); _manipulationLogic.ReportFrame(_manipulators); } } ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - OK to report if manipulation is enabled. /// internal bool IsManipulationActive { [SecurityCritical, SecurityTreatAsSafe] get { return _manipulationLogic.IsManipulationActive; } } ////// Critical: This method can be used for input spoofing. /// [SecurityCritical] private void PostProcessInput(object sender, ProcessInputEventArgs e) { InputEventArgs inputEventArgs = e.StagingItem.Input; if (inputEventArgs.Device == this) { RoutedEvent routedEvent = inputEventArgs.RoutedEvent; if (routedEvent == Manipulation.ManipulationDeltaEvent) { ManipulationDeltaEventArgs deltaEventArgs = inputEventArgs as ManipulationDeltaEventArgs; if (deltaEventArgs != null) { // During deltas, see if panning feedback is needed on the window ManipulationDelta unusedManipulation = deltaEventArgs.UnusedManipulation; _manipulationLogic.RaiseBoundaryFeedback(unusedManipulation, deltaEventArgs.RequestedComplete); _manipulationLogic.PushEventsToDevice(); // If a Complete is requested, then pass it along to the manipulation processor if (deltaEventArgs.RequestedComplete) { _manipulationLogic.Complete(/* withInertia = */ deltaEventArgs.RequestedInertia); _manipulationLogic.PushEventsToDevice(); } else if (deltaEventArgs.RequestedCancel) { Debug.Assert(!deltaEventArgs.IsInertial); OnManipulationCancel(); } } } else if (routedEvent == Manipulation.ManipulationStartingEvent) { ManipulationStartingEventArgs startingEventArgs = inputEventArgs as ManipulationStartingEventArgs; if (startingEventArgs != null && startingEventArgs.RequestedCancel) { OnManipulationCancel(); } } else if (routedEvent == Manipulation.ManipulationStartedEvent) { ManipulationStartedEventArgs startedEventArgs = inputEventArgs as ManipulationStartedEventArgs; if (startedEventArgs != null) { if (startedEventArgs.RequestedComplete) { // If a Complete is requested, pass it along to the manipulation processor _manipulationLogic.Complete(/* withInertia = */ false); _manipulationLogic.PushEventsToDevice(); } else if (startedEventArgs.RequestedCancel) { OnManipulationCancel(); } else { // Start ticking to produce delta events ResumeAllTicking(); // Resumes the ticking of all the suspended devices on the thread StartTicking(); // Ensures that we continue ticking or restart ticking for this device } } } else if (routedEvent == Manipulation.ManipulationInertiaStartingEvent) { // Switching from using rendering for ticking to a timer at lower priority (handled by ManipulationLogic) StopTicking(); // Remove all the manipulators so that we dont re-start manipulations accidentally RemoveAllManipulators(); // Initialize inertia ManipulationInertiaStartingEventArgs inertiaEventArgs = inputEventArgs as ManipulationInertiaStartingEventArgs; if (inertiaEventArgs != null) { if (inertiaEventArgs.RequestedCancel) { OnManipulationCancel(); } else { _manipulationLogic.BeginInertia(inertiaEventArgs); } } } else if (routedEvent == Manipulation.ManipulationCompletedEvent) { _manipulationLogic.OnCompleted(); ManipulationCompletedEventArgs completedEventArgs = inputEventArgs as ManipulationCompletedEventArgs; if (completedEventArgs != null) { if (completedEventArgs.RequestedCancel) { Debug.Assert(!completedEventArgs.IsInertial); OnManipulationCancel(); } else if (!(completedEventArgs.IsInertial && _ticking)) { // Remove the manipulation device only if // another manipulation didnot start OnManipulationComplete(); } } } else if (routedEvent == Manipulation.ManipulationBoundaryFeedbackEvent) { ManipulationBoundaryFeedbackEventArgs boundaryEventArgs = inputEventArgs as ManipulationBoundaryFeedbackEventArgs; if (boundaryEventArgs != null) { _compensateForBoundaryFeedback = boundaryEventArgs.CompensateForBoundaryFeedback; } } } } ////// Critical: Calls IManipulator.ManipulationEnded which can /// potentially do mouse promotions. /// [SecurityCritical] private void OnManipulationCancel() { _manipulationEnded = true; if (_manipulators != null) { if (_removedManipulator != null) { Debug.Assert(_manipulators == null || _manipulators.Count == 0); // Report Manipulation Cancel to last removed manipulator _removedManipulator.ManipulationEnded(true); } else { // Report Manipulation Cancel to all the remaining manipulators Listmanipulators = new List (_manipulators); foreach (IManipulator manipulator in manipulators) { manipulator.ManipulationEnded(true); } } } RemoveManipulationDevice(); } /// /// Critical: Calls IManipulator.ManipulationEnded which can /// potentially do mouse promotions. /// [SecurityCritical] private void OnManipulationComplete() { _manipulationEnded = true; if (_manipulators != null) { // Report Manipulation Complete to all the remaining manipulators Listmanipulators = new List (_manipulators); foreach (IManipulator manipulator in manipulators) { manipulator.ManipulationEnded(false); } } RemoveManipulationDevice(); } /// /// Critical - Accesses _manipulationLogic. /// TreatAsSafe - Does not expose the object. /// [SecurityCritical, SecurityTreatAsSafe] internal void SetManipulationParameters(ManipulationParameters2D parameter) { _manipulationLogic.SetManipulationParameters(parameter); } ////// Completes the pending manipulation or inertia. /// ////// Critical - Accesses _manipulationLogic. /// TreatAsSafe - Does not expose the object. /// [SecurityCritical, SecurityTreatAsSafe] internal void CompleteManipulation(bool withInertia) { if (_manipulationLogic != null) { _manipulationLogic.Complete(withInertia); _manipulationLogic.PushEventsToDevice(); } } ////// Critical - Accesses _inputManager. /// [SecurityCritical] internal void ProcessManipulationInput(InputEventArgs e) { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordInput | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info, EventTrace.Event.ManipulationEventRaised, 0); _inputManager.ProcessInput(e); } ////// Critical: This data is not safe to expose as it holds refrence to PresentationSource. /// [SecurityCritical] private InputManager _inputManager; ////// Critical: Holds the the current manipulation state. Trusted to give manipulation events (and not spoofed input). /// [SecurityCritical] private ManipulationLogic _manipulationLogic; ////// PresentationSource is protected data. /// [SecurityCritical] private PresentationSource _activeSource; private UIElement _target; private List_manipulators; private bool _ticking; private bool _wasTicking; // boolean used to track suspended manipulation devices private Func _compensateForBoundaryFeedback; private bool _manipulationEnded = false; IManipulator _removedManipulator = null; [ThreadStatic] private static Int64 LastUpdatedTimestamp; private const Int64 ThrottleTimeout = TimeSpan.TicksPerSecond * 5; // 5 seconds (in 100ns units) of no activity will throttle down [ThreadStatic] private static Dictionary _manipulationDevices; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- unsafeIndexingFilterStream.cs
- MeasureItemEvent.cs
- Tuple.cs
- HotSpotCollection.cs
- XmlMemberMapping.cs
- StringToken.cs
- AuthenticatedStream.cs
- FileAuthorizationModule.cs
- SerializationInfoEnumerator.cs
- Grant.cs
- XmlBufferReader.cs
- ReliableSessionElement.cs
- ObjectDataSourceWizardForm.cs
- DataRelationPropertyDescriptor.cs
- DataProtection.cs
- MenuAdapter.cs
- XhtmlConformanceSection.cs
- SizeFConverter.cs
- SqlAggregateChecker.cs
- AxisAngleRotation3D.cs
- XmlFormatReaderGenerator.cs
- UIElement3D.cs
- KnowledgeBase.cs
- ResourceDisplayNameAttribute.cs
- AsyncDataRequest.cs
- X509CertificateTokenFactoryCredential.cs
- FixedSOMPage.cs
- BigInt.cs
- LinqDataSourceInsertEventArgs.cs
- PermissionSet.cs
- OraclePermissionAttribute.cs
- SoapHeader.cs
- SelectionListComponentEditor.cs
- GeneralTransform2DTo3DTo2D.cs
- RepeaterItemCollection.cs
- Matrix3D.cs
- ScrollItemProviderWrapper.cs
- ListItem.cs
- ApplicationBuildProvider.cs
- ActivityExecutionContext.cs
- URLIdentityPermission.cs
- ServiceDiscoveryBehavior.cs
- OdbcConnectionStringbuilder.cs
- PictureBox.cs
- WebPartCollection.cs
- XmlBinaryReader.cs
- TreeIterator.cs
- Semaphore.cs
- TransformFinalBlockRequest.cs
- Hash.cs
- Executor.cs
- ExecutionScope.cs
- BooleanAnimationBase.cs
- ColumnHeaderConverter.cs
- PropertyStore.cs
- SqlServices.cs
- EventLog.cs
- ObjectReaderCompiler.cs
- InstanceDataCollection.cs
- ListViewItem.cs
- SymbolMethod.cs
- XmlStreamStore.cs
- SqlSelectStatement.cs
- DateTimeConstantAttribute.cs
- KoreanCalendar.cs
- ParserContext.cs
- MaterialCollection.cs
- Brush.cs
- NullableIntAverageAggregationOperator.cs
- ConnectionProviderAttribute.cs
- TableDetailsRow.cs
- ObservableCollection.cs
- TypeUnloadedException.cs
- ShapingEngine.cs
- SQlBooleanStorage.cs
- AsyncResult.cs
- WindowsNonControl.cs
- Rotation3DAnimation.cs
- sqlmetadatafactory.cs
- ImpersonateTokenRef.cs
- GridViewColumnCollectionChangedEventArgs.cs
- SingleStorage.cs
- CorruptingExceptionCommon.cs
- HttpCapabilitiesBase.cs
- DataSourceGroupCollection.cs
- SignatureGenerator.cs
- ConfigurationStrings.cs
- DataServiceException.cs
- Rights.cs
- TextServicesDisplayAttributePropertyRanges.cs
- URLAttribute.cs
- VisualTarget.cs
- ThreadStateException.cs
- safesecurityhelperavalon.cs
- Pts.cs
- GenerateTemporaryAssemblyTask.cs
- MessageQueueConverter.cs
- PermissionAttributes.cs
- DesignerActionMethodItem.cs
- CodeIndexerExpression.cs