internal void DisposeOrDeferDisposal()
        {
            // Only dispose when no input events are left in the queue
            if (CanDispose)
            {
                // Make sure this device is not the current one.
                if (Tablet.CurrentTabletDevice == this.TabletDevice)
                {
                    StylusLogic.GetCurrentStylusLogicAs <WispLogic>().SelectStylusDevice(null, null, true);
                }

                // A disconnect will be logged in the dispose as WPF will have gotten rid of the tablet.
                StylusTraceLogger.LogDeviceDisconnect(_tabletInfo.Id);

                // DDVSO:174153
                // Force tablets to clean up as soon as they are disposed.  This helps to reduce
                // COM references that might be waiting for RCWs to finalize.
                IPimcTablet tablet = _tabletInfo.PimcTablet?.Value;
                _tabletInfo.PimcTablet = null;

                if (tablet != null)
                {
                    Marshal.ReleaseComObject(tablet);
                }

                StylusDeviceCollection styluses = _stylusDeviceCollection;
                _stylusDeviceCollection = null;

                if (styluses != null)
                {
                    styluses.Dispose();
                }

                _penThread         = null;
                _isDisposalPending = false;
            }
            else
            {
                _isDisposalPending = true;
            }
        }
Beispiel #2
0
 internal TabletDeviceSizeInfo WorkerGetUpdatedSizes(IPimcTablet pimcTablet)
 {
     return(_penThreadWorker.WorkerGetUpdatedSizes(pimcTablet));
 }
Beispiel #3
0
 internal StylusDeviceInfo[] WorkerRefreshCursorInfo(IPimcTablet pimcTablet)
 {
     return(_penThreadWorker.WorkerRefreshCursorInfo(pimcTablet));
 }
Beispiel #4
0
 internal PenContextInfo WorkerCreateContext(IntPtr hwnd, IPimcTablet pimcTablet)
 {
     return(_penThreadWorker.WorkerCreateContext(hwnd, pimcTablet));
 }
Beispiel #5
0
        internal TabletDeviceSizeInfo WorkerGetUpdatedSizes(IPimcTablet pimcTablet)
        {           
            // Set data up for call
            WorkerOperationWorkerGetUpdatedSizes getUpdatedSizes = new WorkerOperationWorkerGetUpdatedSizes(pimcTablet);
            lock(_workerOperationLock)
            {
                _workerOperation.Add(getUpdatedSizes);
            }

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

            // Wait for this work to be completed.
            getUpdatedSizes.DoneEvent.WaitOne();
            getUpdatedSizes.DoneEvent.Close();
            
            return getUpdatedSizes.TabletDeviceSizeInfo;
        }
Beispiel #6
0
        internal StylusDeviceInfo[] WorkerRefreshCursorInfo(IPimcTablet pimcTablet)
        {
            WorkerOperationRefreshCursorInfo refreshCursorInfo = new WorkerOperationRefreshCursorInfo(
                                                                 pimcTablet);
            lock(_workerOperationLock)
            {
                _workerOperation.Add(refreshCursorInfo);
            }

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

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

            return refreshCursorInfo.StylusDevicesInfo;
        }
Beispiel #7
0
        internal PenContextInfo WorkerCreateContext(IntPtr hwnd, IPimcTablet pimcTablet)
        {
            WorkerOperationCreateContext createContextOperation = new WorkerOperationCreateContext(
                                                                    hwnd,
                                                                    pimcTablet);
            lock(_workerOperationLock)
            {
                _workerOperation.Add(createContextOperation);
            }

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

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

            return createContextOperation.Result;
        }
Beispiel #8
0
 internal WorkerOperationWorkerGetUpdatedSizes(IPimcTablet pimcTablet)
 {
     _pimcTablet = pimcTablet;
 }
Beispiel #9
0
 internal WorkerOperationRefreshCursorInfo(IPimcTablet pimcTablet)
 {
     _pimcTablet = pimcTablet;
 }
Beispiel #10
0
 internal WorkerOperationCreateContext(IntPtr hwnd, IPimcTablet pimcTablet)
 {
     _hwnd = hwnd;
     _pimcTablet = pimcTablet;
 }
Beispiel #11
0
        private static StylusDeviceInfo[] GetStylusDevicesInfo(IPimcTablet pimcTablet)
        {
            int cCursors;

            pimcTablet.GetCursorCount(out cCursors); // Calls Unmanaged code - SecurityCritical with SUC.

            StylusDeviceInfo[] stylusDevicesInfo = new StylusDeviceInfo[cCursors];

            for ( int iCursor = 0; iCursor < cCursors; iCursor++ )
            {
                string sCursorName;
                int cursorId;
                bool fCursorInverted;
                pimcTablet.GetCursorInfo(iCursor, out sCursorName, out cursorId, out fCursorInverted); // Calls Unmanaged code - SecurityCritical with SUC.

                int cButtons;

                pimcTablet.GetCursorButtonCount(iCursor, out cButtons); // Calls Unmanaged code - SecurityCritical with SUC.
                StylusButton[] buttons = new StylusButton[cButtons];
                for ( int iButton = 0; iButton < cButtons; iButton++ )
                {
                    string sButtonName;
                    Guid buttonGuid;
                    pimcTablet.GetCursorButtonInfo(iCursor, iButton, out sButtonName, out buttonGuid); // Calls Unmanaged code - SecurityCritical with SUC.
                    buttons[iButton] = new StylusButton(sButtonName, buttonGuid);
                }
                StylusButtonCollection buttonCollection = new StylusButtonCollection(buttons);

                stylusDevicesInfo[iCursor].CursorName = sCursorName;
                stylusDevicesInfo[iCursor].CursorId = cursorId;
                stylusDevicesInfo[iCursor].CursorInverted = fCursorInverted;
                stylusDevicesInfo[iCursor].ButtonCollection = buttonCollection;
            }

            return stylusDevicesInfo;
        }
Beispiel #12
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;
        }
Beispiel #13
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;
        }
Beispiel #14
0
 internal TabletDeviceSizeInfo WorkerGetUpdatedSizes(IPimcTablet pimcTablet)
 { 
     return _penThreadWorker.WorkerGetUpdatedSizes(pimcTablet); 
 }
Beispiel #15
0
 internal StylusDeviceInfo[] WorkerRefreshCursorInfo(IPimcTablet pimcTablet)
 { 
     return _penThreadWorker.WorkerRefreshCursorInfo(pimcTablet);
 } 
Beispiel #16
0
 internal PenContextInfo WorkerCreateContext(IntPtr hwnd, IPimcTablet pimcTablet)
 {
     return _penThreadWorker.WorkerCreateContext(hwnd, pimcTablet); 
 }