Index: intern/ghost/intern/GHOST_SystemX11.h =================================================================== --- intern/ghost/intern/GHOST_SystemX11.h (revisão 34074) +++ intern/ghost/intern/GHOST_SystemX11.h (cópia de trabalho) @@ -215,6 +215,12 @@ unsigned int *context) const; /** + * Create the atoms used by ndof events + * @param display Current display + */ + void createNDOFAtoms(Display * display); + + /** * Returns unsinged char from CUT_BUFFER0 * @param selection Get selection, X11 only feature * @return Returns the Clipboard indicated by Flag @@ -276,6 +282,14 @@ Atom m_incr; Atom m_utf8_string; + /** + * Atoms for NDOF + */ + Atom motion_event; + Atom button_press_event; + Atom button_release_event; + Atom command_event; + private : Display * m_display; Index: intern/ghost/intern/GHOST_NDOFManager.h =================================================================== --- intern/ghost/intern/GHOST_NDOFManager.h (revisão 34074) +++ intern/ghost/intern/GHOST_NDOFManager.h (cópia de trabalho) @@ -45,7 +45,7 @@ // processes most recent raw data into an NDOFMotion event and sends it // returns whether an event was sent - bool sendMotionEvent(); + virtual bool sendMotionEvent(); protected: GHOST_System& m_system; Index: intern/ghost/intern/GHOST_NDOFManagerX11.h =================================================================== --- intern/ghost/intern/GHOST_NDOFManagerX11.h (revisão 34074) +++ intern/ghost/intern/GHOST_NDOFManagerX11.h (cópia de trabalho) @@ -24,22 +24,76 @@ #define _GHOST_NDOFMANAGERX11_H_ #include "GHOST_NDOFManager.h" +#include "GHOST_Types.h" +#include "GHOST_WindowX11.h" +#include "GHOST_EventNDOF.h" +#include +#include - 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 false; + 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; + } }; Index: intern/ghost/intern/GHOST_WindowX11.cpp =================================================================== --- intern/ghost/intern/GHOST_WindowX11.cpp (revisão 34074) +++ intern/ghost/intern/GHOST_WindowX11.cpp (cópia de trabalho) @@ -35,6 +35,10 @@ #include #include +// libspnav +#include +#include "GHOST_NDOFManagerX11.h" + #if defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__) || defined (_AIX) #include #endif @@ -269,6 +273,11 @@ CWBorderPixel|CWColormap|CWEventMask, &xattributes ); + if (spnav_x11_open(m_display, m_window) == -1) { + fprintf(stderr, "failed to connect to the space navigator daemon\n"); + } else { + m_system->createNDOFAtoms(m_display); + } } else { Window root_return; @@ -297,12 +306,12 @@ m_visual->visual, CWBorderPixel|CWColormap|CWEventMask, &xattributes + + ); - XSelectInput(m_display , parentWindow, SubstructureNotifyMask); - } - + /* * One of the problem with WM-spec is that can't set a property * to a window that isn't mapped. That is why we can't "just @@ -428,6 +437,8 @@ XMapWindow(m_display, m_window); GHOST_PRINT("Mapped window\n"); + + ((GHOST_NDOFManagerX11 *)m_system->getNDOFManager())->setGHOSTWindowX11(this);; XFlush(m_display); } @@ -1258,6 +1269,9 @@ if(m_xtablet.StylusDevice) XCloseDevice(m_display, m_xtablet.StylusDevice); + /*close ndof */ + spnav_close(); + if(m_xtablet.EraserDevice) XCloseDevice(m_display, m_xtablet.EraserDevice); Index: intern/ghost/intern/GHOST_SystemX11.cpp =================================================================== --- intern/ghost/intern/GHOST_SystemX11.cpp (revisão 34074) +++ intern/ghost/intern/GHOST_SystemX11.cpp (cópia de trabalho) @@ -267,6 +267,7 @@ m_windowManager->addWindow(window); pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) ); + } else { delete window; @@ -631,10 +632,11 @@ ); } else #endif - if (sNdofInfo.currValues) { + if (m_ndofManager->available()) { + // static GHOST_TEventNDOFData data = {0,0,0,0,0,0,0,0,0,0,0}; - if (xcme.message_type == sNdofInfo.motionAtom) - { + if (xcme.message_type == sNdofInfo.motionAtom + || xcme.message_type == motion_event){ // data.changed = 1; // data.delta = xcme.data.s[8] - data.time; // data.time = xcme.data.s[8]; @@ -646,9 +648,9 @@ // data.rz =-xcme.data.s[7]; short t[3], r[3]; - t[0] = xcme.data.s[2] >> 2; - t[1] = xcme.data.s[3] >> 2; - t[2] = xcme.data.s[4] >> 2; + t[0] = xcme.data.s[2]; + t[1] = xcme.data.s[3]; + t[2] = xcme.data.s[4]; r[0] = xcme.data.s[5]; r[1] = xcme.data.s[6]; r[2] =-xcme.data.s[7]; @@ -663,7 +665,8 @@ // GHOST_kEventNDOFMotion, // window, data); - } else if (xcme.message_type == sNdofInfo.btnPressAtom) { + } else if (xcme.message_type == sNdofInfo.btnPressAtom + || xcme.message_type == button_press_event) { // data.changed = 2; // data.delta = xcme.data.s[8] - data.time; // data.time = xcme.data.s[8]; @@ -803,7 +806,7 @@ XFlush(m_display); break; } - + default: { if(xe->type == window->GetXTablet().MotionEvent) { @@ -1505,3 +1508,9 @@ return NULL; } +void GHOST_SystemX11::createNDOFAtoms(Display * display){ + motion_event = XInternAtom(display, "MotionEvent", True); + button_press_event = XInternAtom(display, "ButtonPressEvent", True); + button_release_event = XInternAtom(display, "ButtonReleaseEvent", True); + command_event = XInternAtom(display, "CommandEvent", True); +} Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (revisão 34074) +++ CMakeLists.txt (cópia de trabalho) @@ -118,6 +118,9 @@ OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation tracking" OFF) OPTION(WITH_INSTALL "Install accompanying scripts and language files needed to run blender" ON) OPTION(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON) +IF(UNIX AND NOT APPLE) +OPTION(WITH_SPACENAV "Support for NDOF devices in Linux" ON) +ENDIF(UNIX AND NOT APPLE) IF(APPLE) OPTION(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" ON) @@ -301,7 +304,9 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux") # BSD's dont use libdl.so SET(LLIBS "${LLIBS} -ldl") - + IF(WITH_SPACENAV) + SET(LLIBS "${LLIBS} -lspnav") + ENDIF(WITH_SPACENAV) # binreloc is linux only SET(BINRELOC ${CMAKE_SOURCE_DIR}/extern/binreloc) SET(BINRELOC_INC ${BINRELOC}/include)