[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37621] branches/merwin-spacenav/intern/ ghost/intern: ndof device detection on Windows, safer button handling

Mike Erwin significant.bit at gmail.com
Sat Jun 18 18:50:55 CEST 2011


Revision: 37621
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37621
Author:   merwin
Date:     2011-06-18 16:50:54 +0000 (Sat, 18 Jun 2011)
Log Message:
-----------
ndof device detection on Windows, safer button handling

Modified Paths:
--------------
    branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.cpp
    branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.h
    branches/merwin-spacenav/intern/ghost/intern/GHOST_SystemWin32.cpp
    branches/merwin-spacenav/intern/ghost/intern/GHOST_SystemWin32.h

Modified: branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.cpp
===================================================================
--- branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.cpp	2011-06-18 15:53:47 UTC (rev 37620)
+++ branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.cpp	2011-06-18 16:50:54 UTC (rev 37621)
@@ -134,7 +134,9 @@
 
 GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys)
 	: m_system(sys)
-	, m_deviceType(NDOF_UnknownDevice) // each platform needs its own device detection code
+	, m_deviceType(NDOF_UnknownDevice) // each platform has its own device detection code
+	, m_buttonCount(0)
+	, m_buttonMask(0)
 	, m_buttons(0)
 	, m_motionTime(1000) // one full second (operators should filter out such large time deltas)
 	, m_prevMotionTime(0)
@@ -154,10 +156,26 @@
 			switch (product_id)
 				{
 				// -- current devices --
-				case 0xC626: m_deviceType = NDOF_SpaceNavigator; break;
-				case 0xC628: m_deviceType = NDOF_SpaceNavigator; /* for Notebooks */ break;
-				case 0xC627: m_deviceType = NDOF_SpaceExplorer; break;
-				case 0xC629: m_deviceType = NDOF_SpacePilotPro; break;
+				case 0xC626:
+					m_deviceType = NDOF_SpaceNavigator;
+					m_buttonCount = 2;
+//					m_buttonMask = 0x3; // 2 buttons
+					break;
+				case 0xC628:
+					m_deviceType = NDOF_SpaceNavigator; // for Notebooks
+					m_buttonCount = 2;
+//					m_buttonMask = 0x3; // 2 buttons
+					break;
+				case 0xC627:
+					m_deviceType = NDOF_SpaceExplorer;
+					m_buttonCount = 15;
+//					m_buttonMask = 0x7FFF; // 15 buttons
+					break;
+				case 0xC629:
+					m_deviceType = NDOF_SpacePilotPro;
+					m_buttonCount = 29;
+//					m_buttonMask = 0x1FFFFFFF; // 29 buttons
+					break;
 
 				// -- older devices --
 				case 0xC623: puts("ndof: SpaceTraveler not supported, please file a bug report"); break;
@@ -169,6 +187,9 @@
 		default:
 			printf("ndof: unknown vendor %04hx\n", vendor_id);
 		}
+
+	m_buttonMask = ~(-1 << m_buttonCount);
+	printf("ndof: %d buttons -> %X\n", m_buttonCount, m_buttonMask);
 	}
 
 void GHOST_NDOFManager::updateTranslation(short t[3], GHOST_TUns64 time)
@@ -217,7 +238,8 @@
 	GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
 
 	#ifdef DEBUG_NDOF_BUTTONS
-	printf("ndof: button %d -> ", button_number);
+	if (m_deviceType != NDOF_UnknownDevice)
+		printf("ndof: button %d -> ", button_number);
 	#endif
 
 	switch (m_deviceType)
@@ -258,6 +280,8 @@
 
 void GHOST_NDOFManager::updateButtons(int button_bits, GHOST_TUns64 time)
 	{
+	button_bits &= m_buttonMask; // discard any "garbage" bits
+
 	int diff = m_buttons ^ button_bits;
 
 	for (int button_number = 0; button_number <= 31; ++button_number)

Modified: branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.h
===================================================================
--- branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.h	2011-06-18 15:53:47 UTC (rev 37620)
+++ branches/merwin-spacenav/intern/ghost/intern/GHOST_NDOFManager.h	2011-06-18 16:50:54 UTC (rev 37621)
@@ -115,6 +115,8 @@
 
 
 	NDOF_DeviceT m_deviceType;
+	int m_buttonCount;
+	int m_buttonMask;
 
 	short m_translation[3];
 	short m_rotation[3];

Modified: branches/merwin-spacenav/intern/ghost/intern/GHOST_SystemWin32.cpp
===================================================================
--- branches/merwin-spacenav/intern/ghost/intern/GHOST_SystemWin32.cpp	2011-06-18 15:53:47 UTC (rev 37620)
+++ branches/merwin-spacenav/intern/ghost/intern/GHOST_SystemWin32.cpp	2011-06-18 16:50:54 UTC (rev 37621)
@@ -818,10 +818,29 @@
 	minmax->ptMinTrackSize.y=240;
 }
 
