Example #1
0
        internal RawStylusInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            PenContext penContext,
            RawStylusActions actions,
            int tabletDeviceId,
            int stylusDeviceId,
            int[] data)
            : base(inputSource, InputType.Stylus, mode, timestamp)
        {
            // Validate parameters
            if (!RawStylusActionsHelper.IsValid(actions))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, "actions"));
            }
            if (data == null && actions != RawStylusActions.InRange)
            {
                throw new ArgumentNullException("data");
            }

            _penContext     = new SecurityCriticalDataClass<PenContext>(penContext);
            _actions        = actions;
            _tabletDeviceId = tabletDeviceId;
            _stylusDeviceId = stylusDeviceId;
            _data           = data;
            _isSynchronize  = false;
        }
Example #2
0
        internal PenContext[] CreateContexts(IntPtr hwnd, PenContexts contexts)
        {
            int c = Count + _deferredTablets.Count;

            PenContext[] ctxs = new PenContext[c];

            int i = 0;

            foreach (TabletDevice tablet in _tablets)
            {
                ctxs[i++] = tablet.CreateContext(hwnd, contexts);
            }

            // DevDiv:1078091
            // We need to re-enable contexts for anything that is marked
            // as a pending disposal.  This is so we continue getting any
            // Wisp messages that might be waiting to come over the shared
            // memory channel.
            foreach (TabletDevice tablet in _deferredTablets)
            {
                ctxs[i++] = tablet.CreateContext(hwnd, contexts);
            }

            return(ctxs);
        }
Example #3
0
        /// <summary>
        ///     Constructs an instance of the RawStylusInputReport class.
        /// </summary>
        /// <param name="mode">
        ///     The mode in which the input is being provided.
        /// </param>
        /// <param name="timestamp">
        ///     The time when the input occurred.
        /// </param>
        /// <param name="inputSource">
        ///     The PresentationSource over which the stylus moved.
        /// </param>
        /// <param name="penContext">
        ///     The PenContext.
        /// </param>
        /// <param name="actions">
        ///     The set of actions being reported.
        /// </param>
        /// <param name="tabletDeviceId">
        ///     Tablet device id.
        /// </param>
        /// <param name="stylusDeviceId">
        ///     Stylus device id.
        /// </param>
        /// <param name="data">
        ///     Raw stylus data.
        /// </param>
        internal RawStylusInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            PenContext penContext,
            RawStylusActions actions,
            int tabletDeviceId,
            int stylusDeviceId,
            int[] data)
            : this(mode, timestamp, inputSource, actions, () => { return(penContext.StylusPointDescription); }, tabletDeviceId, stylusDeviceId, data)
        {
            // Validate parameters
            if (!RawStylusActionsHelper.IsValid(actions))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, nameof(actions)));
            }
            if (data == null && actions != RawStylusActions.InRange)
            {
                throw new ArgumentNullException(nameof(data));
            }

            _actions        = actions;
            _data           = data;
            _isSynchronize  = false;
            _tabletDeviceId = tabletDeviceId;
            _stylusDeviceId = stylusDeviceId;
            PenContext      = penContext;
        }
Example #4
0
        /////////////////////////////////////////////////////////////////////////

        internal bool ConsiderInRange(int timestamp)
        {
            if (_contexts != null)
            {
                for (int i = 0; i < _contexts.Length; i++)
                {
                    PenContext context = _contexts[i];

                    // We consider it InRange if we have a queued up context event or
                    // the timestamp - LastInRangeTime <= 500 (seen one in the last 500ms)
                    //  Here's some info on how this works...
                    //      int.MaxValue - int.MinValue = -1 (subtracting any negative # from MaxValue keeps this negative)
                    //      int.MinValue - int.MaxValue = 1 (subtracting any positive # from MinValue keeps this positive)
                    //  So subtracting wrapping values will return proper sign depending on which was earlier.
                    //  We do have the assumption that these values will be relative close in time.  If the
                    //  time wraps we'll say yet but the only harm is that we may defer a mouse move event temporarily
                    //  which won't cause any harm.
                    if (context.QueuedInRangeCount > 0 || (Math.Abs(unchecked (timestamp - context.LastInRangeTime)) <= 500))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Example #5
0
        internal RawStylusInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            PenContext penContext,
            RawStylusActions actions,
            int tabletDeviceId,
            int stylusDeviceId,
            int[] data)
            : base(inputSource, InputType.Stylus, mode, timestamp)
        {
            // Validate parameters
            if (!RawStylusActionsHelper.IsValid(actions))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, "actions"));
            }
            if (data == null && actions != RawStylusActions.InRange)
            {
                throw new ArgumentNullException("data");
            }

            _penContext     = new SecurityCriticalDataClass <PenContext>(penContext);
            _actions        = actions;
            _tabletDeviceId = tabletDeviceId;
            _stylusDeviceId = stylusDeviceId;
            _data           = data;
            _isSynchronize  = false;
        }
        internal RawStylusSystemGestureInputReport(
            InputMode mode,
            int timestamp,
            PresentationSource inputSource,
            PenContext penContext,
            int tabletId,
            int stylusDeviceId,
            SystemGesture systemGesture,
            int gestureX,
            int gestureY,
            int buttonState)
            : base(mode, timestamp, inputSource,
                   penContext, RawStylusActions.SystemGesture,
                   tabletId, stylusDeviceId, new int[] {})
        {
            if (!RawStylusSystemGestureInputReport.IsValidSystemGesture(systemGesture, true, true))
            {
                throw new InvalidEnumArgumentException(SR.Get(SRID.Enum_Invalid, "systemGesture"));
            }

            _id          = systemGesture;
            _gestureX    = gestureX;
            _gestureY    = gestureY;
            _buttonState = buttonState;
        }
