1 /**
2     Derelict binding of WinTab (Wacom Tablet) API.
3 */
4 module derelict.wintab.wintab;
5 
6 version (Windows):
7 
8 import core.sys.windows.windows;
9 
10 private {
11     import derelict.util.loader;
12     import derelict.util.system;
13     import derelict.util.exception;
14 
15     static if(Derelict_OS_Windows)
16         enum libNames = "wintab32.dll";
17     else
18         static assert(0, "Wintab is supported only on Windows platform.");
19 }
20 
21 alias FIX32 = uint;
22 alias WTPKT = uint;
23 alias HCTX = void *;
24 alias HMGR = void *;
25 
26 enum : ushort {
27     WT_PACKET = 0x7FF0,
28     WT_CTXOPEN,
29     WT_CTXCLOSE,
30     WT_CTXUPDATE,
31     WT_CTXOVERLAP,
32     WT_PROXIMITY,
33     WT_INFOCHANGE,
34     WT_CSRCHANGE,
35     WT_PACKETEXT,
36     WT_MAX,
37 }
38 
39 
40 struct AXIS {
41     int axMin;
42     int axMax;
43     uint    axUnits;
44     FIX32   axResolution;
45 }
46 
47 enum WTI_INTERFACE		= 1;
48 
49 enum {
50     IFC_WINTABID			=1,
51     IFC_SPECVERSION		=2,
52     IFC_IMPLVERSION		=3,
53     IFC_NDEVICES			=4,
54     IFC_NCURSORS			=5,
55     IFC_NCONTEXTS		=6,
56     IFC_CTXOPTIONS		=7,
57     IFC_CTXSAVESIZE		=8,
58     IFC_NEXTENSIONS		=9,
59     IFC_NMANAGERS		=10,
60     IFC_MAX				=10,
61 }
62 
63 enum WTI_DEVICES = 100;
64 enum {
65     DVC_NAME = 1,
66     DVC_HARDWARE = 2,
67     DVC_NCSRTYPES = 3,
68     DVC_FIRSTCSR = 4,
69     DVC_PKTRATE = 5,
70     DVC_PKTDATA = 6,
71     DVC_PKTMODE = 7,
72     DVC_CSRDATA = 8,
73     DVC_XMARGIN = 9,
74     DVC_YMARGIN = 10,
75     DVC_ZMARGIN = 11,
76     DVC_X = 12,
77     DVC_Y = 13,
78     DVC_Z = 14,
79     DVC_NPRESSURE = 15,
80     DVC_TPRESSURE = 16,
81     DVC_ORIENTATION = 17,
82     DVC_ROTATION = 18, /* 1.1 */
83     DVC_PNPID = 19, /* 1.1 */
84     DVC_MAX = 19,
85 }
86 
87 enum WTI_DEFCONTEXT	= 3;
88 enum WTI_DEFSYSCTX	= 4;
89 enum WTI_DDCTXS		=400; /* 1.1 */
90 enum WTI_DSCTXS		=500; /* 1.1 */
91 enum {
92     CTX_NAME			=1,
93     CTX_OPTIONS		=2,
94     CTX_STATUS		=3,
95     CTX_LOCKS			=4,
96     CTX_MSGBASE		=5,
97     CTX_DEVICE		=6,
98     CTX_PKTRATE		=7,
99     CTX_PKTDATA		=8,
100     CTX_PKTMODE		=9,
101     CTX_MOVEMASK		=10,
102     CTX_BTNDNMASK	=11,
103     CTX_BTNUPMASK	=12,
104     CTX_INORGX		=13,
105     CTX_INORGY		=14,
106     CTX_INORGZ		=15,
107     CTX_INEXTX		=16,
108     CTX_INEXTY		=17,
109     CTX_INEXTZ		=18,
110     CTX_OUTORGX		=19,
111     CTX_OUTORGY		=20,
112     CTX_OUTORGZ		=21,
113     CTX_OUTEXTX		=22,
114     CTX_OUTEXTY		=23,
115     CTX_OUTEXTZ		=24,
116     CTX_SENSX			=25,
117     CTX_SENSY			=26,
118     CTX_SENSZ			=27,
119     CTX_SYSMODE		=28,
120     CTX_SYSORGX		=29,
121     CTX_SYSORGY		=30,
122     CTX_SYSEXTX		=31,
123     CTX_SYSEXTY		=32,
124     CTX_SYSSENSX		=33,
125     CTX_SYSSENSY		=34,
126     CTX_MAX			=34,
127 }
128 
129 /* WTPKT bits */
130 enum : uint {
131     PK_CONTEXT				=0x0001,	/* reporting context */
132     PK_STATUS					=0x0002,	/* status bits */
133     PK_TIME					=0x0004,	/* time stamp */
134     PK_CHANGED				=0x0008,	/* change bit vector */
135     PK_SERIAL_NUMBER		=0x0010,	/* packet serial number */
136     PK_CURSOR					=0x0020,	/* reporting cursor */
137     PK_BUTTONS				=0x0040,	/* button information */
138     PK_X						=0x0080,	/* x axis */
139     PK_Y						=0x0100,	/* y axis */
140     PK_Z						=0x0200,	/* z axis */
141     PK_NORMAL_PRESSURE		=0x0400,	/* normal or tip pressure */
142     PK_TANGENT_PRESSURE	=0x0800,	/* tangential or barrel pressure */
143     PK_ORIENTATION			=0x1000,	/* orientation info: tilts */
144     PK_ROTATION				=0x2000,	/* rotation info; 1.1 */
145 }
146 
147 immutable uint PK_ALL = PK_CONTEXT | PK_STATUS | PK_TIME | PK_CHANGED
148                     | PK_SERIAL_NUMBER | PK_CURSOR | PK_BUTTONS | PK_X | PK_Y | PK_Z 
149                     | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION | PK_ROTATION;
150 
151 enum LCNAMELEN = 40;
152 struct LOGCONTEXT {
153     /// Contains a zero-terminated context name string.
154 	wchar[LCNAMELEN] lcName; 
155     /**
156         Specifies options for the context. These options can be com­bined by using the bitwise OR operator. 
157         The lcOptions field can be any combination of the values defined in table 7.11. 
158         Specify­ing options that are unsupported in a particular im­plementation will cause WTOpen to fail.
159     */
160 	uint	lcOptions;
161     /**
162         Specifies current status conditions for the context. These condi­tions can be combined by using the bitwise OR opera­tor. 
163         The lcStatus field can be any combination of the values defined in table 7.12.
164     */
165 	uint	lcStatus;
166     /**
167         Specifies which attributes of the context the application wishes to be locked. 
168         Lock conditions specify attributes of the context that cannot be changed once the context has been opened 
169         (calls to WTConfig will have no effect on the locked attributes). 
170         The lock conditions can be combined by using the bitwise OR opera­tor. 
171         The lcLocks field can be any combina­tion of the values de­fined in table 7.13. 
172         Locks can only be changed by the task or process that owns the context.
173     */
174 	uint	lcLocks;
175     /** Specifies the range of message numbers that will be used for re­porting the activity of the context. See the message descrip­tions in section 6.
176     */
177 	uint	lcMsgBase;
178     /** Specifies the device whose input the context processes. */
179 	uint	lcDevice;
180     /** Specifies the desired packet report rate in Hertz. Once the con­text is opened, this field will contain the actual report rate. */
181 	uint	lcPktRate;
182     /** Specifies which optional data items will be in packets re­turned from the context. Requesting unsupported data items will cause WTOpen to fail. */
183 	WTPKT	lcPktData;
184     /** Specifies whether the packet data items will be returned in abso­lute or relative mode. If the item's bit is set in this field, the item will be returned in relative mode. Bits in this field for items not selected in the lcPktData field will be ignored. Bits for data items that only allow one mode (such as the serial number) will also be ignored. */
185 	WTPKT	lcPktMode;
186     /** Specifies which packet data items can generate move events in the context. Bits for items that are not part of the packet def­ini­tion in the lcPktData field will be ignored. The bits for but­tons, time stamp, and the serial number will also be ig­nored. In the case of overlapping contexts, movement events for data items not selected in this field may be processed by underlying con­texts. */
187 	WTPKT	lcMoveMask;
188     /** Specifies the buttons for which button press events will be proc­essed in the context. 
189         In the case of overlapping contexts, button press events for buttons that are not selected in this 
190         field may be processed by underlying contexts. */
191 	uint	lcBtnDnMask;
192     /** Specifies the buttons for which button release events will be processed in the context. 
193         In the case of overlapping contexts, button release events for buttons that are not selected in this field may be processed by underlying contexts.
194         If both press and re­lease events are selected for a button (see the lcBtnDnMask field above), 
195         then the interface will cause the context to implic­itly capture all tablet events while the button is down. In this case, events occurring outside the context will be clipped to the context and processed as if they had occurred in the context. When the but­ton is released, 
196         the context will receive the button release event, and then event processing will return to normal. */
197 	uint	lcBtnUpMask;
198     /** Each specifies the origin of the context's input area in the tab­let's native coordinates, along the x, y, and z axes, respec­tively. 
199         Each will be clipped to the tablet native coordinate space when the context is opened or modified. */
200 	int	lcInOrgX;
201 	int	lcInOrgY;
202 	int	lcInOrgZ;
203     /** Each specifies the extent of the context's input area in the tab­let's native coordinates, along the x, y, and z axes, respec­tively. 
204         Each will be clipped to the tablet native coordinate space when the context is opened or modified. */
205 	int	lcInExtX;
206 	int	lcInExtY;
207 	int	lcInExtZ;
208     /** Each specifies the origin of the context's output area in con­text output coordinates, along the x, y, and z axes, respec­tively. 
209         Each is used in coordinate scaling for absolute mode only. */
210 	int	lcOutOrgX;
211 	int	lcOutOrgY;
212 	int	lcOutOrgZ;
213     /** Each specifies the extent of the context's output area in con­text output coordinates, along the x, y, and z axes, respec­tively. 
214         Each is used in coordinate scaling for absolute mode only. */
215 	int	lcOutExtX;
216 	int	lcOutExtY;
217 	int	lcOutExtZ;
218     /** Each specifies the relative-mode sensitivity factor for the x, y, and z axes, respectively. */
219 	FIX32	lcSensX;
220 	FIX32	lcSensY;
221 	FIX32	lcSensZ;
222 	int	lcSysMode; // BOOL
223 	int	lcSysOrgX;
224 	int	lcSysOrgY;
225 	int	lcSysExtX;
226 	int	lcSysExtY;
227 	FIX32	lcSysSensX;
228 	FIX32	lcSysSensY;
229 }
230 
231 /* context option values */
232 enum {
233     CXO_SYSTEM		=0x0001,
234     CXO_PEN			=0x0002,
235     CXO_MESSAGES		=0x0004,
236     CXO_MARGIN		=0x8000,
237     CXO_MGNINSIDE	=0x4000,
238     CXO_CSRMESSAGES	=0x0008, /* 1.1 */
239 }
240 
241 /* context status values */
242 enum {
243     CXS_DISABLED		=0x0001,
244     CXS_OBSCURED		=0x0002,
245     CXS_ONTOP			=0x0004,
246 }
247 
248 /* context lock values */
249 enum {
250     CXL_INSIZE		=0x0001,
251     CXL_INASPECT		=0x0002,
252     CXL_SENSITIVITY	=0x0004,
253     CXL_MARGIN		=0x0008,
254     CXL_SYSOUT		=0x0010,
255 }
256 
257 /* -------------------------------------------------------------------------- */
258 /* EVENT DATA DEFS */
259 
260 /* For packet structure definition, see pktdef.h */
261 
262 /* packet status values */
263 enum {
264     TPS_PROXIMITY		=0x0001,
265     TPS_QUEUE_ERR		=0x0002,
266     TPS_MARGIN			=0x0004,
267     TPS_GRAB				=0x0008,
268     TPS_INVERT			=0x0010, /* 1.1 */
269 }
270 
271 struct ORIENTATION {
272 	int orAzimuth;
273 	int orAltitude;
274 	int orTwist;
275 }
276 
277 struct ROTATION { /* 1.1 */
278 	int roPitch;
279 	int roRoll;
280 	int roYaw;
281 }
282 
283 /* relative buttons */
284 enum {
285     TBN_NONE	= 0,
286     TBN_UP		=1,
287     TBN_DOWN	=2
288 }
289 
290 /* DEVICE CONFIG CONSTANTS */
291 enum {
292     WTDC_NONE		=0,
293     WTDC_CANCEL		=1,
294     WTDC_OK			=2,
295     WTDC_RESTART	=3,
296 }
297 
298 
299 /**
300    PACKET struct template. Pass PK_XXX bit mask to select which fields to instantiate.
301 */
302 struct PACKET (uint fields = PK_ALL) {
303     static immutable uint PACKETDATA = fields;
304     static if (fields & PK_CONTEXT) 
305         HCTX pkContext;
306     static if (fields & PK_STATUS) 
307         uint        pkStatus;
308     static if (fields & PK_TIME) 
309         int         pkTime;
310     static if (fields & PK_CHANGED) 
311         WTPKT       pkChanged;
312     static if (fields & PK_SERIAL_NUMBER) 
313         uint        pkSerialNumber;
314     static if (fields & PK_CURSOR) 
315         uint        pkCursor;
316     static if (fields & PK_BUTTONS) 
317         uint        pkButtons;
318     static if (fields & PK_X)
319         uint        pkX;
320     static if (fields & PK_Y)
321         uint        pkY;
322     static if (fields & PK_Z)
323         uint        pkZ;
324     static if (fields & PK_NORMAL_PRESSURE)
325         uint        pkNormalPressure;
326     static if (fields & PK_TANGENT_PRESSURE)
327         uint        pkTangentPressure;
328     static if (fields & PK_ORIENTATION)
329         ORIENTATION pkOrientation;
330     static if (fields & PK_ROTATION)
331         ROTATION    pkRotation;  /* 1.1 */
332 }
333 
334 extern(Windows) @nogc nothrow {
335     /** This function returns global information about the interface in an application-sup­plied buffer. 
336        Different types of information are specified by different index argu­ments. Applications use this function to receive information about tablet coordi­nates, physical dimensions, capabilities, and cursor types.
337        Parameters:
338             wCategory : UINT  Identifies the category from which information is being re­quested.
339             nIndex : UINT  Identifies which information is being requested from within the category.
340             lpOutput : LPVOID  Points to a buffer to hold the requested information. 
341        Returns:
342             The return value specifies the size of the returned information in bytes. 
343             If the infor­mation is not supported, the function returns zero. If a tablet is not physi­cally pres­ent, this function always returns zero.
344     */
345     alias da_WTInfo = uint function(uint wCategory, uint  nIndex, void* lpOutput);
346     alias da_WTOpen = HCTX function (HWND hWnd, LOGCONTEXT * lpLogCtx, BOOL fEnable);
347     alias da_WTGet = int function (HCTX hCtx, LOGCONTEXT * lpLogCtx);
348     alias da_WTSet = int function (HCTX, LOGCONTEXT * lpLogCtx);
349     alias da_WTClose = int function (HCTX hCtx);
350     alias da_WTEnable = int function (HCTX hCtx, BOOL fEnable);
351     alias da_WTPacket = int function (HCTX hCtx, uint wSerial, void * lpPkt);
352     alias da_WTOverlap = int function (HCTX hCtx, BOOL fToTop);
353     alias da_WTSave = int function (HCTX hCtx, void * );
354     alias da_WTConfig = int function (HCTX hCtx, HWND hWnd);
355     alias da_WTRestore = HCTX function (HWND hWnd, void *, int );
356     alias da_WTExtSet = int function (HCTX hCtx, uint, void * );
357     alias da_WTExtGet = int function (HCTX hCtx, uint, void * );
358     alias da_WTQueueSizeSet = int function (HCTX hCtx, int );
359     alias da_WTDataPeek =  int function (HCTX hCtx, uint, uint, int, void *, int*);
360     alias da_WTPacketsGet = int function (HCTX hCtx, int, void *);
361     alias da_WTMgrOpen = HMGR function (HWND hWnd, uint );
362     alias da_WTMgrClose = int function (HMGR hMgr);
363     alias da_WTMgrDefContext = HCTX function (HMGR hMgr, int );
364     alias da_WTMgrDefContextEx = HCTX function (HMGR hMgr, uint, int );
365 }
366 
367 __gshared {
368     da_WTInfo WTInfo;
369     da_WTOpen WTOpen;
370     da_WTGet WTGet;
371     da_WTSet WTSet;
372     da_WTClose WTClose;
373     da_WTEnable WTEnable;
374     da_WTPacket WTPacket;
375     da_WTOverlap WTOverlap;
376     da_WTSave WTSave;
377     da_WTConfig WTConfig;
378     da_WTRestore WTRestore;
379     da_WTExtSet WTExtSet;
380     da_WTExtGet WTExtGet;
381     da_WTQueueSizeSet WTQueueSizeSet;
382     da_WTDataPeek WTDataPeek;
383     da_WTPacketsGet WTPacketsGet;
384     da_WTMgrOpen WTMgrOpen;
385     da_WTMgrClose WTMgrClose;
386     da_WTMgrDefContext WTMgrDefContext;
387     da_WTMgrDefContextEx WTMgrDefContextEx;
388 }
389 
390 class DerelictWintabLoader : SharedLibLoader {
391     public this() {
392         super(libNames);
393     }
394 
395     protected override void loadSymbols()
396     {
397         bindFunc(cast(void**)&WTInfo, "WTInfoW");
398         bindFunc(cast(void**)&WTOpen, "WTOpenW");
399         bindFunc(cast(void**)&WTGet, "WTGetW");
400         bindFunc(cast(void**)&WTSet, "WTSetW");
401         bindFunc(cast(void**)&WTClose, "WTClose");
402         bindFunc(cast(void**)&WTEnable, "WTEnable");
403         bindFunc(cast(void**)&WTPacket, "WTPacket");
404         bindFunc(cast(void**)&WTOverlap, "WTOverlap");
405         bindFunc(cast(void**)&WTSave, "WTSave");
406         bindFunc(cast(void**)&WTConfig, "WTConfig");
407         bindFunc(cast(void**)&WTRestore, "WTRestore");
408         bindFunc(cast(void**)&WTExtSet, "WTExtSet");
409         bindFunc(cast(void**)&WTExtGet, "WTExtGet");
410         bindFunc(cast(void**)&WTQueueSizeSet, "WTQueueSizeSet");
411         bindFunc(cast(void**)&WTDataPeek, "WTDataPeek");
412         bindFunc(cast(void**)&WTPacketsGet, "WTPacketsGet");
413         bindFunc(cast(void**)&WTMgrOpen, "WTMgrOpen");
414         bindFunc(cast(void**)&WTMgrClose, "WTMgrClose");
415         bindFunc(cast(void**)&WTMgrDefContext, "WTMgrDefContext");
416         bindFunc(cast(void**)&WTMgrDefContextEx, "WTMgrDefContextEx");
417     }
418 }
419 
420 
421 __gshared DerelictWintabLoader DerelictWintab;
422 
423 shared static this() {
424     DerelictWintab = new DerelictWintabLoader();
425 }