SpaceNav works on Linux

This commit is contained in:
2011-06-11 00:25:48 +00:00
parent 30fb5710b6
commit 7b124242e7
12 changed files with 178 additions and 106 deletions

View File

@@ -47,11 +47,6 @@ typedef unsigned short GHOST_TUns16;
typedef int GHOST_TInt32;
typedef unsigned int GHOST_TUns32;
#ifdef WIN32
#define WM_BLND_NDOF_AXIS WM_USER + 1
#define WM_BLND_NDOF_BTN WM_USER + 2
#endif
#if defined(WIN32) && !defined(FREE_WINDOWS)
typedef __int64 GHOST_TInt64;
typedef unsigned __int64 GHOST_TUns64;

View File

@@ -42,7 +42,7 @@
#include "GHOST_EventManager.h"
#include <algorithm>
#include "GHOST_Debug.h"
#include <stdio.h> // [mce] temp debug
GHOST_EventManager::GHOST_EventManager()
{
@@ -111,6 +111,7 @@ GHOST_TSuccess GHOST_EventManager::pushEvent(GHOST_IEvent* event)
bool GHOST_EventManager::dispatchEvent(GHOST_IEvent* event)
{
bool handled;
printf("dispatching %d\n", event->getType());
if (event) {
handled = true;
TConsumerVector::iterator iter;

View File

@@ -16,7 +16,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s):
* Mike Erwin
* Mike Erwin
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -54,11 +54,32 @@ void GHOST_NDOFManager::updateRotation(short r[3], GHOST_TUns64 time)
m_atRest = false;
}
void GHOST_NDOFManager::updateButtons(unsigned short buttons, GHOST_TUns64 time)
void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64 time)
{
GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
unsigned short diff = m_buttons ^ buttons;
GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window);
GHOST_TEventNDOFButtonData* data = (GHOST_TEventNDOFButtonData*) event->getData();
data->action = press ? GHOST_kPress : GHOST_kRelease;
data->button = button_number + 1;
printf("sending button %d %s\n", data->button, (data->action == GHOST_kPress) ? "pressed" : "released");
m_system.pushEvent(event);
unsigned short mask = 1 << button_number;
if (press)
m_buttons |= mask; // set this button's bit
else
m_buttons &= ~mask; // clear this button's bit
}
void GHOST_NDOFManager::updateButtons(unsigned short button_bits, GHOST_TUns64 time)
{
GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
unsigned short diff = m_buttons ^ button_bits;
for (int i = 0; i < 16; ++i)
{
@@ -69,16 +90,16 @@ void GHOST_NDOFManager::updateButtons(unsigned short buttons, GHOST_TUns64 time)
GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window);
GHOST_TEventNDOFButtonData* data = (GHOST_TEventNDOFButtonData*) event->getData();
data->action = (buttons & mask) ? GHOST_kPress : GHOST_kRelease;
data->action = (button_bits & mask) ? GHOST_kPress : GHOST_kRelease;
data->button = i + 1;
// printf("sending button %d %s\n", data->button, (data->action == GHOST_kPress) ? "pressed" : "released");
printf("sending button %d %s\n", data->button, (data->action == GHOST_kPress) ? "pressed" : "released");
m_system.pushEvent(event);
}
}
m_buttons = buttons;
m_buttons = button_bits;
}
bool GHOST_NDOFManager::sendMotionEvent()
@@ -109,14 +130,16 @@ bool GHOST_NDOFManager::sendMotionEvent()
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);
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;
// this needs to be aware of calibration -- 0.01 0.01 0.03 might be 'rest'
return true;
}

View File