Example #7
0
 internal static PenThread GetPenThreadForPenContext(PenContext penContext)
 {
     // Create the threadstatic DynamicRendererThreadManager as needed for calling thread. 
     // It only creates one
     if (_penThreadPool == null) 
     { 
         _penThreadPool = new PenThreadPool();
     } 
     return _penThreadPool.GetPenThreadForPenContextHelper(penContext); // Adds to weak ref list if creating new one.
 }
Example #8
0
 /////////////////////////////////////////////////////////////////////
 /// <summary>
 /// </summary>
 internal static PenThread GetPenThreadForPenContext(PenContext penContext)
 {
     // Create the threadstatic DynamicRendererThreadManager as needed for calling thread.
     // It only creates one
     if (_penThreadPool == null)
     {
         _penThreadPool = new PenThreadPool();
     }
     return(_penThreadPool.GetPenThreadForPenContextHelper(penContext)); // Adds to weak ref list if creating new one.
 }
Example #9
0
        private PenThread GetPenThreadForPenContextHelper(PenContext penContext)
        {
            bool      needCleanup = false;
            PenThread penThread   = null;
            int       i;

            // Scan existing penthreads to see if we have an available slot for context.
            for (i = 0; i < _penThreadWeakRefList.Count; i++)
            {
                PenThread penThreadFound = _penThreadWeakRefList[i].Target as PenThread;

                if (penThreadFound == null)
                {
                    needCleanup = true;
                }
                else
                {
                    // See if we can use this one
                    if (penContext == null || penThreadFound.AddPenContext(penContext))
                    {
                        // We can use this one.
                        penThread = penThreadFound;
                        break;
                    }
                }
            }

            if (needCleanup)
            {
                // prune invalid refs
                for (i = _penThreadWeakRefList.Count - 1; i >= 0; i--)
                {
                    if (_penThreadWeakRefList[i].Target == null)
                    {
                        _penThreadWeakRefList.RemoveAt(i);
                    }
                }
            }

            if (penThread == null)
            {
                penThread = new PenThread();
                // Make sure we add this context to the penthread
                if (penContext != null)
                {
                    penThread.AddPenContext(penContext);
                }
                _penThreadWeakRefList.Add(new WeakReference(penThread));
            }

            return(penThread);
        }
        internal PenContext[] CreateContexts(IntPtr hwnd, PenContexts contexts)
        {
            int c = Count;

            PenContext[] ctxs = new PenContext[c];
            int          i    = 0;

            foreach (TabletDevice tablet in _tablets)
            {
                ctxs[i] = tablet.CreateContext(hwnd, contexts);
                i++;
            }
            return(ctxs);
        }
Example #11
0
 /////////////////////////////////////////////////////////////////////
 /// <summary>
 ///     Constructs an instance of the RawStylusSystemGestureInputReport class.
 /// </summary>
 /// <param name="mode">
 ///     The mode in which the input is being provided.
 /// </param>
 /// <param name="timestamp">
 ///     The time when the input occured.
 /// </param>
 /// <param name="inputSource">
 ///     The PresentationSource over which the stylus moved.
 /// </param>
 /// <param name="penContext">
 ///     PenContext that generated this event.
 /// </param>
 /// <param name="tabletId">
 ///     tablet id.
 /// </param>
 /// <param name="stylusDeviceId">
 ///     Stylus device id.
 /// </param>
 /// <param name="systemGesture">
 ///     System Gesture.
 /// </param>
 /// <param name="gestureX">
 ///     X location of the system gesture (in tablet device coordindates).
 /// </param>
 /// <param name="gestureY">
 ///     Y location of the system gesture (in tablet device coordindates).
 /// </param>
 /// <param name="buttonState">
 ///     Button state info data.
 /// </param>
 internal RawStylusSystemGestureInputReport(
     InputMode mode,
     int timestamp,
     PresentationSource inputSource,
     PenContext penContext,
     int tabletId,
     int stylusDeviceId,
     SystemGesture systemGesture,
     int gestureX,
     int gestureY,
     int buttonState)
     : base(mode, timestamp, inputSource, penContext, RawStylusActions.SystemGesture, tabletId, stylusDeviceId, new int[] { })
 {
     Initialize(systemGesture, gestureX, gestureY, buttonState);
 }
