예제 #1
0
        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));
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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();
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        /////////////////////////////////////////////////////////////////////////

        /////////////////////////////////////////////////////////////////////
        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));
        }
예제 #6
0
            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();
                }
            }
예제 #7
0
            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];
                }
            }
예제 #8
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;
        }
예제 #9
0
        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;
        }
예제 #10
0
        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.
            }
        }