Hi there, As a (newly) proud owner of a 3dconnextion space navigator http://www.3dconnexion.com/3dmouse/spacenavigator.php I also would like to use it with gmsh in linux. Searching for some demo source code, I was quite sucessful, and already managed to access the device by the attached code, which I changed a bit (sadly using c++) to find the correct event device automatically. Its not high quality code yet, i only spend 15 min on changing it.
However, to add a patch to support this space mouse in gmsh, I would need to add a polling routine to gmsh, that is exectued e.g. each 50 ms and checks the device for the current position, and changes the view angles accordingly. Where in the source would be a good point to hook this into gmsh?? I really havent looked into how to access the device in windows. very nice greetings, Bernhard PS: the thing works awsome under windows, as expected, but only with supported software, e.g. pro engineer. In linux, there is a plugin for blender and maya, which both I both don't really care about. Google earth only works in windows. Also, on could in principle steer the mouse cursor with the space mouse, but I wonder what that should be good for...
/* * spacenavi.c - a proof-of-concept hack to access the * 3dconnexion space navigator * * compile with gcc -Wall -o spacenavi spacenavi.c * * run with ./spacenavi [/path/to/eventdevice] * * Written by Simon Budig, placed in the public domain. * it helps to read http://www.frogmouth.net/hid-doco/linux-hid.html . * * For the LED to work a patch to the linux kernel is needed: * http://www.home.unix-ag.org/simon/files/spacenavigator-hid.patch * */ #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <linux/types.h> #include <linux/input.h> #include <string> #include <sstream> using namespace std; #define test_bit(bit, array) (array [bit / 8] & (1 << (bit % 8))) int snavi_set_led (int snavi_dev, int led_state) { /* this does not seem to work with 2.6.19, it apparently * has worked with 2.6.8. Needs further investigation */ struct input_event event; int ret; event.type = EV_LED; event.code = LED_MISC; event.value = led_state; ret = write (snavi_dev, &event, sizeof (struct input_event)); if (ret < 0) perror ("setting led state failed"); return ret < sizeof (struct input_event); } int findevent() { int snavi; for(int i=0;i<10;i++) { stringstream dname; dname<<"/dev/input/event"<<i; string s; char cdname[100]; dname>>cdname; snavi = open (cdname, O_RDWR); char name[256]= "Unknown"; printf("%s %i \n",cdname,snavi); if (snavi >= 0) { if (ioctl (snavi, EVIOCGNAME (sizeof (name)), name) >= 0) { string ss; ss=name; if(ss=="3Dconnexion SpaceNavigator") { printf("%s\n",name); return snavi; } } } close(snavi); } } int main (int argc, char *argv[]) { //exit(1); int snavi, i; snavi=findevent(); char name[256]= "Unknown"; u_int8_t evtype_bitmask[(EV_MAX + 7) / 8]; u_int8_t rel_bitmask[(REL_MAX + 7) / 8]; u_int8_t led_bitmask[(LED_MAX + 7) / 8]; struct input_event event; int axes[6]; int buttons[2]; int led_state = 0; /* snavi = open (argc > 1 ? argv[1] : "/dev/input/3d-nav", O_RDWR); if (snavi < 0) { perror ("opening the device failed"); exit (1); } if (ioctl (snavi, EVIOCGNAME (sizeof (name)), name) < 0) { perror ("EVIOCGNAME ioctl failed"); exit (1); } printf ("found \"%s\" on %s\n", name, argv[1]); */ if (ioctl (snavi, EVIOCGBIT (0, sizeof (evtype_bitmask)), evtype_bitmask) < 0) { perror ("EVIOCGBIT ioctl failed"); exit (1); } printf ("Supported event types:\n"); for (i = 0; i < EV_MAX; i++) { if (test_bit (i, evtype_bitmask)) { /* this means that the bit is set in the event types list */ printf(" Event type 0x%02x ", i); switch (i) { case EV_SYN : printf(" (Sync?)\n"); break; case EV_KEY : printf(" (Keys or Buttons)\n"); break; case EV_REL : printf(" (Relative Axes)\n"); break; case EV_ABS : printf(" (Absolute Axes)\n"); break; case EV_LED : printf(" (LEDs)\n"); break; case EV_REP : printf(" (Repeat)\n"); break; default: printf(" (Unknown event type)\n"); } } } memset (rel_bitmask, 0, sizeof (rel_bitmask)); memset (led_bitmask, 0, sizeof (led_bitmask)); if (ioctl (snavi, EVIOCGBIT (EV_LED, sizeof (led_bitmask)), led_bitmask) < 0) { perror ("EVIOCGBIT ioctl failed"); exit (1); } printf ("detected leds:\n "); for (i = 0; i < LED_MAX; i++) { if (test_bit (i, led_bitmask)) printf ("%d, ", i); } printf ("\n"); axes[0] = axes[1] = axes[2] = axes[3] = axes[4] = axes[5] = 0; buttons[0] = buttons[1] = 0; while (1) { if (read (snavi, &event, sizeof (struct input_event)) < 0) { perror ("read error"); break; } switch (event.type) { case EV_REL: if (event.code <= REL_RZ) axes[event.code - REL_X] = event.value; break; case EV_KEY: if (event.code >= BTN_0 && event.code <= BTN_1) buttons[event.code - BTN_0] = event.value; if (event.code - BTN_0 == 1) { led_state = 1 - led_state; snavi_set_led (snavi, led_state); } break; case EV_SYN: /* if multiple axes change simultaneously the linux * input system sends multiple EV_REL events. EV_SYN * then indicates that all changes have been reported. */ fprintf (stderr, "\rState: %4d %4d %4d %4d %4d %4d - %3s %3s", axes[0], axes[1], axes[2], axes[3], axes[4], axes[5], buttons[0] ? "on" : "off", buttons[1] ? "on" : "off"); axes[0] = axes[1] = axes[2] = axes[3] = axes[4] = axes[5] = 0; break; case EV_LED: break; default: fprintf (stderr, "\nunknown event type %d\n", event.code); } } close (snavi); exit (0); }
_______________________________________________ gmsh mailing list [email protected] http://www.geuz.org/mailman/listinfo/gmsh