Example #12
0
        /////////////////////////////////////////////////////////////////////////

        internal PenContext GetTabletDeviceIDPenContext(int tabletDeviceId)
        {
            if (_contexts != null)
            {
                for (int i = 0; i < _contexts.Length; i++)
                {
                    PenContext context = _contexts[i];
                    if (context.TabletDeviceId == tabletDeviceId)
                    {
                        return(context);
                    }
                }
            }
            return(null);
        }
Example #13
0
        internal PenContext CreateContext(IntPtr hwnd, PenContexts contexts)
        {
            PenContext penContext;
            bool       supportInRange = (this.TabletHardwareCapabilities & TabletHardwareCapabilities.HardProximity) != 0;
            bool       isIntegrated   = (this.TabletHardwareCapabilities & TabletHardwareCapabilities.Integrated) != 0;

            // Use a PenThread to create a tablet context so we don't cause reentrancy.
            PenContextInfo result = _penThread.WorkerCreateContext(hwnd, _tabletInfo.PimcTablet.Value);

            penContext = new PenContext(result.PimcContext != null ? result.PimcContext.Value : null,
                                        hwnd, contexts,
                                        supportInRange, isIntegrated, result.ContextId,
                                        result.CommHandle != null ? result.CommHandle.Value : IntPtr.Zero,
                                        Id);
            return(penContext);
        }
Example #14
0
        /////////////////////////////////////////////////////////////////////

        void ProcessInput(
            RawStylusActions actions,
            PenContext penContext,
            int tabletDeviceId,
            int stylusPointerId,
            int[] data, int timestamp)
        {
            // (all events but SystemEvent go thru here)
            _stylusLogic.ProcessInput(
                actions,
                penContext,
                tabletDeviceId,
                stylusPointerId,
                data,
                timestamp,
                _inputSource.Value);
        }
Example #15
0
        /////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This method adds the specified pen context index in response
        /// to the WM_TABLET_ADDED notification
        /// </summary>
        internal void AddContext(uint index)
        {
            // We only tear down the old context when PenContexts are enabled without being
            // dispose and we have a valid index. Otherwise, no-op here.
            if (_contexts != null && index <= _contexts.Length && _inputSource.Value.CriticalHandle != IntPtr.Zero)
            {
                PenContext[] ctxs          = new PenContext[_contexts.Length + 1];
                uint         preCopyCount  = index;
                uint         postCopyCount = (uint)_contexts.Length - index;

                Array.Copy(_contexts, 0, ctxs, 0, preCopyCount);
                PenContext newContext = _stylusLogic.TabletDevices[(int)index].As <WispTabletDevice>().CreateContext(_inputSource.Value.CriticalHandle, this);
                ctxs[index] = newContext;
                Array.Copy(_contexts, index, ctxs, index + 1, postCopyCount);
                _contexts = ctxs;
                newContext.Enable();
            }
        }
Example #16
0
        /////////////////////////////////////////////////////////////////////


        internal void OnSystemEvent(PenContext penContext,
                                    int tabletDeviceId,
                                    int stylusPointerId,
                                    int timestamp,
                                    SystemGesture id,
                                    int gestureX,
                                    int gestureY,
                                    int buttonState)
        {
            _stylusLogic.ProcessSystemEvent(penContext,
                                            tabletDeviceId,
                                            stylusPointerId,
                                            timestamp,
                                            id,
                                            gestureX,
                                            gestureY,
                                            buttonState,
                                            _inputSource.Value);
        }
Example #17
0
        /////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This method removes the specified pen context index in response
        /// to the WM_TABLET_REMOVED notification
        /// </summary>
        internal void RemoveContext(uint index)
        {
            // We only tear down the old context when PenContexts are enabled without being
            // dispose and we have a valid index. Otherwise, no-op here.
            if (_contexts != null && index < _contexts.Length)
            {
                PenContext removeCtx = _contexts[index];

                PenContext[] ctxs          = new PenContext[_contexts.Length - 1];
                uint         preCopyCount  = index;
                uint         postCopyCount = (uint)_contexts.Length - index - 1;

                Array.Copy(_contexts, 0, ctxs, 0, preCopyCount);
                Array.Copy(_contexts, index + 1, ctxs, index, postCopyCount);

                removeCtx.Disable(false); // shut down this context.

                _contexts = ctxs;
            }
        }
