Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Input / Stylus / PenContext.cs / 1 / PenContext.cs
using System; using System.Diagnostics; using System.Collections.Specialized; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Collections; using System.Collections.Generic; using System.Security; using System.Security.Permissions; using MS.Internal; using MS.Win32.Penimc; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Input { ///////////////////////////////////////////////////////////////////////// internal sealed class PenContext { ////// Critical - Handles security critical data pimcContext, hwnd, and commHandle that /// is created under elavated priviledge. /// Called directly by TabletDevice.CreateContext(). /// TreatAsSafe boundry is Stylus.EnableCore, Stylus.RegisterHwndForInput /// and HwndWrapperHook class (via HwndSource.InputFilterMessage). /// [SecurityCritical] internal PenContext(IPimcContext pimcContext, IntPtr hwnd, PenContexts contexts, bool supportInRange, bool isIntegrated, int id, IntPtr commHandle, int tabletDeviceId) { _contexts = contexts; _pimcContext = new SecurityCriticalDataClass(pimcContext); _id = id; _tabletDeviceId = tabletDeviceId; _commHandle = new SecurityCriticalData (commHandle); _hwnd = new SecurityCriticalData (hwnd); _supportInRange = supportInRange; _isIntegrated = isIntegrated; } ///////////////////////////////////////////////////////////////////// ~PenContext() { Dispose(); } ///////////////////////////////////////////////////////////////////// /// /// Handles clean up of internal object data. /// ////// Critical - Calls critical code Disable. /// Called by Finalizer. /// TreatAsSafe - Handles critical data but does not expose it. /// - No critical data returned or accepted as input. /// [SecurityCritical, SecurityTreatAsSafe] void Dispose() { Disable(false /*shutdownWorkerThread*/); // Make sure we remove the context from the active list. _pimcContext = null; _contexts = null; GC.KeepAlive(this); } ///////////////////////////////////////////////////////////////////// ////// Critical: Accesses and returns SecurityCritical data _contexts. /// internal PenContexts Contexts { [SecurityCritical] get { return _contexts; } } ///////////////////////////////////////////////////////////////////// ////// Critical - Critical since it returns critical data. /// internal IntPtr CommHandle { [SecurityCritical] get { return _commHandle.Value; } } ///////////////////////////////////////////////////////////////////// internal int Id { get { return _id; } } ///////////////////////////////////////////////////////////////////// internal int TabletDeviceId { get { return _tabletDeviceId; } } ///////////////////////////////////////////////////////////////////////// internal StylusPointDescription StylusPointDescription { get { if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } return _stylusPointDescription; } } ///////////////////////////////////////////////////////////////////// ////// Critical - Critical since it calls into unmanaged code (GetPacketPropertyInfo /// GetPacketButtonInfo and GetPacketDescriptionInfo PenImc.dll /// methods on IPimcContext COM interfaces stored in _pimcContext) that /// is SecurityCritical with SUC attribute. /// TreatAsSafe - Takes no input and returns StylusPointDescription that is handed out publically /// on StylusEvents. Nothing inside StylusPointDescription is security critical. /// [SecurityCritical,SecurityTreatAsSafe] private void InitStylusPointDescription() { int cProps; int cButtons; int pressureIndex = -1; // Make sure we are never called on the application thread when we need to talk // to penimc or else we can cause reentrancy! Debug.Assert(!_contexts._inputSource.Value.CheckAccess()); // We should always have a valid IPimcContext interface pointer. Debug.Assert(_pimcContext != null && _pimcContext.Value != null); _pimcContext.Value.GetPacketDescriptionInfo(out cProps, out cButtons); // Calls Unmanaged code - SecurityCritical with SUC. ListpropertyInfos = new List (cProps + cButtons + 3); for (int i = 0; i < cProps; i++) { Guid guid; int min, max; int units; float res; _pimcContext.Value.GetPacketPropertyInfo(i, out guid, out min, out max, out units, out res); // Calls Unmanaged code - SecurityCritical with SUC. if (pressureIndex == -1 && guid == StylusPointPropertyIds.NormalPressure) { pressureIndex = i; } if (_statusPropertyIndex == -1 && guid == StylusPointPropertyIds.PacketStatus) { _statusPropertyIndex = i; } StylusPointPropertyInfo propertyInfo = new StylusPointPropertyInfo(new StylusPointProperty(guid, false), min, max, (StylusPointPropertyUnit)units, res); propertyInfos.Add(propertyInfo); } Debug.Assert(_statusPropertyIndex != -1); // We should always see this. // Make sure we actually created propertyInfos OK if (propertyInfos != null) { for (int i = 0; i < cButtons; i++) { Guid buttonGuid; _pimcContext.Value.GetPacketButtonInfo(i, out buttonGuid); // Calls Unmanaged code - SecurityCritical with SUC. StylusPointProperty buttonProperty = new StylusPointProperty(buttonGuid, true); StylusPointPropertyInfo buttonInfo = new StylusPointPropertyInfo(buttonProperty); propertyInfos.Add(buttonInfo); } //validate we can never get X, Y at index != 0, 1 Debug.Assert(propertyInfos[StylusPointDescription.RequiredXIndex /*0*/].Id == StylusPointPropertyIds.X, "X isn't where we expect it! Fix PenImc to ask for X at index 0"); Debug.Assert(propertyInfos[StylusPointDescription.RequiredYIndex /*0*/].Id == StylusPointPropertyIds.Y, "Y isn't where we expect it! Fix PenImc to ask for Y at index 1"); Debug.Assert(pressureIndex == -1 || pressureIndex == StylusPointDescription.RequiredPressureIndex /*2*/, "Fix PenImc to ask for NormalPressure at index 2!"); if (pressureIndex == -1) { //pressure wasn't found. Add it propertyInfos.Insert(StylusPointDescription.RequiredPressureIndex /*2*/, StylusPointPropertyInfoDefaults.NormalPressure); } _infoX = propertyInfos[0]; _infoY = propertyInfos[1]; _stylusPointDescription = new StylusPointDescription(propertyInfos, pressureIndex); } } /// /// Critical - Calls SecurityCritical code PenThreadPool.GetPenThreadForPenContext(). /// Accesses SecurityCriticalData _pimcContext.Value and sets _penThreadPenContext. /// Called by PenContexts.Enable(). /// TreatAsSafe boundry is Stylus.EnableCore, Stylus.RegisterHwndForInput /// and HwndWrapperHook class (via HwndSource.InputFilterMessage). /// [SecurityCritical] internal void Enable() { if (_pimcContext != null && _pimcContext.Value != null) { _penThreadPenContext = PenThreadPool.GetPenThreadForPenContext(this); } } ////// Critical - Calls SecurityCritical code (PenThread.RemovePenContext). /// Called by PenContexts.RemoveContext and PenContexts.Disable. /// [SecurityCritical] internal void Disable(bool shutdownWorkerThread) { // Note that we should always be called under a Dispatcher.DisableProcessing. if (_penThreadPenContext != null) { if (_penThreadPenContext.RemovePenContext(this)) { _pimcContext = null; // Make sure we release wisptis ref if we removed it (ie - not in use). // Check if we need to shut down our pen thread. if (shutdownWorkerThread) { _penThreadPenContext.Dispose(); } _penThreadPenContext = null; // Can't free this ref until we can remove this context or else we won't see the stylus OutOfRange. } } } ///////////////////////////////////////////////////////////////////// internal bool SupportInRange { get { return _supportInRange; } } internal bool IsInRange(int stylusPointerId) { // zero is a special case where we want to know if any stylus devices are in range. if (stylusPointerId == 0) return _stylusDevicesInRange != null && _stylusDevicesInRange.Count > 0; else return (_stylusDevicesInRange != null && _stylusDevicesInRange.Contains(stylusPointerId)); } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code PenContexts.OnPenDown. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePenDown (int stylusPointerId, int[] data, int timestamp) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } _contexts.OnPenDown(this, _tabletDeviceId, stylusPointerId, data, timestamp); } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code PenContext.OnPenUp. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePenUp (int stylusPointerId, int[] data, int timestamp) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } _contexts.OnPenUp(this, _tabletDeviceId, stylusPointerId, data, timestamp); } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code PenContexts.OnPackets and PenContexts.OnInAirPackets. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePackets(int stylusPointerId, int[] data, int timestamp) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } bool fDownPackets = false; if (_statusPropertyIndex != -1) { int status = data[_statusPropertyIndex]; // (we take status of the first packet for status of all of them) fDownPackets = (status & 1/*IP_CURSOR_DOWN*/) != 0; } if (fDownPackets) { _contexts.OnPackets(this, _tabletDeviceId, stylusPointerId, data, timestamp); } else { _contexts.OnInAirPackets(this, _tabletDeviceId, stylusPointerId, data, timestamp); } } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code PenContexts.OnPenInRange. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePenInRange(int stylusPointerId, int[] data, int timestamp) { // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } // Special case where we want to forward this to the application early (this is the real // stylus InRange event we don't currently use). if (data == null) { _lastInRangeTime = timestamp; // Always reset timestamp on InRange!! Don't call EnsureTimestampUnique. _queuedInRangeCount++; _contexts.OnPenInRange(this, _tabletDeviceId, stylusPointerId, data, timestamp); return; } // This should not be called if this stylus ID is 0 System.Diagnostics.Debug.Assert(stylusPointerId != 0); if (!IsInRange(stylusPointerId)) { _lastInRangeTime = timestamp; // Always reset timestamp on InRange!! Don't call EnsureTimestampUnique. if (_stylusDevicesInRange == null) { _stylusDevicesInRange = new List(); // create it as needed. } _stylusDevicesInRange.Add(stylusPointerId); _contexts.OnPenInRange(this, _tabletDeviceId, stylusPointerId, data, timestamp); } } ///////////////////////////////////////////////////////////////////// /// /// Critical - Calls SecurityCritical code PenContexts.OnPenOutOfRange. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePenOutOfRange(int stylusPointerId, int timestamp) { // We only do work here if we truly had a stylus in range. if (stylusPointerId != 0) { if (IsInRange(stylusPointerId)) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } _stylusDevicesInRange.Remove(stylusPointerId); _contexts.OnPenOutOfRange(this, _tabletDeviceId, stylusPointerId, timestamp); if (_stylusDevicesInRange.Count == 0) { _stylusDevicesInRange = null; // not needed anymore. } } } else if (_stylusDevicesInRange != null) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } // Send event for each StylusDevice being out of range, then clear out the map. for(int i=0; i < _stylusDevicesInRange.Count; i++) { _contexts.OnPenOutOfRange(this, _tabletDeviceId, _stylusDevicesInRange[i], timestamp); } _stylusDevicesInRange = null; // nothing in range now. } } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code MS.Win32.Penimc.UnsafeNativeMethods.GetLastSystemEventData /// and PenContexts.OnSystemEvent. Also handles SecurityCritical data _commHandle. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FireSystemGesture(int stylusPointerId, int timestamp) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } int id; int modifier; int character; int stylusMode; int x, y, buttonState; // (these are not used) MS.Win32.Penimc.UnsafeNativeMethods.GetLastSystemEventData( _commHandle.Value, out id, out modifier, out character, out x, out y, out stylusMode, out buttonState); _contexts.OnSystemEvent( this, _tabletDeviceId, stylusPointerId, timestamp, (SystemGesture)id, x, y, buttonState); } ///////////////////////////////////////////////////////////////////// // // Make sure timestamp is unique for each event. Note that on each InRange event the // timestamp _lastInRangeTime is reset to the real event time so we don't have to worry // about really stale timestamps due to lack of use of a stylus device. // private int EnsureTimestampUnique(int timestamp) { int delta = unchecked(_lastInRangeTime - timestamp); // Is last time more current? If so we need to increment and return this. // NOTE: This deals with wrapping from MaxInt to MinInt. // Here's some info on how this works... // int.MaxValue - int.MinValue = -1 (subtracting any negative # from MaxValue keeps this negative) // int.MinValue - int.MaxValue = 1 (subtracting any positive # from MinValue keeps this positive) // So as _lastInRangeTime approaches MaxInt if subtracting timestamp is positive then timestamp // is older and we want to use _lastInRangeTime + 1 to keep the time unique. // and if _lastInRangeTime is near MinInt then if subtracting timestamp is positive the // same condition is true in that timestamp is older. if (delta >= 0) { timestamp = unchecked(_lastInRangeTime + 1); } return timestamp; } // This keeps track of the last time we saw an InRange/OutOfRange event on the pen thread. internal int LastInRangeTime { get { return _lastInRangeTime; } } // This returns the count of queued special InRange reports that we use to know if we are // potentially going inrange. internal int QueuedInRangeCount { get { return _queuedInRangeCount; } } // The application uses this to decrement the queued InRange count when it arrives on the app thread. internal void DecrementQueuedInRangeCount() { _queuedInRangeCount--; } ///////////////////////////////////////////////////////////////////// ////// SecurityCritical - This is got under an elevation and is hence critical. /// internal SecurityCriticalDataClass_pimcContext; /// /// SecurityCritical - This is got under an elevation and is hence critical. /// SecurityCriticalData_hwnd; /// /// SecurityCritical - This is got under an elevation and is hence critical. /// SecurityCriticalData_commHandle; /// /// Critical to prevent accidental spread to transparent code /// [SecurityCritical] PenContexts _contexts; ////// Critical to prevent accidental spread to transparent code /// [SecurityCritical] PenThread _penThreadPenContext; int _id; int _tabletDeviceId; StylusPointPropertyInfo _infoX; StylusPointPropertyInfo _infoY; bool _supportInRange; List_stylusDevicesInRange; bool _isIntegrated; StylusPointDescription _stylusPointDescription; int _statusPropertyIndex = -1; int _lastInRangeTime; int _queuedInRangeCount; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Diagnostics; using System.Collections.Specialized; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Collections; using System.Collections.Generic; using System.Security; using System.Security.Permissions; using MS.Internal; using MS.Win32.Penimc; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace System.Windows.Input { ///////////////////////////////////////////////////////////////////////// internal sealed class PenContext { /// /// Critical - Handles security critical data pimcContext, hwnd, and commHandle that /// is created under elavated priviledge. /// Called directly by TabletDevice.CreateContext(). /// TreatAsSafe boundry is Stylus.EnableCore, Stylus.RegisterHwndForInput /// and HwndWrapperHook class (via HwndSource.InputFilterMessage). /// [SecurityCritical] internal PenContext(IPimcContext pimcContext, IntPtr hwnd, PenContexts contexts, bool supportInRange, bool isIntegrated, int id, IntPtr commHandle, int tabletDeviceId) { _contexts = contexts; _pimcContext = new SecurityCriticalDataClass(pimcContext); _id = id; _tabletDeviceId = tabletDeviceId; _commHandle = new SecurityCriticalData (commHandle); _hwnd = new SecurityCriticalData (hwnd); _supportInRange = supportInRange; _isIntegrated = isIntegrated; } ///////////////////////////////////////////////////////////////////// ~PenContext() { Dispose(); } ///////////////////////////////////////////////////////////////////// /// /// Handles clean up of internal object data. /// ////// Critical - Calls critical code Disable. /// Called by Finalizer. /// TreatAsSafe - Handles critical data but does not expose it. /// - No critical data returned or accepted as input. /// [SecurityCritical, SecurityTreatAsSafe] void Dispose() { Disable(false /*shutdownWorkerThread*/); // Make sure we remove the context from the active list. _pimcContext = null; _contexts = null; GC.KeepAlive(this); } ///////////////////////////////////////////////////////////////////// ////// Critical: Accesses and returns SecurityCritical data _contexts. /// internal PenContexts Contexts { [SecurityCritical] get { return _contexts; } } ///////////////////////////////////////////////////////////////////// ////// Critical - Critical since it returns critical data. /// internal IntPtr CommHandle { [SecurityCritical] get { return _commHandle.Value; } } ///////////////////////////////////////////////////////////////////// internal int Id { get { return _id; } } ///////////////////////////////////////////////////////////////////// internal int TabletDeviceId { get { return _tabletDeviceId; } } ///////////////////////////////////////////////////////////////////////// internal StylusPointDescription StylusPointDescription { get { if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } return _stylusPointDescription; } } ///////////////////////////////////////////////////////////////////// ////// Critical - Critical since it calls into unmanaged code (GetPacketPropertyInfo /// GetPacketButtonInfo and GetPacketDescriptionInfo PenImc.dll /// methods on IPimcContext COM interfaces stored in _pimcContext) that /// is SecurityCritical with SUC attribute. /// TreatAsSafe - Takes no input and returns StylusPointDescription that is handed out publically /// on StylusEvents. Nothing inside StylusPointDescription is security critical. /// [SecurityCritical,SecurityTreatAsSafe] private void InitStylusPointDescription() { int cProps; int cButtons; int pressureIndex = -1; // Make sure we are never called on the application thread when we need to talk // to penimc or else we can cause reentrancy! Debug.Assert(!_contexts._inputSource.Value.CheckAccess()); // We should always have a valid IPimcContext interface pointer. Debug.Assert(_pimcContext != null && _pimcContext.Value != null); _pimcContext.Value.GetPacketDescriptionInfo(out cProps, out cButtons); // Calls Unmanaged code - SecurityCritical with SUC. ListpropertyInfos = new List (cProps + cButtons + 3); for (int i = 0; i < cProps; i++) { Guid guid; int min, max; int units; float res; _pimcContext.Value.GetPacketPropertyInfo(i, out guid, out min, out max, out units, out res); // Calls Unmanaged code - SecurityCritical with SUC. if (pressureIndex == -1 && guid == StylusPointPropertyIds.NormalPressure) { pressureIndex = i; } if (_statusPropertyIndex == -1 && guid == StylusPointPropertyIds.PacketStatus) { _statusPropertyIndex = i; } StylusPointPropertyInfo propertyInfo = new StylusPointPropertyInfo(new StylusPointProperty(guid, false), min, max, (StylusPointPropertyUnit)units, res); propertyInfos.Add(propertyInfo); } Debug.Assert(_statusPropertyIndex != -1); // We should always see this. // Make sure we actually created propertyInfos OK if (propertyInfos != null) { for (int i = 0; i < cButtons; i++) { Guid buttonGuid; _pimcContext.Value.GetPacketButtonInfo(i, out buttonGuid); // Calls Unmanaged code - SecurityCritical with SUC. StylusPointProperty buttonProperty = new StylusPointProperty(buttonGuid, true); StylusPointPropertyInfo buttonInfo = new StylusPointPropertyInfo(buttonProperty); propertyInfos.Add(buttonInfo); } //validate we can never get X, Y at index != 0, 1 Debug.Assert(propertyInfos[StylusPointDescription.RequiredXIndex /*0*/].Id == StylusPointPropertyIds.X, "X isn't where we expect it! Fix PenImc to ask for X at index 0"); Debug.Assert(propertyInfos[StylusPointDescription.RequiredYIndex /*0*/].Id == StylusPointPropertyIds.Y, "Y isn't where we expect it! Fix PenImc to ask for Y at index 1"); Debug.Assert(pressureIndex == -1 || pressureIndex == StylusPointDescription.RequiredPressureIndex /*2*/, "Fix PenImc to ask for NormalPressure at index 2!"); if (pressureIndex == -1) { //pressure wasn't found. Add it propertyInfos.Insert(StylusPointDescription.RequiredPressureIndex /*2*/, StylusPointPropertyInfoDefaults.NormalPressure); } _infoX = propertyInfos[0]; _infoY = propertyInfos[1]; _stylusPointDescription = new StylusPointDescription(propertyInfos, pressureIndex); } } /// /// Critical - Calls SecurityCritical code PenThreadPool.GetPenThreadForPenContext(). /// Accesses SecurityCriticalData _pimcContext.Value and sets _penThreadPenContext. /// Called by PenContexts.Enable(). /// TreatAsSafe boundry is Stylus.EnableCore, Stylus.RegisterHwndForInput /// and HwndWrapperHook class (via HwndSource.InputFilterMessage). /// [SecurityCritical] internal void Enable() { if (_pimcContext != null && _pimcContext.Value != null) { _penThreadPenContext = PenThreadPool.GetPenThreadForPenContext(this); } } ////// Critical - Calls SecurityCritical code (PenThread.RemovePenContext). /// Called by PenContexts.RemoveContext and PenContexts.Disable. /// [SecurityCritical] internal void Disable(bool shutdownWorkerThread) { // Note that we should always be called under a Dispatcher.DisableProcessing. if (_penThreadPenContext != null) { if (_penThreadPenContext.RemovePenContext(this)) { _pimcContext = null; // Make sure we release wisptis ref if we removed it (ie - not in use). // Check if we need to shut down our pen thread. if (shutdownWorkerThread) { _penThreadPenContext.Dispose(); } _penThreadPenContext = null; // Can't free this ref until we can remove this context or else we won't see the stylus OutOfRange. } } } ///////////////////////////////////////////////////////////////////// internal bool SupportInRange { get { return _supportInRange; } } internal bool IsInRange(int stylusPointerId) { // zero is a special case where we want to know if any stylus devices are in range. if (stylusPointerId == 0) return _stylusDevicesInRange != null && _stylusDevicesInRange.Count > 0; else return (_stylusDevicesInRange != null && _stylusDevicesInRange.Contains(stylusPointerId)); } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code PenContexts.OnPenDown. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePenDown (int stylusPointerId, int[] data, int timestamp) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } _contexts.OnPenDown(this, _tabletDeviceId, stylusPointerId, data, timestamp); } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code PenContext.OnPenUp. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePenUp (int stylusPointerId, int[] data, int timestamp) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } _contexts.OnPenUp(this, _tabletDeviceId, stylusPointerId, data, timestamp); } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code PenContexts.OnPackets and PenContexts.OnInAirPackets. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePackets(int stylusPointerId, int[] data, int timestamp) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } bool fDownPackets = false; if (_statusPropertyIndex != -1) { int status = data[_statusPropertyIndex]; // (we take status of the first packet for status of all of them) fDownPackets = (status & 1/*IP_CURSOR_DOWN*/) != 0; } if (fDownPackets) { _contexts.OnPackets(this, _tabletDeviceId, stylusPointerId, data, timestamp); } else { _contexts.OnInAirPackets(this, _tabletDeviceId, stylusPointerId, data, timestamp); } } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code PenContexts.OnPenInRange. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePenInRange(int stylusPointerId, int[] data, int timestamp) { // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } // Special case where we want to forward this to the application early (this is the real // stylus InRange event we don't currently use). if (data == null) { _lastInRangeTime = timestamp; // Always reset timestamp on InRange!! Don't call EnsureTimestampUnique. _queuedInRangeCount++; _contexts.OnPenInRange(this, _tabletDeviceId, stylusPointerId, data, timestamp); return; } // This should not be called if this stylus ID is 0 System.Diagnostics.Debug.Assert(stylusPointerId != 0); if (!IsInRange(stylusPointerId)) { _lastInRangeTime = timestamp; // Always reset timestamp on InRange!! Don't call EnsureTimestampUnique. if (_stylusDevicesInRange == null) { _stylusDevicesInRange = new List(); // create it as needed. } _stylusDevicesInRange.Add(stylusPointerId); _contexts.OnPenInRange(this, _tabletDeviceId, stylusPointerId, data, timestamp); } } ///////////////////////////////////////////////////////////////////// /// /// Critical - Calls SecurityCritical code PenContexts.OnPenOutOfRange. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FirePenOutOfRange(int stylusPointerId, int timestamp) { // We only do work here if we truly had a stylus in range. if (stylusPointerId != 0) { if (IsInRange(stylusPointerId)) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } _stylusDevicesInRange.Remove(stylusPointerId); _contexts.OnPenOutOfRange(this, _tabletDeviceId, stylusPointerId, timestamp); if (_stylusDevicesInRange.Count == 0) { _stylusDevicesInRange = null; // not needed anymore. } } } else if (_stylusDevicesInRange != null) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } // Send event for each StylusDevice being out of range, then clear out the map. for(int i=0; i < _stylusDevicesInRange.Count; i++) { _contexts.OnPenOutOfRange(this, _tabletDeviceId, _stylusDevicesInRange[i], timestamp); } _stylusDevicesInRange = null; // nothing in range now. } } ///////////////////////////////////////////////////////////////////// ////// Critical - Calls SecurityCritical code MS.Win32.Penimc.UnsafeNativeMethods.GetLastSystemEventData /// and PenContexts.OnSystemEvent. Also handles SecurityCritical data _commHandle. /// Called by PenThread.FireEvent. /// TreatAsSafe boundary is PenThread.ThreadProc. /// [SecurityCritical] internal void FireSystemGesture(int stylusPointerId, int timestamp) { timestamp = EnsureTimestampUnique(timestamp); _lastInRangeTime = timestamp; // make sure this gets initialized on the penthread!! if (_stylusPointDescription == null) { InitStylusPointDescription(); // init _stylusPointDescription. } int id; int modifier; int character; int stylusMode; int x, y, buttonState; // (these are not used) MS.Win32.Penimc.UnsafeNativeMethods.GetLastSystemEventData( _commHandle.Value, out id, out modifier, out character, out x, out y, out stylusMode, out buttonState); _contexts.OnSystemEvent( this, _tabletDeviceId, stylusPointerId, timestamp, (SystemGesture)id, x, y, buttonState); } ///////////////////////////////////////////////////////////////////// // // Make sure timestamp is unique for each event. Note that on each InRange event the // timestamp _lastInRangeTime is reset to the real event time so we don't have to worry // about really stale timestamps due to lack of use of a stylus device. // private int EnsureTimestampUnique(int timestamp) { int delta = unchecked(_lastInRangeTime - timestamp); // Is last time more current? If so we need to increment and return this. // NOTE: This deals with wrapping from MaxInt to MinInt. // Here's some info on how this works... // int.MaxValue - int.MinValue = -1 (subtracting any negative # from MaxValue keeps this negative) // int.MinValue - int.MaxValue = 1 (subtracting any positive # from MinValue keeps this positive) // So as _lastInRangeTime approaches MaxInt if subtracting timestamp is positive then timestamp // is older and we want to use _lastInRangeTime + 1 to keep the time unique. // and if _lastInRangeTime is near MinInt then if subtracting timestamp is positive the // same condition is true in that timestamp is older. if (delta >= 0) { timestamp = unchecked(_lastInRangeTime + 1); } return timestamp; } // This keeps track of the last time we saw an InRange/OutOfRange event on the pen thread. internal int LastInRangeTime { get { return _lastInRangeTime; } } // This returns the count of queued special InRange reports that we use to know if we are // potentially going inrange. internal int QueuedInRangeCount { get { return _queuedInRangeCount; } } // The application uses this to decrement the queued InRange count when it arrives on the app thread. internal void DecrementQueuedInRangeCount() { _queuedInRangeCount--; } ///////////////////////////////////////////////////////////////////// ////// SecurityCritical - This is got under an elevation and is hence critical. /// internal SecurityCriticalDataClass_pimcContext; /// /// SecurityCritical - This is got under an elevation and is hence critical. /// SecurityCriticalData_hwnd; /// /// SecurityCritical - This is got under an elevation and is hence critical. /// SecurityCriticalData_commHandle; /// /// Critical to prevent accidental spread to transparent code /// [SecurityCritical] PenContexts _contexts; ////// Critical to prevent accidental spread to transparent code /// [SecurityCritical] PenThread _penThreadPenContext; int _id; int _tabletDeviceId; StylusPointPropertyInfo _infoX; StylusPointPropertyInfo _infoY; bool _supportInRange; List_stylusDevicesInRange; bool _isIntegrated; StylusPointDescription _stylusPointDescription; int _statusPropertyIndex = -1; int _lastInRangeTime; int _queuedInRangeCount; } } // 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
- DesignerAttribute.cs
- QueryOutputWriter.cs
- OutputCacheEntry.cs
- StylusButtonEventArgs.cs
- ReflectionServiceProvider.cs
- RadioButtonFlatAdapter.cs
- UnsafeNativeMethodsMilCoreApi.cs
- RegexRunner.cs
- UserControl.cs
- Helpers.cs
- TableRowCollection.cs
- LinkLabelLinkClickedEvent.cs
- Ops.cs
- ToolboxControl.cs
- SafeEventLogWriteHandle.cs
- COM2FontConverter.cs
- QueryReaderSettings.cs
- SchemaTableOptionalColumn.cs
- ExtentCqlBlock.cs
- DataGridViewRowContextMenuStripNeededEventArgs.cs
- PerformanceCounterPermissionAttribute.cs
- __ConsoleStream.cs
- SerializationHelper.cs
- InputScopeManager.cs
- IDictionary.cs
- RC2.cs
- UserControl.cs
- FieldInfo.cs
- SmiSettersStream.cs
- MutexSecurity.cs
- ConnectionStringsExpressionBuilder.cs
- StringReader.cs
- DynamicValidatorEventArgs.cs
- Stackframe.cs
- WebPartPersonalization.cs
- NumericUpDown.cs
- ContainerFilterService.cs
- DataServiceQueryProvider.cs
- PartialCachingControl.cs
- FontFamily.cs
- SponsorHelper.cs
- ModelEditingScope.cs
- SmtpReplyReader.cs
- SharedPersonalizationStateInfo.cs
- PolyBezierSegment.cs
- Object.cs
- EventMetadata.cs
- DataGridViewRowPrePaintEventArgs.cs
- ProfilePropertySettingsCollection.cs
- BitmapEffectState.cs
- GeneralTransform3DTo2DTo3D.cs
- ValidatedControlConverter.cs
- SqlBuilder.cs
- EntityDataSourceReferenceGroup.cs
- ResourceBinder.cs
- SqlDataSourceCache.cs
- EditorPartCollection.cs
- Transactions.cs
- CounterCreationDataCollection.cs
- SingleStorage.cs
- HttpCapabilitiesEvaluator.cs
- ResourceDictionaryCollection.cs
- QueryStringParameter.cs
- DbParameterCollectionHelper.cs
- ComboBox.cs
- KnownTypesHelper.cs
- ReflectionServiceProvider.cs
- BaseCollection.cs
- ErrorInfoXmlDocument.cs
- TableLayoutRowStyleCollection.cs
- ResourcePool.cs
- PocoEntityKeyStrategy.cs
- ReadOnlyState.cs
- UseLicense.cs
- NewArray.cs
- ConnectionStringSettingsCollection.cs
- TailPinnedEventArgs.cs
- PeerApplicationLaunchInfo.cs
- SRGSCompiler.cs
- RegexInterpreter.cs
- XmlSerializerSection.cs
- Annotation.cs
- SqlDataSourceQueryConverter.cs
- translator.cs
- _CommandStream.cs
- SiteMapNodeItem.cs
- CachingParameterInspector.cs
- HierarchicalDataSourceDesigner.cs
- HwndSourceParameters.cs
- BaseAsyncResult.cs
- ListViewCommandEventArgs.cs
- Visual3DCollection.cs
- WebPartTracker.cs
- WebPartConnectionsCloseVerb.cs
- DelegateOutArgument.cs
- NumberFormatInfo.cs
- HMACSHA512.cs
- DefaultDiscoveryServiceExtension.cs
- EntityDataSourceColumn.cs
- ImpersonationContext.cs