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. IPimcTablet 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 TabletDeviceSizeInfo WorkerGetUpdatedSizes(IPimcTablet pimcTablet) { return(_penThreadWorker.WorkerGetUpdatedSizes(pimcTablet)); }
internal StylusDeviceInfo[] WorkerRefreshCursorInfo(IPimcTablet pimcTablet) { return(_penThreadWorker.WorkerRefreshCursorInfo(pimcTablet)); }
internal PenContextInfo WorkerCreateContext(IntPtr hwnd, IPimcTablet pimcTablet) { return(_penThreadWorker.WorkerCreateContext(hwnd, pimcTablet)); }
internal TabletDeviceSizeInfo WorkerGetUpdatedSizes(IPimcTablet pimcTablet) { // Set data up for call WorkerOperationWorkerGetUpdatedSizes getUpdatedSizes = new WorkerOperationWorkerGetUpdatedSizes(pimcTablet); lock(_workerOperationLock) { _workerOperation.Add(getUpdatedSizes); } // Kick thread to do this work. MS.Win32.Penimc.UnsafeNativeMethods.RaiseResetEvent(_pimcResetHandle.Value); // Wait for this work to be completed. getUpdatedSizes.DoneEvent.WaitOne(); getUpdatedSizes.DoneEvent.Close(); return getUpdatedSizes.TabletDeviceSizeInfo; }
internal StylusDeviceInfo[] WorkerRefreshCursorInfo(IPimcTablet pimcTablet) { WorkerOperationRefreshCursorInfo refreshCursorInfo = new WorkerOperationRefreshCursorInfo( pimcTablet); lock(_workerOperationLock) { _workerOperation.Add(refreshCursorInfo); } // Kick thread to do this work. MS.Win32.Penimc.UnsafeNativeMethods.RaiseResetEvent(_pimcResetHandle.Value); // Wait for this work to be completed. refreshCursorInfo.DoneEvent.WaitOne(); refreshCursorInfo.DoneEvent.Close(); return refreshCursorInfo.StylusDevicesInfo; }
internal PenContextInfo WorkerCreateContext(IntPtr hwnd, IPimcTablet pimcTablet) { WorkerOperationCreateContext createContextOperation = new WorkerOperationCreateContext( hwnd, pimcTablet); lock(_workerOperationLock) { _workerOperation.Add(createContextOperation); } // Kick thread to do this work. MS.Win32.Penimc.UnsafeNativeMethods.RaiseResetEvent(_pimcResetHandle.Value); // Wait for this work to be completed. createContextOperation.DoneEvent.WaitOne(); createContextOperation.DoneEvent.Close(); return createContextOperation.Result; }
internal WorkerOperationWorkerGetUpdatedSizes(IPimcTablet pimcTablet) { _pimcTablet = pimcTablet; }
internal WorkerOperationRefreshCursorInfo(IPimcTablet pimcTablet) { _pimcTablet = pimcTablet; }
internal WorkerOperationCreateContext(IntPtr hwnd, IPimcTablet pimcTablet) { _hwnd = hwnd; _pimcTablet = pimcTablet; }
private static StylusDeviceInfo[] GetStylusDevicesInfo(IPimcTablet pimcTablet) { int cCursors; pimcTablet.GetCursorCount(out cCursors); // Calls Unmanaged code - SecurityCritical with SUC. StylusDeviceInfo[] stylusDevicesInfo = new StylusDeviceInfo[cCursors]; for ( int iCursor = 0; iCursor < cCursors; iCursor++ ) { string sCursorName; int cursorId; bool fCursorInverted; pimcTablet.GetCursorInfo(iCursor, out sCursorName, out cursorId, out fCursorInverted); // Calls Unmanaged code - SecurityCritical with SUC. int cButtons; pimcTablet.GetCursorButtonCount(iCursor, out cButtons); // Calls Unmanaged code - SecurityCritical with SUC. StylusButton[] buttons = new StylusButton[cButtons]; for ( int iButton = 0; iButton < cButtons; iButton++ ) { string sButtonName; Guid buttonGuid; pimcTablet.GetCursorButtonInfo(iCursor, iButton, out sButtonName, out buttonGuid); // Calls Unmanaged code - SecurityCritical with SUC. buttons[iButton] = new StylusButton(sButtonName, buttonGuid); } StylusButtonCollection buttonCollection = new StylusButtonCollection(buttons); stylusDevicesInfo[iCursor].CursorName = sCursorName; stylusDevicesInfo[iCursor].CursorId = cursorId; stylusDevicesInfo[iCursor].CursorInverted = fCursorInverted; stylusDevicesInfo[iCursor].ButtonCollection = buttonCollection; } return stylusDevicesInfo; }
private static void InitializeSupportedStylusPointProperties(IPimcTablet pimcTablet, TabletDeviceInfo tabletInfo) { int cProps; int cButtons; int pressureIndex = -1; pimcTablet.GetPacketDescriptionInfo(out cProps, out cButtons); // Calls Unmanaged code - SecurityCritical with SUC. List<StylusPointProperty> properties = new List<StylusPointProperty>(cProps + cButtons + 3); for ( int i = 0; i < cProps; i++ ) { Guid guid; int min, max; int units; float res; pimcTablet.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; } StylusPointProperty property = new StylusPointProperty(guid, false); properties.Add(property); } for ( int i = 0; i < cButtons; i++ ) { Guid buttonGuid; pimcTablet.GetPacketButtonInfo(i, out buttonGuid); // Calls Unmanaged code - SecurityCritical with SUC. StylusPointProperty buttonProperty = new StylusPointProperty(buttonGuid, true); properties.Add(buttonProperty); } //validate we can never get X, Y at index != 0, 1 Debug.Assert(properties[StylusPointDescription.RequiredXIndex /*0*/].Id == StylusPointPropertyIds.X, "X isn't where we expect it! Fix PenImc to ask for X at index 0"); Debug.Assert(properties[StylusPointDescription.RequiredYIndex /*1*/].Id == StylusPointPropertyIds.Y, "Y isn't where we expect it! Fix PenImc to ask for Y at index 1"); // NOTE: We can't force pressure since touch digitizers may not provide this info. The following assert is bogus. //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 properties.Insert(StylusPointDescription.RequiredPressureIndex /*2*/, System.Windows.Input.StylusPointProperties.NormalPressure); } else { //this device supports pressure tabletInfo.HardwareCapabilities |= TabletHardwareCapabilities.SupportsPressure; } tabletInfo.StylusPointProperties = new ReadOnlyCollection<StylusPointProperty>(properties); tabletInfo.PressureIndex = pressureIndex; }
private static TabletDeviceInfo GetTabletInfoHelper(IPimcTablet pimcTablet) { TabletDeviceInfo tabletInfo = new TabletDeviceInfo(); tabletInfo.PimcTablet = new SecurityCriticalDataClass<IPimcTablet>(pimcTablet); pimcTablet.GetKey(out tabletInfo.Id); pimcTablet.GetName(out tabletInfo.Name); pimcTablet.GetPlugAndPlayId(out tabletInfo.PlugAndPlayId); int iTabletWidth, iTabletHeight, iDisplayWidth, iDisplayHeight; pimcTablet.GetTabletAndDisplaySize(out iTabletWidth, out iTabletHeight, out iDisplayWidth, out iDisplayHeight); tabletInfo.SizeInfo = new TabletDeviceSizeInfo(new Size(iTabletWidth, iTabletHeight), new Size(iDisplayWidth, iDisplayHeight)); int caps; pimcTablet.GetHardwareCaps(out caps); tabletInfo.HardwareCapabilities = (TabletHardwareCapabilities)caps; int deviceType; pimcTablet.GetDeviceType(out deviceType); tabletInfo.DeviceType = (TabletDeviceType)(deviceType -1); // NTRAID:WINDOWSOS#1679154-2006/06/09-WAYNEZEN, // REENTRANCY NOTE: Let a PenThread do this work to avoid reentrancy! // The IPimcTablet object is created in the pen thread. If we access it from the UI thread, // COM will set up message pumping which will cause reentrancy here. InitializeSupportedStylusPointProperties(pimcTablet, tabletInfo); tabletInfo.StylusDevicesInfo = GetStylusDevicesInfo(pimcTablet); return tabletInfo; }
internal TabletDeviceSizeInfo WorkerGetUpdatedSizes(IPimcTablet pimcTablet) { return _penThreadWorker.WorkerGetUpdatedSizes(pimcTablet); }
internal StylusDeviceInfo[] WorkerRefreshCursorInfo(IPimcTablet pimcTablet) { return _penThreadWorker.WorkerRefreshCursorInfo(pimcTablet); }
internal PenContextInfo WorkerCreateContext(IntPtr hwnd, IPimcTablet pimcTablet) { return _penThreadWorker.WorkerCreateContext(hwnd, pimcTablet); }