diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 945e4c16a39..757d9d962fd 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -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 // for debug, remove soon [mce] + // Need glew for some defines #include #include @@ -122,7 +126,7 @@ GHOST_WindowWin32::GHOST_WindowWin32( 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 @@ GHOST_WindowWin32::GHOST_WindowWin32( } } - 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 @@ GHOST_WindowWin32::GHOST_WindowWin32( // 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 @@ GHOST_WindowWin32::GHOST_WindowWin32( } } - 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( 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 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cur 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 @@ void GHOST_WindowWin32::processWin32TabletInitEvent() } 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 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam) } } } - } + putchar('\n'); } } diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index a4d31f87ffa..da3c47c39ac 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -39,9 +39,10 @@ #include "GHOST_Window.h" +#define _WIN32_WINNT 0x501 // require Windows XP or newer +#define WIN32_LEAN_AND_MEAN #include - #include #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 @@ protected: 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; diff --git a/intern/ghost/intern/Utils.c b/intern/ghost/intern/Utils.c new file mode 100644 index 00000000000..05392793e21 --- /dev/null +++ b/intern/ghost/intern/Utils.c @@ -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 diff --git a/intern/ghost/intern/Utils.h b/intern/ghost/intern/Utils.h new file mode 100644 index 00000000000..e886389796f --- /dev/null +++ b/intern/ghost/intern/Utils.h @@ -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 +#include +#include +#include + +#include // NOTE: get from wactab header package + + +////////////////////////////////////////////////////////////////////////////// +#define WACOM_DEBUG + +// Ignore warnings about using unsafe string functions. +#pragma warning( disable : 4996 ) + +////////////////////////////////////////////////////////////////////////////// +// Function pointers to Wintab functions exported from wintab32.dll. +typedef UINT ( API * WTINFOA ) ( UINT, UINT, LPVOID ); +typedef HCTX ( API * WTOPENA )( HWND, LPLOGCONTEXTA, BOOL ); +typedef BOOL ( API * WTGETA ) ( HCTX, LPLOGCONTEXT ); +typedef BOOL ( API * WTSETA ) ( HCTX, LPLOGCONTEXT ); +typedef BOOL ( API * WTCLOSE ) ( HCTX ); +typedef BOOL ( API * WTENABLE ) ( HCTX, BOOL ); +typedef BOOL ( API * WTPACKET ) ( HCTX, UINT, LPVOID ); +typedef BOOL ( API * WTOVERLAP ) ( HCTX, BOOL ); +typedef BOOL ( API * WTSAVE ) ( HCTX, LPVOID ); +typedef BOOL ( API * WTCONFIG ) ( HCTX, HWND ); +typedef HCTX ( API * WTRESTORE ) ( HWND, LPVOID, BOOL ); +typedef BOOL ( API * WTEXTSET ) ( HCTX, UINT, LPVOID ); +typedef BOOL ( API * WTEXTGET ) ( HCTX, UINT, LPVOID ); +typedef BOOL ( API * WTQUEUESIZESET ) ( HCTX, int ); +typedef int ( API * WTDATAPEEK ) ( HCTX, UINT, UINT, int, LPVOID, LPINT); +typedef int ( API * WTPACKETSGET ) (HCTX, int, LPVOID); + +// TODO - add more wintab32 function defs as needed + +////////////////////////////////////////////////////////////////////////////// +extern char* gpszProgramName; + +// Loaded Wintab32 API functions. +extern HINSTANCE ghWintab; + +extern WTINFOA gpWTInfoA; +extern WTOPENA gpWTOpenA; +extern WTGETA gpWTGetA; +extern WTSETA gpWTSetA; +extern WTCLOSE gpWTClose; +extern WTPACKET gpWTPacket; +extern WTENABLE gpWTEnable; +extern WTOVERLAP gpWTOverlap; +extern WTSAVE gpWTSave; +extern WTCONFIG gpWTConfig; +extern WTRESTORE gpWTRestore; +extern WTEXTSET gpWTExtSet; +extern WTEXTGET gpWTExtGet; +extern WTQUEUESIZESET gpWTQueueSizeSet; +extern WTDATAPEEK gpWTDataPeek; +extern WTPACKETSGET gpWTPacketsGet; + +// TODO - add more wintab32 function pointers as needed + +////////////////////////////////////////////////////////////////////////////// +BOOL LoadWintab( void ); +void UnloadWintab( void ); + +void ShowError( char *pszErrorMessage ); + +////////////////////////////////////////////////////////////////////////////// +#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 +