[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33724] branches/soc-2010-merwin/intern/ ghost/intern: late summer -- overhauled tablet-handling for Windows
Mike Erwin
significant.bit at gmail.com
Fri Dec 17 01:13:23 CET 2010
Revision: 33724
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33724
Author: merwin
Date: 2010-12-17 01:13:23 +0100 (Fri, 17 Dec 2010)
Log Message:
-----------
late summer -- overhauled tablet-handling for Windows
Modified Paths:
--------------
branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemWin32.cpp
branches/soc-2010-merwin/intern/ghost/intern/GHOST_TabletManagerWin32.cpp
branches/soc-2010-merwin/intern/ghost/intern/GHOST_TabletManagerWin32.h
Modified: branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemWin32.cpp
===================================================================
--- branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemWin32.cpp 2010-12-17 00:12:23 UTC (rev 33723)
+++ branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemWin32.cpp 2010-12-17 00:13:23 UTC (rev 33724)
@@ -1022,7 +1022,7 @@
{
// tablet manager handles all its own cursor moves.
// ignore 'regular' mouse while a tablet tool is being used.
- DefWindowProc(window->getHWND(), WM_MOUSEMOVE, wParam, lParam);
+ // DefWindowProc(window->getHWND(), WM_MOUSEMOVE, wParam, lParam);
eventHandled = true;
break;
}
Modified: branches/soc-2010-merwin/intern/ghost/intern/GHOST_TabletManagerWin32.cpp
===================================================================
--- branches/soc-2010-merwin/intern/ghost/intern/GHOST_TabletManagerWin32.cpp 2010-12-17 00:12:23 UTC (rev 33723)
+++ branches/soc-2010-merwin/intern/ghost/intern/GHOST_TabletManagerWin32.cpp 2010-12-17 00:13:23 UTC (rev 33724)
@@ -10,14 +10,30 @@
#include <stdlib.h>
#include <math.h>
-#define PACKETDATA (PK_CURSOR | PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION)
-#define PACKETMODE (0 /*PK_BUTTONS*/)
-// #define PACKETTILT PKEXT_ABSOLUTE
+#define MAX_QUEUE_SIZE 100
-#include "pktdef.h"
+static bool wintab_initialized = false;
-#define MAX_QUEUE_SIZE 100
+// BEGIN from Wacom's Utils.h
+typedef UINT ( API * WTINFOA ) ( UINT, UINT, LPVOID );
+typedef HCTX ( API * WTOPENA ) ( HWND, LPLOGCONTEXTA, BOOL );
+typedef BOOL ( API * WTCLOSE ) ( HCTX );
+typedef BOOL ( API * WTQUEUESIZESET ) ( HCTX, int );
+typedef int ( API * WTPACKETSGET ) ( HCTX, int, LPVOID );
+typedef BOOL ( API * WTPACKET ) ( HCTX, UINT, LPVOID );
+// END
+// the Wintab library
+static HMODULE lib_Wintab;
+
+// WinTab function pointers
+static WTOPENA func_Open;
+static WTCLOSE func_Close;
+static WTINFOA func_Info;
+static WTQUEUESIZESET func_QueueSizeSet;
+static WTPACKETSGET func_PacketsGet;
+static WTPACKET func_Packet;
+
static void print(AXIS const& t, char const* label = NULL)
{
const char* unitName[] = {"dinosaur","inch","cm","circle"};
@@ -54,121 +70,225 @@
}
}
-GHOST_TabletManagerWin32::GHOST_TabletManagerWin32()
- : activeWindow(NULL)
+Tablet::Tablet(int tabletID)
+ : id(tabletID)
{
- dropTool();
+ GHOST_ASSERT(wintab_initialized, "Tablet objects should only be created by TabletManager");
- // open WinTab
- lib_Wintab = LoadLibrary("wintab32.dll");
+ // query for overall capabilities and ranges
+ func_Info(WTI_DEVICES, DVC_NAME, name);
+ printf("\n-- tablet %d: %s --\n", id, name);
- if (lib_Wintab)
+ puts("\nactive tablet area");
+ AXIS xRange, yRange;
+ func_Info(WTI_DEVICES + id, DVC_X, &xRange);
+ func_Info(WTI_DEVICES + id, DVC_Y, &yRange);
+ print(xRange,"x"); print(yRange,"y");
+ size_x = xRange.axMax;
+ size_y = yRange.axMax;
+
+ func_Info(WTI_DEVICES + id, DVC_NCSRTYPES, &cursorCount);
+ func_Info(WTI_DEVICES + id, DVC_FIRSTCSR, &cursorBase);
+ printf("\nowns tools %d to %d\n", cursorBase, cursorBase + cursorCount - 1);
+
+ func_Info(WTI_DEVICES + id, DVC_PKTDATA, &(allTools));
+ puts("\nall tools have"); print(allTools);
+ func_Info(WTI_DEVICES + id, DVC_CSRDATA, &(someTools));
+ puts("some tools also have"); print(someTools);
+
+ puts("\npressure sensitivity");
+ AXIS pressureRange;
+ hasPressure = (allTools|someTools) & PK_NORMAL_PRESSURE
+ && func_Info(WTI_DEVICES + id, DVC_NPRESSURE, &pressureRange)
+ && pressureRange.axMax;
+
+ if (hasPressure)
{
- // connect function pointers
- func_Open = (WTOPENA) GetProcAddress(lib_Wintab,"WTOpenA");
- func_Close = (WTCLOSE) GetProcAddress(lib_Wintab,"WTClose");
- func_Info = (WTINFOA) GetProcAddress(lib_Wintab,"WTInfoA");
- func_QueueSizeSet = (WTQUEUESIZESET) GetProcAddress(lib_Wintab,"WTQueueSizeSet");
- func_PacketsGet = (WTPACKETSGET) GetProcAddress(lib_Wintab,"WTPacketsGet");
- func_Packet = (WTPACKET) GetProcAddress(lib_Wintab,"WTPacket");
+ print(pressureRange);
+ pressureScale = 1.f / pressureRange.axMax;
+ }
+ else
+ pressureScale = 0.f;
- puts("\n-- essential tablet info --");
- func_Info(WTI_DEVICES, DVC_NCSRTYPES, &cursorCount);
- func_Info(WTI_DEVICES, DVC_FIRSTCSR, &cursorBase);
+ puts("\ntilt sensitivity");
+ AXIS tiltRange[3];
+ hasTilt = (allTools|someTools) & PK_ORIENTATION
+ && func_Info(WTI_DEVICES + id, DVC_ORIENTATION, tiltRange)
+ && tiltRange[0].axResolution && tiltRange[1].axResolution;
- func_Info(WTI_DEVICES, DVC_PKTDATA, &allTools);
- puts("\nall tools have"); print(allTools);
- func_Info(WTI_DEVICES, DVC_CSRDATA, &someTools);
- puts("some tools also have"); print(someTools);
+ if (hasTilt)
+ {
+ // leave this code in place to help support tablets I haven't tested
+ const char* axisName[] = {"azimuth","altitude","twist"};
+ for (int i = 0; i < 3; ++i)
+ print(tiltRange[i], axisName[i]);
- puts("\npressure sensitivity");
- AXIS pressureRange;
- hasPressure = (allTools|someTools) & PK_NORMAL_PRESSURE
- && func_Info(WTI_DEVICES, DVC_NPRESSURE, &pressureRange);
+ azimuthScale = 1.f / tiltRange[0].axMax;
+ altitudeScale = 1.f / tiltRange[1].axMax;
+ }
+ else
+ {
+ puts("none");
+ azimuthScale = altitudeScale = 0.f;
+ }
- if (hasPressure)
- {
- print(pressureRange);
- pressureScale = 1.f / pressureRange.axMax;
- }
- else
- pressureScale = 0.f;
+ for (UINT i = cursorBase; i < cursorBase + cursorCount; ++i)
+ {
+ // what can each cursor do?
- puts("\ntilt sensitivity");
- AXIS tiltRange[3];
- hasTilt = (allTools|someTools) & PK_ORIENTATION
- && func_Info(WTI_DEVICES, DVC_ORIENTATION, &tiltRange);
+ UINT physID;
+ func_Info(WTI_CURSORS + i, CSR_PHYSID, &physID);
+ if (physID == 0)
+ // each 'real' cursor has a physical ID
+ // (on Wacom at least, not tested with other vendors)
+ continue;
- if (hasTilt)
- {
- // leave this code in place to help support tablets I haven't tested
- const char* axisName[] = {"azimuth","altitude","twist"};
- for (int i = 0; i < 3; ++i)
- print(tiltRange[i], axisName[i]);
+ TCHAR name[40];
+ func_Info(WTI_CURSORS + i, CSR_NAME, name);
+ printf("\ncursor %d: %s\n", i, name);
- // cheat by using available data from Intuos4. test on other tablets!!!
- azimuthScale = 1.f / HIWORD(tiltRange[1].axResolution);
- altitudeScale = 1.f / tiltRange[1].axMax;
- }
- else
+ // always returns 'yes' so don't bother
+ // BOOL active;
+ // func_Info(WTI_CURSORS + i, CSR_ACTIVE, &active);
+ // printf("active: %s\n", active ? "yes" : "no");
+
+ WTPKT packet;
+ func_Info(WTI_CURSORS + i, CSR_PKTDATA, &packet);
+ // only report the 'special' bits that distinguish this cursor from the rest
+ puts("packet support"); print(packet & someTools);
+
+ puts("buttons:");
+ BYTE buttons;
+ BYTE sysButtonMap[32];
+ func_Info(WTI_CURSORS + i, CSR_BUTTONS, &buttons);
+ func_Info(WTI_CURSORS + i, CSR_SYSBTNMAP, sysButtonMap);
+ for (int i = 0; i < buttons; ++i)
+ printf(" %d -> %d\n", i, sysButtonMap[i]);
+ }
+ }
+
+bool Tablet::ownsCursor(int cursor)
+ {
+ return (cursor - cursorBase) < cursorCount;
+ }
+
+TabletTool Tablet::toolForCursor(int cursor)
+ {
+ TabletTool tool = {TABLET_NONE,false,false};
+ if (ownsCursor(cursor))
+ {
+ // try one way to classify cursor
+ UINT cursorType = (cursor - cursorBase) % cursorCount;
+ printf("%d mod %d = %d\n", cursor - cursorBase, cursorCount, cursorType);
+ switch (cursorType)
{
- puts("none");
- azimuthScale = altitudeScale = 0.f;
+ case 0: // older Intuos tablets can track two cursors at once
+ case 3: // so we test for both here
+ tool.type = TABLET_MOUSE;
+ break;
+ case 1:
+ case 4:
+ tool.type = TABLET_PEN;
+ break;
+ case 2:
+ case 5:
+ tool.type = TABLET_ERASER;
+ break;
+ default:
+ tool.type = TABLET_NONE;
}
-#if 0 // WTX_TILT -- cartesian tilt extension, no conversion needed
- // this isn't working for [mce], so let it rest for now
- puts("\nraw tilt sensitivity");
- hasTilt = false;
- UINT tag = 0;
- UINT extensionCount;
- func_Info(WTI_INTERFACE, IFC_NEXTENSIONS, &extensionCount);
- for (UINT i = 0; i < extensionCount; ++i)
+ #if 0
+ // now try another way
+ func_Info(WTI_CURSORS + cursor, CSR_TYPE, &cursorType);
+ switch (cursorType & 0xf06)
{
- printf("trying extension %d\n", i);
- func_Info(WTI_EXTENSIONS + i, EXT_TAG, &tag);
- if (tag == WTX_TILT)
- {
- hasTilt = true;
+ case 0x802:
+ puts("general stylus");
break;
- }
+ case 0x902:
+ puts("airbrush");
+ break;
+ case 0x804:
+ puts("art pen");
+ break;
+ case 0x004:
+ puts("4D mouse");
+ break;
+ case 0x006:
+ puts("5-button puck");
+ break;
+ default:
+ puts("???");
}
+ #endif
- if (hasTilt)
+ WTPKT toolData;
+ func_Info(WTI_CURSORS + cursor, CSR_PKTDATA, &toolData);
+ // discard any stray capabilities
+ // (sometimes cursors claim to be able to do things
+ // that their tablet doesn't support)
+ toolData &= (allTools|someTools);
+ // only report the 'special' bits that distinguish this cursor from the rest
+ puts("packet support"); print(toolData & someTools);
+ putchar('\n');
+
+ if (tool.type == TABLET_MOUSE)
{
- AXIS tiltRange[2];
- func_Info(WTI_EXTENSIONS + tag, EXT_AXES, tiltRange);
- print("x", tiltRange[0]);
- print("y", tiltRange[1]);
- tiltScaleX = 1.f / tiltRange[0].axMax;
- tiltScaleY = 1.f / tiltRange[1].axMax;
- func_Info(WTI_EXTENSIONS + tag, EXT_MASK, &tiltMask);
+ // don't always trust CSR_PKTDATA!
+ tool.hasPressure = false;
+ tool.hasTilt = false;
}
else
{
- puts("none");
- tiltScaleX = tiltScaleY = 0.f;
+ tool.hasPressure = toolData & PK_NORMAL_PRESSURE;
+ tool.hasTilt = toolData & PK_ORIENTATION;
}
-#endif // WTX_TILT
+ }
- getExtraInfo();
+ return tool;
+ }
+
+GHOST_TabletManagerWin32::GHOST_TabletManagerWin32()
+ : activeWindow(NULL)
+ {
+ dropTool();
+
+ // open WinTab
+ GHOST_ASSERT(!wintab_initialized,"There should be only one TabletManagerWin32 object");
+ lib_Wintab = LoadLibrary("wintab32.dll");
+
+ if (lib_Wintab)
+ {
+ // connect function pointers
+ func_Open = (WTOPENA) GetProcAddress(lib_Wintab,"WTOpenA");
+ func_Close = (WTCLOSE) GetProcAddress(lib_Wintab,"WTClose");
+ func_Info = (WTINFOA) GetProcAddress(lib_Wintab,"WTInfoA");
+ func_QueueSizeSet = (WTQUEUESIZESET) GetProcAddress(lib_Wintab,"WTQueueSizeSet");
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list