[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30376] branches/soc-2010-merwin/ experimental: The beginnings of a safe and useful WinTab wrapper.

Mike Erwin significant.bit at gmail.com
Thu Jul 15 14:34:14 CEST 2010


Revision: 30376
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30376
Author:   merwin
Date:     2010-07-15 14:34:14 +0200 (Thu, 15 Jul 2010)

Log Message:
-----------
The beginnings of a safe and useful WinTab wrapper.

Added Paths:
-----------
    branches/soc-2010-merwin/experimental/WinTablet/
    branches/soc-2010-merwin/experimental/WinTablet/Tablet.cpp
    branches/soc-2010-merwin/experimental/WinTablet/Tablet.h
    branches/soc-2010-merwin/experimental/WinTablet/Utils.c
    branches/soc-2010-merwin/experimental/WinTablet/Utils.h
    branches/soc-2010-merwin/experimental/WinTablet/main.cpp
    branches/soc-2010-merwin/experimental/WinTablet/msgpack.h
    branches/soc-2010-merwin/experimental/WinTablet/pktdef.h
    branches/soc-2010-merwin/experimental/WinTablet/wintab.h

Added: branches/soc-2010-merwin/experimental/WinTablet/Tablet.cpp
===================================================================
--- branches/soc-2010-merwin/experimental/WinTablet/Tablet.cpp	                        (rev 0)
+++ branches/soc-2010-merwin/experimental/WinTablet/Tablet.cpp	2010-07-15 12:34:14 UTC (rev 30376)
@@ -0,0 +1,104 @@
+#include "Tablet.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "wintab.h"
+
+#define PACKETDATA	PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE
+#define PACKETTILT 	PKEXT_ABSOLUTE
+#define PACKETMODE	PK_BUTTONS
+
+#include "pktdef.h"
+
+#define MAX_QUEUE_SIZE 128
+
+	Tablet::Tablet()
+		{
+		// open WinTab
+		lib_Wintab = LoadLibrary("wintab32.dll");
+
+		if (lib_Wintab)
+			{
+			// connect function pointers
+			func_Open = (WTOPENA) GetProcAddress(lib_Wintab,"WTOpenA");
+			func_Info = (WTINFOA) GetProcAddress(lib_Wintab,"WTInfoA");
+			func_QueueSizeSet = (WTQUEUESIZESET) GetProcAddress(lib_Wintab,"WTQueueSizeSet");
+			func_PacketsGet = (WTPACKETSGET) GetProcAddress(lib_Wintab,"WTPacketsGet");
+
+			WORD specV, implV;
+			func_Info(WTI_INTERFACE, IFC_SPECVERSION, &specV);
+			func_Info(WTI_INTERFACE, IFC_IMPLVERSION, &implV);
+			printf("Wintab version %d.%d (%d.%d)\n",
+				HIBYTE(specV), LOBYTE(specV), HIBYTE(implV), LOBYTE(implV));
+//				specV >> 8, specV & 0xff, implV >> 8, implV & 0xff);
+
+			// query for overall capabilities and ranges
+			char tabletName[40];
+			if (func_Info(WTI_DEVICES, DVC_NAME, tabletName))
+				puts(tabletName);
+			
+			AXIS xRange, yRange, pressureRange;
+			func_Info(WTI_DEVICES, DVC_X, &xRange);
+			func_Info(WTI_DEVICES, DVC_Y, &yRange);
+			bool hasPressure = func_Info(WTI_DEVICES, DVC_NPRESSURE, &pressureRange);
+			
+			printf("active area: %dx%d\n", xRange.axMax, yRange.axMax);
+			printf("pressure sensitivity: ");
+			if (hasPressure)
+				{
+				printf("%d to %d\n", pressureRange.axMin, pressureRange.axMax);
+				pressure_scale = 1.f / pressureRange.axMax;
+				}
+			else printf("none\n");
+			}
+		}
+
+	Tablet::~Tablet()
+		{
+		// close WinTab
+		FreeLibrary(lib_Wintab);
+		}
+
+	bool Tablet::available()
+		{
+		return lib_Wintab // driver installed
+			&& func_Info(0,0,NULL); // tablet plugged in
+		}
+
+	HCTX Tablet::openForWindow(HWND window)
+		// instead of returning the context, could remember the window/context mapping.
+		// this class should handle all tablet internals, not push work onto the window.
+		{
+		// set up context
+		LOGCONTEXT archetype;
+		func_Info(WTI_DEFCONTEXT, 0, &archetype);
+
+		strcpy(archetype.lcName, "merwin special");
+		archetype.lcPktData = PACKETDATA;
+		archetype.lcPktMode = PACKETMODE;
+		archetype.lcOptions |= CXO_SYSTEM; // this might already be the default
+
+		// open the context
+		HCTX context = func_Open(window, &archetype, TRUE);
+
+		// request a deep packet queue
+		int tabletQueueSize = MAX_QUEUE_SIZE;
+		while (!func_QueueSizeSet(context, tabletQueueSize))
+			--tabletQueueSize;
+		printf("tablet queue size: %d\n", tabletQueueSize);
+
+		return context;
+		}
+
+	void Tablet::processPackets(HCTX context)
+		{
+		PACKET packets[MAX_QUEUE_SIZE];
+		int n = func_PacketsGet(context, MAX_QUEUE_SIZE, packets);
+		printf("processing %d packets\n", n);
+		for (int i = 0; i < n; ++i)
+			{
+			PACKET const& packet = packets[i];
+			int x = packet.pkX;
+			int y = packet.pkY;
+			int pressure = packet.pkNormalPressure;
+			}
+		}

