[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [34345] branches/merwin-tablet-2/intern/ ghost/intern: introducing GHOST TabletManager for Linux/Win32

Mike Erwin significant.bit at gmail.com
Sun Jan 16 05:57:52 CET 2011


Revision: 34345
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=34345
Author:   merwin
Date:     2011-01-16 04:57:51 +0000 (Sun, 16 Jan 2011)
Log Message:
-----------
introducing GHOST TabletManager for Linux/Win32

Added Paths:
-----------
    branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.cpp
    branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.h
    branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManagerWin32.cpp
    branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManagerWin32.h
    branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManagerX11.cpp
    branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManagerX11.h

Added: branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.cpp
===================================================================
--- branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.cpp	                        (rev 0)
+++ branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.cpp	2011-01-16 04:57:51 UTC (rev 34345)
@@ -0,0 +1,16 @@
+
+#include "GHOST_TabletManager.h"
+#include "GHOST_Window.h"
+
+GHOST_TabletManager::GHOST_TabletManager()
+	: hasPressure(false)
+	, hasTilt(false)
+	, activeWindow(NULL)
+	{
+	activeTool.type = TABLET_NONE;
+	}
+
+GHOST_TabletManager::~GHOST_TabletManager()
+	{
+	}
+


Property changes on: branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.cpp
___________________________________________________________________
Added: svn:eol-style
   + native

Added: branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.h
===================================================================
--- branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.h	                        (rev 0)
+++ branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.h	2011-01-16 04:57:51 UTC (rev 34345)
@@ -0,0 +1,70 @@
+#ifndef GHOST_TABLET_MANAGER_H
+#define GHOST_TABLET_MANAGER_H
+
+// #include <vector>
+
+class GHOST_Window;
+
+// TabletToolData (and its components) are meant to replace GHOST_TabletData
+// and its customdata analogue in the window manager. For now it's confined to the
+// TabletManager.
+
+typedef enum { TABLET_NONE, TABLET_PEN, TABLET_ERASER, TABLET_MOUSE } TabletToolType;
+
+typedef struct
+	{
+	TabletToolType type : 4; // plenty of room to grow
+
+	// capabilities
+	bool hasPressure : 1;
+	bool hasTilt : 1;
+
+	} TabletTool;
+
+
+typedef struct
+	{
+	TabletTool tool;
+
+	float pressure;
+	float tilt_x, tilt_y;
+
+	} TabletToolData;
+
+/*
+struct Tablet
+	{
+	bool hasPressure;
+	float pressureScale;
+
+	bool hasTilt;
+	float azimuthScale;
+	float altitudeScale;
+	};
+*/
+
+class GHOST_TabletManager
+	{
+protected:
+	// tablet attributes
+	bool hasPressure;
+	float pressureScale;
+	bool hasTilt;
+	float azimuthScale;
+	float altitudeScale;
+
+//	std::vector<Tablet> tablets;
+//	std::vector<TabletTool> tools;
+
+	GHOST_Window* activeWindow;
+	TabletTool activeTool;
+
+public:
+	GHOST_TabletManager();
+	virtual ~GHOST_TabletManager();
+
+	virtual bool available() = 0;
+	};
+
+#endif
+


Property changes on: branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManager.h
___________________________________________________________________
Added: svn:eol-style
   + native

Added: branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManagerWin32.cpp
===================================================================
--- branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManagerWin32.cpp	                        (rev 0)
+++ branches/merwin-tablet-2/intern/ghost/intern/GHOST_TabletManagerWin32.cpp	2011-01-16 04:57:51 UTC (rev 34345)
@@ -0,0 +1,662 @@
+// safe & friendly WinTab wrapper
+// by Mike Erwin, July 2010
+
+#include "GHOST_TabletManagerWin32.h"
+#include "GHOST_WindowWin32.h"
+#include "GHOST_System.h"
+#include "GHOST_EventCursor.h"
+#include "GHOST_EventButton.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#define MAX_QUEUE_SIZE 100
+
+static bool wintab_initialized = false;
+
+// 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"};
+
+	if (label)
+		printf("%s: ", label);
+
+	printf("%d to %d, %d.%d per %s\n",
+		t.axMin, t.axMax,
+		HIWORD(t.axResolution), LOWORD(t.axResolution),
+		unitName[t.axUnits]);
+	}
+
+static void print(WTPKT packet)
+	{
+	if (packet == 0)
+		puts("- nothing special");
+	else
+		{
+		if (packet & PK_CONTEXT) puts("- reporting context");
+		if (packet & PK_STATUS) puts("- status bits");
+		if (packet & PK_TIME) puts("- time stamp");
+		if (packet & PK_CHANGED) puts("- change bit vector");
+		if (packet & PK_SERIAL_NUMBER) puts("- packet serial number");
+		if (packet & PK_CURSOR) puts("- reporting cursor");
+		if (packet & PK_BUTTONS) puts("- buttons");
+		if (packet & PK_X) puts("- x axis");
+		if (packet & PK_Y) puts("- y axis");
+		if (packet & PK_Z) puts("- z axis");
+		if (packet & PK_NORMAL_PRESSURE) puts("- tip pressure");
+		if (packet & PK_TANGENT_PRESSURE) puts("- barrel pressure");
+		if (packet & PK_ORIENTATION) puts("- orientation/tilt");
+		if (packet & PK_ROTATION) puts("- rotation");
+		}
+	}
+
+Tablet::Tablet(int tabletID)
+	: id(tabletID)
+	{
+	GHOST_ASSERT(wintab_initialized, "Tablet objects should only be created by TabletManager");
+
+	// query for overall capabilities and ranges
+	func_Info(WTI_DEVICES, DVC_NAME, name);
+	printf("\n-- tablet %d: %s --\n", id, name);
+
+	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)
+		{
+		print(pressureRange);
+		pressureScale = 1.f / pressureRange.axMax;
+		}
+	else
+		pressureScale = 0.f;
+
+	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;
+
+	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]);
+
+		azimuthScale = 1.f / tiltRange[0].axMax;
+		altitudeScale = 1.f / tiltRange[1].axMax;
+		}
+	else
+		{
+		puts("none");
+		azimuthScale = altitudeScale = 0.f;
+		}
+
+	for (UINT i = cursorBase; i < cursorBase + cursorCount; ++i)
+		{
+		// what can each cursor do?
+
+		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;
+
+		TCHAR name[40];
+		func_Info(WTI_CURSORS + i, CSR_NAME, name);
+		printf("\ncursor %d: %s\n", i, name);
+
+		// 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)
+			{
+			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
+		// now try another way
+		func_Info(WTI_CURSORS + cursor, CSR_TYPE, &cursorType);
+		switch (cursorType & 0xf06)
+			{
+			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
+
+		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)
+			{
+			// don't always trust CSR_PKTDATA!
+			tool.hasPressure = false;
+			tool.hasTilt = false;
+			}
+		else
+			{
+			tool.hasPressure = toolData & PK_NORMAL_PRESSURE;
+			tool.hasTilt = toolData & PK_ORIENTATION;
+			}
+		}
+
+	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