Wacom tablet input script in C#

Hi all,
I’m Miky, I’m looking to write a script to manage input by wacom tablet in unity.
I try to understand and integrate in my unity project the WintabDN exemple that you find here:

I recompile the project in framework 3.5 and integrate the dll in unity. I try to use the TestForm code class in a unity script and so I can see and read input from Wacom, but my problem is that when I try to close the application I cant and I need to force it to close.

I found that the problem could be in the context.Open() function but I can’t figure out how to solve it. could someone please help me.

Thanks a lot Miky.

Here after the class code:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UnityEngine;
using System.Threading;
using System.Windows;

//using Assets.Resource.Plugin;
//using System.Data;

using WintabDN;

namespace Assets.Resource.Scripts
{

public class WacomTabletTest : MonoBehaviour
{
public CWintabContext m_logContext = null;
private CWintabData m_wtData = null;
private UInt32 m_maxPkts = 1; // max num pkts to capture/display at a time

private Int32 m_pkX = 0;
private Int32 m_pkY = 0;
public UInt32 m_pressure = 0;
private UInt32 m_pkTime = 0;
private UInt32 m_pkTimeLast = 0;

// These constants can be used to force Wintab X/Y data to map into a
// a 10000 x 10000 grid, as an example of mapping tablet data to values
// that make sense for your application.
private const Int32 m_TABEXTX = 10000;
private const Int32 m_TABEXTY = 10000;

private bool m_showingTextButton = true;

public WacomTabletTest()
{
//InitializeComponent();

//this.FormClosing += new FormClosingEventHandler(TestForm_FormClosing);
}

///////////////////////////////////////////////////////////////////////
public HCTX HLogContext { get { return m_logContext.HCtx; } }

void OnApplicationQuit()
{
CloseCurrentContext();
//DestroyImmediate(this);
}
///////////////////////////////////////////////////////////////////////
//private void TestForm_FormClosing(System.Object sender, FormClosingEventArgs e)
//{
// CloseCurrentContext();
//}

///////////////////////////////////////////////////////////////////////
private void testButton_Click()
{
// Close whatever context is open.
CloseCurrentContext();

if (m_showingTextButton)
{
// Set up to STOP the next time button is pushed.
m_showingTextButton = false;

// Run the tests
Test_IsWintabAvailable();
Test_GetDeviceInfo();
Test_GetDefaultDigitizingContext();
Test_GetDefaultSystemContext();
Test_GetDefaultDeviceIndex();
Test_GetDeviceAxis();
Test_GetDeviceOrientation();
Test_GetDeviceRotation();
Test_GetNumberOfDevices();
Test_IsStylusActive();
Test_GetStylusName();
Test_GetExtensionMask();
//Test_Context();
//Test_DataPacketQueueSize();
Test_MaxPressure();
Test_GetDataPackets(1);
//Test_QueryDataPackets(); // opens up another form

}
else
{
CloseCurrentContext();
m_showingTextButton = true;
}
}

///////////////////////////////////////////////////////////////////////
private void Test_IsWintabAvailable()
{
if (CWintabInfo.IsWintabAvailable())
{
Debug.Log(“Wintab was found!\n”);
}
else
{
Debug.Log(“Wintab was not found!\nCheck to see if tablet driver service is running.\n”);
}
}

///////////////////////////////////////////////////////////////////////
private void Test_GetDeviceInfo()
{
//Debug.Log("DeviceInfo: " + CWintabInfo.GetDeviceInfo() + “\n”);
string devInfo = CWintabInfo.GetDeviceInfo();
Debug.Log("DeviceInfo: " + devInfo + “\n”);
}

///////////////////////////////////////////////////////////////////////
private void Test_GetDefaultDigitizingContext()
{
CWintabContext context = CWintabInfo.GetDefaultDigitizingContext();

Debug.Log(“Default Digitizing Context:\n”);
Debug.Log(“\tSysOrgX, SysOrgY, SysExtX, SysExtY\t[” +
context.SysOrgX + “,” + context.SysOrgY + “,” +
context.SysExtX + “,” + context.SysExtY + “]\n”);

Debug.Log(“\tInOrgX, InOrgY, InExtX, InExtY\t[” +
context.InOrgX + “,” + context.InOrgY + “,” +
context.InExtX + “,” + context.InExtY + “]\n”);

Debug.Log(“\tOutOrgX, OutOrgY, OutExtX, OutExt\t[” +
context.OutOrgX + “,” + context.OutOrgY + “,” +
context.OutExtX + “,” + context.OutExtY + “]\n”);
}

///////////////////////////////////////////////////////////////////////
private void Test_GetDefaultSystemContext()
{
CWintabContext context = CWintabInfo.GetDefaultSystemContext();

Debug.Log(“Default System Context:\n”);
Debug.Log(“\tSysOrgX, SysOrgY, SysExtX, SysExtY\t[” +
context.SysOrgX + “,” + context.SysOrgY + “,” +
context.SysExtX + “,” + context.SysExtY + “]\n”);

Debug.Log(“\tInOrgX, InOrgY, InExtX, InExtY\t[” +
context.InOrgX + “,” + context.InOrgY + “,” +
context.InExtX + “,” + context.InExtY + “]\n”);

Debug.Log(“\tOutOrgX, OutOrgY, OutExtX, OutExt\t[” +
context.OutOrgX + “,” + context.OutOrgY + “,” +
context.OutExtX + “,” + context.OutExtY + “]\n”);
}

///////////////////////////////////////////////////////////////////////
private void Test_GetDefaultDeviceIndex()
{
Int32 devIndex = CWintabInfo.GetDefaultDeviceIndex();

Debug.Log(“Default device index is: " + devIndex + (devIndex == -1 ? " (virtual device)\n” : “\n”));
}

///////////////////////////////////////////////////////////////////////
private void Test_GetDeviceAxis()
{
WintabAxis axis;

// Get virtual device axis for X, Y and Z.
axis = CWintabInfo.GetDeviceAxis(-1, EAxisDimension.AXIS_X);

Debug.Log(“Device axis X for virtual device:\n”);
Debug.Log("\taxMin, axMax, axUnits, axResolution: " + axis.axMin + “,” + axis.axMax + “,” + axis.axUnits + “,” + axis.axResolution.ToString() + “\n”);

axis = CWintabInfo.GetDeviceAxis(-1, EAxisDimension.AXIS_Y);
Debug.Log(“Device axis Y for virtual device:\n”);
Debug.Log("\taxMin, axMax, axUnits, axResolution: " + axis.axMin + “,” + axis.axMax + “,” + axis.axUnits + “,” + axis.axResolution.ToString() + “\n”);

axis = CWintabInfo.GetDeviceAxis(-1, EAxisDimension.AXIS_Z);
Debug.Log(“Device axis Z for virtual device:\n”);
Debug.Log("\taxMin, axMax, axUnits, axResolution: " + axis.axMin + “,” + axis.axMax + “,” + axis.axUnits + “,” + axis.axResolution.ToString() + “\n”);
}

///////////////////////////////////////////////////////////////////////
private void Test_GetDeviceOrientation()
{
bool tiltSupported = false;
WintabAxisArray axisArray = CWintabInfo.GetDeviceOrientation(out tiltSupported);
Debug.Log(“Device orientation:\n”);
Debug.Log("\ttilt supported for current tablet: " + (tiltSupported ? “YES\n” : “NO\n”));

if (tiltSupported)
{
for (int idx = 0; idx < axisArray.array.Length; idx++)
{
Debug.Log(“\t[” + idx + "] axMin, axMax, axResolution, axUnits: " +
axisArray.array[idx].axMin + “,” +
axisArray.array[idx].axMax + “,” +
axisArray.array[idx].axResolution + “,” +
axisArray.array[idx].axUnits + “\n”);
}
}
}

///////////////////////////////////////////////////////////////////////
private void Test_GetDeviceRotation()
{
bool rotationSupported = false;
WintabAxisArray axisArray = CWintabInfo.GetDeviceRotation(out rotationSupported);
Debug.Log(“Device rotation:\n”);
Debug.Log("\trotation supported for current tablet: " + (rotationSupported ? “YES\n” : “NO\n”));

if (rotationSupported)
{
for (int idx = 0; idx < axisArray.array.Length; idx++)
{
Debug.Log(“\t[” + idx + "] axMin, axMax, axResolution, axUnits: " +
axisArray.array[idx].axMin + “,” +
axisArray.array[idx].axMax + “,” +
axisArray.array[idx].axResolution + “,” +
axisArray.array[idx].axUnits + “\n”);
}
}
}

///////////////////////////////////////////////////////////////////////
private void Test_GetNumberOfDevices()
{
UInt32 numDevices = CWintabInfo.GetNumberOfDevices();
Debug.Log("Number of tablets connected: " + numDevices + “\n”);
}

///////////////////////////////////////////////////////////////////////
private void Test_IsStylusActive()
{
bool isStylusActive = CWintabInfo.IsStylusActive();
Debug.Log("Is stylus active: " + (isStylusActive ? “YES\n” : “NO\n”));
}

///////////////////////////////////////////////////////////////////////
private void Test_GetStylusName()
{
Debug.Log("Stylus name (puck): " + CWintabInfo.GetStylusName(EWTICursorNameIndex.CSR_NAME_PUCK) + “\n”);
Debug.Log("Stylus name (pen): " + CWintabInfo.GetStylusName(EWTICursorNameIndex.CSR_NAME_PRESSURE_STYLUS) + “\n”);
Debug.Log("Stylus name (eraser): " + CWintabInfo.GetStylusName(EWTICursorNameIndex.CSR_NAME_ERASER) + “\n”);
}

///////////////////////////////////////////////////////////////////////
private void Test_GetExtensionMask()
{
Debug.Log(“Extension touchring mask: 0x” + CWintabExtensions.GetWTExtensionMask(EWTXExtensionTag.WTX_TOUCHRING).ToString(“x”) + “\n”);
Debug.Log(“Extension touchstring mask: 0x” + CWintabExtensions.GetWTExtensionMask(EWTXExtensionTag.WTX_TOUCHSTRIP).ToString(“x”) + “\n”);
Debug.Log(“Extension express key mask: 0x” + CWintabExtensions.GetWTExtensionMask(EWTXExtensionTag.WTX_EXPKEYS2).ToString(“x”) + “\n”);
}

///////////////////////////////////////////////////////////////////////
private void Test_Context()
{
bool status = false;
CWintabContext logContext = null;

try
{
logContext = OpenTestDigitizerContext();

if (logContext == null)
{
Debug.Log(“Test_Context: FAILED OpenTestDigitizerContext - bailing out…\n”);
return;
}

status = logContext.Enable(true);
Debug.Log("Context Enable: " + (status ? “PASSED” : “FAILED”) + “\n”);

status = logContext.SetOverlapOrder(false);
Debug.Log("Context SetOverlapOrder to bottom: " + (status ? “PASSED” : “FAILED”) + “\n”);
status = logContext.SetOverlapOrder(true);
Debug.Log("Context SetOverlapOrder to top: " + (status ? “PASSED” : “FAILED”) + “\n”);

Debug.Log(“Modified Context:\n”);
Debug.Log(" Name: " + logContext.Name + “\n”);
Debug.Log(" Options: " + logContext.Options + “\n”);
Debug.Log(" Status: " + logContext.Status + “\n”);
Debug.Log(" Locks: " + logContext.Locks + “\n”);
Debug.Log(" MsgBase: " + logContext.MsgBase + “\n”);
Debug.Log(" Device: " + logContext.Device + “\n”);
Debug.Log(" PktRate: 0x" + logContext.PktRate.ToString(“x”) + “\n”);
Debug.Log(" PktData: 0x" + ((uint)logContext.PktData).ToString(“x”) + “\n”);
Debug.Log(" PktMode: 0x" + ((uint)logContext.PktMode).ToString(“x”) + “\n”);
Debug.Log(" MoveMask: " + logContext.MoveMask + “\n”);
Debug.Log(" BZtnDnMask: 0x" + logContext.BtnDnMask.ToString(“x”) + “\n”);
Debug.Log(" BtnUpMask: 0x" + logContext.BtnUpMask.ToString(“x”) + “\n”);
Debug.Log(" InOrgX: " + logContext.InOrgX + “\n”);
Debug.Log(" InOrgY: " + logContext.InOrgY + “\n”);
Debug.Log(" InOrgZ: " + logContext.InOrgZ + “\n”);
Debug.Log(" InExtX: " + logContext.InExtX + “\n”);
Debug.Log(" InExtY: " + logContext.InExtY + “\n”);
Debug.Log(" InExtZ: " + logContext.InExtZ + “\n”);
Debug.Log(" OutOrgX: " + logContext.OutOrgX + “\n”);
Debug.Log(" OutOrgY: " + logContext.OutOrgY + “\n”);
Debug.Log(" OutOrgZ: " + logContext.OutOrgZ + “\n”);
Debug.Log(" OutExtX: " + logContext.OutExtX + “\n”);
Debug.Log(" OutExtY: " + logContext.OutExtY + “\n”);
Debug.Log(" OutExtZ: " + logContext.OutExtZ + “\n”);
Debug.Log(" SensX: " + logContext.SensX + “\n”);
Debug.Log(" SensY: " + logContext.SensY + “\n”);
Debug.Log(" SensZ: " + logContext.SensZ + “\n”);
Debug.Log(" SysMode: " + logContext.SysMode + “\n”);
Debug.Log(" SysOrgX: " + logContext.SysOrgX + “\n”);
Debug.Log(" SysOrgY: " + logContext.SysOrgY + “\n”);
Debug.Log(" SysExtX: " + logContext.SysExtX + “\n”);
Debug.Log(" SysExtY: " + logContext.SysExtY + “\n”);
Debug.Log(" SysSensX: " + logContext.SysSensX + “\n”);
Debug.Log(" SysSensY: " + logContext.SysSensY + “\n”);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
finally
{
logContext = null;
if (logContext != null)
{
status = logContext.Close();
Debug.Log("Context Close: " + (status ? “PASSED” : “FAILED”) + “\n”);
logContext = null;
}
}
}

///////////////////////////////////////////////////////////////////////
private CWintabContext OpenTestDigitizerContext(
int width_I = m_TABEXTX, int height_I = m_TABEXTY, bool ctrlSysCursor = true)
{
bool status = false;
CWintabContext logContext = null;

try
{
// Get the default digitizing context.
// Default is to receive data events.
logContext = CWintabInfo.GetDefaultDigitizingContext(ECTXOptionValues.CXO_MESSAGES);

// Set system cursor if caller wants it.
if (ctrlSysCursor)
{
logContext.Options |= (uint)ECTXOptionValues.CXO_SYSTEM;
}

if (logContext == null)
{
Debug.Log(“FAILED to get default digitizing context.\n”);
return null;
}

// Modify the digitizing region.
logContext.Name = “WintabDN Event Data Context”;

// output in a grid of the specified dimensions.
logContext.OutOrgX = logContext.OutOrgY = 0;
logContext.OutExtX = width_I;
logContext.OutExtY = height_I;

// Open the context, which will also tell Wintab to send data packets.
status = logContext.Open();

Debug.Log("Context Open: " + (status ? “PASSED [ctx=” + logContext.HCtx + “]” : “FAILED”) + “\n”);
}
catch (Exception ex)
{
Debug.Log("OpenTestDigitizerContext ERROR: " + ex.ToString());
}

return logContext;
}

///////////////////////////////////////////////////////////////////////
private CWintabContext OpenTestSystemContext(
int width_I = m_TABEXTX, int height_I = m_TABEXTY, bool ctrlSysCursor = true)
{
bool status = false;
CWintabContext logContext = null;

try
{
// Get the default system context.
// Default is to receive data events.
logContext = CWintabInfo.GetDefaultDigitizingContext(ECTXOptionValues.CXO_MESSAGES);

//logContext = CWintabInfo.GetDefaultSystemContext(ECTXOptionValues.CXO_MESSAGES);

// Set system cursor if caller wants it.
if (ctrlSysCursor)
{
logContext.Options |= (uint)ECTXOptionValues.CXO_SYSTEM;
}
else
{
logContext.Options &= ~(uint)ECTXOptionValues.CXO_SYSTEM;
}

if (logContext == null)
{
Debug.Log(“FAILED to get default digitizing context.\n”);
return null;
}

//Modify the digitizing region.
logContext.Name = “WintabDN Event Data Context”;

WintabAxis tabletX = CWintabInfo.GetTabletAxis(EAxisDimension.AXIS_X);
WintabAxis tabletY = CWintabInfo.GetTabletAxis(EAxisDimension.AXIS_Y);

logContext.InOrgX = 0;
logContext.InOrgY = 0;
logContext.InExtX = tabletX.axMax;
logContext.InExtY = tabletY.axMax;

// SetSystemExtents() is (almost) a NO-OP redundant if you opened a system context.
//SetSystemExtents(ref logContext);

// Open the context, which will also tell Wintab to send data packets.
//status = logContext.Open();

Debug.Log("Context Open: " + (status ? “PASSED [ctx=” + logContext.HCtx + “]” : “FAILED”) + “\n”);

}
catch (Exception ex)
{
Debug.Log("OpenTestDigitizerContext ERROR: " + ex.ToString());
}

return logContext;
}

///////////////////////////////////////////////////////////////////////
private void Test_DataPacketQueueSize()
{
bool status = false;
UInt32 numPackets = 0;
CWintabContext logContext = null;

try
{
logContext = OpenTestDigitizerContext();

if (logContext == null)
{
Debug.Log(“Test_DataPacketQueueSize: FAILED OpenTestDigitizerContext - bailing out…\n”);
return;
}

CWintabData wtData = new CWintabData(logContext);
Debug.Log("Creating CWintabData object: " + (wtData != null ? “PASSED” : “FAILED”) + “\n”);
if (wtData == null)
{
throw new Exception(“Could not create CWintabData object.”);
}

numPackets = wtData.GetPacketQueueSize();
Debug.Log("Initial packet queue size: " + numPackets + “\n”);

status = wtData.SetPacketQueueSize(17);
Debug.Log("Setting packet queue size: " + (status ? “PASSED” : “FAILED”) + “\n”);

numPackets = wtData.GetPacketQueueSize();
Debug.Log("Modified packet queue size: " + numPackets + “\n”);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
finally
{
if (logContext != null)
{
status = logContext.Close();
Debug.Log("Context Close: " + (status ? “PASSED” : “FAILED”) + “\n”);
}
}
}

///////////////////////////////////////////////////////////////////////
private void Test_MaxPressure()
{
Debug.Log("Max normal pressure is: " + CWintabInfo.GetMaxPressure() + “\n”);
Debug.Log("Max tangential pressure is: " + CWintabInfo.GetMaxPressure(false) + “\n”);
}

///////////////////////////////////////////////////////////////////////
private void Test_GetDataPackets(UInt32 maxNumPkts_I)
{
// Set up to capture/display maxNumPkts_I packet at a time.
m_maxPkts = maxNumPkts_I;

// Open a context and try to capture pen data.
InitDataCapture();

// Touch pen to the tablet. You should see data appear in the TestForm window.
}

///////////////////////////////////////////////////////////////////////
//private void Test_QueryDataPackets()
//{
// QueryDataForm qdForm = new QueryDataForm();

// qdForm.ShowDialog();

//}

///////////////////////////////////////////////////////////////////////
// Helper functions
//

///////////////////////////////////////////////////////////////////////
private void InitDataCapture(
int ctxWidth_I = m_TABEXTX, int ctxHeight_I = m_TABEXTY, bool ctrlSysCursor_I = true)
{
try
{
// Close context from any previous test.
CloseCurrentContext();

Debug.Log(“Opening context…\n”);

m_logContext = OpenTestSystemContext(ctxWidth_I, ctxHeight_I, ctrlSysCursor_I);

if (m_logContext == null)
{
Debug.Log(“Test_DataPacketQueueSize: FAILED OpenTestSystemContext - bailing out…\n”);
return;
}

// Create a data object and set its WT_PACKET handler.
// m_wtData = new CWintabData(m_logContext);
// m_wtData.SetWTPacketEventHandler(MyWTPacketEventHandler);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
}

///////////////////////////////////////////////////////////////////////
private void CloseCurrentContext()
{
try
{

Debug.Log(“Closing context…\n”);
if (m_logContext != null)
{
//m_logContext.Close();
m_logContext = null;
m_wtData = null;
}

}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
}

///////////////////////////////////////////////////////////////////////
// Sets logContext.Out
//
// Note:
// SystemParameters.VirtualScreenLeft{Top} and SystemParameters.VirtualScreenWidth{Height}
// don’t always give correct answers.
//
// Uncomment the TODO code below that enumerates all system displays
// if you want to customize.
// Else assume the passed-in extents were already set by call to WTInfo,
// in which case we still have to invert the Y extent.
private void SetSystemExtents(ref CWintabContext logContext)
{
//TODO Rectangle rect = new Rectangle(int.MaxValue, int.MaxValue, int.MinValue, int.MinValue);

//TODO foreach (Screen screen in Screen.AllScreens)
//TODO rect = Rectangle.Union(rect, screen.Bounds);

//TODO logContext.OutOrgX = rect.Left;
//TODO logContext.OutOrgY = rect.Top;
//TODO logContext.OutExtX = rect.Width;
//TODO logContext.OutExtY = rect.Height;

// In Wintab, the tablet origin is lower left. Move origin to upper left
// so that it coincides with screen origin.
logContext.OutExtY = -logContext.OutExtY;
}

///////////////////////////////////////////////////////////////////////
///


/// Called when Wintab WT_PACKET events are received.
///

/// The EventMessage object sending the report.
/// eventArgs_I.Message.WParam contains ID of packet containing the data.
public void MyWTPacketEventHandler(System.Object sender_I, MessageReceivedEventArgs eventArgs_I)
{
//System.Diagnostics.Debug.WriteLine(“Received WT_PACKET event”);
if (m_wtData == null)
{
return;
}

try
{
if (m_maxPkts == 1)
{
uint pktID = (uint)eventArgs_I.Message.WParam;
WintabPacket pkt = m_wtData.GetDataPacket((uint)eventArgs_I.Message.LParam, pktID);
//DEPRECATED WintabPacket pkt = m_wtData.GetDataPacket(pktID);

if (pkt.pkContext != 0)
{
m_pkX = pkt.pkX;
m_pkY = pkt.pkY;
m_pressure = pkt.pkNormalPressure;

Debug.Log("SCREEN: pkX: " + pkt.pkX + “, pkY:” + pkt.pkY + ", pressure: " + pkt.pkNormalPressure);

m_pkTime = pkt.pkTime;

//if (m_graphics == null)
//{
// display data mode
Debug.Log(“Received WT_PACKET event[” + pktID + "]: X/Y/P = " +
pkt.pkX + " / " + pkt.pkY + " / " + pkt.pkNormalPressure + “\n”);
//}
//else
//{
// // scribble mode
// int clientWidth = scribblePanel.Width;
// int clientHeight = scribblePanel.Height;

// // m_pkX and m_pkY are in screen (system) coordinates.

// Point clientPoint = scribblePanel.PointToClient(new Point(m_pkX, m_pkY));
// Debug.Log("CLIENT: X: " + clientPoint.X + “, Y:” + clientPoint.Y);

// if (m_lastPoint.Equals(Point.Empty))
// {
// m_lastPoint = clientPoint;
// m_pkTimeLast = m_pkTime;
// }

// m_pen.Width = (float)(m_pressure / 200);

// if (m_pressure > 0)
// {
// if (m_pkTime - m_pkTimeLast < 5)
// {
// m_graphics.DrawRectangle(m_pen, clientPoint.X, clientPoint.Y, 1, 1);
// }
// else
// {
// m_graphics.DrawLine(m_pen, clientPoint, m_lastPoint);
// }
// }

// m_lastPoint = clientPoint;
// m_pkTimeLast = m_pkTime;
//}
}
}
}
catch (Exception ex)
{
throw new Exception("FAILED to get packet data: " + ex.ToString());
}
}

private void testQDPButton_Click(object sender, EventArgs e)
{
//Test_QueryDataPackets();
}

public void ShowIt()
{
Color c = m_showingTextButton == true ? Color.green : Color.white;
GUI.color = c;
// if button pressed
if (GUI.Button(new Rect(10, 10, 250, 60), “Press Here” ))
{
testButton_Click();
}
GUI.Box(new Rect(10, 80, 250, 70), m_pressure.ToString());
}
}
}

Hi Miky!

I’m facing something very similar, it crashes (hangs) when we try to close the context. Did you manage to solve this?

So this seems to be caused by the WinTabDN code using threads. The only thing i’ve managed to do to solve this in a standalone build is to explicitly exit mono threads using the following code in OnApplicationQuit

#if UNITY_STANDALONE_WIN
[DllImport(“mono”, SetLastError=true)]
static extern void mono_thread_exit();
#endif

void OnApplicationQuit()
{
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
mono_thread_exit();
#endif
}

I tried to do integrate the WintabDN demo in Unity, too. I got quite a similar problem. In the editor I can run the example and stop it. But when I click the play button again, the editor hangs and I have to force quit it.

Did anyone have success integrating a Wacom tablet as input?

I’m using Unity 5.3.2f1 personal, Win 8.1 and a Wacom CTL-490DW Intuos Draw

hi, everyone

I try to compile WIntabDN.dll in framwork 3.5

but I get ‘System.IntPtr’ does not contain a definition for ‘Add’ error

Is anyone having this error, too?

Holy code tags, Batman!

3 Likes

Inside MessageEvents.cs

make the variable MessageWindow _window; public
make the class MessageWindow public

than inside the body of the MessageWindow class add this new function:

public void Kill(){
Application.Exit();
}

than inside the WacomTabletTest.cs script add:

void OnApplicationQuit()
{
MessageEvents._window.Kill();
}