SpaceNav works on Linux
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
86
intern/ghost/intern/GHOST_NDOFManagerX11.cpp
Normal file
86
intern/ghost/intern/GHOST_NDOFManagerX11.cpp
Normal 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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -215,7 +215,6 @@ GHOST_SystemWin32::~GHOST_SystemWin32()
|
||||
// Shutdown COM
|
||||
OleUninitialize();
|
||||
toggleConsole(1);
|
||||
delete m_ndofManager;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user