/// <summary> /// Return the extension mask for the given tag. /// </summary> /// <param name="tag_I"></param> /// <returns></returns> public static UInt32 GetExtensionMask(EWTXExtensionTag tag_I) { UInt32 extMask = 0; IntPtr buf = WMemUtils.AllocUnmanagedBuf(extMask); try { UInt32 extIndex = FindWTXExtensionIndex(tag_I); // Supported if extIndex != -1 if (extIndex != 0xffffffff) { int size = (int)WNativeMethods.WTInfo( (uint)EWTICategoryIndex.WTI_EXTENSIONS + extIndex, (uint)EWTIExtensionIndex.EXT_MASK, buf); extMask = WMemUtils.MarshalUnmanagedBuf <UInt32>(buf, size); } } catch (Exception ex) { throw new Exception("FAILED GetExtensionMask: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(extMask); }
/// <summary> /// Returns a string containing the name of the selected stylus. /// </summary> /// <param name="index_I">indicates stylus type</param> /// <returns></returns> public static string GetStylusName(EWTICursorNameIndex index_I) { string stylusName = null; IntPtr buf = WMemUtils.AllocUnmanagedBuf(MAX_STRING_SIZE); try { int size = (int)WNativeMethods.WTInfo( (uint)index_I, (uint)EWTICursorsIndex.CSR_NAME, buf); if (size < 1) { throw new Exception("GetStylusName returned empty string."); } // Strip off final null character before marshalling. stylusName = WMemUtils.MarshalUnmanagedString(buf, size - 1); } catch (Exception ex) { throw new Exception("FAILED GetDeviceInfo: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(stylusName); }
/// <summary> /// Returns extension index for given tag, if possible. /// </summary> /// <param name="tag_I">type of extension being searched for</param> /// <returns></returns> private static UInt32 FindWTXExtensionIndex(EWTXExtensionTag tag_I) { UInt32 thisTag = 0; UInt32 extIndex = 0xffffffff; IntPtr buf = WMemUtils.AllocUnmanagedBuf(thisTag); for (Int32 loopIdx = 0, size = -1; size != 0; loopIdx++) { size = (int)WNativeMethods.WTInfo( (uint)EWTICategoryIndex.WTI_EXTENSIONS + (UInt32)loopIdx, (uint)EWTIExtensionIndex.EXT_TAG, buf); if (size > 0) { thisTag = WMemUtils.MarshalUnmanagedBuf <UInt32>(buf, size); if ((EWTXExtensionTag)thisTag == tag_I) { extIndex = (UInt32)loopIdx; break; } } } WMemUtils.FreeUnmanagedBuf(buf); return(extIndex); }
/// <summary> /// Returns one packet of Wintab data from the packet queue. /// </summary> /// <param name="pktID_I">Identifier for the tablet event packet to return.</param> /// <returns>Returns a data packet with non-null context if successful.</returns> public WintabPacket GetDataPacket(UInt32 pktID_I) { WintabPacket packet = new WintabPacket(); try { bool status = false; if (pktID_I == 0) { throw new Exception("GetDataPacket - invalid pktID"); } CheckForValidHCTX("GetDataPacket"); status = WNativeMethods.WTPacket(m_context.HCtx, pktID_I, ref packet); // If fails, make sure context is zero. if (!status) { packet.pkContext = HCTX.Zero; } } catch (Exception ex) { throw new Exception("FAILED GetDataPacket: " + ex.ToString()); } return(packet); }
/// <summary> /// Open a Wintab context to the specified hwnd. /// </summary> /// <param name="hwnd_I">parent window for the context</param> /// <param name="enable_I">true to enable, false to disable</param> /// <returns>Returns non-zero context handle if successful.</returns> public HCTX Open(HWND hwnd_I, bool enable_I) { try { m_hCTX = WNativeMethods.WTOpen(hwnd_I, ref m_logContext, enable_I); } catch (Exception ex) { throw new Exception("FAILED OpenContext: " + ex.ToString()); } return(m_hCTX); }
/// <summary> /// Get packet queue size for this data object's context. /// </summary> /// <returns>Returns a packet queue size in #packets or 0 if fails</returns> public UInt32 GetPacketQueueSize() { UInt32 numPkts = 0; try { CheckForValidHCTX("GetPacketQueueSize"); numPkts = WNativeMethods.WTQueueSizeGet(m_context.HCtx); } catch (Exception ex) { throw new Exception("FAILED GetPacketQueueSize: " + ex.ToString()); } return(numPkts); }
/// <summary> /// Returns TRUE if Wintab service is running and responsive. /// </summary> /// <returns></returns> public static bool IsWintabAvailable() { IntPtr buf = IntPtr.Zero; bool status = false; try { status = (WNativeMethods.WTInfo(0, 0, buf) > 0); } catch (Exception ex) { throw new Exception("FAILED IsWintabAvailable: " + ex.ToString()); } return(status); }
/// <summary> /// Set packet queue size for this data object's context. /// </summary> /// <param name="numPkts_I">desired #packets in queue</param> /// <returns>Returns true if operation successful</returns> public bool SetPacketQueueSize(UInt32 numPkts_I) { bool status = false; try { CheckForValidHCTX("SetPacketQueueSize"); status = WNativeMethods.WTQueueSizeSet(m_context.HCtx, numPkts_I); } catch (Exception ex) { throw new Exception("FAILED SetPacketQueueSize: " + ex.ToString()); } return(status); }
/// <summary> /// Open a Wintab context that will send packet events to a message window. /// </summary> /// <returns>Returns true if successful.</returns> public bool Open() { // Get the handle of the anonymous MessageEvents window. This is a // static (global) object, so there's only one of these at a time. WMessageEvents.Start(); HWND hwnd = WMessageEvents.WindowHandle; try { m_hCTX = WNativeMethods.WTOpen(hwnd, ref m_logContext, true); } catch (Exception ex) { throw new Exception("FAILED OpenContext: " + ex.ToString()); } return(m_hCTX.IsValid); }
/// <summary> /// Helper function to get digitizing or system default context. /// </summary> /// <param name="contextType_I">Use WTI_DEFCONTEXT for digital context or WTI_DEFSYSCTX for system context</param> /// <returns>Returns the default context or null on error.</returns> private static WContext GetDefaultContext(EWTICategoryIndex contextIndex_I) { WContext context = new WContext(); IntPtr buf = WMemUtils.AllocUnmanagedBuf(context.LogContext); try { int size = (int)WNativeMethods.WTInfo((uint)contextIndex_I, 0, buf); context.LogContext = WMemUtils.MarshalUnmanagedBuf <WintabLogContext>(buf, size); } catch (Exception ex) { throw new Exception("FAILED GetDefaultContext: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(context); }
/// <summary> /// Sends a tablet context to the top or bottom of the order of overlapping tablet contexts /// </summary> /// <param name="toTop_I">true = send tablet to top of order</param> /// <returns>Returns true if successsful</returns> public bool SetOverlapOrder(bool toTop_I) { bool status = false; try { if (!m_hCTX.IsValid) { throw new Exception("EnableContext: invalid context"); } status = WNativeMethods.WTOverlap(m_hCTX, toTop_I); } catch (Exception ex) { throw new Exception("FAILED SetContextOverlapOrder: " + ex.ToString()); } return(status); }
/// <summary> /// Enable/disable this Wintab context. /// </summary> /// <param name="enable_I">true = enable</param> /// <returns>Returns true if completed successfully</returns> public bool Enable(bool enable_I) { bool status = false; try { if (!m_hCTX.IsValid) { throw new Exception("EnableContext: invalid context"); } status = WNativeMethods.WTEnable(m_hCTX, enable_I); } catch (Exception ex) { throw new Exception("FAILED EnableContext: " + ex.ToString()); } return(status); }
/// <summary> /// Returns the number of devices connected. /// </summary> /// <returns></returns> public static UInt32 GetNumberOfDevices() { UInt32 numDevices = 0; IntPtr buf = WMemUtils.AllocUnmanagedBuf(numDevices); try { int size = (int)WNativeMethods.WTInfo( (uint)EWTICategoryIndex.WTI_INTERFACE, (uint)EWTIInterfaceIndex.IFC_NDEVICES, buf); numDevices = WMemUtils.MarshalUnmanagedBuf <UInt32>(buf, size); } catch (Exception ex) { throw new Exception("FAILED GetNumberOfDevices: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(numDevices); }
/// <summary> /// Returns whether a stylus is currently connected to the active cursor. /// </summary> /// <returns></returns> public static bool IsStylusActive() { bool isStylusActive = false; IntPtr buf = WMemUtils.AllocUnmanagedBuf(isStylusActive); try { int size = (int)WNativeMethods.WTInfo( (uint)EWTICategoryIndex.WTI_INTERFACE, (uint)EWTIInterfaceIndex.IFC_NDEVICES, buf); isStylusActive = WMemUtils.MarshalUnmanagedBuf <bool>(buf, size); } catch (Exception ex) { throw new Exception("FAILED GetNumberOfDevices: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(isStylusActive); }
/// <summary> /// Returns the default device. If this value is -1, then it also known as a "virtual device". /// </summary> /// <returns></returns> public static Int32 GetDefaultDeviceIndex() { Int32 devIndex = 0; IntPtr buf = WMemUtils.AllocUnmanagedBuf(devIndex); try { int size = (int)WNativeMethods.WTInfo( (uint)EWTICategoryIndex.WTI_DEFCONTEXT, (uint)EWTIContextIndex.CTX_DEVICE, buf); devIndex = WMemUtils.MarshalUnmanagedBuf <Int32>(buf, size); } catch (Exception ex) { throw new Exception("FAILED GetDefaultDeviceIndex: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(devIndex); }
/// <summary> /// Close the context for this object. /// /// </summary> /// <returns>true if context successfully closed</returns> public bool Close() { bool status = false; try { if (!m_hCTX.IsValid) { throw new Exception("CloseContext: invalid context"); } status = WNativeMethods.WTClose(m_hCTX); m_hCTX = HCTX.Zero; m_logContext = new WintabLogContext(); WMessageEvents.Close(); } catch (Exception ex) { throw new Exception("FAILED CloseContext: " + ex.ToString()); } return(status); }
/// <summary> /// Returns the WintabAxis object for specified device and dimension. /// </summary> /// <param name="devIndex_I">Device index (-1 = virtual device)</param> /// <param name="dim_I">Dimension: AXIS_X, AXIS_Y or AXIS_Z</param> /// <returns></returns> public static WintabAxis GetDeviceAxis(Int32 devIndex_I, EAxisDimension dim_I) { WintabAxis axis = new WintabAxis(); IntPtr buf = WMemUtils.AllocUnmanagedBuf(axis); try { int size = (int)WNativeMethods.WTInfo( (uint)(EWTICategoryIndex.WTI_DEVICES + devIndex_I), (uint)dim_I, buf); // If size == 0, then returns a zeroed struct. axis = WMemUtils.MarshalUnmanagedBuf <WintabAxis>(buf, size); } catch (Exception ex) { throw new Exception("FAILED GetDeviceAxis: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(axis); }
/// <summary> /// Return max normal pressure supported by tablet. /// </summary> /// <param name="getNormalPressure_I">TRUE=> normal pressure; /// FALSE=> tangential pressure (not supported on all tablets)</param> /// <returns>maximum pressure value or zero on error</returns> public static Int32 GetMaxPressure(bool getNormalPressure_I = true) { WintabAxis pressureAxis = new WintabAxis(); IntPtr buf = WMemUtils.AllocUnmanagedBuf(pressureAxis); EWTIDevicesIndex devIdx = (getNormalPressure_I ? EWTIDevicesIndex.DVC_NPRESSURE : EWTIDevicesIndex.DVC_TPRESSURE); try { int size = (int)WNativeMethods.WTInfo( (uint)EWTICategoryIndex.WTI_DEVICES, (uint)devIdx, buf); pressureAxis = WMemUtils.MarshalUnmanagedBuf <WintabAxis>(buf, size); } catch (Exception ex) { throw new Exception("FAILED GetMaxPressure: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(pressureAxis.axMax); }
/// <summary> /// Returns a 3-element array describing the tablet's rotation range and resolution capabilities /// </summary> /// <returns></returns> public static WintabAxisArray GetDeviceRotation(out bool rotationSupported_O) { WintabAxisArray axisArray = new WintabAxisArray(); rotationSupported_O = false; IntPtr buf = WMemUtils.AllocUnmanagedBuf(axisArray); try { int size = (int)WNativeMethods.WTInfo( (uint)EWTICategoryIndex.WTI_DEVICES, (uint)EWTIDevicesIndex.DVC_ROTATION, buf); // If size == 0, then returns a zeroed struct. axisArray = WMemUtils.MarshalUnmanagedBuf <WintabAxisArray>(buf, size); rotationSupported_O = (axisArray.array[0].axResolution != 0 && axisArray.array[1].axResolution != 0); } catch (Exception ex) { throw new Exception("FAILED GetDeviceRotation: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(axisArray); }
/// <summary> /// Returns a string containing device name. /// </summary> /// <returns></returns> public static String GetDeviceInfo() { string devInfo = null; IntPtr buf = WMemUtils.AllocUnmanagedBuf(MAX_STRING_SIZE); try { int size = (int)WNativeMethods.WTInfo( (uint)EWTICategoryIndex.WTI_DEVICES, (uint)EWTIDevicesIndex.DVC_NAME, buf); if (size < 1) { throw new Exception("GetDeviceInfo returned empty string."); } // Strip off final null character before marshalling. devInfo = WMemUtils.MarshalUnmanagedString(buf, size - 1); } catch (Exception ex) { throw new Exception("FAILED GetDeviceInfo: " + ex.ToString()); } WMemUtils.FreeUnmanagedBuf(buf); return(devInfo); }
/// <summary> /// Returns an array of Wintab data packets from the packet queue. /// </summary> /// <param name="maxPkts_I">Specifies the maximum number of packets to return.</param> /// <param name="remove_I">If true, returns data packets and removes them from the queue.</param> /// <param name="numPkts_O">Number of packets actually returned.</param> /// <returns>Returns the next maxPkts_I from the list. Note that if remove_I is false, then /// repeated calls will return the same packets. If remove_I is true, then packets will be /// removed and subsequent calls will get different packets (if any).</returns> public WintabPacket[] GetDataPackets(UInt32 maxPkts_I, bool remove_I, ref UInt32 numPkts_O) { WintabPacket[] packets = null; try { CheckForValidHCTX("GetDataPackets"); if (maxPkts_I == 0) { throw new Exception("GetDataPackets - maxPkts_I is zero."); } // Packet array is used whether we're just looking or buying. int size = (int)(maxPkts_I * Marshal.SizeOf(new WintabPacket())); IntPtr buf = WMemUtils.AllocUnmanagedBuf(size); if (remove_I) { // Return data packets and remove packets from queue. numPkts_O = WNativeMethods.WTPacketsGet(m_context.HCtx, maxPkts_I, buf); packets = WMemUtils.MarshalDataPackets(numPkts_O, buf); //System.Diagnostics.Debug.WriteLine("GetDataPackets: numPkts_O: " + numPkts_O); } else { // Return data packets, but leave on queue. (Peek mode) UInt32 pktIDOldest = 0; UInt32 pktIDNewest = 0; // Get oldest and newest packet identifiers in the queue. These will bound the // packets that are actually returned. if (WNativeMethods.WTQueuePacketsEx(m_context.HCtx, ref pktIDOldest, ref pktIDNewest)) { UInt32 pktIDStart = pktIDOldest; UInt32 pktIDEnd = pktIDNewest; if (pktIDStart == 0) { throw new Exception("WTQueuePacketsEx reports zero start packet identifier"); } if (pktIDEnd == 0) { throw new Exception("WTQueuePacketsEx reports zero end packet identifier"); } // Peek up to the max number of packets specified. UInt32 numFoundPkts = WNativeMethods.WTDataPeek(m_context.HCtx, pktIDStart, pktIDEnd, maxPkts_I, buf, ref numPkts_O); System.Diagnostics.Debug.WriteLine("GetDataPackets: WTDataPeek - numFoundPkts: " + numFoundPkts + ", numPkts_O: " + numPkts_O); if (numFoundPkts > 0 && numFoundPkts < numPkts_O) { throw new Exception("WTDataPeek reports more packets returned than actually exist in queue."); } packets = WMemUtils.MarshalDataPackets(numPkts_O, buf); } } } catch (Exception ex) { throw new Exception("FAILED GetPacketDataRange: " + ex.ToString()); } return(packets); }