Wintab/PASCAL calling convention

Mike vertex at gmx.at
Tue Mar 11 16:04:55 PDT 2008


On Tue, 11 Mar 2008 22:43:44 +0100, Bill Baxter  
<dnewsgroup at billbaxter.com> wrote:

> What did you say you did about the Pascal calling convention?  Was that  
> you?  Someone explained previously here you have to reverse the order of  
> the arguments or something like that, but I can't find the message.

Yeah, that was me. I've never tried to import the lib, what I've done is  
load wintab32.dll directly and call the functions in there. That works, at  
least in my little exploratory tests. The important thing is this:

wintab.h:

HCTX WTOpenW(HWND, LPLOGCONTEXTW, BOOL);

wintab.d:

extern (Pascal)
{
     alias HCTX function(BOOL, LPLOGCONTEXTW, HWND) WTOpenFunc;
}

Below is what I have tried out, and what seems to work. I still need to  
find out the location of wintab32.dll (should be in the registry) and fill  
in the missing dll functions then it should be ready to build some  
higher-level stuff on top.

---------------------------------------------------------------------------------------

// test to see how tablet support works in D

module tablet;

import std.stdio;
import std.string;
import std.c.windows.windows;

// wintab32 magic numbers

// info categories
enum ETabConsts
{
	WTI_INTERFACE = 1,
		IFC_WINTABID = 1,
		IFC_SPECVERSION = 2,
		IFC_IMPLVERSION = 3,
		IFC_NDEVICES = 4,
		IFC_NCURSORS = 5,
		IFC_NCONTEXTS = 6,
		IFC_CTXOPTIONS = 7,
		IFC_CTXSAVESIZE = 8,
		IFC_NEXTENSIONS = 9,
		IFC_NMANAGERS = 10,
		IFC_MAX = 10,
	
	
	WTI_STATUS = 2,
		STA_CONTEXTS = 1,
		STA_SYSCTXS = 2,
		STA_PKTRATE = 3,
		STA_PKTDATA = 4,
		STA_MANAGERS = 5,
		STA_SYSTEM = 6,
		STA_BUTTONUSE = 7,
		STA_SYSBTNUSE = 8,
		STA_MAX = 8,
	
	WTI_DEFCONTEXT = 3,
	WTI_DEFSYSCTX = 4,
	WTI_DDCTXS = 400,
	WTI_DSCTXS = 500,
		CTX_NAME = 1,
		CTX_OPTIONS = 2,
		CTX_STATUS = 3,
		CTX_LOCKS = 4,
		CTX_MSGBASE = 5,
		CTX_DEVICE = 6,
		CTX_PKTRATE = 7,
		CTX_PKTDATA = 8,
		CTX_PKTMODE = 9,
		CTX_MOVEMASK = 10,
		CTX_BTNDNMASK = 11,
		CTX_BTNUPMASK = 12,
		CTX_INORGX = 13,
		CTX_INORGY = 14,
		CTX_INORGZ = 15,
		CTX_INEXTX = 16,
		CTX_INEXTY = 17,
		CTX_INEXTZ = 18,
		CTX_OUTORGX = 19,
		CTX_OUTORGY = 20,
		CTX_OUTORGZ = 21,
		CTX_OUTEXTX = 22,
		CTX_OUTEXTY = 23,
		CTX_OUTEXTZ = 24,
		CTX_SENSX = 25,
		CTX_SENSY = 26,
		CTX_SENSZ = 27,
		CTX_SYSMODE = 28,
		CTX_SYSORGX = 29,
		CTX_SYSORGY = 30,
		CTX_SYSEXTX = 31,
		CTX_SYSEXTY = 32,
		CTX_SYSSENSX = 33,
		CTX_SYSSENSY = 34,
		CTX_MAX = 34,
	
