diff -r d74fd886c8a6 autobuild.xml --- a/autobuild.xml Thu Jun 02 17:34:12 2011 -0400 +++ b/autobuild.xml Sat Jun 04 03:04:36 2011 +0200 @@ -1290,9 +1290,9 @@ archive hash - c81bacf922bb3b540d92b660364c48ce + 593fc39605d9d90186a44cfc1fbbf68a url - http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-linux-0.2-20101013.tar.bz2 + http://sourceforge.net/projects/sythos/files/p3/kv-linux-ndof-0.3-20110422.tar.bz2 name linux diff -r d74fd886c8a6 doc/contributions.txt --- a/doc/contributions.txt Thu Jun 02 17:34:12 2011 -0400 +++ b/doc/contributions.txt Sat Jun 04 03:04:36 2011 +0200 @@ -151,6 +151,8 @@ VWR-12620 VWR-12789 SNOW-322 +Altair Memo + OPEN-21 Angus Boyd VWR-592 Ann Congrejo diff -r d74fd886c8a6 indra/cmake/NDOF.cmake --- a/indra/cmake/NDOF.cmake Thu Jun 02 17:34:12 2011 -0400 +++ b/indra/cmake/NDOF.cmake Sat Jun 04 03:04:36 2011 +0200 @@ -1,4 +1,7 @@ # -*- cmake -*- + +if (!LINUX) +if (!STANDALONE) include(Prebuilt) set(NDOF ON CACHE BOOL "Use NDOF space navigator joystick library.") @@ -30,3 +33,13 @@ set(NDOF_LIBRARY "") endif (NDOF_FOUND) +endif (!STANDALONE) +endif (!LINUX) + +if (LINUX) + set(LLNDOF-LINUX_INCLUDE_DIRS + ${LIBS_OPEN_DIR}/llndof-linux + ) + +set(LLNDOF-LINUX_LIBRARIES llndof-linux) +endif (LINUX) diff -r d74fd886c8a6 indra/llndof-linux/CMakeLists.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/indra/llndof-linux/CMakeLists.txt Sat Jun 04 03:04:36 2011 +0200 @@ -0,0 +1,27 @@ +# -*- cmake -*- + +project(llndof-linux) + +include(00-Common) +include(LLCommon) +include(UnixInstall) + +include_directories( + ${LLCOMMON_INCLUDE_DIRS} + ) + +set(llndof-linux_SOURCE_FILES + libndofdev.cpp + ) + +set(llndof-linux_HEADER_FILES + CMakeLists.txt + ndofdev_external.h + ) + +if (LINUX) + set_source_files_properties(${llndof-linux_HEADER_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + list(APPEND llndof-linux_SOURCE_FILES ${llndof-linux_HEADER_FILES}) + add_library (llndof-linux ${llndof-linux_SOURCE_FILES}) +endif (LINUX) diff -r d74fd886c8a6 indra/llndof-linux/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/indra/llndof-linux/Makefile Sat Jun 04 03:04:36 2011 +0200 @@ -0,0 +1,9 @@ +CFLAGS=-pipe -fexceptions -fno-math-errno -fno-strict-aliasing -fsigned-char -g -pthread -mtune=i686 -march=i686 -w -O2 + + +libndofdev.a: ndofdev.o + $(AR) -r $@ $< + +clean: + -rm -f *.a *.o + diff -r d74fd886c8a6 indra/llndof-linux/ndofdev.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/indra/llndof-linux/ndofdev.c Sat Jun 04 03:04:36 2011 +0200 @@ -0,0 +1,263 @@ +/* +* +* Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com) +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * The name of its contributors may not be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY Jan Ciger ''AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL Jan Ciger BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * Drop-in replacement for the 3D Connexion SDK library not available on Linux + * + * Uses native Linux input (evdev) device for SpaceNavigator, otherwise SDL for + * regular joysticks. + * + * Evdev could be used for joysticks as well, but higher level logic would have to be + * re-implemented (calibration, filtering, etc.) - SDL includes it already. + * + * Release 0.3 +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "ndofdev_external.h" + +// Hack - we need to store the descriptor +// of the SpaceNavigator in order to be able to +// turn its LED off in the ndof_cleanup() function :( +static int spacenav_fd = -1; + +const int SPACE_NAVIG_THRESHOLD = 20; // minimum change threshold + +typedef struct +{ + // native HID interface or SDL? + int USE_SDL; + + // SpaceNavigator + int fd; // file descriptor of the device + long int *axes; // last state + long int *buttons; + + // SDL joysticks + SDL_Joystick *j; + +} LinJoystickPrivate; + +NDOF_Device *ndof_create() +{ + NDOF_Device *d = (NDOF_Device *) calloc(1, sizeof(NDOF_Device)); + return d; +} + +int ndof_init_first(NDOF_Device *in_out_dev, void *param) +{ + // try to find 3DConnexion SpaceNavigator first + int i = 0; + int fd = -1; + char *fname = NULL; + struct input_id ID; + + fname = (char *)malloc(1000 * sizeof(char)); + while (i < 32) + { + sprintf(fname, "/dev/input/event%d", i++); + fd = open(fname, O_RDWR | O_NONBLOCK); + if (fd > 0) + { + ioctl(fd, EVIOCGID, &ID); // get device ID + if ((ID.vendor == 0x046d) && + ((ID.product == 0xc626) || // SpaceNavigators + (ID.product == 0xc623) || // SpaceTraveler (untested) + (ID.product == 0xc603))) // SpaceMouse (untested) + { + // printf("Using device: %s\n", fname); + break; + } else { + close(fd); + fd = -1; + } + } + } + + if(fd > 0) + { + // We have SpaceNavigator, use it + spacenav_fd = fd; + + int N_AXES = 6; // FIXME: shouldn't be hardwired! + int N_BUTTONS = 2; + + in_out_dev->axes_count = N_AXES; + in_out_dev->btn_count = N_BUTTONS; + in_out_dev->absolute = 0; + in_out_dev->valid = 1; + in_out_dev->axes_max = 512; + in_out_dev->axes_min = -512; + ioctl(fd, EVIOCGNAME(255), &in_out_dev->product); // copy name of the device + + // private data + LinJoystickPrivate *priv = (LinJoystickPrivate *) malloc (sizeof(LinJoystickPrivate)); + priv->fd = fd; + priv->axes = (long int *) calloc(N_AXES, sizeof(long int)); + priv->buttons = (long int *) calloc(N_BUTTONS, sizeof(long int)); + priv->USE_SDL = 0; + priv->j = NULL; + in_out_dev->private_data = priv; + + // turn the LED on + struct input_event led_ev; + + led_ev.type = EV_LED; + led_ev.code = LED_MISC; + led_ev.value = 1; + write(spacenav_fd, &led_ev, sizeof(struct input_event)); + + return 0; + + } else { + // SpaceNavigator not found, use SDL Joystick + SDL_Joystick *j = SDL_JoystickOpen(0); + if(j) + { + in_out_dev->axes_count = SDL_JoystickNumAxes(j); + in_out_dev->btn_count = SDL_JoystickNumButtons(j); + in_out_dev->absolute = 0; // always relative on Linux + in_out_dev->valid = 1; + in_out_dev->axes_max = 32767; + in_out_dev->axes_min = -32767; + strncpy(in_out_dev->product, SDL_JoystickName(0), 255); + + // private data + LinJoystickPrivate *priv = (LinJoystickPrivate *) malloc (sizeof(LinJoystickPrivate)); + priv->j = j; + priv->fd = -1; + priv->USE_SDL = 1; + in_out_dev->private_data = priv; + + return 0; + } else { + + // no joysticks found + return -1; + } + } +} + +void ndof_libcleanup() +{ + if(spacenav_fd > 0) + { + // turn the LED off + struct input_event led_ev; + + led_ev.type = EV_LED; + led_ev.code = LED_MISC; + led_ev.value = 0; + write(spacenav_fd, &led_ev, sizeof(struct input_event)); + } + + // FIXME: needs to cleanup the memory +} + +int ndof_libinit(NDOF_DeviceAddCallback in_add_cb, + NDOF_DeviceRemovalCallback in_removal_cb, + void *platform_specific) +{ + // Initialize the joystick subsystem + SDL_InitSubSystem(SDL_INIT_JOYSTICK); + + return 0; +} + +void ndof_update(NDOF_Device *in_dev) +{ + int i; + + LinJoystickPrivate *priv = (LinJoystickPrivate *) in_dev->private_data; + assert(priv != NULL); + + if(priv->USE_SDL) + { + SDL_JoystickUpdate(); + SDL_Joystick *j = priv->j; + + for(i = 0; i < in_dev->axes_count; i++) + { + in_dev->axes[i] = (int) (SDL_JoystickGetAxis(j, i)); + } + + for(i = 0; i < in_dev->btn_count; i++) + { + in_dev->buttons[i] = SDL_JoystickGetButton(j, i); + } + } else { + // update SpaceNavigator + + struct input_event ev; + + while(read(priv->fd, &ev, sizeof(struct input_event)) > 0) + { + switch (ev.type) + { + case EV_KEY: + // printf("Key %d pressed %d.\n", ev.code, ev.value); + priv->buttons[ev.code & 0xff] = ev.value; + break; + + case EV_REL: + case EV_ABS: // 2.6.35 and up, maybe earlier kernels too send EV_ABS instead of EV_REL + // printf("%d %g\n", ev.code, ev.value); + + // clean up small values + priv->axes[ev.code] = abs(ev.value) > SPACE_NAVIG_THRESHOLD ? ev.value : 0; + break; + + default: + break; + } + } + + memcpy(in_dev->axes, priv->axes, in_dev->axes_count * sizeof(long int)); + memcpy(in_dev->buttons, priv->buttons, in_dev->btn_count * sizeof(long int)); + } +} + +void ndof_dump(NDOF_Device *dev) +{ + +} + +void ndof_dump_list() +{ + +} diff -r d74fd886c8a6 indra/llndof-linux/ndofdev_external.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/indra/llndof-linux/ndofdev_external.h Sat Jun 04 03:04:36 2011 +0200 @@ -0,0 +1,133 @@ +/* + @file ndofdev_external.h + @brief libndofdev main header file for external use. + + Copyright (c) 2007, 3Dconnexion, Inc. - All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the 3Dconnexion, Inc. nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ndofdev_external_h__ +#define __ndofdev_external_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define NDOF_MAX_AXES_COUNT 6 +#define NDOF_MAX_BUTTONS_COUNT 32 + +typedef enum NDOF_HotPlugResult { + NDOF_KEEP_HOTPLUGGED, + NDOF_DISCARD_HOTPLUGGED +} NDOF_HotPlugResult; + +/** Do NOT create NDOF_Device variables manually. Always use ndof_create. */ +typedef struct NDOF_Device { + long axes[NDOF_MAX_AXES_COUNT]; /* axes current values */ + long buttons[NDOF_MAX_BUTTONS_COUNT]; /* buttons current values */ + short axes_count; /* actual # axes (self sensed on OS X) */ + short btn_count; /* actual # buttons (self sensed on OS X) */ + long axes_max; /* logical max */ + long axes_min; /* logical min */ + unsigned char absolute; /* if 0 calc delta. On OSX we always have deltas. */ + unsigned char valid; /* if 0, clients should not access this device. */ + char manufacturer[256]; /* name of device manufacturer */ + char product[256]; /* name of the device */ + void *private_data; /* ptr to platform specific/private data */ +} NDOF_Device; + +/** Callback type for new hot-plugged devices. + * Parameters: dev - pointer to the newly added NDOF device. A new NDOF_Device + * struct is allocated for the client. Clients can express + * interest in the device by returning NDOF_KEEP_HOTPLUGGED, + * otherwise the memory pointed by dev will be released. */ +typedef NDOF_HotPlugResult (*NDOF_DeviceAddCallback)(NDOF_Device *dev); + +/** Removal callback type. Parameter points to the removed device. */ +typedef void (*NDOF_DeviceRemovalCallback)(NDOF_Device *device); + +/** Purpose: Initializes the library. + * Parameters: in_add_cb - Callback invoked when a new device is hotplugged in. + * Pass NULL if you don't care. + * in_removal_cb - Callback invoked when a device is removed. + * Pass NULL if you don't care. + * platform_specific - On Windows, it can be a pointer to a already + * initialized LPDIRECTINPUT8 value; pass NULL + * for full initialization. Unused on OS X. + * Notes: The callbacks functionality is currently implemented on Mac OS X + * only. The callbacks functions are currently ignored on Windows. + * Returns: 0 if ok. + */ +extern int ndof_libinit(NDOF_DeviceAddCallback in_add_cb, + NDOF_DeviceRemovalCallback in_removal_cb, + void *platform_specific); + +/** Purpose: Clean up. Must be called before program termination. + */ +extern void ndof_libcleanup(); + +/** Purpose: Allocates memory for a new NDOF_Device struct and initializes + * it with default values. + * Notes: Always use this function to allocate a new NDOF_Device. + * Call ndof_libcleanup to free the memory. + * Returns: Pointer to a mallocated struct. + */ +extern NDOF_Device *ndof_create(); + +/** Purpose: Get the _first_ NDOF device found in the USB bus. + * Notes: It will be attempted to use the max and min values of the + * input struct as the range of returned values from the device. + * This may not work for every device. In any case, when this + * function returns, the axes_min, axes_max values will contain + * the actual range. + * Parameters: in_out_dev - Must be allocated externally using ndof_create(). + * param - On Windows, you may use this to pass in a + * LPDIRECTINPUTDEVICE8. It will be attempted to use + * that instead of creating a new one. In all other cases + * just pass NULL. + * Returns: 0 if all is ok, -1 otherwise. + */ +extern int ndof_init_first(NDOF_Device *in_out_dev, void *param); + +/** Purpose: Reads the current status of the input device. + * Parameters: Must be initialized with ndof_create(). + */ +extern void ndof_update(NDOF_Device *in_dev); + +/** Purpose: Dumps device info on stderr. */ +extern void ndof_dump(NDOF_Device *dev); + +/** Purpose: Dumps list of NDOF devices currently in use on stderr. */ +extern void ndof_dump_list(); + +#if TARGET_OS_MAC +/** Returns the number of connected NDOF devices. Implemented only on OS X. */ +extern int ndof_devcount(); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __ndofdev_external_h__ */