private InputManager() { // STA Requirement // // Avalon doesn't necessarily require STA, but many components do. Examples // include Cicero, OLE, COM, etc. So we throw an exception here if the // thread is not STA. if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) { throw new InvalidOperationException(SR.Get(SRID.RequiresSTA)); } _stagingArea = new Stack(); _primaryKeyboardDevice = new Win32KeyboardDevice(this); _primaryMouseDevice = new Win32MouseDevice(this); _primaryCommandDevice = new CommandDevice(this); _stylusLogic = new StylusLogic(this); _continueProcessingStagingAreaCallback = new DispatcherOperationCallback(ContinueProcessingStagingArea); _hitTestInvalidatedAsyncOperation = null; _hitTestInvalidatedAsyncCallback = new DispatcherOperationCallback(HitTestInvalidatedAsyncCallback); _layoutUpdatedCallback = new EventHandler(OnLayoutUpdated); //need to cache it, LM only keeps weak ref ContextLayoutManager.From(Dispatcher).LayoutEvents.Add(_layoutUpdatedCallback); // Timer used to synchronize the input devices periodically _inputTimer = new DispatcherTimer(DispatcherPriority.Background); _inputTimer.Tick += new EventHandler(ValidateInputDevices); _inputTimer.Interval = TimeSpan.FromMilliseconds(125); }
internal override void OnShutDown(object target, object sender, EventArgs e) { StylusLogic stylusLogic = (StylusLogic)target; StylusTraceLogger.LogStatistics(stylusLogic.Statistics); StylusTraceLogger.LogShutdown(); }
internal PenContexts(StylusLogic stylusLogic, PresentationSource inputSource) { HwndSource hwndSource = inputSource as HwndSource; if(hwndSource == null || IntPtr.Zero == (hwndSource).CriticalHandle) { throw new InvalidOperationException(SR.Get(SRID.Stylus_PenContextFailure)); } _stylusLogic = stylusLogic; _inputSource = new SecurityCriticalData<HwndSource>(hwndSource); }
internal PenContexts(StylusLogic stylusLogic, PresentationSource inputSource) { HwndSource hwndSource = inputSource as HwndSource; if (hwndSource == null || IntPtr.Zero == (hwndSource).CriticalHandle) { throw new InvalidOperationException(SR.Get(SRID.Stylus_PenContextFailure)); } _stylusLogic = stylusLogic; _inputSource = new SecurityCriticalData <HwndSource>(hwndSource); }
internal void DisposeOrDeferDisposal() { // Only dispose when no input events are left in the queue if (CanDispose) { // Make sure this device is not the current one. if (Tablet.CurrentTabletDevice == this.TabletDevice) { StylusLogic.GetCurrentStylusLogicAs <WispLogic>().SelectStylusDevice(null, null, true); } // A disconnect will be logged in the dispose as WPF will have gotten rid of the tablet. StylusTraceLogger.LogDeviceDisconnect(_tabletInfo.Id); // DDVSO:174153 // Force tablets to clean up as soon as they are disposed. This helps to reduce // COM references that might be waiting for RCWs to finalize. IPimcTablet2 tablet = _tabletInfo.PimcTablet?.Value; _tabletInfo.PimcTablet = null; if (tablet != null) { // DDVSO:514949 // Balance calls in PenThreadWorker.GetTabletInfoHelper and CPimcTablet::Init. PenThread.WorkerReleaseTabletLocks(tablet, _tabletInfo.WispTabletKey); Marshal.ReleaseComObject(tablet); } StylusDeviceCollection styluses = _stylusDeviceCollection; _stylusDeviceCollection = null; if (styluses != null) { styluses.Dispose(); } _penThread = null; _isDisposalPending = false; // DDVSO:614343 // Ensure that we are marked disposed and no longer attempt to finalize. _disposed = true; GC.SuppressFinalize(this); } else { _isDisposalPending = true; } }
/// <summary> /// Instantiates a new instance of this class. /// </summary> /// <param name="deviceId"> /// The ID of this device. /// For a particular subclass of TouchDevice, ID should be unique. /// Note: This is not validated to be unique. /// </param> protected TouchDevice(int deviceId) : base() { _deviceId = deviceId; _inputManager = InputManager.UnsecureCurrent; // If this is instantiated and the derived type is not a StylusTouchDevice then it is a 3rd party // custom touch device. StylusLogic stylusLogic = StylusLogic.CurrentStylusLogic; if (stylusLogic != null && !(this is StylusTouchDeviceBase)) { stylusLogic.Statistics.FeaturesUsed |= StylusTraceLogger.FeatureFlags.CustomTouchDeviceUsed; } }
internal void UpdateSizeDeltas(StylusPointDescription description, StylusLogic stylusLogic) { if (_doubleTapSize.IsEmpty || _cancelSize.IsEmpty || _forceUpdateSizeDeltas) { // Query default settings for mouse drag and double tap (with minimum of 1x1 size). Size mouseDragDefault = new Size(Math.Max(1, SafeSystemMetrics.DragDeltaX / 2), Math.Max(1, SafeSystemMetrics.DragDeltaY / 2)); Size mouseDoubleTapDefault = new Size(Math.Max(1, SafeSystemMetrics.DoubleClickDeltaX / 2), Math.Max(1, SafeSystemMetrics.DoubleClickDeltaY / 2)); StylusPointPropertyInfo xProperty = description.GetPropertyInfo(StylusPointProperties.X); StylusPointPropertyInfo yProperty = description.GetPropertyInfo(StylusPointProperties.Y); uint dwXValue = GetPropertyValue(xProperty); uint dwYValue = GetPropertyValue(yProperty); if (dwXValue != 0 && dwYValue != 0) { _cancelSize = new Size((int)Math.Round((ScreenSize.Width * stylusLogic.CancelDelta) / dwXValue), (int)Math.Round((ScreenSize.Height * stylusLogic.CancelDelta) / dwYValue)); // Make sure we return whole numbers (pixels are whole numbers) and take the maximum // value between mouse and stylus settings to be safe. _cancelSize.Width = Math.Max(mouseDragDefault.Width, _cancelSize.Width); _cancelSize.Height = Math.Max(mouseDragDefault.Height, _cancelSize.Height); _doubleTapSize = new Size((int)Math.Round((ScreenSize.Width * stylusLogic.DoubleTapDelta) / dwXValue), (int)Math.Round((ScreenSize.Height * stylusLogic.DoubleTapDelta) / dwYValue)); // Make sure we return whole numbers (pixels are whole numbers) and take the maximum // value between mouse and stylus settings to be safe. _doubleTapSize.Width = Math.Max(mouseDoubleTapDefault.Width, _doubleTapSize.Width); _doubleTapSize.Height = Math.Max(mouseDoubleTapDefault.Height, _doubleTapSize.Height); } else { // If no info to do the calculation then use the mouse settings for the default. _doubleTapSize = mouseDoubleTapDefault; _cancelSize = mouseDragDefault; } _forceUpdateSizeDeltas = false; } }
internal void DisposeOrDeferDisposal() { // Only dispose when no input events are left in the queue if (CanDispose) { // Make sure this device is not the current one. if (Tablet.CurrentTabletDevice == this.TabletDevice) { StylusLogic.GetCurrentStylusLogicAs <WispLogic>().SelectStylusDevice(null, null, true); } // A disconnect will be logged in the dispose as WPF will have gotten rid of the tablet. StylusTraceLogger.LogDeviceDisconnect(_tabletInfo.Id); // DDVSO:174153 // Force tablets to clean up as soon as they are disposed. This helps to reduce // COM references that might be waiting for RCWs to finalize. IPimcTablet2 tablet = _tabletInfo.PimcTablet?.Value; _tabletInfo.PimcTablet = null; if (tablet != null) { Marshal.ReleaseComObject(tablet); } StylusDeviceCollection styluses = _stylusDeviceCollection; _stylusDeviceCollection = null; if (styluses != null) { styluses.Dispose(); } _penThread = null; _isDisposalPending = false; } else { _isDisposalPending = true; } }
internal TabletDeviceCollection() { StylusLogic stylusLogic = StylusLogic.CurrentStylusLogic; bool enabled = stylusLogic.Enabled; if (!enabled) { enabled = ShouldEnableTablets(); } // If enabled or we are a tabletpc (vista sets dynamically if digitizers present) then enable the pen! if (enabled) { UpdateTablets(); // Create the tablet device collection! // Enable stylus input on all hwnds if we have not yet done so. if (!stylusLogic.Enabled) { stylusLogic.EnableCore(); } } }
public StylusLogicShutDownListener(StylusLogic target, ShutDownEvents events) : base(target, events) { }
private InputManager() { // STA Requirement // // Avalon doesn't necessarily require STA, but many components do. Examples // include Cicero, OLE, COM, etc. So we throw an exception here if the // thread is not STA. if(Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) { throw new InvalidOperationException(SR.Get(SRID.RequiresSTA)); } _stagingArea = new Stack(); _primaryKeyboardDevice = new Win32KeyboardDevice(this); _primaryMouseDevice = new Win32MouseDevice(this); _primaryCommandDevice = new CommandDevice(this); _stylusLogic = new StylusLogic(this); _continueProcessingStagingAreaCallback = new DispatcherOperationCallback(ContinueProcessingStagingArea); _hitTestInvalidatedAsyncOperation = null; _hitTestInvalidatedAsyncCallback = new DispatcherOperationCallback(HitTestInvalidatedAsyncCallback); _layoutUpdatedCallback = new EventHandler(OnLayoutUpdated); //need to cache it, LM only keeps weak ref ContextLayoutManager.From(Dispatcher).LayoutEvents.Add(_layoutUpdatedCallback); // Timer used to synchronize the input devices periodically _inputTimer = new DispatcherTimer(DispatcherPriority.Background); _inputTimer.Tick += new EventHandler(ValidateInputDevices); _inputTimer.Interval = TimeSpan.FromMilliseconds(125); }