internal WispTabletDevice(TabletDeviceInfo tabletInfo, PenThread penThread) : base(tabletInfo) { _penThread = penThread; int count = tabletInfo.StylusDevicesInfo.Length; WispStylusDevice[] styluses = new WispStylusDevice[count]; for (int i = 0; i < count; i++) { StylusDeviceInfo cursorInfo = tabletInfo.StylusDevicesInfo[i]; styluses[i] = new WispStylusDevice( this, cursorInfo.CursorName, cursorInfo.CursorId, cursorInfo.CursorInverted, cursorInfo.ButtonCollection); } _stylusDeviceCollection = new StylusDeviceCollection(styluses); // We only create a TabletDevice when one is connected (physically or virtually). // So we can log the connection in the constructor. StylusTraceLogger.LogDeviceConnect( new StylusTraceLogger.StylusDeviceInfo( Id, Name, ProductId, TabletHardwareCapabilities, TabletSize, ScreenSize, _tabletInfo.DeviceType, StylusDevices.Count)); }
internal TabletDevice(TabletDeviceInfo tabletInfo, PenThread penThread) { _tabletInfo = tabletInfo; _penThread = penThread; int count = tabletInfo.StylusDevicesInfo.Length; StylusDevice[] styluses = new StylusDevice[count]; for ( int i = 0; i < count; i++ ) { StylusDeviceInfo cursorInfo = tabletInfo.StylusDevicesInfo[i]; styluses[i] = new StylusDevice( this, cursorInfo.CursorName, cursorInfo.CursorId, cursorInfo.CursorInverted, cursorInfo.ButtonCollection); } _stylusDeviceCollection = new StylusDeviceCollection(styluses); if (_tabletInfo.DeviceType == TabletDeviceType.Touch) { // _multiTouchSystemGestureLogic = new MultiTouchSystemGestureLogic(); } }
internal TabletDevice(TabletDeviceInfo tabletInfo, PenThread penThread) { _tabletInfo = tabletInfo; _penThread = penThread; int count = tabletInfo.StylusDevicesInfo.Length; StylusDevice[] styluses = new StylusDevice[count]; for (int i = 0; i < count; i++) { StylusDeviceInfo cursorInfo = tabletInfo.StylusDevicesInfo[i]; styluses[i] = new StylusDevice( this, cursorInfo.CursorName, cursorInfo.CursorId, cursorInfo.CursorInverted, cursorInfo.ButtonCollection); } _stylusDeviceCollection = new StylusDeviceCollection(styluses); if (_tabletInfo.DeviceType == TabletDeviceType.Touch) { // _multiTouchSystemGestureLogic = new MultiTouchSystemGestureLogic(); } }
protected TabletDeviceBase(TabletDeviceInfo info) { // Generate a wrapper for public use TabletDevice = new TabletDevice(this); _tabletInfo = info; if (_tabletInfo.DeviceType == TabletDeviceType.Touch) { // A touch device requires multi-touch logic _multiTouchSystemGestureLogic = new MultiTouchSystemGestureLogic(); } }
///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// internal WispTabletDevice(TabletDeviceInfo tabletInfo, PenThread penThread) : base(tabletInfo) { _penThread = penThread; // Constructing a WispTabletDevice means we will actually use this tablet for input purposes. // Lock the tablet and underlying WISP tablet at this point. // This is balanced in DisposeOrDeferDisposal. _penThread.WorkerAcquireTabletLocks(tabletInfo.PimcTablet.Value, tabletInfo.WispTabletKey); int count = tabletInfo.StylusDevicesInfo.Length; WispStylusDevice[] styluses = new WispStylusDevice[count]; for (int i = 0; i < count; i++) { StylusDeviceInfo cursorInfo = tabletInfo.StylusDevicesInfo[i]; styluses[i] = new WispStylusDevice( this, cursorInfo.CursorName, cursorInfo.CursorId, cursorInfo.CursorInverted, cursorInfo.ButtonCollection); } _stylusDeviceCollection = new StylusDeviceCollection(styluses); // We only create a TabletDevice when one is connected (physically or virtually). // So we can log the connection in the constructor. StylusTraceLogger.LogDeviceConnect( new StylusTraceLogger.StylusDeviceInfo( Id, Name, ProductId, TabletHardwareCapabilities, TabletSize, ScreenSize, _tabletInfo.DeviceType, StylusDevices.Count)); }
protected override void OnDoWork() { try { // create new collection of tablets MS.Win32.Penimc.IPimcManager pimcManager = MS.Win32.Penimc.UnsafeNativeMethods.PimcManager; MS.Win32.Penimc.IPimcTablet pimcTablet; pimcManager.GetTablet(_index, out pimcTablet); // Set result data and signal we are done. _tabletDeviceInfo = PenThreadWorker.GetTabletInfoHelper(pimcTablet); } catch ( System.Runtime.InteropServices.COMException ) { // result will not be initialized if we fail due to a COM exception. Debug.WriteLine("WorkerOperationGetTabletInfo.OnDoWork failed due to COMException"); // set to uninitialized TabletDeviceInfo struct (all zeros) to signal failure. _tabletDeviceInfo = new TabletDeviceInfo(); } catch ( System.ArgumentException ) { // result will not be initialized if we fail due to an ArgumentException. Debug.WriteLine("WorkerOperationGetTabletInfo.OnDoWork failed due to an ArgumentException"); // set to uninitialized TabletDeviceInfo struct (all zeros) to signal failure. _tabletDeviceInfo = new TabletDeviceInfo(); } catch ( System.UnauthorizedAccessException ) { // result will not be initialized if we fail due to an UnauthorizedAccessException. Debug.WriteLine("WorkerOperationGetTabletInfo.OnDoWork failed due to an UnauthorizedAccessException"); // set to uninitialized TabletDeviceInfo struct (all zeros) to signal failure. _tabletDeviceInfo = new TabletDeviceInfo(); } }
protected override void OnDoWork() { try { // create new collection of tablets MS.Win32.Penimc.IPimcManager pimcManager = MS.Win32.Penimc.UnsafeNativeMethods.PimcManager; uint cTablets; pimcManager.GetTabletCount(out cTablets); TabletDeviceInfo[] tablets = new TabletDeviceInfo[cTablets]; for ( uint iTablet = 0; iTablet < cTablets; iTablet++ ) { MS.Win32.Penimc.IPimcTablet pimcTablet; pimcManager.GetTablet(iTablet, out pimcTablet); tablets[iTablet] = PenThreadWorker.GetTabletInfoHelper(pimcTablet); } // Set result data and signal we are done. _tabletDevicesInfo = tablets; } catch ( System.Runtime.InteropServices.COMException ) { // result will not be initialized if we fail due to a COM exception. Debug.WriteLine("WorkerOperationGetTabletsInfo.OnDoWork failed due to a COMException"); // return no devices found on error. _tabletDevicesInfo = new TabletDeviceInfo[0]; } catch ( System.ArgumentException ) { // result will not be initialized if we fail due to an ArgumentException. Debug.WriteLine("WorkerOperationGetTabletsInfo.OnDoWork failed due to an ArgumentException"); // return no devices found on error. _tabletDevicesInfo = new TabletDeviceInfo[0]; } catch ( System.UnauthorizedAccessException ) { // result will not be initialized if we fail due to an UnauthorizedAccessException. Debug.WriteLine("WorkerOperationGetTabletsInfo.OnDoWork failed due to an UnauthorizedAccessException"); // return no devices found on error. _tabletDevicesInfo = new TabletDeviceInfo[0]; } }
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 bool HandleTabletAdded(uint wisptisIndex, ref uint tabletIndexChanged) { if (_tablets == null) { throw new ObjectDisposedException("TabletDeviceCollection"); } tabletIndexChanged = UInt32.MaxValue; // REENTRANCY NOTE: Let a PenThread do this work to avoid reentrancy! // On return you get the tablet info needed to // create a tablet devices (and stylus device info gets // cached in penimc too which avoids calls to wisptis.exe). // Use existing penthread if we have one otherwise grab an available one. PenThread penThread = _tablets.Length > 0 ? _tablets[0].PenThread : PenThreadPool.GetPenThreadForPenContext(null); TabletDeviceInfo tabletInfo = penThread.WorkerGetTabletInfo(wisptisIndex); // If we failed due to a COM exception on the pen thread then return if (tabletInfo.PimcTablet == null) { return(true); // make sure we rebuild our tablet collection. (return true + MaxValue). } // if mouse tabletdevice then ignore it. if (tabletInfo.DeviceType == (TabletDeviceType)(-1)) { _indexMouseTablet = wisptisIndex; // update index. return(false); // TabletDevices did not change. } // Now see if this is a duplicate add call we want to filter out (ie - already added to tablet collection). uint indexFound = UInt32.MaxValue; for (uint i = 0; i < _tablets.Length; i++) { // If it is the mouse tablet device we want to ignore it. if (_tablets[i].Id == tabletInfo.Id) { indexFound = i; break; } } // We only want to add this if it is not currently in the collection. Wisptis will send // us duplicate adds at times so this is a work around for that issue. uint tabletIndex = UInt32.MaxValue; if (indexFound == UInt32.MaxValue) { tabletIndex = wisptisIndex; if (tabletIndex > _indexMouseTablet) { tabletIndex--; } else { _indexMouseTablet++; } // if index is out of range then ignore it. Return of MaxValue causes a rebuild of the devices. if (tabletIndex <= _tablets.Length) { try { // Add new tablet at end of collection AddTablet(tabletIndex, new TabletDevice(tabletInfo, penThread)); } catch (InvalidOperationException ex) { // This is caused by the Stylus ID not being unique when trying // to register it in the StylusLogic.__stylusDeviceMap. If we // come across a dup then we should rebuild the tablet device collection. // There seems to be an issue in wisptis where different tablet IDs get // duplicate Stylus Ids when installing the VHID test devices. if (ex.Data.Contains("System.Windows.Input.StylusLogic")) { return(true); // trigger the tabletdevices to be rebuilt. } else { throw; // not an expected exception, rethrow it. } } tabletIndexChanged = tabletIndex; return(true); } else { return(true); // bogus index. Return true so that the caller can rebuild the collection. } } else { return(false); // We found this tablet device already. Don't do anything. } }