Пример #1
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].As <WispTabletDevice>().PenThread :
                                  PenThreadPool.GetPenThreadForPenContext(null);

            // There was an error acquiring a PenThread, return true to force a complete tablet refresh
            if (penThread == null)
            {
                Debug.Assert(false, "Error acquiring PenThread in HandleTabletAdded()");
                return(true);
            }

            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(new WispTabletDevice(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.
            }
        }
Пример #2
0
        void UpdateTabletsImpl()
        {
            // REENTRANCY NOTE: Let a PenThread do this work to avoid reentrancy!
            //                  On return you get entire list of tablet and info needed to
            //                  create all the tablet devices (and stylus device info gets
            //                  cached too in penimc 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].As <WispTabletDevice>().PenThread :
                                  PenThreadPool.GetPenThreadForPenContext(null);

            // There was an error acquiring a PenThread, do no work here.
            if (penThread == null)
            {
                Debug.Assert(false, "Error acquiring PenThread in UpdateTabletsImpl()");
                return;
            }

            TabletDeviceInfo [] tabletdevices = penThread.WorkerGetTabletsInfo();

            // First find out the index of the mouse device (usually the first at index 0)
            uint indexMouseTablet = UInt32.MaxValue;

            for (uint i = 0; i < tabletdevices.Length; i++)
            {
                // See if this is a bogus entry first.
                if (tabletdevices[i].PimcTablet == null)
                {
                    continue;
                }

                // If it is the mouse tablet device we want to ignore it.
                if (tabletdevices[i].DeviceType == (TabletDeviceType)(-1))
                {
                    indexMouseTablet            = i;
                    tabletdevices[i].PimcTablet = null; // ignore this one!
                }
            }

            // Now figure out count of valid tablet devices left
            uint count = 0;

            for (uint k = 0; k < tabletdevices.Length; k++)
            {
                if (tabletdevices[k].PimcTablet != null)
                {
                    count++;
                }
            }

            TabletDevice[] tablets = new TabletDevice[count];

            uint tabletsIndex         = 0;
            uint unchangedTabletCount = 0;

            for (uint iTablet = 0; iTablet < tabletdevices.Length; iTablet++)
            {
                if (tabletdevices[iTablet].PimcTablet == null)
                {
                    continue; // Skip looking at this index (mouse and bogus tablets are ignored).
                }

                int id = tabletdevices[iTablet].Id;

                // First see if same index has not changed (typical case)
                if (tabletsIndex < _tablets.Length && _tablets[tabletsIndex] != null && _tablets[tabletsIndex].Id == id)
                {
                    tablets[tabletsIndex]  = _tablets[tabletsIndex];
                    _tablets[tabletsIndex] = null; // clear to ignore on cleanup pass.
                    unchangedTabletCount++;
                }
                else
                {
                    // Look up and see if we have this tabletdevice created already...
                    TabletDevice tablet = null;
                    for (uint i = 0; i < _tablets.Length; i++)
                    {
                        if (_tablets[i] != null && _tablets[i].Id == id)
                        {
                            tablet      = _tablets[i];
                            _tablets[i] = null; // clear it so we don't dispose it.
                            break;
                        }
                    }
                    // Not found so create it.
                    if (tablet == null)
                    {
                        try
                        {
                            tablet = new TabletDevice(new WispTabletDevice(tabletdevices[iTablet], 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 just ignore registering this tablet device.
                            // 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"))
                            {
                                continue; // Just go to next without adding this one.
                            }
                            else
                            {
                                throw; // not an expected exception, rethrow it.
                            }
                        }
                    }
                    tablets[tabletsIndex] = tablet;
                }

                tabletsIndex++;
            }

            if (unchangedTabletCount == _tablets.Length &&
                unchangedTabletCount == tabletsIndex &&
                tabletsIndex == count)
            {
                // Keep the _tablet reference when nothing changes.
                // The reason is that if this method gets called from within
                // CreateContexts while looping on _tablets, it could result in
                // a null ref exception since the original _tablets array has
                // been purged to nulls.
                // NOTE: There is still the case of changing the ref (else case below)
                // when tablet devices actually change. But such a case is rare
                // (if not improbable) from within CreateContexts.
                Array.Copy(tablets, 0, _tablets, 0, count);
                _indexMouseTablet = indexMouseTablet;
            }
            else
            {
                // See if we need to re alloc the array due to invalid tabletdevice being seen.
                if (tabletsIndex != count)
                {
                    TabletDevice[] updatedTablets = new TabletDevice[tabletsIndex];
                    Array.Copy(tablets, 0, updatedTablets, 0, tabletsIndex);
                    tablets = updatedTablets;
                }

                DisposeTablets();            // Clean up any non null TabletDevice entries on old array.
                _tablets          = tablets; // set updated tabletdevice array
                TabletDevices     = new List <TabletDevice>(_tablets);
                _indexMouseTablet = indexMouseTablet;
            }

            // DevDiv:1078091
            // Any deferred tablet should be properly disposed of when applicable and
            // removed from the list of deferred tablets.
            DisposeDeferredTablets();
        }