Example #18
0
        bool DoCacheEvent(int evt, PenContext penContext, int stylusPointerId, int [] data, int timestamp)
        {
            // NOTE: Big assumption is that we always get other events between packets (ie don't get move
            // down position followed by move in up position).  We don't account for that here but it should
            // never happen.
            if (evt == PenEventPackets)
            {
                // If no cache then just cache it.
                if (_cachedMoveData == null)
                {
                    _cachedMovePenContext = penContext;
                    _cachedMoveStylusPointerId = stylusPointerId;
                    _cachedMoveStartTimestamp = timestamp;
                    _cachedMoveData = data;
                    return true;
                }
                else if (_cachedMovePenContext == penContext && stylusPointerId == _cachedMoveStylusPointerId)
                {
                    int sinceBeginning = timestamp - _cachedMoveStartTimestamp;
                    if (timestamp < _cachedMoveStartTimestamp)
                        sinceBeginning = (Int32.MaxValue - _cachedMoveStartTimestamp) + timestamp;

                    if (EventsFrequency > sinceBeginning)
                    {
                        // Add to cache data
                        int[] data0 = _cachedMoveData;
                        _cachedMoveData = new int [data0.Length + data.Length];
                        data0.CopyTo(_cachedMoveData, 0);
                        data.CopyTo(_cachedMoveData, data0.Length);
                        return true;
                    }
                }
            }

            return false;
        }
Example #19
0
        void FlushCache(bool goingOutOfRange)
        {
            // Force any cached move/inairmove data to be flushed if we have any.
            if (_cachedMoveData != null)
            {
                // If we are going out of range and this stylus id is not currently in range
                // then eat these cached events (keeps from going in and out of range quickly)
                if (!goingOutOfRange || _cachedMovePenContext.IsInRange(_cachedMoveStylusPointerId))
                {
                    _cachedMovePenContext.FirePenInRange(_cachedMoveStylusPointerId, _cachedMoveData, _cachedMoveStartTimestamp);
                    _cachedMovePenContext.FirePackets(_cachedMoveStylusPointerId, _cachedMoveData, _cachedMoveStartTimestamp);
                }

                _cachedMoveData = null;
                _cachedMovePenContext = null;
                _cachedMoveStylusPointerId = 0;
            }
        }
Example #20
0
 internal void OnPenOutOfRange(PenContext penContext, int tabletDeviceId, int stylusPointerId, int timestamp)
 {
     ProcessInput(RawStylusActions.OutOfRange, penContext, tabletDeviceId, stylusPointerId, new int[]{}, timestamp);
 }
Example #21
0
 internal PenContext[] CreateContexts(IntPtr hwnd, PenContexts contexts)
 {
     int c = Count;
     PenContext[] ctxs = new PenContext[c];
     int i = 0;
     foreach (TabletDevice tablet in _tablets)
     {
         ctxs[i] = tablet.CreateContext(hwnd, contexts);
         i++;
     }
     return ctxs;
 }
        internal PenContext CreateContext(IntPtr hwnd, PenContexts contexts)
        {
            PenContext penContext;
            bool supportInRange = (this.TabletHardwareCapabilities & TabletHardwareCapabilities.HardProximity) != 0;
            bool isIntegrated = (this.TabletHardwareCapabilities & TabletHardwareCapabilities.Integrated) != 0;

            // Use a PenThread to create a tablet context so we don't cause reentrancy.
            PenContextInfo result = _penThread.WorkerCreateContext(hwnd, _tabletInfo.PimcTablet.Value);

            penContext = new PenContext(result.PimcContext != null ? result.PimcContext.Value : null, 
                                        hwnd, contexts, 
                                        supportInRange, isIntegrated, result.ContextId,
                                        result.CommHandle != null ? result.CommHandle.Value : IntPtr.Zero, 
                                        Id);
            return penContext;
        }
Example #23
0
        /////////////////////////////////////////////////////////////////////

        internal void OnPenOutOfRange(PenContext penContext, int tabletDeviceId, int stylusPointerId, int timestamp)
        {
            ProcessInput(RawStylusActions.OutOfRange, penContext, tabletDeviceId, stylusPointerId, new int[] {}, timestamp);
        }
Example #24
0
 internal bool AddPenContext(PenContext penContext) 
 {
     return _penThreadWorker.WorkerAddPenContext(penContext);
 }
