Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Erwin <significant.bit@gmail.com>2011-06-09 01:18:03 +0400
committerMike Erwin <significant.bit@gmail.com>2011-06-09 01:18:03 +0400
commite75ff53452d6c989e2846521f5d00523bc90906a (patch)
tree869f0b62410d6efe24a9900dda0b84796b3cec12 /intern/ghost
parente2e0bc2c444dfa333d7c5c174a851c271fcd4732 (diff)
parent6132f8c4b49991ad7c60e15bfda6360a95a234aa (diff)
migrated NDOF code from soc-2010-merwin, SpaceNavigator now works on Mac blender
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/GHOST_C-api.h15
-rw-r--r--intern/ghost/GHOST_ISystem.h16
-rw-r--r--intern/ghost/GHOST_Types.h44
-rw-r--r--intern/ghost/SConscript2
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp17
-rw-r--r--intern/ghost/intern/GHOST_EventNDOF.h56
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp204
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.h49
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.h48
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.mm121
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerWin32.h47
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerX11.h100
-rw-r--r--intern/ghost/intern/GHOST_System.cpp31
-rw-r--r--intern/ghost/intern/GHOST_System.h19
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h7
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm10
16 files changed, 506 insertions, 280 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 75837239c4a..a315dfa85e9 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -288,21 +288,6 @@ extern GHOST_TSuccess GHOST_SetProgressBar(GHOST_WindowHandle windowhandle, floa
* @param windowhandle The handle to the window
*/
extern GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle);
-
-
-/***************************************************************************************
- ** N-degree of freedom device management functionality
- ***************************************************************************************/
-
-/**
-* Open N-degree of freedom devices
- */
-extern int GHOST_OpenNDOF(GHOST_SystemHandle systemhandle,
- GHOST_WindowHandle windowhandle,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen
- );
/***************************************************************************************
** Cursor management functionality
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 69e10070be5..015ae780bea 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -298,22 +298,6 @@ public:
*/
virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer* consumer) = 0;
- /***************************************************************************************
- ** N-degree of freedom device management functionality
- ***************************************************************************************/
-
- /**
- * Starts the N-degree of freedom device manager
- */
- virtual int openNDOF(GHOST_IWindow*,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen
- // original patch only
- // GHOST_NDOFEventHandler_fp setNdofEventHandler
- ) = 0;
-
-
/***************************************************************************************
** Cursor management functionality
***************************************************************************************/
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 705f4916619..7fa94b14716 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -439,37 +439,23 @@ typedef struct {
GHOST_TUns8 **strings;
} GHOST_TStringArray;
-
-/* original patch used floats, but the driver return ints and uns. We will calibrate in view, no sense on doing conversions twice */
-/* as all USB device controls are likely to use ints, this is also more future proof */
-//typedef struct {
-// /** N-degree of freedom device data */
-// float tx, ty, tz; /** -x left, +y up, +z forward */
-// float rx, ry, rz;
-// float dt;
-//} GHOST_TEventNDOFData;
+typedef struct {
+ /** N-degree of freedom device data v3 [GSoC 2010]*/
+ /* Each component normally ranges from -1 to +1, but can exceed that. */
+ float tx, ty, tz; /* translation: -x left, +y forward, -z up */
+ float rx, ry, rz; /* rotation:
+ axis = (rx,ry,rz).normalized
+ amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg] */
+ float dt; // time since previous NDOF Motion event (or zero if this is the first)
+} GHOST_TEventNDOFMotionData;
+
+typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction;
+ // good for mouse or other buttons too, hmmm?
typedef struct {
- /** N-degree of freedom device data v2*/
- int changed;
- GHOST_TUns64 client;
- GHOST_TUns64 address;
- GHOST_TInt16 tx, ty, tz; /** -x left, +y up, +z forward */
- GHOST_TInt16 rx, ry, rz;
- GHOST_TInt16 buttons;
- GHOST_TUns64 time;
- GHOST_TUns64 delta;
-} GHOST_TEventNDOFData;
-
-typedef int (*GHOST_NDOFLibraryInit_fp)(void);
-typedef void (*GHOST_NDOFLibraryShutdown_fp)(void* deviceHandle);
-typedef void* (*GHOST_NDOFDeviceOpen_fp)(void* platformData);
-
-// original patch windows callback. In mac os X version the callback is internal to the plug-in and post an event to main thead.
-// not necessary faster, but better integration with other events.
-
-//typedef int (*GHOST_NDOFEventHandler_fp)(float* result7, void* deviceHandle, unsigned int message, unsigned int* wParam, unsigned long* lParam);
-//typedef void (*GHOST_NDOFCallBack_fp)(GHOST_TEventNDOFDataV2 *VolDatas);
+ GHOST_TButtonAction action;
+ short button;
+} GHOST_TEventNDOFButtonData;
typedef struct {
/** The key code. */
diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript
index b67545f216a..3b144ba95cb 100644
--- a/intern/ghost/SConscript
+++ b/intern/ghost/SConscript
@@ -11,7 +11,7 @@ if window_system == 'darwin':
sources += env.Glob('intern/*.mm')
-pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_SystemPaths', 'GHOST_Window', 'GHOST_DropTarget']
+pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_SystemPaths', 'GHOST_Window', 'GHOST_DropTarget', 'GHOST_NDOFManager']
defs=['_USE_MATH_DEFINES']
if window_system in ('linux2', 'openbsd3', 'sunos5', 'freebsd7', 'freebsd8', 'freebsd9', 'irix6', 'aix4', 'aix5'):
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 7ba8d7db411..6332d72a42f 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -275,23 +275,6 @@ GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle)
}
-int GHOST_OpenNDOF(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen)
- //original patch only
- /* GHOST_NDOFEventHandler_fp setNdofEventHandler)*/
-{
- GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
-
- return system->openNDOF((GHOST_IWindow*) windowhandle,
- setNdofLibraryInit, setNdofLibraryShutdown, setNdofDeviceOpen);
-// original patch
-// setNdofLibraryInit, setNdofLibraryShutdown, setNdofDeviceOpen, setNdofEventHandler);
-}
-
-
-
GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
diff --git a/intern/ghost/intern/GHOST_EventNDOF.h b/intern/ghost/intern/GHOST_EventNDOF.h
index 70861b08fc6..394aff0493f 100644
--- a/intern/ghost/intern/GHOST_EventNDOF.h
+++ b/intern/ghost/intern/GHOST_EventNDOF.h
@@ -19,11 +19,6 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-
-/** \file ghost/intern/GHOST_EventNDOF.h
- * \ingroup GHOST
- */
-
#ifndef _GHOST_EVENT_NDOF_H_
@@ -31,32 +26,33 @@
#include "GHOST_Event.h"
-/**
- * N-degree of freedom device event.
- */
-class GHOST_EventNDOF : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * @param msec The time this event was generated.
- * @param type The type of this event.
- * @param x The x-coordinate of the location the cursor was at at the time of the event.
- * @param y The y-coordinate of the location the cursor was at at the time of the event.
- */
- GHOST_EventNDOF(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window,
- GHOST_TEventNDOFData data)
- : GHOST_Event(msec, type, window)
- {
- m_ndofEventData = data;
- m_data = &m_ndofEventData;
- }
-protected:
- /** translation & rotation from the device. */
- GHOST_TEventNDOFData m_ndofEventData;
-};
+class GHOST_EventNDOFMotion : public GHOST_Event
+ {
+ protected:
+ GHOST_TEventNDOFMotionData m_axisData;
+
+ public:
+ GHOST_EventNDOFMotion(GHOST_TUns64 time, GHOST_IWindow* window)
+ : GHOST_Event(time, GHOST_kEventNDOFMotion, window)
+ {
+ m_data = &m_axisData;
+ }
+ };
+
+
+class GHOST_EventNDOFButton : public GHOST_Event
+ {
+ protected:
+ GHOST_TEventNDOFButtonData m_buttonData;
+
+ public:
+ GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_IWindow* window)
+ : GHOST_Event(time, GHOST_kEventNDOFButton, window)
+ {
+ m_data = &m_buttonData;
+ }
+ };
#endif // _GHOST_EVENT_NDOF_H_
-
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index 7721b1708f9..1042398650e 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -15,120 +15,108 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * Contributor(s): none yet.
+ * Contributor(s):
+ * Mike Erwin
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file ghost/intern/GHOST_NDOFManager.cpp
- * \ingroup GHOST
- */
+#include "GHOST_NDOFManager.h"
+#include "GHOST_EventNDOF.h"
+#include "GHOST_WindowManager.h"
+#include <string.h> // for memory functions
+#include <stdio.h> // for debug tracing
+
+GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys)
+ : m_system(sys)
+ , m_buttons(0)
+ , m_motionTime(1000) // one full second (operators should filter out such large time deltas)
+ , m_prevMotionTime(0)
+ , m_atRest(true)
+ {
+ // to avoid the rare situation where one triple is updated and
+ // the other is not, initialize them both here:
+ memset(m_translation, 0, sizeof(m_translation));
+ memset(m_rotation, 0, sizeof(m_rotation));
+ }
+
+void GHOST_NDOFManager::updateTranslation(short t[3], GHOST_TUns64 time)
+ {
+ memcpy(m_translation, t, sizeof(m_translation));
+ m_motionTime = time;
+ m_atRest = false;
+ }
+
+void GHOST_NDOFManager::updateRotation(short r[3], GHOST_TUns64 time)
+ {
+ memcpy(m_rotation, r, sizeof(m_rotation));
+ m_motionTime = time;
+ m_atRest = false;
+ }
+
+void GHOST_NDOFManager::updateButtons(unsigned short buttons, GHOST_TUns64 time)
+ {
+ GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
+
+ unsigned short diff = m_buttons ^ buttons;
+
+ for (int i = 0; i < 16; ++i)
+ {
+ unsigned short mask = 1 << i;
+
+ if (diff & mask)
+ {
+ GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window);
+ GHOST_TEventNDOFButtonData* data = (GHOST_TEventNDOFButtonData*) event->getData();
+
+ data->action = (buttons & mask) ? GHOST_kPress : GHOST_kRelease;
+ data->button = i + 1;
+ // printf("sending button %d %s\n", data->button, (data->action == GHOST_kPress) ? "pressed" : "released");
-#include <stdio.h> /* just for printf */
+ m_system.pushEvent(event);
+ }
+ }
-#include "GHOST_NDOFManager.h"
+ m_buttons = buttons;
+ }
+bool GHOST_NDOFManager::sendMotionEvent()
+ {
+ if (m_atRest)
+ return false;
-// the variable is outside the class because it must be accessed from plugin
-static volatile GHOST_TEventNDOFData currentNdofValues = {0,0,0,0,0,0,0,0,0,0,0};
-
-#if !defined(_WIN32) && !defined(__APPLE__)
-#include "GHOST_SystemX11.h"
-#endif
-
-namespace
-{
- GHOST_NDOFLibraryInit_fp ndofLibraryInit = 0;
- GHOST_NDOFLibraryShutdown_fp ndofLibraryShutdown = 0;
- GHOST_NDOFDeviceOpen_fp ndofDeviceOpen = 0;
-}
-
-GHOST_NDOFManager::GHOST_NDOFManager()
-{
- m_DeviceHandle = 0;
-
- // discover the API from the plugin
- ndofLibraryInit = 0;
- ndofLibraryShutdown = 0;
- ndofDeviceOpen = 0;
-}
-
-GHOST_NDOFManager::~GHOST_NDOFManager()
-{
- if (ndofLibraryShutdown)
- ndofLibraryShutdown(m_DeviceHandle);
-
- m_DeviceHandle = 0;
-}
-
-
-int
-GHOST_NDOFManager::deviceOpen(GHOST_IWindow* window,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen)
-{
- int Pid;
-
- ndofLibraryInit = setNdofLibraryInit;
- ndofLibraryShutdown = setNdofLibraryShutdown;
- ndofDeviceOpen = setNdofDeviceOpen;
-
- if (ndofLibraryInit && ndofDeviceOpen)
- {
- Pid= ndofLibraryInit();
-#if 0
- printf("%i client \n", Pid);
-#endif
- #if defined(WITH_HEADLESS)
- /* do nothing */
- #elif defined(_WIN32) || defined(__APPLE__)
- m_DeviceHandle = ndofDeviceOpen((void *)&currentNdofValues);
- #else
- GHOST_SystemX11 *sys;
- sys = static_cast<GHOST_SystemX11*>(GHOST_ISystem::getSystem());
- void *ndofInfo = sys->prepareNdofInfo(&currentNdofValues);
- m_DeviceHandle = ndofDeviceOpen(ndofInfo);
- #endif
- return (Pid > 0) ? 0 : 1;
-
- } else
- return 1;
-}
-
-
-bool
-GHOST_NDOFManager::available() const
-{
- return m_DeviceHandle != 0;
-}
-
-bool
-GHOST_NDOFManager::event_present() const
-{
- if( currentNdofValues.changed >0) {
- printf("time %llu but%u x%i y%i z%i rx%i ry%i rz%i \n" ,
- currentNdofValues.time, currentNdofValues.buttons,
- currentNdofValues.tx,currentNdofValues.ty,currentNdofValues.tz,
- currentNdofValues.rx,currentNdofValues.ry,currentNdofValues.rz);
- return true;
- }else
- return false;
-
-}
-
-void GHOST_NDOFManager::GHOST_NDOFGetDatas(GHOST_TEventNDOFData &datas) const
-{
- datas.tx = currentNdofValues.tx;
- datas.ty = currentNdofValues.ty;
- datas.tz = currentNdofValues.tz;
- datas.rx = currentNdofValues.rx;
- datas.ry = currentNdofValues.ry;
- datas.rz = currentNdofValues.rz;
- datas.buttons = currentNdofValues.buttons;
- datas.client = currentNdofValues.client;
- datas.address = currentNdofValues.address;
- datas.time = currentNdofValues.time;
- datas.delta = currentNdofValues.delta;
-}
+ GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
+
+ GHOST_EventNDOFMotion* event = new GHOST_EventNDOFMotion(m_motionTime, window);
+ GHOST_TEventNDOFMotionData* data = (GHOST_TEventNDOFMotionData*) event->getData();
+
+ const float scale = 1.f / 350.f; // SpaceNavigator sends +/- 350 usually
+ // 350 according to their developer's guide; others recommend 500 as comfortable
+
+ // possible future enhancement
+ // scale *= m_sensitivity;
+
+ data->tx = -scale * m_translation[0];
+ data->ty = scale * m_translation[1];
+ data->tz = scale * m_translation[2];
+
+ data->rx = scale * m_rotation[0];
+ data->ry = scale * m_rotation[1];
+ data->rz = scale * m_rotation[2];
+
+ data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds
+
+ m_prevMotionTime = m_motionTime;
+
+ // printf("sending T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n",
+ // data->tx, data->ty, data->tz, data->rx, data->ry, data->rz, data->dt);
+
+ m_system.pushEvent(event);
+
+ // 'at rest' test goes at the end so that the first 'rest' event gets sent
+ m_atRest = m_rotation[0] == 0 && m_rotation[1] == 0 && m_rotation[2] == 0 &&
+ m_translation[0] == 0 && m_translation[1] == 0 && m_translation[2] == 0;
+
+ return true;
+ }
diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h
index c9e09370e09..f4adb4cab1d 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.h
+++ b/intern/ghost/intern/GHOST_NDOFManager.h
@@ -19,38 +19,47 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-
-/** \file ghost/intern/GHOST_NDOFManager.h
- * \ingroup GHOST
- */
-
#ifndef _GHOST_NDOFMANAGER_H_
#define _GHOST_NDOFMANAGER_H_
#include "GHOST_System.h"
-#include "GHOST_IWindow.h"
-
class GHOST_NDOFManager
{
public:
- GHOST_NDOFManager();
- virtual ~GHOST_NDOFManager();
-
- int deviceOpen(GHOST_IWindow* window,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen);
-
- void GHOST_NDOFGetDatas(GHOST_TEventNDOFData &datas) const;
-
- bool available() const;
- bool event_present() const;
+ GHOST_NDOFManager(GHOST_System&);
+
+ virtual ~GHOST_NDOFManager() {};
+
+ // whether multi-axis functionality is available (via the OS or driver)
+ // does not imply that a device is plugged in or being used
+ virtual bool available() = 0;
+
+ // the latest raw data from the device
+ void updateTranslation(short t[3], GHOST_TUns64 time);
+ void updateRotation(short r[3], GHOST_TUns64 time);
+ // this one sends events immediately for changed buttons
+ void updateButtons(unsigned short b, GHOST_TUns64 time);
+
+ // processes most recent raw data into an NDOFMotion event and sends it
+ // returns whether an event was sent
+ virtual bool sendMotionEvent();
protected:
- void* m_DeviceHandle;
+ GHOST_System& m_system;
+
+ short m_translation[3];
+ short m_rotation[3];
+ unsigned short m_buttons;
+
+ GHOST_TUns64 m_motionTime;
+ GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent
+ bool m_atRest;
+
+ void updateMotionTime(GHOST_TUns64 t);
+ void resetMotion();
};
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
new file mode 100644
index 00000000000..efe840bab4a
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
@@ -0,0 +1,48 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s):
+ * Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _GHOST_NDOFMANAGERCOCOA_H_
+#define _GHOST_NDOFMANAGERCOCOA_H_
+
+#include "GHOST_NDOFManager.h"
+
+// Event capture is handled within the NDOFManager on Macintosh,
+// so there's no need for SystemCocoa to look for them.
+
+class GHOST_NDOFManagerCocoa : public GHOST_NDOFManager
+{
+public:
+ GHOST_NDOFManagerCocoa(GHOST_System&);
+
+ ~GHOST_NDOFManagerCocoa();
+
+ // whether multi-axis functionality is available (via the OS or driver)
+ // does not imply that a device is plugged in or being used
+ bool available();
+
+private:
+ unsigned short m_clientID;
+};
+
+
+#endif
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
new file mode 100644
index 00000000000..75a96556ff1
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
@@ -0,0 +1,121 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s):
+ * Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GHOST_NDOFManagerCocoa.h"
+#include "GHOST_SystemCocoa.h"
+
+extern "C" {
+ #include <3DconnexionClient/ConnexionClientAPI.h>
+ #include <stdio.h>
+ }
+
+static void SpaceNavAdded(io_connect_t connection)
+ {
+ printf("SpaceNav added\n"); // change these: printf --> informational reports
+ }
+
+static void SpaceNavRemoved(io_connect_t connection)
+ {
+ printf("SpaceNav removed\n");
+ }
+
+static void SpaceNavEvent(io_connect_t connection, natural_t messageType, void* messageArgument)
+ {
+ GHOST_SystemCocoa* system = (GHOST_SystemCocoa*) GHOST_ISystem::getSystem();
+ GHOST_NDOFManager* manager = system->getNDOFManager();
+ switch (messageType)
+ {
+ case kConnexionMsgDeviceState:
+ {
+ ConnexionDeviceState* s = (ConnexionDeviceState*)messageArgument;
+
+ GHOST_TUns64 now = system->getMilliSeconds();
+
+ switch (s->command)
+ {
+ case kConnexionCmdHandleAxis:
+ manager->updateTranslation(s->axis, now);
+ manager->updateRotation(s->axis + 3, now);
+ system->notifyExternalEventProcessed();
+ break;
+
+ case kConnexionCmdHandleButtons:
+ manager->updateButtons(s->buttons, now);
+ system->notifyExternalEventProcessed();
+ break;
+
+ default:
+ printf("device state command %d\n", s->command);
+ }
+ break;
+ }
+ case kConnexionMsgPrefsChanged:
+ printf("prefs changed\n"); // this includes app switches
+ break;
+ case kConnexionMsgDoAction:
+ printf("do action\n"); // no idea what this means
+ // 'calibrate device' in System Prefs sends this
+ // 3Dx header file says to ignore these
+ break;
+ default:
+ printf("<!> mystery event\n");
+ }
+ }
+
+GHOST_NDOFManagerCocoa::GHOST_NDOFManagerCocoa(GHOST_System& sys)
+ : GHOST_NDOFManager(sys)
+ {
+ if (available())
+ {
+ OSErr error = InstallConnexionHandlers(SpaceNavEvent, SpaceNavAdded, SpaceNavRemoved);
+ if (error)
+ {
+ printf("<!> error = %d\n", error);
+ return;
+ }
+
+ // Pascal string *and* a four-letter constant. How old-skool.
+ m_clientID = RegisterConnexionClient('blnd', (UInt8*) "\pblender",
+ kConnexionClientModeTakeOver, kConnexionMaskAll);
+
+ printf("client id = %d\n", m_clientID);
+ }
+ else
+ {
+ printf("<!> SpaceNav driver not found\n");
+ // This isn't a hard error, just means the user doesn't have a SpaceNavigator.
+ }
+ }
+
+GHOST_NDOFManagerCocoa::~GHOST_NDOFManagerCocoa()
+ {
+ UnregisterConnexionClient(m_clientID);
+ CleanupConnexionHandlers();
+ }
+
+bool GHOST_NDOFManagerCocoa::available()
+ {
+// extern OSErr InstallConnexionHandlers() __attribute__((weak_import));
+// ^-- not needed since the entire framework is weak-linked
+ return InstallConnexionHandlers != NULL;
+ }
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.h b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
new file mode 100644
index 00000000000..0570eefa951
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
@@ -0,0 +1,47 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s):
+ * Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _GHOST_NDOFMANAGERWIN32_H_
+#define _GHOST_NDOFMANAGERWIN32_H_
+
+#include "GHOST_NDOFManager.h"
+
+
+class GHOST_NDOFManagerWin32 : public GHOST_NDOFManager
+{
+public:
+ GHOST_NDOFManagerWin32(GHOST_System& sys)
+ : GHOST_NDOFManager(sys)
+ {}
+
+ // whether multi-axis functionality is available (via the OS or driver)
+ // does not imply that a device is plugged in or being used
+ bool available()
+ {
+ // always available since RawInput is built into Windows
+ return true;
+ }
+};
+
+
+#endif
diff --git a/intern/ghost/intern/GHOST_NDOFManagerX11.h b/intern/ghost/intern/GHOST_NDOFManagerX11.h
new file mode 100644
index 00000000000..4c89bfe0ca6
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerX11.h
@@ -0,0 +1,100 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _GHOST_NDOFMANAGERX11_H_
+#define _GHOST_NDOFMANAGERX11_H_
+
+#include "GHOST_NDOFManager.h"
+#include "GHOST_Types.h"
+#include "GHOST_WindowX11.h"
+#include "GHOST_EventNDOF.h"
+#include <X11/Xlib.h>
+#include <stdio.h>
+
+class GHOST_NDOFManagerX11 : public GHOST_NDOFManager
+{
+GHOST_WindowX11 * m_ghost_window_x11;
+
+public:
+ GHOST_NDOFManagerX11(GHOST_System& sys)
+ : GHOST_NDOFManager(sys)
+ {}
+
+ void setGHOSTWindowX11(GHOST_WindowX11 * w){
+ if (m_ghost_window_x11 == NULL)
+ m_ghost_window_x11 = w;
+ }
+
+ GHOST_WindowX11 * getGHOSTWindowX11(){
+ return m_ghost_window_x11;
+ }
+
+ // whether multi-axis functionality is available (via the OS or driver)
+ // does not imply that a device is plugged in or being used
+ bool available()
+ {
+ // never available since I've not yet written it!
+ return true;
+ }
+
+ virtual bool sendMotionEvent()
+ {
+ if (m_atRest)
+ return false;
+
+ GHOST_EventNDOFMotion* event = new GHOST_EventNDOFMotion(m_motionTime, getGHOSTWindowX11());
+ GHOST_TEventNDOFMotionData* data = (GHOST_TEventNDOFMotionData*) event->getData();
+
+ const float scale = 1.f/350.f; // SpaceNavigator sends +/- 350 usually
+ // 350 according to their developer's guide; others recommend 500 as comfortable
+
+ // possible future enhancement
+ // scale *= m_sensitivity;
+
+ data->tx = -scale * m_translation[0];
+ data->ty = scale * m_translation[1];
+ data->tz = scale * m_translation[2];
+
+ data->rx = scale * m_rotation[0];
+ data->ry = scale * m_rotation[1];
+ data->rz = scale * m_rotation[2];
+
+ data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds
+
+ m_prevMotionTime = m_motionTime;
+
+ printf("sending T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n",
+ data->tx, data->ty, data->tz, data->rx, data->ry, data->rz, data->dt);
+
+ if (!m_system.pushEvent(event))
+ return false;
+
+ // 'at rest' test goes at the end so that the first 'rest' event gets sent
+ m_atRest = m_rotation[0] == 0 && m_rotation[1] == 0 && m_rotation[2] == 0 &&
+ m_translation[0] == 0 && m_translation[1] == 0 && m_translation[2] == 0;
+
+ return true;
+ }
+};
+
+
+#endif
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index cb3e97fc574..792adba7ce3 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -194,12 +194,15 @@ bool GHOST_System::getFullScreen(void)
bool GHOST_System::dispatchEvents()
{
- bool handled;
- if (m_eventManager) {
- handled = m_eventManager->dispatchEvents();
+ bool handled = false;
+
+ // NDOF Motion event is sent only once per dispatch, so do it now:
+ if (m_ndofManager) {
+ handled |= m_ndofManager->sendMotionEvent();
}
- else {
- handled = false;
+
+ if (m_eventManager) {
+ handled |= m_eventManager->dispatchEvents();
}
m_timerManager->fireTimers(getMilliSeconds());
@@ -243,18 +246,6 @@ GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent* event)
return success;
}
-int GHOST_System::openNDOF(GHOST_IWindow* w,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen)
-{
- return m_ndofManager->deviceOpen(w,
- setNdofLibraryInit,
- setNdofLibraryShutdown,
- setNdofDeviceOpen);
-}
-
-
GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const
{
GHOST_ModifierKeys keys;
@@ -285,12 +276,6 @@ GHOST_TSuccess GHOST_System::init()
m_timerManager = new GHOST_TimerManager ();
m_windowManager = new GHOST_WindowManager ();
m_eventManager = new GHOST_EventManager ();
- m_ndofManager = new GHOST_NDOFManager();
-
-#if 0
- if(m_ndofManager)
- printf("ndof manager \n");
-#endif
#ifdef GHOST_DEBUG
if (m_eventManager) {
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index b5c64bfceb6..f62c0984c80 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -191,25 +191,6 @@ public:
virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer* consumer);
/***************************************************************************************
- ** N-degree of freedom devcice management functionality
- ***************************************************************************************/
-
- /** Inherited from GHOST_ISystem
- * Opens the N-degree of freedom device manager
- * return 0 if device found, 1 otherwise
- */
- virtual int openNDOF(GHOST_IWindow* w,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen);
-
-// original patch only
-// GHOST_NDOFEventHandler_fp setNdofEventHandler);
-
-
-
-
- /***************************************************************************************
** Cursor management functionality
***************************************************************************************/
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index e7a8178a382..882c365cdb1 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -229,6 +229,11 @@ public:
GHOST_TSuccess handleApplicationBecomeActiveEvent();
/**
+ * External objects should call this when they send an event outside processEvents.
+ */
+ void notifyExternalEventProcessed();
+
+ /**
* @see GHOST_ISystem
*/
int toggleConsole(int action) { return 0; }
@@ -275,7 +280,7 @@ protected:
/** Start time at initialization. */
GHOST_TUns64 m_start_time;
- /** Event has been processed directly by Cocoa and has sent a ghost event to be dispatched */
+ /** Event has been processed directly by Cocoa (or NDOF manager) and has sent a ghost event to be dispatched */
bool m_outsideLoopEventProcessed;
/** Raised window is not yet known by the window manager, so delay application become active event handling */
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index bf401138cf1..1cc692e7b78 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -52,7 +52,7 @@
#include "GHOST_TimerTask.h"
#include "GHOST_WindowManager.h"
#include "GHOST_WindowCocoa.h"
-#include "GHOST_NDOFManager.h"
+#include "GHOST_NDOFManagerCocoa.h"
#include "AssertMacros.h"
#pragma mark KeyMap, mouse converters
@@ -596,6 +596,9 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
GHOST_TSuccess success = GHOST_System::init();
if (success) {
+
+ m_ndofManager = new GHOST_NDOFManagerCocoa(*this);
+
//ProcessSerialNumber psn;
//Carbon stuff to move window & menu to foreground
@@ -1027,6 +1030,11 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
return GHOST_kSuccess;
}
+void GHOST_SystemCocoa::notifyExternalEventProcessed()
+{
+ m_outsideLoopEventProcessed = true;
+}
+
//Note: called from NSWindow delegate
GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window)
{