	WTI_DEVICES = 100,
		DVC_NAME = 1,
		DVC_HARDWARE = 2,
		DVC_NCSRTYPES = 3,
		DVC_FIRSTCSR = 4,
		DVC_PKTRATE = 5,
		DVC_PKTDATA = 6,
		DVC_PKTMODE = 7,
		DVC_CSRDATA = 8,
		DVC_XMARGIN = 9,
		DVC_YMARGIN = 10,
		DVC_ZMARGIN = 11,
		DVC_X = 12,
		DVC_Y = 13,
		DVC_Z = 14,
		DVC_NPRESSURE = 15,
		DVC_TPRESSURE = 16,
		DVC_ORIENTATION = 17,
		DVC_ROTATION = 18,
		DVC_PNPID = 19,
		DVC_MAX = 19,
	
	WTI_CURSORS = 200,
		CSR_NAME = 1,
		CSR_ACTIVE = 2,
		CSR_PKTDATA = 3,
		CSR_BUTTONS = 4,
		CSR_BUTTONBITS = 5,
		CSR_BTNNAMES = 6,
		CSR_BUTTONMAP = 7,
		CSR_SYSBTNMAP = 8,
		CSR_NPBUTTON = 9,
		CSR_NPBTNMARKS = 10,
		CSR_NPRESPONSE = 11,
		CSR_TPBUTTON = 12,
		CSR_TPBTNMARKS = 13,
		CSR_TPRESPONSE = 14,
		CSR_PHYSID = 15,
		CSR_MODE = 16,
		CSR_MINPKTDATA = 17,
		CSR_MINBUTTONS = 18,
		CSR_CAPABILITIES = 19,
		CSR_TYPE = 20,
		CSR_MAX = 20,
	
	WTI_EXTENSIONS = 300,
		EXT_NAME = 1,
		EXT_TAG = 2,
		EXT_MASK = 3,
		EXT_SIZE = 4,
		EXT_AXES = 5,
		EXT_DEFAULT = 6,
		EXT_DEFCONTEXT = 7,
		EXT_DEFSYSCTX = 8,
		EXT_CURSORS = 9 ,
		EXT_MAX = 109,
}

// wintab32.dll function prototypes
// note: define arguments in reverse order for extern(Pascal) to work
extern (Pascal)
{
	typedef UINT function(void *lpOutput, UINT nIndex, UINT wCategory)  
WTInfoFunc;

}

class CTabletTest
{
	public:
		this()
		{
			writef("Checking tablet ... ");
			mLibraryHandle =  
LoadLibraryA(toStringz("C:\\WINDOWS\\system32\\wintab32.dll")); // aargh!
			if (mLibraryHandle is null)
			{
				writefln("not found.");
			}
			else
			{
				try
				{
					UINT temp;
					writefln("found.");
					WTInfo = cast(WTInfoFunc)GetProcAddress(myLibraryHandle,  
toStringz("WTInfoA"));
					temp = WTInfo(&myBuffer, ETabConsts.IFC_WINTABID,  
ETabConsts.WTI_INTERFACE);
					for (UINT i = 0; i < temp - 1; i++)
					{
						writef(cast(char)mBuffer[i]);
					}
					writef(" (spec/impl: ");
					temp = WTInfo(&mBuffer, ETabConsts.IFC_SPECVERSION,  
ETabConsts.WTI_INTERFACE);
					writef(mBuffer[1], ".", mBuffer[0]);
					temp = WTInfo(&mBuffer, ETabConsts.IFC_IMPLVERSION,  
ETabConsts.WTI_INTERFACE);
					writef("/", mBuffer[1], ".", mBuffer[0]);
					writefln(")");
					
					temp = WTInfo(&mBuffer, ETabConsts.IFC_NDEVICES,  
ETabConsts.WTI_INTERFACE);
					writefln("Devices: ", mBufferUINT);
					
				}
				catch (Exception e)
				{
					writefln("Exception while initializing tablet support: ", e.msg);
					FreeLibrary(mLibraryHandle);
				}
			}
		}
		
		~this()
		{
			if (mLibraryHandle !is null) FreeLibrary(mLibraryHandle);
		}
		
	private:
		HMODULE mLibraryHandle = null;
		
		// WTab functions
		WTInfoFunc WTInfo;
		
		// buffer for communicating with wintab32.dll
		union
		{
			UINT mBufferUINT;
			byte[1000] mBuffer;
		}
}



-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/



More information about the Digitalmars-d mailing list