@@ -15,7 +15,8 @@
* 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 *****
*/
@@ -40,27 +41,28 @@ public:
// 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);
// send events immediately for changed buttons
void updateButton(int button_number, bool press, GHOST_TUns64 time);
void updateButtons(unsigned short button_bits, GHOST_TUns64 time);
// processes most recent raw data into an NDOFMotion event and sends it
// returns whether an event was sent
virtual bool sendMotionEvent();
bool sendMotionEvent();
protected:
GHOST_System& m_system;
short m_translation[3];
short m_rotation[3];
unsigned short m_buttons;
unsigned short m_buttons; // bit field
GHOST_TUns64 m_motionTime;
GHOST_TUns64 m_motionTime; // in milliseconds
GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent
bool m_atRest;
void updateMotionTime(GHOST_TUns64 t);
void resetMotion();
// void updateMotionTime(GHOST_TUns64 t);
// void resetMotion();
};
#endif

View File

@@ -0,0 +1,86 @@
/*
* ***** 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_NDOFManagerX11.h"
#include "GHOST_SystemX11.h"
#include <spnav.h>
#include <stdio.h>
GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys)
: GHOST_NDOFManager(sys)
{
if (spnav_open() != -1)
{
m_available = true;
}
else
{
printf("<!> SpaceNav driver not found\n");
// This isn't a hard error, just means the user doesn't have a SpaceNavigator.
m_available = false;
}
}
GHOST_NDOFManagerX11::~GHOST_NDOFManagerX11()
{
if (m_available)
{
spnav_remove_events(SPNAV_EVENT_ANY); // ask nuclear if this is needed
spnav_close();
}
}
bool GHOST_NDOFManagerX11::available()
{
return m_available;
}
bool GHOST_NDOFManagerX11::processEvents()
{
GHOST_TUns64 now = m_system.getMilliSeconds();
bool anyProcessed = false;
spnav_event e;
while (spnav_poll_event(&e))
{
switch (e.type)
{
case SPNAV_EVENT_MOTION:
{
short t[3] = {e.motion.x, e.motion.y, e.motion.z};
short r[3] = {e.motion.rx, e.motion.ry, e.motion.rz};
updateTranslation(t, now);
updateRotation(r, now);
break;
}
case SPNAV_EVENT_BUTTON:
updateButton(e.button.bnum, e.button.press, now);
break;
}
anyProcessed = true;
}
return anyProcessed;
}

View File

@@ -15,7 +15,8 @@
* 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 *****
*/
@@ -24,77 +25,18 @@
#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;
}
};
GHOST_NDOFManagerX11(GHOST_System&);
~GHOST_NDOFManagerX11();
bool available();
bool processEvents();
private:
bool m_available;
};
#endif

View File

@@ -215,7 +215,6 @@ GHOST_SystemWin32::~GHOST_SystemWin32()
// Shutdown COM
OleUninitialize();
toggleConsole(1);
delete m_ndofManager;
}

View File

