revamped NDOF event system for ghost, added (untested) Mac support
This commit is contained in:
@@ -154,7 +154,8 @@ typedef enum {
|
||||
GHOST_kEventTrackpad, /// Trackpad event
|
||||
|
||||
GHOST_kEventNDOFMotion, /// N degree of freedom device motion event
|
||||
GHOST_kEventNDOFButton, /// N degree of freedom device button event
|
||||
GHOST_kEventNDOFButtonDown,/// N degree of freedom device button events
|
||||
GHOST_kEventNDOFButtonUp,
|
||||
|
||||
GHOST_kEventKeyDown,
|
||||
GHOST_kEventKeyUp,
|
||||
@@ -432,17 +433,17 @@ typedef struct {
|
||||
// float dt;
|
||||
//} GHOST_TEventNDOFData;
|
||||
|
||||
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 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 struct {
|
||||
/** N-degree of freedom device data v3 [GSoC 2010]*/
|
||||
@@ -454,13 +455,8 @@ typedef struct {
|
||||
|
||||
float tx, ty, tz; /** -x left, +y forward, -z up */
|
||||
float rx, ry, rz;
|
||||
GHOST_TInt16 buttons;
|
||||
} GHOST_TEventNDOFData_3;
|
||||
} GHOST_TEventNDOFData;
|
||||
|
||||
// [mce] consider scrapping these, in favor of built-in SpaceNav handling.
|
||||
typedef int (*GHOST_NDOFLibraryInit_fp)();
|
||||
typedef void (*GHOST_NDOFLibraryShutdown_fp)(void* deviceHandle);
|
||||
typedef void* (*GHOST_NDOFDeviceOpen_fp)(void* platformData);
|
||||
|
||||
typedef struct {
|
||||
/** The key code. */
|
||||
|
||||
@@ -26,32 +26,35 @@
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
class GHOST_EventNDOFMotion : public GHOST_Event
|
||||
{
|
||||
protected:
|
||||
/** translation & rotation from the device. */
|
||||
GHOST_TEventNDOFData m_ndofEventData;
|
||||
GHOST_TEventNDOFData m_axisData;
|
||||
|
||||
public:
|
||||
GHOST_EventNDOFMotion(GHOST_TUns64 time)
|
||||
: GHOST_Event(time, GHOST_kEventNDOFMotion, NULL)
|
||||
// , m_data(&m_axisData)
|
||||
{
|
||||
m_data = &m_axisData;
|
||||
}
|
||||
};
|
||||
|
||||
class GHOST_EventNDOFButton : public GHOST_Event
|
||||
{
|
||||
protected:
|
||||
GHOST_TUns16 m_buttonNumber;
|
||||
|
||||
public:
|
||||
GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_TUns16 buttonNumber, GHOST_TEventType upOrDown)
|
||||
: GHOST_Event(time, upOrDown, NULL)
|
||||
, m_buttonNumber(buttonNumber)
|
||||
// , m_data(&m_buttonNumber)
|
||||
{
|
||||
m_data = &m_buttonNumber;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // _GHOST_EVENT_NDOF_H_
|
||||
|
||||
|
||||
@@ -20,108 +20,70 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* just for printf */
|
||||
|
||||
#include "GHOST_NDOFManager.h"
|
||||
#include "GHOST_EventNDOF.h"
|
||||
|
||||
GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys)
|
||||
: m_system(sys)
|
||||
// , m_translation((short[]){0,0,0})
|
||||
// , m_rotation((short[]){0,0,0})
|
||||
, m_buttons(0)
|
||||
, m_atRest(true)
|
||||
{ }
|
||||
|
||||
// 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};
|
||||
void GHOST_NDOFManager::updateTranslation(short t[3], GHOST_TUns64 time)
|
||||
{
|
||||
memcpy(m_translation, t, sizeof(m_translation));
|
||||
m_motionTime = time;
|
||||
m_atRest = false;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
#include "GHOST_SystemX11.h"
|
||||
#endif
|
||||
void GHOST_NDOFManager::updateRotation(short r[3], GHOST_TUns64 time)
|
||||
{
|
||||
memcpy(m_rotation, r, sizeof(m_rotation));
|
||||
m_motionTime = time;
|
||||
m_atRest = false;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
GHOST_NDOFLibraryInit_fp ndofLibraryInit = 0;
|
||||
GHOST_NDOFLibraryShutdown_fp ndofLibraryShutdown = 0;
|
||||
GHOST_NDOFDeviceOpen_fp ndofDeviceOpen = 0;
|
||||
}
|
||||
void GHOST_NDOFManager::updateButtons(unsigned short buttons, GHOST_TUns64 time)
|
||||
{
|
||||
unsigned short diff = m_buttons ^ buttons;
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
unsigned short mask = 1 << i;
|
||||
if (diff & mask)
|
||||
m_system.pushEvent(new GHOST_EventNDOFButton(time, i + 1,
|
||||
(buttons & mask) ? GHOST_kEventNDOFButtonDown : GHOST_kEventNDOFButtonUp));
|
||||
}
|
||||
|
||||
GHOST_NDOFManager::GHOST_NDOFManager()
|
||||
{
|
||||
m_DeviceHandle = 0;
|
||||
m_buttons = buttons;
|
||||
}
|
||||
|
||||
// discover the API from the plugin
|
||||
ndofLibraryInit = 0;
|
||||
ndofLibraryShutdown = 0;
|
||||
ndofDeviceOpen = 0;
|
||||
}
|
||||
bool GHOST_NDOFManager::sendMotionEvent()
|
||||
{
|
||||
if (m_atRest)
|
||||
return false;
|
||||
|
||||
GHOST_NDOFManager::~GHOST_NDOFManager()
|
||||
{
|
||||
if (ndofLibraryShutdown)
|
||||
ndofLibraryShutdown(m_DeviceHandle);
|
||||
GHOST_EventNDOFMotion* event = new GHOST_EventNDOFMotion(m_motionTime);
|
||||
GHOST_TEventNDOFData* data = (GHOST_TEventNDOFData*) event->getData();
|
||||
|
||||
m_DeviceHandle = 0;
|
||||
}
|
||||
const float scale = 1.f / 350.f; // SpaceNavigator sends +/- 350 usually
|
||||
|
||||
// scale *= m_sensitivity;
|
||||
|
||||
int
|
||||
GHOST_NDOFManager::deviceOpen(GHOST_IWindow* window,
|
||||
GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
|
||||
GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
|
||||
GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen)
|
||||
{
|
||||
int Pid;
|
||||
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];
|
||||
|
||||
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;
|
||||
|
||||
ndofLibraryInit = setNdofLibraryInit;
|
||||
ndofLibraryShutdown = setNdofLibraryShutdown;
|
||||
ndofDeviceOpen = setNdofDeviceOpen;
|
||||
|
||||
if (ndofLibraryInit && ndofDeviceOpen)
|
||||
{
|
||||
Pid= ndofLibraryInit();
|
||||
#if 0
|
||||
printf("%i client \n", Pid);
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
m_DeviceHandle = ndofDeviceOpen((void *)¤tNdofValues);
|
||||
#else
|
||||
GHOST_SystemX11 *sys;
|
||||
sys = static_cast<GHOST_SystemX11*>(GHOST_ISystem::getSystem());
|
||||
void *ndofInfo = sys->prepareNdofInfo(¤tNdofValues);
|
||||
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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,28 +24,38 @@
|
||||
#define _GHOST_NDOFMANAGER_H_
|
||||
|
||||
#include "GHOST_System.h"
|
||||
#include "GHOST_IWindow.h"
|
||||
|
||||
|
||||
|
||||
class GHOST_NDOFManager
|
||||
{
|
||||
public:
|
||||
GHOST_NDOFManager();
|
||||
virtual ~GHOST_NDOFManager();
|
||||
GHOST_NDOFManager(GHOST_System&);
|
||||
|
||||
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;
|
||||
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
|
||||
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;
|
||||
bool m_atRest;
|
||||
};
|
||||
|
||||
|
||||
|
||||
111
intern/ghost/intern/GHOST_NDOFManagerCocoa.cpp
Normal file
111
intern/ghost/intern/GHOST_NDOFManagerCocoa.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* ***** 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 *****
|
||||
*/
|
||||
|
||||
#include "GHOST_NDOFManagerCocoa.h"
|
||||
#include <3DconnexionClient/ConnexionClientAPI.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void SpaceNavAdded(io_connect_t connection)
|
||||
{
|
||||
printf("SpaceNav added\n");
|
||||
}
|
||||
|
||||
static void SpaceNavRemoved(io_connect_t connection)
|
||||
{
|
||||
printf("SpaceNav removed\n");
|
||||
}
|
||||
|
||||
static void SpaceNavEvent(io_connect_t connection, natural_t messageType, void *messageArgument)
|
||||
{
|
||||
GHOST_System* system = (GHOST_System*) GHOST_ISystem::getSystem();
|
||||
GHOST_NDOFManager* manager = system->getNDOFManager();
|
||||
switch (messageType)
|
||||
{
|
||||
case kConnexionMsgDeviceState:
|
||||
{
|
||||
ConnexionDeviceState* s = (ConnexionDeviceState*)messageArgument;
|
||||
switch (s->command)
|
||||
{
|
||||
case kConnexionCmdHandleAxis:
|
||||
manager->updateTranslation(s->axis, s->time);
|
||||
manager->updateRotation(s->axis + 3, s->time);
|
||||
break;
|
||||
|
||||
case kConnexionCmdHandleButtons:
|
||||
manager->updateButtons(s->buttons, s->time);
|
||||
break;
|
||||
}
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
// char* name = "\pBlender";
|
||||
// name[0] = 7; // convert to Pascal string
|
||||
|
||||
m_clientID = RegisterConnexionClient('blnd', (UInt8*) "\pBlender"/*name*/,
|
||||
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));
|
||||
// [mce] C likes the above line, but Obj-C++ does not. Make sure it works for
|
||||
// machines without the driver installed! Try it on the QuickSilver.
|
||||
|
||||
return InstallConnexionHandlers != NULL;
|
||||
}
|
||||
45
intern/ghost/intern/GHOST_NDOFManagerCocoa.h
Normal file
45
intern/ghost/intern/GHOST_NDOFManagerCocoa.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* ***** 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_NDOFMANAGERCOCOA_H_
|
||||
#define _GHOST_NDOFMANAGERCOCOA_H_
|
||||
|
||||
#include "GHOST_NDOFManager.h"
|
||||
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user