Added: branches/soc-2010-merwin/experimental/WinTablet/Tablet.h
===================================================================
--- branches/soc-2010-merwin/experimental/WinTablet/Tablet.h	                        (rev 0)
+++ branches/soc-2010-merwin/experimental/WinTablet/Tablet.h	2010-07-15 12:34:14 UTC (rev 30376)
@@ -0,0 +1,43 @@
+// safe & friendly Wintab wrapper
+// by Mike Erwin, July 2010
+
+#ifndef mce_tablet_h
+#define mce_tablet_h
+
+#define _WIN32_WINNT 0x501 // require Windows XP or newer
+#define WIN32_LEAN_AND_MEAN
+#include	<windows.h>
+#include "wintab.h"
+
+// from Wacom's Utils.h
+typedef UINT ( API * WTINFOA ) ( UINT, UINT, LPVOID );
+typedef HCTX ( API * WTOPENA )( HWND, LPLOGCONTEXTA, BOOL );
+typedef BOOL ( API * WTQUEUESIZESET ) ( HCTX, int );
+typedef int  ( API * WTPACKETSGET ) (HCTX, int, LPVOID);
+
+class Tablet
+	{
+	// the Wintab library
+	HINSTANCE lib_Wintab;
+//	HMODULE
+
+	// WinTab function pointers
+	WTOPENA func_Open;
+	WTINFOA func_Info;
+	WTQUEUESIZESET func_QueueSizeSet;
+	WTPACKETSGET func_PacketsGet;
+
+	// tablet attributes
+	float pressure_scale;
+	float tilt_x_scale, tilt_y_scale;
+	// others?
+
+public:
+	Tablet();
+	~Tablet();
+	bool available();
+	HCTX openForWindow(HWND window);
+	void processPackets(HCTX context);
+	};
+
+#endif

