[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