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 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)); }
/// <summary> /// Retrieves the latest device information from connected touch devices. /// </summary> internal void Refresh() { try { // Keep track of old tablets so that we can properly log connects/disconnects Dictionary <IntPtr, PointerTabletDevice> oldTablets = _tabletDeviceMap; _tabletDeviceMap = new Dictionary <IntPtr, PointerTabletDevice>(); TabletDevices.Clear(); uint deviceCount = 0; // Pattern is to first get the count, then declare an array of that size // which is then marshaled via the second call with the proper data. IsValid = UnsafeNativeMethods.GetPointerDevices(ref deviceCount, null); if (IsValid) { UnsafeNativeMethods.POINTER_DEVICE_INFO[] deviceInfos = new UnsafeNativeMethods.POINTER_DEVICE_INFO[deviceCount]; IsValid = UnsafeNativeMethods.GetPointerDevices(ref deviceCount, deviceInfos); if (IsValid) { foreach (var deviceInfo in deviceInfos) { // Old PenIMC code gets this id via a straight cast from COM pointer address // into an int32. This does a very similar thing semantically using the pointer // to the tablet from the WM_POINTER stack. While it may have similar issues // (chopping the upper bits, duplicate ids) we don't use this id internally // and have never received complaints about this in the WISP stack. int id = MS.Win32.NativeMethods.IntPtrToInt32(deviceInfo.device); PointerTabletDeviceInfo ptdi = new PointerTabletDeviceInfo(id, deviceInfo); // Don't add a device that fails initialization. This means we will try a refresh // next time around if we receive stylus input and the device is not available. // <see cref="HwndPointerInputProvider.UpdateCurrentTabletAndStylus"> if (ptdi.TryInitialize()) { PointerTabletDevice tablet = new PointerTabletDevice(ptdi); if (!oldTablets.Remove(tablet.Device)) { // We only create a TabletDevice when one is connected (physically or virtually). // As such we have to log when there is no corresponding old tablet being refreshed. StylusTraceLogger.LogDeviceConnect( new StylusTraceLogger.StylusDeviceInfo( tablet.Id, tablet.Name, tablet.ProductId, tablet.TabletHardwareCapabilities, tablet.TabletSize, tablet.ScreenSize, tablet.Type, tablet.StylusDevices.Count)); } _tabletDeviceMap[tablet.Device] = tablet; TabletDevices.Add(tablet.TabletDevice); } } } // Any tablet leftover here was not refreshed from the previous set of tablets // and should be logged as disconnected. foreach (var oldTablet in oldTablets.Values) { StylusTraceLogger.LogDeviceDisconnect(oldTablet.Id); } } } catch (Win32Exception) { IsValid = false; } }