Пример #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 WispStylusDevice UpdateStylusDevices(int stylusId)
        {
            // REENTRANCY NOTE: Use PenThread to talk to wisptis.exe to make sure we are not reentrant!
            //                  PenImc will cache all the stylus device info so we don't have
            //                  any Out of Proc calls to wisptis.exe to get this info.

            StylusDeviceInfo[] stylusDevicesInfo = _penThread.WorkerRefreshCursorInfo(_tabletInfo.PimcTablet.Value);

            int cCursors = stylusDevicesInfo.Length;

            if (cCursors > StylusDevices.Count)
            {
                for (int iCursor = 0; iCursor < cCursors; iCursor++)
                {
                    StylusDeviceInfo stylusDeviceInfo = stylusDevicesInfo[iCursor];

                    // See if we found it.  If so go and create the new StylusDevice and add it.
                    if (stylusDeviceInfo.CursorId == stylusId)
                    {
                        WispStylusDevice newStylusDevice = new WispStylusDevice(
                            this,
                            stylusDeviceInfo.CursorName,
                            stylusDeviceInfo.CursorId,
                            stylusDeviceInfo.CursorInverted,
                            stylusDeviceInfo.ButtonCollection);
                        StylusDevices.AddStylusDevice(iCursor, newStylusDevice);

                        return(newStylusDevice);
                    }
                }
            }

            return(null);  // Nothing to add
        }
Пример #3
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));
        }
Пример #4
0
        internal StylusPlugInCollection TargetPlugInCollection(RawStylusInputReport inputReport)
        {
            // Caller must make call to this routine inside of lock(__rtiLock)!
            StylusPlugInCollection pic = null;

            // We should only be called when not on the application thread!
            System.Diagnostics.Debug.Assert(!inputReport.StylusDevice.CheckAccess());

            WispStylusDevice stylusDevice = inputReport.StylusDevice.As <WispStylusDevice>();

            // We're on the pen thread so can't touch visual tree.  Use capturedPlugIn (if capture on) or cached rects.
            bool elementHasCapture = false;

            pic = stylusDevice.GetCapturedPlugInCollection(ref elementHasCapture);
            int pointLength = inputReport.PenContext.StylusPointDescription.GetInputArrayLengthPerPoint();

            // Make sure that the captured Plugin Collection is still in the list.  CaptureChanges are
            // deferred so there is a window where the stylus device is not updated yet.  This protects us
            // from using a bogus plugin collecton for an element that is in an invalid state.
            if (elementHasCapture && !_plugInCollectionList.Contains(pic))
            {
                elementHasCapture = false;  // force true hittesting to be done!
            }

            if (!elementHasCapture && inputReport.Data != null && inputReport.Data.Length >= pointLength)
            {
                int[] data = inputReport.Data;
                System.Diagnostics.Debug.Assert(data.Length % pointLength == 0);
                Point ptTablet = new Point(data[data.Length - pointLength], data[data.Length - pointLength + 1]);
                // Note: the StylusLogic data inside DeviceUnitsFromMeasurUnits is protected by __rtiLock.
                ptTablet   = ptTablet * stylusDevice.TabletDevice.TabletDeviceImpl.TabletToScreen;
                ptTablet.X = (int)Math.Round(ptTablet.X);                        // Make sure we snap to whole window pixels.
                ptTablet.Y = (int)Math.Round(ptTablet.Y);
                ptTablet   = _stylusLogic.MeasureUnitsFromDeviceUnits(ptTablet); // change to measured units now.

                pic = HittestPlugInCollection(ptTablet);                         // Use cached rectangles for UIElements.
            }
            return(pic);
        }
Пример #5
0
        internal void InvokeStylusPluginCollection(RawStylusInputReport inputReport)
        {
            // Find PenContexts object for this inputReport.
            StylusPlugInCollection pic = null;

            // lock to make sure only one event is processed at a time and no changes to state can
            // be made until we finish routing this event.
            lock (__rtiLock)
            {
                switch (inputReport.Actions)
                {
                case RawStylusActions.Down:
                case RawStylusActions.Move:
                case RawStylusActions.Up:
                    // Figure out current target plugincollection.
                    pic = TargetPlugInCollection(inputReport);
                    break;

                default:
                    return;     // Nothing to do unless one of the above events
                }

                WispStylusDevice stylusDevice = inputReport.StylusDevice.As <WispStylusDevice>();

                StylusPlugInCollection currentPic = stylusDevice.CurrentNonVerifiedTarget;

                // Fire Leave event if we need to.
                if (currentPic != null && currentPic != pic)
                {
                    // Create new RawStylusInput to send
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
                    transformTabletToView.Children.Add(currentPic.ViewToElement);                                                              // Make it relative to the element.
                    transformTabletToView.Freeze();                                                                                            // Must be frozen for multi-threaded access.

                    RawStylusInput tempRawStylusInput = new RawStylusInput(inputReport, transformTabletToView, currentPic);

                    currentPic.FireEnterLeave(false, tempRawStylusInput, false);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                    stylusDevice.CurrentNonVerifiedTarget = null;
                }

                if (pic != null)
                {
                    // NOTE: PenContext info will not change (it gets rebuilt instead so keeping ref is fine)
                    //    The transformTabletToView matrix and plugincollection rects though can change based
                    //    off of layout events which is why we need to lock this.
                    GeneralTransformGroup transformTabletToView = new GeneralTransformGroup();
                    transformTabletToView.Children.Add(new MatrixTransform(_stylusLogic.GetTabletToViewTransform(stylusDevice.TabletDevice))); // this gives matrix in measured units (not device)
                    transformTabletToView.Children.Add(pic.ViewToElement);                                                                     // Make it relative to the element.
                    transformTabletToView.Freeze();                                                                                            // Must be frozen for multi-threaded access.

                    RawStylusInput rawStylusInput = new RawStylusInput(inputReport, transformTabletToView, pic);
                    inputReport.RawStylusInput = rawStylusInput;

                    if (pic != currentPic)
                    {
                        stylusDevice.CurrentNonVerifiedTarget = pic;
                        pic.FireEnterLeave(true, rawStylusInput, false);
                    }

                    // We are on the pen thread, just call directly.
                    pic.FireRawStylusInput(rawStylusInput);

                    // Indicate we've used a stylus plugin
                    _stylusLogic.Statistics.FeaturesUsed |= Tracing.StylusTraceLogger.FeatureFlags.StylusPluginsUsed;
                }
            } // lock(__rtiLock)
        }