Example #25
0
 internal void OnInAirPackets(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
 {
     ProcessInput(RawStylusActions.InAirMove, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
 }
Example #26
0
 internal bool AddPenContext(PenContext penContext)
 {
     return(_penThreadWorker.WorkerAddPenContext(penContext));
 }
Example #27
0
        internal void AddContext(uint index)
        {
            // We only tear down the old context when PenContexts are enabled without being
            // dispose and we have a valid index. Otherwise, no-op here.
            if (_contexts != null && index <= _contexts.Length && _inputSource.Value.CriticalHandle != IntPtr.Zero)
            {
                PenContext[] ctxs = new PenContext[_contexts.Length + 1];
                uint preCopyCount = index;
                uint postCopyCount = (uint)_contexts.Length - index;

                Array.Copy(_contexts, 0, ctxs, 0, preCopyCount);
                PenContext newContext = _stylusLogic.TabletDevices[(int)index].CreateContext(_inputSource.Value.CriticalHandle, this);
                ctxs[index] = newContext;
                Array.Copy(_contexts, index, ctxs, index+1, postCopyCount);
                _contexts = ctxs;
                newContext.Enable();
            }
        }
Example #28
0
 void ProcessInput(
     RawStylusActions actions,
     PenContext penContext,
     int tabletDeviceId, 
     int stylusPointerId,
     int[] data, int timestamp)
 {
     // (all events but SystemEvent go thru here)
     _stylusLogic.ProcessInput(
                                 actions,
                                 penContext,
                                 tabletDeviceId,
                                 stylusPointerId,
                                 data, 
                                 timestamp,
                                 _inputSource.Value);
 }
Example #29
0
 internal void OnSystemEvent(PenContext penContext, 
                                    int tabletDeviceId, 
                                    int stylusPointerId, 
                                    int timestamp, 
                                    SystemGesture id, 
                                    int gestureX,
                                    int gestureY,
                                    int buttonState)
 {
     _stylusLogic.ProcessSystemEvent(penContext, 
                                      tabletDeviceId,
                                      stylusPointerId, 
                                      timestamp,
                                      id, 
                                      gestureX, 
                                      gestureY,
                                      buttonState, 
                                      _inputSource.Value);
 }
Example #30
0
        internal void FireEvent(PenContext penContext, int evt, int stylusPointerId, int cPackets, int cbPacket, IntPtr pPackets)
        {
            // disposed?
            if (__disposed)
            {
                return;  // Don't process this event if we're in the process of shutting down.
            }

            // marshal the data to our cache
            if (cbPacket % 4 != 0)
            {
                throw new InvalidOperationException(SR.Get(SRID.PenService_InvalidPacketData));
            }

            int cItems = cPackets * (cbPacket / 4);
            int[] data = null;
            if (0 < cItems)
            {
                data = new int [cItems]; // GetDataArray(cItems); // see comment on GetDataArray
                Marshal.Copy(pPackets, data, 0, cItems);
                penContext.CheckForRectMappingChanged(data, cPackets);
            }
            else
            {
                data = null;
            }

            int timestamp = Environment.TickCount;
            
            // Deal with caching packet data.
            if (DoCacheEvent(evt, penContext, stylusPointerId, data, timestamp))
            {
                return;
            }
            else
            {
                FlushCache(false);  // make sure we flush cache if not caching.
            }

            //
            // fire it
            //
            switch (evt)
            {
                case PenEventPenDown:
                    penContext.FirePenInRange(stylusPointerId, data, timestamp);
                    penContext.FirePenDown(stylusPointerId, data, timestamp);
                    break;

                case PenEventPenUp:
                    penContext.FirePenInRange(stylusPointerId, data, timestamp);
                    penContext.FirePenUp(stylusPointerId, data, timestamp);
                    break;

                case PenEventPackets:
                    penContext.FirePenInRange(stylusPointerId, data, timestamp);
                    penContext.FirePackets(stylusPointerId, data, timestamp);
                    break;

                case PenEventPenInRange:
                    // We fire this special event just to give the app thread an early peak at
                    // the inrange to filter out mouse moves before we get our first stylus event.
                    penContext.FirePenInRange(stylusPointerId, null, timestamp);
                    break;

                case PenEventPenOutOfRange:
                    penContext.FirePenOutOfRange(stylusPointerId, timestamp);
                    break;

                case PenEventSystem:
                    penContext.FireSystemGesture(stylusPointerId, timestamp);
                    break;
            }
        }
Example #31
0
 internal bool RemovePenContext(PenContext penContext)
 { 
     return _penThreadWorker.WorkerRemovePenContext(penContext);
 } 
        internal void UpdateInRange(bool inRange, PenContext penContext)
        {
            _fInRange = inRange;

            // Make sure we clean the last _inputSource for down at this time.
            //_inputSourceForDown = null;
            if (inRange)
                _activePenContext = new SecurityCriticalDataClass<PenContext>(penContext);
            else
                _activePenContext = null;
        }
Example #33
0
        /////////////////////////////////////////////////////////////////////

        internal void OnInAirPackets(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
        {
            ProcessInput(RawStylusActions.InAirMove, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
        }
Example #34
0
        internal void ProcessInput(
                            RawStylusActions actions,
                            PenContext penContext, 
                            int tabletDeviceId,
                            int stylusDeviceId, 
                            int[] data, 
                            int timestamp,
                            PresentationSource inputSource) 
        {
            RawStylusInputReport inputReport =
                new RawStylusInputReport(InputMode.Foreground,
                                         timestamp, 
                                         inputSource,
                                         penContext, 
                                         actions, 
                                         tabletDeviceId,
                                         stylusDeviceId, 
                                         data);

            ProcessInputReport(inputReport);
        } 
Example #35
0
 internal WorkerOperationRemoveContext(PenContext penContext, PenThreadWorker penThreadWorker)
 {
     _penContextToRemove = penContext;
     _penThreadWorker = penThreadWorker;
 }
Example #36
0
        internal bool WorkerAddPenContext(PenContext penContext)
        {
            if (__disposed)
            {
                throw new ObjectDisposedException(null, SR.Get(SRID.Penservice_Disposed));
            }

            Debug.Assert(penContext != null);
            
            WorkerOperationAddContext addContextOperation = new WorkerOperationAddContext(penContext, this);

            lock(_workerOperationLock)
            {
                _workerOperation.Add(addContextOperation);
            }

            // Kick thread to do this work.
            MS.Win32.Penimc.UnsafeNativeMethods.RaiseResetEvent(_pimcResetHandle.Value);

            // Wait for this work to be completed.
            addContextOperation.DoneEvent.WaitOne();
            addContextOperation.DoneEvent.Close();

            return addContextOperation.Result;
        }
Example #37
0
        private PenThread GetPenThreadForPenContextHelper(PenContext penContext)
        {
            bool needCleanup = false;
            PenThread penThread = null; 
            int i;
 
            // Scan existing penthreads to see if we have an available slot for context. 
            for (i=0; i < _penThreadWeakRefList.Count; i++)
            { 
                PenThread penThreadFound = _penThreadWeakRefList[i].Target as PenThread;

                if (penThreadFound == null)
                { 
                    needCleanup = true;
                } 
                else 
                {
                    // See if we can use this one 
                    if (penContext == null || penThreadFound.AddPenContext(penContext))
                    {
                        // We can use this one.
                        penThread = penThreadFound; 
                        break;
                    } 
                } 
            }
 
            if (needCleanup)
            {
                // prune invalid refs
                for (i=_penThreadWeakRefList.Count - 1; i >= 0; i--) 
                {
                    if (_penThreadWeakRefList[i].Target == null) 
                    { 
                        _penThreadWeakRefList.RemoveAt(i);
                    } 
                }
            }

            if (penThread == null) 
            {
                penThread = new PenThread(); 
                // Make sure we add this context to the penthread 
                if (penContext != null)
                { 
                    penThread.AddPenContext(penContext);
                }
                _penThreadWeakRefList.Add(new WeakReference(penThread));
            } 

            return penThread; 
        } 
Example #38
0
        internal bool WorkerRemovePenContext(PenContext penContext)
        {
            if (__disposed)
            {
                return true;
            }

            Debug.Assert(penContext != null);
            
            WorkerOperationRemoveContext removeContextOperation = new WorkerOperationRemoveContext(penContext, this);

            lock(_workerOperationLock)
            {
                _workerOperation.Add(removeContextOperation);
            }

            // Kick thread to do this work.
            MS.Win32.Penimc.UnsafeNativeMethods.RaiseResetEvent(_pimcResetHandle.Value);

            // Wait for this work to be completed.
            removeContextOperation.DoneEvent.WaitOne();
            removeContextOperation.DoneEvent.Close();

            return removeContextOperation.Result;
        }
Example #39
0
        internal void RemoveContext(uint index)
        {
            // We only tear down the old context when PenContexts are enabled without being
            // dispose and we have a valid index. Otherwise, no-op here.
            if (_contexts != null && index < _contexts.Length)
            {
                PenContext removeCtx = _contexts[index];

                PenContext[] ctxs = new PenContext[_contexts.Length - 1];
                uint preCopyCount = index;
                uint postCopyCount = (uint)_contexts.Length - index - 1;

                Array.Copy(_contexts, 0, ctxs, 0, preCopyCount);
                Array.Copy(_contexts, index+1, ctxs, index, postCopyCount);

                removeCtx.Disable(false); // shut down this context.

                _contexts = ctxs;
            }
        }
Example #40
0
 internal void OnPenInRange(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
 {
     ProcessInput(RawStylusActions.InRange, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
 }
Example #41
0
        /////////////////////////////////////////////////////////////////////

        internal void OnPenUp(PenContext penContext, int tabletDeviceId, int stylusPointerId, int[] data, int timestamp)
        {
            ProcessInput(RawStylusActions.Up, penContext, tabletDeviceId, stylusPointerId, data, timestamp);
        }
Example #42
0
        internal bool AddPenContext(PenContext penContext)
        {
            List <PenContext> penContextRefs = new List<PenContext>(); // keep them alive while processing!
            int i;
            bool result = false;

            // Now go through and figure out the good entries
            // Need to clean up the list for gc'd references.
            for (i=0; i<_penContexts.Length; i++)
            {
                if (_penContexts[i].IsAlive)
                {
                    PenContext pc = _penContexts[i].Target as PenContext;
                    // We only need to ref if we have a penContext.
                    if (pc != null)
                    {
                        penContextRefs.Add(pc);
                    }
                }
            }

            // Now try again to see if we have room.
            if (penContextRefs.Count < MaxContextPerThread)
            {
                penContextRefs.Add(penContext); // add the new one to our list.

                // Now build up the handle array and PimcContext ref array.
                _pimcContexts = new IPimcContext[penContextRefs.Count];
                _penContexts = new WeakReference[penContextRefs.Count];
                _handles = new IntPtr[penContextRefs.Count];
                
                for (i=0; i < penContextRefs.Count; i++)
                {
                    PenContext pc = penContextRefs[i];
                    // We'd have hole in our array if this ever happened.
                    Debug.Assert(pc != null && pc.CommHandle != IntPtr.Zero);
                    _handles[i] = pc.CommHandle; // Add to array.
                    _pimcContexts[i] = pc._pimcContext.Value;
                    _penContexts[i] = new WeakReference(pc);
                    pc = null;
                }

                result = true;
            }

            // Now clean up old refs and assign new array.
            penContextRefs.Clear(); // Make sure we remove refs!
            penContextRefs = null;

            return result;
        }
Example #43
0
 internal bool RemovePenContext(PenContext penContext)
 {
     return(_penThreadWorker.WorkerRemovePenContext(penContext));
 }
Example #44
0
        internal bool RemovePenContext(PenContext penContext)
        {
            List <PenContext> penContextRefs = new List<PenContext>(); // keep them alive while processing!
            int i;
            bool removed = false;

            // Now go through and figure out the good entries
            // Need to clean up the list for gc'd references.
            for (i=0; i<_penContexts.Length; i++)
            {
                if (_penContexts[i].IsAlive)
                {
                    PenContext pc = _penContexts[i].Target as PenContext;
                    // See if we should keep this PenContext.  
                    // We keep if not GC'd and not the removing one (except if it is 
                    // in range where we need to wait till it goes out of range).
                    if (pc != null && (pc != penContext || pc.IsInRange(0)))
                    {
                        penContextRefs.Add(pc);
                    }
                }
            }

            removed = !penContextRefs.Contains(penContext);

            // Now build up the handle array and PimcContext ref array.
            _pimcContexts = new IPimcContext[penContextRefs.Count];
            _penContexts = new WeakReference[penContextRefs.Count];
            _handles = new IntPtr[penContextRefs.Count];
            
            for (i=0; i < penContextRefs.Count; i++)
            {
                PenContext pc = penContextRefs[i];
                // We'd have hole in our array if this ever happened.
                Debug.Assert(pc != null && pc.CommHandle != IntPtr.Zero);
                _handles[i] = pc.CommHandle; // Add to array.
                _pimcContexts[i] = pc._pimcContext.Value;
                _penContexts[i] = new WeakReference(pc);
                pc = null;
            }

            // Now clean up old refs and assign new array.
            penContextRefs.Clear(); // Make sure we remove refs!
            penContextRefs = null;
            
            return removed;
        }
Example #45
0
        /// <summary>
        /// DevDiv:1192272
        ///
        /// This function has been changed to avoid re-entrancy issues.  Previously, the
        /// PenThread selection depended on calls to AddPenContext in the selection mechanism
        /// or when creating a new PenThread.  Since AddPenContext will wait on operations done
        /// on a PenThread, this would allow re-entrant calls to occur.  These calls had the
        /// potential to generate redundant PenThreads that could cause performance and functional
        /// issues in touch-enabled applications.
        ///
        /// By removing calls to AddPenContext from the selection loops, we can be certain that there is
        /// no re-entrancy possible during this part of the code.  The call to AddPenContext is now done
        /// post thread selection/creation.  While this is still re-entrant, we handle the possible issues
        /// from that case by retrying thread selection for any failed AddPenContext calls, ignoring the
        /// specific thread that failed.  After MAX_PENTHREAD_RETRIES, we exit and log an error.
        /// </summary>
        private PenThread GetPenThreadForPenContextHelper(PenContext penContext)
        {
            // A list of full PenThreads that we should ignore when attempting to select a thread
            // for this context.
            List <PenThread> ignoredThreads = new List <PenThread>();

            PenThread selectedPenThread = null;

            // We have gone over the max retries, something is forcing a huge amount
            // of re-entrancy.  In this case, break the loop and exit even if we might
            // have some issues with missing touch contexts and bad touch behavior.
            while (ignoredThreads.Count < MAX_PENTHREAD_RETRIES)
            {
                // Scan existing penthreads to find one to add the context to
                // We scan back to front to enable list cleanup.
                for (int i = _penThreadWeakRefList.Count - 1; i >= 0; i--)
                {
                    PenThread candidatePenThread = null;

                    // Select a thread if it's a valid WeakReference and we're not ignoring it
                    // Allow selection to happen multiple times so we get the first valid candidate
                    // in forward order.
                    if (_penThreadWeakRefList[i].TryGetTarget(out candidatePenThread) &&
                        !ignoredThreads.Contains(candidatePenThread))
                    {
                        selectedPenThread = candidatePenThread;
                    }
                    // This is an invalid WeakReference and should be removed
                    else if (candidatePenThread == null)
                    {
                        _penThreadWeakRefList.RemoveAt(i);
                    }
                }

                // If no valid thread was found, create a new one and add to the pool
                if (selectedPenThread == null)
                {
                    selectedPenThread = new PenThread();

                    _penThreadWeakRefList.Add(new WeakReference <PenThread>(selectedPenThread));
                }

                // If we have no context or we can successfully add to it, then end with this thread
                if (penContext == null || selectedPenThread.AddPenContext(penContext))
                {
                    break;
                }
                // If the add wasn't successful, this thread is full, so try again and ignore it
                else
                {
                    ignoredThreads.Add(selectedPenThread);

                    selectedPenThread = null;

                    // Log re-entrant calls
                    StylusTraceLogger.LogReentrancy();
                }
            }

            //  If we're here due to max retries, log errors appropriately
            if (selectedPenThread == null)
            {
                StylusTraceLogger.LogReentrancyRetryLimitReached();

                Debug.Assert(false, "Retry limit reached when acquiring PenThread");
            }

            return(selectedPenThread);
        }
Example #46
0
 internal WorkerOperationAddContext(PenContext penContext, PenThreadWorker penThreadWorker)
 {
     _newPenContext = penContext;
     _penThreadWorker = penThreadWorker;
 }
        internal RawStylusSystemGestureInputReport(
            InputMode           mode, 
            int           	    timestamp, 
            PresentationSource  inputSource,
            PenContext          penContext, 
            int                 tabletId,
            int                 stylusDeviceId,
            SystemGesture       systemGesture,
            int                 gestureX, 
            int                 gestureY,
            int                 buttonState) 
            : base( mode, timestamp, inputSource, 
                    penContext, RawStylusActions.SystemGesture,
                    tabletId, stylusDeviceId, new int[] {}) 
        {
            if (!RawStylusSystemGestureInputReport.IsValidSystemGesture(systemGesture, true, true))
            {
                throw new InvalidEnumArgumentException(SR.Get( SRID.Enum_Invalid, "systemGesture")); 
            }
 
            _id             = systemGesture; 
            _gestureX       = gestureX;
            _gestureY       = gestureY; 
            _buttonState    = buttonState;
        }
Example #48
0
        internal void ProcessSystemEvent(PenContext penContext,
                                                  int tabletDeviceId, 
                                                  int stylusDeviceId, 
                                                  int timestamp,
                                                  SystemGesture systemGesture, 
                                                  int gestureX,
                                                  int gestureY,
                                                  int buttonState,
                                                  PresentationSource inputSource) 
        {
            // We only want to process the system events we expose in the public enum 
            // for SystemSystemGesture.  There are a bunch of other system gestures that 
            // can come through.
            if (systemGesture == SystemGesture.Tap || 
                systemGesture == SystemGesture.RightTap ||
                systemGesture == SystemGesture.Drag ||
                systemGesture == SystemGesture.RightDrag ||
                systemGesture == SystemGesture.HoldEnter || 
                systemGesture == SystemGesture.HoldLeave ||
                systemGesture == SystemGesture.HoverEnter || 
                systemGesture == SystemGesture.HoverLeave || 
                systemGesture == SystemGesture.Flick ||
                systemGesture == RawStylusSystemGestureInputReport.InternalSystemGestureDoubleTap || 
                systemGesture == SystemGesture.None)
            {
                Debug.Assert(systemGesture != SystemGesture.None);  // We should ever see this as input.
                RawStylusSystemGestureInputReport inputReport = 
                            new RawStylusSystemGestureInputReport(
                                   InputMode.Foreground, 
                                   timestamp, 
                                   inputSource,
                                   penContext, 
                                   tabletDeviceId,
                                   stylusDeviceId,
                                   systemGesture,
                                   gestureX, // location of system gesture in tablet device coordinates 
                                   gestureY,
                                   buttonState); // flicks passes the flickinfo in this param 
 
                // actions: RawStylusActions.StylusSystemEvent
                ProcessInputReport(inputReport); 
            }
        }