[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30372] branches/soc-2010-merwin/intern/ ghost/intern: Improved tablet support on Windows.

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


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

Log Message:
-----------
Improved tablet support on Windows. Nice deep queue for input points. Much more is being captured now. WT_PACKET events are disabled until I can revisit in a day or two.

Also added Wacom's driver wrappers, with their permission. These won't live here very long, but the WindowWin32 tablet code uses it for now.

Modified Paths:
--------------
    branches/soc-2010-merwin/intern/ghost/intern/GHOST_WindowWin32.cpp
    branches/soc-2010-merwin/intern/ghost/intern/GHOST_WindowWin32.h

Added Paths:
-----------
    branches/soc-2010-merwin/intern/ghost/intern/Utils.c
    branches/soc-2010-merwin/intern/ghost/intern/Utils.h

Modified: branches/soc-2010-merwin/intern/ghost/intern/GHOST_WindowWin32.cpp
===================================================================
--- branches/soc-2010-merwin/intern/ghost/intern/GHOST_WindowWin32.cpp	2010-07-15 11:54:24 UTC (rev 30371)
+++ branches/soc-2010-merwin/intern/ghost/intern/GHOST_WindowWin32.cpp	2010-07-15 12:12:52 UTC (rev 30372)
@@ -39,6 +39,10 @@
 #include "GHOST_SystemWin32.h"
 #include "GHOST_DropTargetWin32.h"
 
+//#include "wintab.h" // for tablets, naturally
+#include "Utils.c" // that's right, .c, with permission from Wacom
+#include <stdio.h> // for debug, remove soon [mce]
+
 // Need glew for some defines
 #include <GL/glew.h>
 #include <GL/wglew.h>
@@ -122,7 +126,7 @@
 	m_hasMouseCaptured(false),
 	m_nPressedButtons(0),
 	m_customCursor(0),
-	m_wintab(NULL),
+	m_wintab(false),
 	m_tabletData(NULL),
 	m_tablet(0),
 	m_maxPressure(0),
@@ -238,14 +242,11 @@
 		}
 	}
 