-bool GHOST_SystemWin32::processNDOF(/*GHOST_WindowWin32* window,*/ RAWINPUT const& raw)
+bool GHOST_SystemWin32::processNDOF(RAWINPUT const& raw)
 {
 	bool eventSent = false;
+	GHOST_TUns64 now = getMilliSeconds();
 
+	static bool firstEvent = true;
+	if (firstEvent)
+		{ // determine exactly which device is plugged in
+		RID_DEVICE_INFO info;
+		unsigned infoSize = sizeof(RID_DEVICE_INFO);
+		info.cbSize = infoSize;
+
+		GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICEINFO, &info, &infoSize);
+		if (info.dwType == RIM_TYPEHID)
+			{
+			printf("hardware ID = %08X:%08X\n", info.hid.dwVendorId, info.hid.dwProductId);
+			m_ndofManager->setDevice(info.hid.dwVendorId, info.hid.dwProductId);
+			}
+		else puts("<!> not a HID device... mouse/kb perhaps?");
+
+		firstEvent = false;
+		}
+
 	// The NDOF manager sends button changes immediately, and *pretends* to
 	// send motion. Mark as 'sent' so motion will always get dispatched.
 	eventSent = true;
@@ -839,26 +858,39 @@
 		{
 		case 1: // translation
 			{
-			short t[3];
-			memcpy(t, data + 1, sizeof(t));
-			m_ndofManager->updateTranslation(t, getMilliSeconds());
+			short axis_data[3];
+			memcpy(axis_data, data + 1, sizeof(axis_data));
+			m_ndofManager->updateTranslation(axis_data, now);
 			// wariness of alignment issues prevents me from saying it this way:
 			// m_ndofManager->updateTranslation((short*)(data + 1), getMilliSeconds());
 			// though it probably (94.7%) would work fine
+
+			if (raw.data.hid.dwSizeHid == 13)
+				{ // this report also includes rotation
+				puts("ndof: combined T + R");
+				memcpy(axis_data, data + 7, sizeof(axis_data));
+				m_ndofManager->updateRotation(axis_data, now);
+				}
 			break;
 			}
 		case 2: // rotation
 			{
-			short r[3];
-			memcpy(r, data + 1, sizeof(r));
-			m_ndofManager->updateRotation(r, getMilliSeconds());
+			short axis_data[3];
+			memcpy(axis_data, data + 1, sizeof(axis_data));
+			m_ndofManager->updateRotation(axis_data, now);
 			break;
 			}
 		case 3: // buttons
 			{
+			// I'm getting garbage bits -- examine whole report:
+			printf("ndof: HID report for buttons [");
+			for (int i = 0; i < raw.data.hid.dwSizeHid; ++i)
+				printf(" %02X", data[i]);
+			printf(" ]\n");
+
 			int button_bits;
 			memcpy(&button_bits, data + 1, sizeof(button_bits));
-			m_ndofManager->updateButtons(button_bits, getMilliSeconds());
+			m_ndofManager->updateButtons(button_bits, now);
 			break;
 			}
 		}
@@ -910,7 +942,7 @@
 						}
 						break;
 					case RIM_TYPEHID:
-						if (system->processNDOF(/*window,*/ raw))
+						if (system->processNDOF(raw))
 							eventHandled = true;
 						break;
 					}

Modified: branches/merwin-spacenav/intern/ghost/intern/GHOST_SystemWin32.h
===================================================================
--- branches/merwin-spacenav/intern/ghost/intern/GHOST_SystemWin32.h	2011-06-18 15:53:47 UTC (rev 37620)
+++ branches/merwin-spacenav/intern/ghost/intern/GHOST_SystemWin32.h	2011-06-18 16:50:54 UTC (rev 37621)
@@ -397,11 +397,10 @@
 	 * Handles Motion and Button events from a SpaceNavigator or related device.
 	 * Instead of returning an event object, this function communicates directly
 	 * with the GHOST_NDOFManager.
-	 * @param window	The window receiving the event (the active window).
 	 * @param raw		RawInput structure with detailed info about the NDOF event
 	 * @return Whether an event was generated and sent.
 	 */
-	bool processNDOF(/*GHOST_IWindow *window,*/ RAWINPUT const& raw);
+	bool processNDOF(RAWINPUT const& raw);
 
 	/**
 	 * Returns the local state of the modifier keys (from the message queue).




More information about the Bf-blender-cvs mailing list