Added: branches/soc-2010-merwin/experimental/WinTablet/Utils.c
===================================================================
--- branches/soc-2010-merwin/experimental/WinTablet/Utils.c	                        (rev 0)
+++ branches/soc-2010-merwin/experimental/WinTablet/Utils.c	2010-07-15 12:34:14 UTC (rev 30376)
@@ -0,0 +1,182 @@
+/*----------------------------------------------------------------------------
+
+	NAME
+		Utils.c
+
+	PURPOSE
+		Some general-purpose functions for the WinTab demos.
+
+	COPYRIGHT
+		Copyright (c) Wacom Company, Ltd. 2010 All Rights Reserved
+		All rights reserved.
+
+---------------------------------------------------------------------------- */
+
+#include "Utils.h"
+
+#ifdef WACOM_DEBUG
+
+void WacomTrace( char *lpszFormat, ...);
+
+#define WACOM_ASSERT( x ) assert( x )
+#define WACOM_TRACE(...)  WacomTrace(__VA_ARGS__)
+#else
+#define WACOM_TRACE(...)
+#define WACOM_ASSERT( x )
+
+#endif // WACOM_DEBUG
+
+//////////////////////////////////////////////////////////////////////////////
+HINSTANCE ghWintab = NULL;
+
+WTINFOA gpWTInfoA = NULL;
+WTOPENA gpWTOpenA = NULL;
+WTGETA gpWTGetA = NULL;
+WTSETA gpWTSetA = NULL;
+WTCLOSE gpWTClose = NULL;
+WTPACKET gpWTPacket = NULL;
+WTENABLE gpWTEnable = NULL;
+WTOVERLAP gpWTOverlap = NULL;
+WTSAVE gpWTSave = NULL;
+WTCONFIG gpWTConfig = NULL;
+WTRESTORE gpWTRestore = NULL;
+WTEXTSET gpWTExtSet = NULL;
+WTEXTGET gpWTExtGet = NULL;
+WTQUEUESIZESET gpWTQueueSizeSet = NULL;
+WTDATAPEEK gpWTDataPeek = NULL;
+WTPACKETSGET gpWTPacketsGet = NULL;
+
+// TODO - add more wintab32 function pointers as needed
+
+char* pszProgramName = NULL;
+
+#define GETPROCADDRESS(type, func) \
+	gp##func = (type)GetProcAddress(ghWintab, #func); \
+	if (!gp##func){ WACOM_ASSERT(FALSE); UnloadWintab(); return FALSE; }
+
+//////////////////////////////////////////////////////////////////////////////
+// Purpose
+//		Find wintab32.dll and load it.  
+//		Find the exported functions we need from it.
+//
+//	Returns
+//		TRUE on success.
+//		FALSE on failure.
+//
+BOOL LoadWintab( void )
+{
+	ghWintab = LoadLibraryA(  "Wintab32.dll" );
+	if ( !ghWintab )
+	{
+		DWORD err = GetLastError();
+		WACOM_TRACE("LoadLibrary error: %i\n", err);
+		ShowError("Could not load Wintab32.dll");
+		return FALSE;
+	}
+
+	// Explicitly find the exported Wintab functions in which we are interested.
+	// We are using the ASCII, not unicode versions (where applicable).
+	GETPROCADDRESS( WTOPENA, WTOpenA );
+	GETPROCADDRESS( WTINFOA, WTInfoA );
+	GETPROCADDRESS( WTGETA, WTGetA );
+	GETPROCADDRESS( WTSETA, WTSetA );
+	GETPROCADDRESS( WTPACKET, WTPacket );
+	GETPROCADDRESS( WTCLOSE, WTClose );
+	GETPROCADDRESS( WTENABLE, WTEnable );
+	GETPROCADDRESS( WTOVERLAP, WTOverlap );
+	GETPROCADDRESS( WTSAVE, WTSave );
+	GETPROCADDRESS( WTCONFIG, WTConfig );
+	GETPROCADDRESS( WTRESTORE, WTRestore );
+	GETPROCADDRESS( WTEXTSET, WTExtSet );
+	GETPROCADDRESS( WTEXTGET, WTExtGet );
+	GETPROCADDRESS( WTQUEUESIZESET, WTQueueSizeSet );
+	GETPROCADDRESS( WTDATAPEEK, WTDataPeek );
+	GETPROCADDRESS( WTPACKETSGET, WTPacketsGet );
+
+
+	// TODO - don't forget to NULL out pointers in UnloadWintab().
+	return TRUE;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Purpose
+//		Uninitializes use of wintab32.dll
+//
+// Returns
+//		Nothing.
+//
+void UnloadWintab( void )
+{
+	WACOM_TRACE( "UnloadWintab()\n" );
+
+	if ( ghWintab )
+	{
+		FreeLibrary( ghWintab );
+		ghWintab = NULL;
+	}
+
+	gpWTOpenA			= NULL;
+	gpWTClose			= NULL;
+	gpWTInfoA			= NULL;
+	gpWTPacket			= NULL;
+	gpWTEnable			= NULL;
+	gpWTOverlap			= NULL;
+	gpWTSave			= NULL;
+	gpWTConfig			= NULL;
+	gpWTGetA				= NULL;
+	gpWTSetA				= NULL;
+	gpWTRestore			= NULL;
+	gpWTExtSet			= NULL;
+	gpWTExtGet			= NULL;
+	gpWTQueueSizeSet	= NULL;
+	gpWTDataPeek		= NULL;
+	gpWTPacketsGet		= NULL;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Purpose
+//		Display error to user.
+//
+void ShowError( char *pszErrorMessage )
+{
+	WACOM_TRACE( "ShowError()\n" );
+
+	WACOM_ASSERT( pszErrorMessage );
+
+	MessageBoxA( NULL, pszErrorMessage, gpszProgramName, MB_OK | MB_ICONHAND );
+}
+
+
+
+#ifdef WACOM_DEBUG
+
+//////////////////////////////////////////////////////////////////////////////
+
+void WacomTrace( char *lpszFormat, ...)
+{
+	char szTraceMessage[ 128 ];
+
+	int nBytesWritten;
+
+	va_list args;
+
+	WACOM_ASSERT( lpszFormat );
+
+	va_start( args, lpszFormat );
+
+	nBytesWritten = _vsnprintf( szTraceMessage, sizeof( szTraceMessage ) - 1, 
+		lpszFormat, args );
+
+	if ( nBytesWritten > 0 )
+	{
+		OutputDebugStringA( szTraceMessage );
+	}
+
+	va_end( args );
+}
+
+#endif // WACOM_DEBUG

Added: branches/soc-2010-merwin/experimental/WinTablet/Utils.h
===================================================================
--- branches/soc-2010-merwin/experimental/WinTablet/Utils.h	                        (rev 0)
+++ branches/soc-2010-merwin/experimental/WinTablet/Utils.h	2010-07-15 12:34:14 UTC (rev 30376)
@@ -0,0 +1,94 @@
+/*----------------------------------------------------------------------------
+
+	NAME
+		Utils.h
+
+	PURPOSE
+		Defines for the general-purpose functions for the WinTab demos.
+
+	COPYRIGHT
+		Copyright (c) Wacom Company, Ltd. 2010 All Rights Reserved
+		All rights reserved.
+
+---------------------------------------------------------------------------- */
+#pragma once
+
+#include	<windows.h>
+#include	<stdio.h>
+#include	<assert.h>
+#include	<stdarg.h>
+
+#include	<wintab.h>		// NOTE: get from wactab header package
+
+
+//////////////////////////////////////////////////////////////////////////////
+#define WACOM_DEBUG
+
+// Ignore warnings about using unsafe string functions.
+#pragma warning( disable : 4996 )
+
+//////////////////////////////////////////////////////////////////////////////

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list