-	m_wintab = ::LoadLibrary("Wintab32.dll");
+   m_wintab = LoadWintab();
 	if (m_wintab) {
-		GHOST_WIN32_WTInfo fpWTInfo = ( GHOST_WIN32_WTInfo ) ::GetProcAddress( m_wintab, "WTInfoA" );
-		GHOST_WIN32_WTOpen fpWTOpen = ( GHOST_WIN32_WTOpen ) ::GetProcAddress( m_wintab, "WTOpenA" );
-
 		// let's see if we can initialize tablet here
 		/* check if WinTab available. */
-		if (fpWTInfo && fpWTInfo(0, 0, NULL)) {
+		if (gpWTInfoA(0, 0, NULL)) {
 			// Now init the tablet
 			LOGCONTEXT lc;
 			AXIS TabletX, TabletY, Pressure, Orientation[3]; /* The maximum tablet size, pressure and orientation (tilt) */
@@ -253,26 +254,27 @@
 			// Open a Wintab context
 
 			// Get default context information
-			fpWTInfo( WTI_DEFCONTEXT, 0, &lc );
+			gpWTInfoA( WTI_DEFCONTEXT, 0, &lc );
 
 			// Open the context
 			lc.lcPktData = PACKETDATA;
 			lc.lcPktMode = PACKETMODE;
-			lc.lcOptions |= CXO_MESSAGES | CXO_SYSTEM;
+			lc.lcOptions |= /* CXO_MESSAGES | */ CXO_SYSTEM;
+			lc.lcOptions &= ~CXO_MESSAGES;
 
 			/* Set the entire tablet as active */
-			fpWTInfo(WTI_DEVICES,DVC_X,&TabletX);
-			fpWTInfo(WTI_DEVICES,DVC_Y,&TabletY);
+			gpWTInfoA(WTI_DEVICES,DVC_X,&TabletX);
+			gpWTInfoA(WTI_DEVICES,DVC_Y,&TabletY);
 
 			/* get the max pressure, to divide into a float */
-			BOOL pressureSupport = fpWTInfo (WTI_DEVICES, DVC_NPRESSURE, &Pressure);
+			BOOL pressureSupport = gpWTInfoA(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
 			if (pressureSupport)
 				m_maxPressure = Pressure.axMax;
 			else
 				m_maxPressure = 0;
 
 			/* get the max tilt axes, to divide into floats */
-			BOOL tiltSupport = fpWTInfo (WTI_DEVICES, DVC_ORIENTATION, &Orientation);
+			BOOL tiltSupport = gpWTInfoA(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
 			if (tiltSupport) {
 				/* does the tablet support azimuth ([0]) and altitude ([1]) */
 				if (Orientation[0].axResolution && Orientation[1].axResolution) {
@@ -285,12 +287,16 @@
 				}
 			}
 
-			if (fpWTOpen) {
-				m_tablet = fpWTOpen( m_hWnd, &lc, TRUE );
-				if (m_tablet) {
-					m_tabletData = new GHOST_TabletData();
-					m_tabletData->Active = GHOST_kTabletModeNone;
-				}
+			m_tablet = gpWTOpenA( m_hWnd, &lc, TRUE );
+			if (m_tablet) {
+				m_tabletData = new GHOST_TabletData();
+				m_tabletData->Active = GHOST_kTabletModeNone;
+
+            // request a deep queue, to capture every pen point
+            int tabletQueueSize = 128;
+            while (!gpWTQueueSizeSet(m_tablet, tabletQueueSize))
+                  --tabletQueueSize;
+            printf("tablet queue size: %d\n", tabletQueueSize);
 			}
 		}
 	}
@@ -300,14 +306,12 @@
 GHOST_WindowWin32::~GHOST_WindowWin32()
 {
 	if (m_wintab) {
-		GHOST_WIN32_WTClose fpWTClose = ( GHOST_WIN32_WTClose ) ::GetProcAddress( m_wintab, "WTClose" );
-		if (fpWTClose) {
-			if (m_tablet)
-				fpWTClose(m_tablet);
-			if (m_tabletData)
-				delete m_tabletData;
-				m_tabletData = NULL;
-		}
+		if (m_tablet)
+			gpWTClose(m_tablet);
+		if (m_tabletData)
+			delete m_tabletData;
+		m_tabletData = NULL;
+      UnloadWintab();
 	}
 	if (m_customCursor) {
 		DestroyCursor(m_customCursor);
@@ -912,20 +916,16 @@
 void GHOST_WindowWin32::processWin32TabletInitEvent()
 {
 	if (m_wintab) {
-		GHOST_WIN32_WTInfo fpWTInfo = ( GHOST_WIN32_WTInfo ) ::GetProcAddress( m_wintab, "WTInfoA" );
-
 		// let's see if we can initialize tablet here
-		/* check if WinTab available. */
-		if (fpWTInfo) {
 			AXIS Pressure, Orientation[3]; /* The maximum tablet size */
 
-			BOOL pressureSupport = fpWTInfo (WTI_DEVICES, DVC_NPRESSURE, &Pressure);
+			BOOL pressureSupport = gpWTInfoA(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
 			if (pressureSupport)
 				m_maxPressure = Pressure.axMax;
 			else
 				m_maxPressure = 0;
 
-			BOOL tiltSupport = fpWTInfo (WTI_DEVICES, DVC_ORIENTATION, &Orientation);
+			BOOL tiltSupport = gpWTInfoA(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
 			if (tiltSupport) {
 				/* does the tablet support azimuth ([0]) and altitude ([1]) */
 				if (Orientation[0].axResolution && Orientation[1].axResolution) {
@@ -938,17 +938,22 @@
 			}
 
 			m_tabletData->Active = GHOST_kTabletModeNone;
-		}
 	}
 }
 
 void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
 {
-	PACKET pkt;
+//	PACKET pkt;
 	if (m_wintab) {
-		GHOST_WIN32_WTPacket fpWTPacket = ( GHOST_WIN32_WTPacket ) ::GetProcAddress( m_wintab, "WTPacket" );
-		if (fpWTPacket) {
-			if (fpWTPacket((HCTX)lParam, wParam, &pkt)) {
+     printf("tablet event ");
+     		PACKET pkt_buffer[128];
+     		int n = gpWTPacketsGet((HCTX)lParam, 128, pkt_buffer);
+     		printf("(%d in queue) ", n);
+     		for (int i = 0; i < n; ++i) {
+				PACKET& pkt = pkt_buffer[i];
+     // "while" not "if" -- drain the queue!
+//			while (gpWTPacket((HCTX)lParam, wParam, &pkt)) {
+				putchar('.');
 				if (m_tabletData) {
 					switch (pkt.pkCursor) {
 						case 0: /* first device */
@@ -1008,7 +1013,7 @@
 					}
 				}
 			}
-		}
+		putchar('\n');
 	}
 }
 

Modified: branches/soc-2010-merwin/intern/ghost/intern/GHOST_WindowWin32.h
===================================================================
--- branches/soc-2010-merwin/intern/ghost/intern/GHOST_WindowWin32.h	2010-07-15 11:54:24 UTC (rev 30371)
+++ branches/soc-2010-merwin/intern/ghost/intern/GHOST_WindowWin32.h	2010-07-15 12:12:52 UTC (rev 30372)
@@ -39,9 +39,10 @@
 
 #include "GHOST_Window.h"
 
+#define _WIN32_WINNT 0x501 // require Windows XP or newer
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
-
 #include <wintab.h>
 #define PACKETDATA	(PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
 #define PACKETMODE	PK_BUTTONS
@@ -50,11 +51,13 @@
 class GHOST_SystemWin32;
 class GHOST_DropTargetWin32;
 
+/*
 // typedefs for WinTab functions to allow dynamic loading
 typedef UINT (API * GHOST_WIN32_WTInfo) ( UINT, UINT, LPVOID );
 typedef HCTX (API * GHOST_WIN32_WTOpen) (HWND, LPLOGCONTEXTA, BOOL);
 typedef BOOL (API * GHOST_WIN32_WTClose) (HCTX);
 typedef BOOL (API * GHOST_WIN32_WTPacket) (HCTX, UINT, LPVOID);
+*/
 
 /**
  * GHOST window on M$ Windows OSs.
@@ -328,7 +331,8 @@
 	static const int s_maxTitleLength;
 
 	/** WinTab dll handle */
-	HMODULE m_wintab;
+//	HMODULE m_wintab;
+   bool m_wintab;
 
 	/** Tablet data for GHOST */
 	GHOST_TabletData* m_tabletData;

Added: branches/soc-2010-merwin/intern/ghost/intern/Utils.c
===================================================================
--- branches/soc-2010-merwin/intern/ghost/intern/Utils.c	                        (rev 0)
+++ branches/soc-2010-merwin/intern/ghost/intern/Utils.c	2010-07-15 12:12:52 UTC (rev 30372)
@@ -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 )
+{

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list