@@ -42,8 +42,7 @@
#include "GHOST_EventKey.h"
#include "GHOST_EventButton.h"
#include "GHOST_EventWheel.h"
#include "GHOST_EventNDOF.h"
#include "GHOST_NDOFManager.h"
#include "GHOST_NDOFManagerX11.h"
#include "GHOST_DisplayManagerX11.h"
#include "GHOST_Debug.h"
@@ -76,6 +75,8 @@
#include <stdio.h> // for fprintf only
#include <cstdlib> // for exit
#if 0 // obsolete SpaceNav code
typedef struct NDOFPlatformInfo {
Display *display;
Window window;
@@ -88,6 +89,7 @@ typedef struct NDOFPlatformInfo {
static NDOFPlatformInfo sNdofInfo = {NULL, 0, NULL, 0, 0, 0, 0};
#endif
//these are for copy and select copy
static char *txt_cut_buffer= NULL;
@@ -177,6 +179,7 @@ init(
GHOST_TSuccess success = GHOST_System::init();
if (success) {
m_ndofManager = new GHOST_NDOFManagerX11(*this);
m_displayManager = new GHOST_DisplayManagerX11(this);
if (m_displayManager) {
@@ -270,7 +273,7 @@ createWindow(
if (window->getValid()) {
// Store the pointer to the window
m_windowManager->addWindow(window);
m_windowManager->setActiveWindow(window);
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
}
else {
@@ -381,8 +384,6 @@ lastEventTime(Time default_time) {
return data.timestamp;
}
bool
GHOST_SystemX11::
processEvents(
@@ -423,6 +424,11 @@ processEvents(
if (generateWindowExposeEvents()) {
anyProcessed = true;
}
if (dynamic_cast<GHOST_NDOFManagerX11*>(m_ndofManager)->processEvents()) {
anyProcessed = true;
}
} while (waitForEvent && !anyProcessed);
return anyProcessed;
@@ -636,6 +642,9 @@ GHOST_SystemX11::processEvent(XEvent *xe)
);
} else
#endif
#if 0 // obsolete SpaceNav code
if (sNdofInfo.currValues) {
static GHOST_TEventNDOFData data = {0,0,0,0,0,0,0,0,0,0,0};
if (xcme.message_type == sNdofInfo.motionAtom)
@@ -661,7 +670,10 @@ GHOST_SystemX11::processEvent(XEvent *xe)
GHOST_kEventNDOFButton,
window, data);
}
} else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
#endif
if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
XWindowAttributes attr;
Window fwin;
int revert_to;
@@ -829,6 +841,8 @@ GHOST_SystemX11::processEvent(XEvent *xe)
}
}
#if 0 // obsolete SpaceNav code
void *
GHOST_SystemX11::
prepareNdofInfo(volatile GHOST_TEventNDOFData *currentNdofValues)
@@ -841,6 +855,8 @@ prepareNdofInfo(volatile GHOST_TEventNDOFData *currentNdofValues)
return (void*)&sNdofInfo;
}
#endif
GHOST_TSuccess
GHOST_SystemX11::
getModifierKeys(

View File

@@ -203,11 +203,15 @@ public:
return m_display;
}
#if 0 // obsolete SpaceNav code
void *
prepareNdofInfo(
volatile GHOST_TEventNDOFData *current_values
);
#endif
/* Helped function for get data from the clipboard. */
void getClipboard_xcout(XEvent evt, Atom sel, Atom target,
unsigned char **txt, unsigned long *len,

View File

@@ -958,10 +958,6 @@ static int viewndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
RegionView3D* rv3d = CTX_wm_region_view3d(C);
if (dt > 0.25f)
/* this is probably the first event for this motion, so set dt to something reasonable */
dt = 0.0125f;
/* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
float phi, q1[4];
float m[3][3];
@@ -970,6 +966,10 @@ static int viewndof_invoke(bContext *C, wmOperator *op, wmEvent *event)
const float sensitivity = 0.035;
if (dt > 0.25f)
/* this is probably the first event for this motion, so set dt to something reasonable */
dt = 0.0125f;
/* Get the 3x3 matrix and its inverse from the quaternion */
quat_to_mat3(m,rv3d->viewquat);
invert_m3_m3(m_inv,m);

View File

@@ -2375,7 +2375,9 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
{
wmWindow *owin;
wmEvent event, *evt= win->eventstate;
printf("ghost (%d) --> wm\n", type);
/* initialize and copy state (only mouse x y and modifiers) */
event= *evt;
@@ -2579,6 +2581,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
}
case GHOST_kEventNDOFMotion: {
puts("ndof motion in wm");
event.type = NDOF_MOTION;
attach_ndof_data(&event, customdata);
wm_event_add(win, &event);
@@ -2588,6 +2591,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
case GHOST_kEventNDOFButton: {
GHOST_TEventNDOFButtonData* e = customdata;
puts("ndof button in wm");
event.type = NDOF_BUTTON_NONE + e->button;

View File

@@ -621,12 +621,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
if (!ghostwin) {
// XXX - should be checked, why are we getting an event here, and
// what is it?
puts("<!> event has no window");
return 1;
} else if (!GHOST_ValidWindow(g_system, ghostwin)) {
// XXX - should be checked, why are we getting an event here, and
// what is it?
puts("<!> event has invalid window");
return 1;
} else {
win= GHOST_GetWindowUserData(ghostwin);