From 1a25e7c7b2e06554f1abd8a138e3823b23dd4ed7 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 7 Jun 2010 00:47:02 +0000 Subject: [PATCH] - added serial device support (merged libsball by John Stone). - fixed a bug where the swap-xy would only affect translation. git-svn-id: svn+ssh://svn.code.sf.net/p/spacenav/code/trunk/spacenavd@103 ef983eb1-d774-4af8-acfd-baaf7b16a646 --- Makefile.in | 8 +- src/cfgfile.c | 12 +- src/cfgfile.h | 5 +- src/client.c | 2 +- src/client.h | 2 +- src/dev.h | 2 +- src/dev_linux.c | 84 +++-- src/dev_serial.c | 43 +++ src/dev_serial.h | 28 ++ src/event.c | 2 +- src/event.h | 2 +- src/proto_unix.c | 2 +- src/proto_unix.h | 2 +- src/proto_x11.c | 2 +- src/proto_x11.h | 2 +- src/serial/sball.c | 746 +++++++++++++++++++++++++++++++++++++++ src/serial/sball.h | 177 ++++++++++ src/serial/sballserial.c | 152 ++++++++ src/serial/sballserial.h | 67 ++++ src/spnavd.c | 6 +- src/spnavd.h | 2 +- src/xdetect.h | 2 +- src/xdetect_linux.c | 4 +- 23 files changed, 1301 insertions(+), 53 deletions(-) create mode 100644 src/dev_serial.c create mode 100644 src/dev_serial.h create mode 100644 src/serial/sball.c create mode 100644 src/serial/sball.h create mode 100644 src/serial/sballserial.c create mode 100644 src/serial/sballserial.h diff --git a/Makefile.in b/Makefile.in index 4cf3de8..f5226e1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,16 +1,20 @@ -src = $(wildcard src/*.c) +src = $(wildcard src/*.c) $(wildcard src/serial/*.c) +hdr = $(wildcard src/*.h) $(wildcard src/serial/*.h) obj = $(src:.c=.o) bin = spacenavd ctl = spnavd_ctl CC = gcc INSTALL = install -CFLAGS = -pedantic -Wall $(dbg) $(opt) -fno-strict-aliasing +CFLAGS = -pedantic -Wall $(dbg) $(opt) -fno-strict-aliasing -I$(srcdir)/src LDFLAGS = $(xlib) $(bin): $(obj) $(CC) -o $@ $(obj) $(LDFLAGS) +tags: $(src) $(hdr) + ctags $(src) $(hdr) + %.o: $(srcdir)/%.c $(CC) $(CFLAGS) -c $< -o $@ diff --git a/src/cfgfile.c b/src/cfgfile.c index f38b623..cb1be48 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 @@ -153,7 +153,7 @@ int read_cfg(const char *fname, struct cfg *cfg) } for(i=0; i<6; i++) { - cfg->map_axis[i] = swap_yz && i < 3 ? i : def_axmap[i]; + cfg->map_axis[i] = swap_yz ? i : def_axmap[i]; } } else if(strcmp(key_str, "led") == 0) { @@ -170,6 +170,9 @@ int read_cfg(const char *fname, struct cfg *cfg) } } + } else if(strcmp(key_str, "serial") == 0) { + strncpy(cfg->serial_dev, val_str, PATH_MAX); + } else { fprintf(stderr, "unrecognized config option: %s\n", key_str); } @@ -237,6 +240,11 @@ int write_cfg(const char *fname, struct cfg *cfg) fprintf(fp, "led = 0\n\n"); } + if(cfg->serial_dev[0]) { + fprintf(fp, "# serial device\n"); + fprintf(fp, "serial = %s\n\n", cfg->serial_dev); + } + /* unlock */ flk.l_type = F_UNLCK; flk.l_start = flk.l_len = 0; diff --git a/src/cfgfile.h b/src/cfgfile.h index b3c99cc..570012b 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 @@ -19,6 +19,8 @@ along with this program. If not, see . #ifndef CFGFILE_H_ #define CFGFILE_H_ +#include + #define MAX_BUTTONS 64 struct cfg { @@ -28,6 +30,7 @@ struct cfg { int map_axis[6]; int map_button[MAX_BUTTONS]; int led; + char serial_dev[PATH_MAX]; }; void default_cfg(struct cfg *cfg); diff --git a/src/client.c b/src/client.c index 6ce91e3..b879669 100644 --- a/src/client.c +++ b/src/client.c @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/client.h b/src/client.h index 73f61c1..97cd1e3 100644 --- a/src/client.h +++ b/src/client.h @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/dev.h b/src/dev.h index 6819bf1..201b480 100644 --- a/src/dev.h +++ b/src/dev.h @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/dev_linux.c b/src/dev_linux.c index 9cd16c3..202c11c 100644 --- a/src/dev_linux.c +++ b/src/dev_linux.c @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 @@ -36,6 +36,7 @@ along with this program. If not, see . #include "dev.h" #include "cfgfile.h" #include "spnavd.h" +#include "dev_serial.h" #define DEV_POLL_INTERVAL 30 @@ -52,8 +53,8 @@ along with this program. If not, see . #endif -static int open_dev(const char *path); -static void close_dev(void); +static int open_dev_usb(const char *path); +static int read_dev_usb(struct dev_input *inp); static char *get_dev_path(void); static int con_hotplug(void); static void poll_timeout(int sig); @@ -67,6 +68,8 @@ static int hotplug_fd = -1; static int poll_time, poll_pipe; #define MAX_POLL_TIME 30 +static int dev_is_serial; + /* hotplug stuff */ int init_hotplug(void) @@ -171,25 +174,44 @@ static void poll_timeout(int sig) int init_dev(void) { - char *dev_path; + if(cfg.serial_dev[0]) { + /* try to open a serial device if specified in the config file */ + printf("using device: %s\n", cfg.serial_dev); - if(!(dev_path = get_dev_path())) { - fprintf(stderr, "failed to find the spaceball device file\n"); - return -1; + if((dev_fd = open_dev_serial(cfg.serial_dev)) == -1) { + return -1; + } + dev_is_serial = 1; + + } else { + char *dev_path; + if(!(dev_path = get_dev_path())) { + fprintf(stderr, "failed to find the spaceball device file\n"); + return -1; + } + printf("using device: %s\n", dev_path); + + if((dev_fd = open_dev_usb(dev_path)) == -1) { + return -1; + } + dev_is_serial = 0; + + printf("device name: %s\n", dev_name); } - printf("using device: %s\n", dev_path); - - if(open_dev(dev_path) == -1) { - return -1; - } - printf("device name: %s\n", dev_name); - return 0; } void shutdown_dev(void) { - close_dev(); + if(dev_is_serial) { + close_dev_serial(); + } else { + if(dev_fd != -1) { + set_led(0); + close(dev_fd); + } + } + dev_fd = -1; } int get_dev_fd(void) @@ -198,6 +220,11 @@ int get_dev_fd(void) } int read_dev(struct dev_input *inp) +{ + return dev_is_serial ? read_dev_serial(inp) : read_dev_usb(inp); +} + +static int read_dev_usb(struct dev_input *inp) { struct input_event iev; int rdbytes; @@ -212,11 +239,13 @@ int read_dev(struct dev_input *inp) /* disconnect? */ if(rdbytes == -1) { - perror("read error"); - close(dev_fd); - dev_fd = -1; + if(errno != EAGAIN) { + perror("read error"); + close(dev_fd); + dev_fd = -1; - init_hotplug(); + init_hotplug(); + } return -1; } @@ -273,7 +302,7 @@ void set_led(int state) } } -static int open_dev(const char *path) +static int open_dev_usb(const char *path) { int grab = 1; @@ -293,7 +322,6 @@ static int open_dev(const char *path) if(ioctl(dev_fd, EVIOCGBIT(0, sizeof(evtype_mask)), evtype_mask) == -1) { perror("EVIOCGBIT ioctl failed\n"); close(dev_fd); - dev_fd = -1; return -1; } @@ -302,19 +330,13 @@ static int open_dev(const char *path) perror("failed to grab the spacenav device"); } + /* set non-blocking */ + fcntl(dev_fd, F_SETFL, fcntl(dev_fd, F_GETFL) | O_NONBLOCK); + if(cfg.led) { set_led(1); } - return 0; -} - -static void close_dev(void) -{ - if(dev_fd != -1) { - set_led(0); - close(dev_fd); - dev_fd = -1; - } + return dev_fd; } diff --git a/src/dev_serial.c b/src/dev_serial.c new file mode 100644 index 0000000..0c456bc --- /dev/null +++ b/src/dev_serial.c @@ -0,0 +1,43 @@ +/* +spacenavd - a free software replacement driver for 6dof space-mice. +Copyright (C) 2007-2010 John Tsiombikas + +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 3 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, see . +*/ + +#include "dev_serial.h" +#include "serial/sball.h" + +static void *dev; + +int open_dev_serial(const char *devfile) +{ + if(!(dev = sball_open(devfile))) { + return -1; + } + return sball_get_fd(dev); +} + +void close_dev_serial(void) +{ + sball_close(dev); +} + +int read_dev_serial(struct dev_input *inp) +{ + if(!sball_get_input(dev, inp)) { + return -1; + } + return 0; +} diff --git a/src/dev_serial.h b/src/dev_serial.h new file mode 100644 index 0000000..3f0cbef --- /dev/null +++ b/src/dev_serial.h @@ -0,0 +1,28 @@ +/* +spacenavd - a free software replacement driver for 6dof space-mice. +Copyright (C) 2007-2010 John Tsiombikas + +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 3 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, see . +*/ + +#ifndef DEV_SERIAL_H_ +#define DEV_SERIAL_H_ + +#include "event.h" + +int open_dev_serial(const char *devfile); +void close_dev_serial(void); +int read_dev_serial(struct dev_input *inp); + +#endif /* DEV_SERIAL_H_ */ diff --git a/src/event.c b/src/event.c index 71b0118..6e37dbf 100644 --- a/src/event.c +++ b/src/event.c @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/event.h b/src/event.h index 969797e..1bee234 100644 --- a/src/event.h +++ b/src/event.h @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/proto_unix.c b/src/proto_unix.c index ca0ab8f..1c3ec15 100644 --- a/src/proto_unix.c +++ b/src/proto_unix.c @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/proto_unix.h b/src/proto_unix.h index 8ff9cb7..045b379 100644 --- a/src/proto_unix.h +++ b/src/proto_unix.h @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/proto_x11.c b/src/proto_x11.c index c61c9b6..d869949 100644 --- a/src/proto_x11.c +++ b/src/proto_x11.c @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/proto_x11.h b/src/proto_x11.h index 3fb9a4d..6b78361 100644 --- a/src/proto_x11.h +++ b/src/proto_x11.h @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/serial/sball.c b/src/serial/sball.c new file mode 100644 index 0000000..cfbbdd1 --- /dev/null +++ b/src/serial/sball.c @@ -0,0 +1,746 @@ +/* +spacenavd - a free software replacement driver for 6dof space-mice. +Copyright (C) 2007-2010 John Tsiombikas + +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 3 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, see . + +This file incorporates work covered by the following copyright and +permission notice: + + Copyright 1997-2001 John E. Stone (j.stone@acm.org) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. 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. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +*/ + +#define _POSIX_SOURCE 1 + +#include +#include +#include +#include +#include + +#include "sball.h" +#include "sballserial.h" + +struct event { + struct dev_input data; + struct event *next; +}; + +static struct event *ev_free_list; +int evpool_size; + +static struct event *alloc_event(void); +static void free_event(struct event *ev); + + +typedef struct { + SBallCommHandle commhandle; + unsigned char buf[256]; + char resetstring[256]; + int bufpos; /* current char position in packet buffer */ + int packtype; /* what kind of packet is it */ + int packlen; /* how many bytes do we ultimately expect? */ + int escapedchar; /* if set, we're processing an escape sequence */ + int erroroccured; /* if set, we've received an error packet or packets */ + int resetoccured; /* if set, ball was reset, so have to reinitialize it */ + int spaceball4000; /* if set, its a Spaceball 4000 */ + int leftymode4000; /* if set, Spaceball 4000 in "lefty" orientation */ + int trans[3]; /* last translational data received */ + int rot[3]; /* last rotational data received */ + int buttons; /* current button status */ + int timer; /* time since last packet was received */ + int usenullregion; /* software-implemented null region flag */ + int nulltrans[3]; /* translational null region values */ + int nullrot[3]; /* rotational null region values */ + + /* event list added for spacenavd integration */ + struct event *evhead, *evtail; +} sballhandle; + + +static void generate_motion_events(sballhandle *handle, int *prev_val, int *new_val, int timer); +static void generate_button_events(sballhandle *handle, int prevstate, int newstate); + + +/* Spaceball 1003/2003 recommended initialization string. */ + +/* Newer documentation suggests eliminating several of these */ + +/* settings during initialization, leaving them at factory values. */ +static char *initstring = "CB\rNT\rFTp\rFRp\rP@r@r\rMSSV\rZ\rBcCcC\r"; + +/* Reset spaceball and ideally determine model */ +static void sball_hwreset(sballhandle * handle) +{ + /* Reset some state variables back to zero */ + handle->spaceball4000 = 0; /* re-determine which type it is */ + handle->leftymode4000 = 0; /* re-determine if its in lefty mode */ + + if(!handle->resetoccured) { +#if defined(DEBUG) + printf("Sending reset command to spaceball...\n"); +#endif + handle->resetoccured = 1; + sball_comm_write(handle->commhandle, "@\r"); /* force reset */ + } +#if 0 + /* give the spaceball time to reset itself */ + sleep(2); +#endif + +#if defined(DEBUG) + printf("Sending initialization sequence to spaceball...\n"); +#endif + + sball_comm_write(handle->commhandle, initstring); /* do remaining init */ +} + + +SBallHandle sball_open(const char *sballname) +{ + sballhandle *handle; + + if(sballname == NULL) + return NULL; + + handle = (sballhandle *) malloc(sizeof(sballhandle)); + if(handle == NULL) + return NULL; + + /* clear all values in sballhandle to 0 */ + memset(handle, 0, sizeof(sballhandle)); + handle->packlen = 1; + handle->resetoccured = 0; + + if(sball_comm_open(sballname, &handle->commhandle) == -1) { + free(handle); + return NULL; + } + + sball_hwreset(handle); + + return handle; /* successfull open */ +} + + +int sball_close(SBallHandle voidhandle) +{ + sballhandle *handle = voidhandle; + + if(handle == NULL) + return -1; + + sball_comm_close(&handle->commhandle); + free(handle); + return 0; /* successfull close */ +} + + +static int sball_update(SBallHandle voidhandle) +{ + int i, num, packs; + + unsigned char rawbuf[1024]; + + sballhandle *handle = voidhandle; + + if(handle == NULL) + return -1; + + packs = 0; /* no packs received yet */ + + num = sball_comm_read(handle->commhandle, (char *)rawbuf, 1023); + + if(num > 0) { + for(i = 0; i < num; i++) { + + + /* process potentially occuring escaped character sequences */ + if(rawbuf[i] == '^') { + if(!handle->escapedchar) { + handle->escapedchar = 1; + continue; /* eat the escape character from buffer */ + } + } + + if(handle->escapedchar) { + handle->escapedchar = 0; + + switch(rawbuf[i]) { + case '^': /* leave char in buffer unchanged */ + break; + + case 'Q': + case 'S': + case 'M': + rawbuf[i] &= 0x1F; /* convert character to unescaped form */ + break; + + default: +#if defined(DEBUG) + printf("\nGot a bad escape sequence! 0x%02x", rawbuf[i]); + if(isprint(rawbuf[i])) + printf(" (%c)", rawbuf[i]); + else + printf(" (unprintable)"); + printf("\n"); +#endif + break; + } + } + + + /* figure out what kind of packet we received */ + if(handle->bufpos == 0) { + switch(rawbuf[i]) { + case 'D': /* Displacement packet */ + handle->packtype = 'D'; + handle->packlen = 16; /* D packets are 15 bytes long */ + break; + + case 'K': /* Button/Key packet */ + handle->packtype = 'K'; + handle->packlen = 4; /* K packets are 3 bytes long */ + break; + + case '.': /* Spaceball 4000 FLX "advanced" button press event */ + handle->packtype = '.'; + handle->packlen = 4; /* . packets are 3 bytes long */ + break; + + case 'C': /* Communications mode packet */ + handle->packtype = 'C'; + handle->packlen = 4; + break; + + case 'F': /* Spaceball sensitization mode packet */ + handle->packtype = 'F'; + handle->packlen = 4; + break; + + case 'M': /* Movement mode packet */ + handle->packtype = 'M'; + handle->packlen = 5; + break; + + case 'N': /* Null region packet */ + handle->packtype = 'N'; + handle->packlen = 3; + break; + + case 'P': /* Update rate packet */ + handle->packtype = 'P'; + handle->packlen = 6; + break; + + case '\v': /* XON at poweron */ + handle->packtype = '\v'; + handle->packlen = 1; + break; + + case '\n': /* carriage return at poweron */ + case '\r': /* carriage return at poweron */ + handle->packtype = '\r'; + handle->packlen = 1; + break; + + case '@': /* Spaceball Hard/Soft Reset packet */ + handle->resetoccured = 1; + handle->packtype = '@'; + handle->packlen = 62; /* Resets aren't longer than 62 chars */ + break; + + case 'E': /* Error packet */ + handle->packtype = 'E'; + handle->packlen = 8; /* E packets are up to 7 bytes long */ + break; + + case 'Z': /* Zero packet (Spaceball 2003/3003/4000 FLX) */ + handle->packtype = 'Z'; + handle->packlen = 14; /* Z packets are hardware dependent */ + break; + + default: /* Unknown packet! */ +#if defined(DEBUG) + printf("\nUnknown packet (1): 0x%02x \n ", rawbuf[i]); + printf(" char: "); + if(isprint(rawbuf[i])) + printf("%c", rawbuf[i]); + else + printf(" (unprintable)"); + printf("\n"); +#endif + continue; + } + } + + + handle->buf[handle->bufpos] = rawbuf[i]; + handle->bufpos++; + + /* Reset packet processing */ + if(handle->packtype == '@') { + if(rawbuf[i] != '\r') + continue; + else + handle->packlen = handle->bufpos; + } + + /* Error packet processing */ + if(handle->packtype == 'E') { + if(rawbuf[i] != '\r') + continue; + else + handle->packlen = handle->bufpos; + } else if(handle->bufpos != handle->packlen) + continue; + + switch(handle->packtype) { + case 'D': /* ball displacement event */ + /* modified by John Tsiombikas for spacenavd integration */ + { + unsigned int tx, ty, tz, rx, ry, rz; + int i, prev_val[6], new_val[6]; + + /* number of 1/16ths of milliseconds since last */ + /* ball displacement packet */ + handle->timer = ((handle->buf[1]) << 8) | (handle->buf[2]); + + tx = ((handle->buf[3]) << 8) | ((handle->buf[4])); + ty = ((handle->buf[5]) << 8) | ((handle->buf[6])); + tz = ((handle->buf[7]) << 8) | ((handle->buf[8])); + rx = ((handle->buf[9]) << 8) | ((handle->buf[10])); + ry = ((handle->buf[11]) << 8) | ((handle->buf[12])); + rz = ((handle->buf[13]) << 8) | ((handle->buf[14])); + + for(i=0; i<3; i++) { + prev_val[i] = handle->trans[i]; + prev_val[i + 3] = handle->rot[i]; + } + + new_val[0] = (((int)tx) << 16) >> 16; + new_val[1] = (((int)ty) << 16) >> 16; + new_val[2] = (((int)tz) << 16) >> 16; + new_val[3] = (((int)rx) << 16) >> 16; + new_val[4] = (((int)ry) << 16) >> 16; + new_val[5] = (((int)rz) << 16) >> 16; + + generate_motion_events(handle, prev_val, new_val, handle->timer); + + for(i=0; i<3; i++) { + handle->trans[i] = new_val[i]; + handle->rot[i] = new_val[i + 3]; + } + } + break; + + case 'K': /* button press event */ + /* modified by John Tsiombikas for spacenavd integration */ + { + int newstate; + + /* Spaceball 2003A, 2003B, 2003 FLX, 3003 FLX, 4000 FLX */ + /* button packet. (4000 only for backwards compatibility) */ + /* The lowest 5 bits of the first byte are buttons 5-9 */ + /* Button '8' on a Spaceball 2003 is the rezero button */ + /* The lowest 4 bits of the second byte are buttons 1-4 */ + /* For Spaceball 2003, we'll map the buttons 1-7 normally */ + /* skip 8, as its a hardware "rezero button" on that device */ + /* and call the "pick" button "8". */ + /* On the Spaceball 3003, the "right" button also triggers */ + /* the "pick" bit. We OR the 2003/3003 rezero bits together */ + + /* if we have found a Spaceball 4000, then we ignore the 'K' */ + /* packets entirely, and only use the '.' packets. */ + if(handle->spaceball4000) + break; + + newstate = ((handle->buf[1] & 0x10) << 3) | /* 2003 pick button is "8" */ + ((handle->buf[1] & 0x20) << 9) | /* 3003 rezero button */ + ((handle->buf[1] & 0x08) << 11) | /* 2003 rezero button */ + ((handle->buf[1] & 0x07) << 4) | /* 5,6,7 (2003/4000) */ + ((handle->buf[2] & 0x30) << 8) | /* 3003 Left/Right buttons */ + ((handle->buf[2] & 0x0F)); /* 1,2,3,4 (2003/4000) */ + + generate_button_events(handle, handle->buttons, newstate); + handle->buttons = newstate; + } + break; + + case '.': /* button press event (4000) */ + /* modified by John Tsiombikas for spacenavd integration */ + { + int newstate; + /* Spaceball 4000 FLX "expanded" button packet, with 12 buttons */ + + /* extra packet validity check, since we use this packet type */ + /* to override the 'K' button packets, and determine if its a */ + /* Spaceball 4000 or not... */ + if(handle->buf[3] != '\r') { + break; /* if not terminated with a '\r', probably garbage */ + } + + /* if we got a valid '.' packet, this must be a Spaceball 4000 */ +#if defined(DEBUG) + if(!handle->spaceball4000) + printf("\nDetected a Spaceball 4000 FLX\n"); +#endif + handle->spaceball4000 = 1; /* Must be talking to a Spaceball 4000 */ + + /* Spaceball 4000 series "expanded" button press event */ + /* includes data for 12 buttons, and left/right orientation */ + newstate = (((~handle->buf[1]) & 0x20) << 10) | /* "left handed" mode */ + ((handle->buf[1] & 0x1F) << 7) | /* 8,9,10,11,12 */ + ((handle->buf[2] & 0x3F)) | /* 1,2,3,4,5,6 (4000) */ + ((handle->buf[2] & 0x80) >> 1); /* 7 (4000) */ + + generate_button_events(handle, handle->buttons, newstate); + handle->buttons = newstate; + +#if defined(DEBUG) + if(handle->leftymode4000 != ((handle->buf[1] & 0x20) == 0)) + printf("\nSpaceball 4000 mode changed to: %s\n", + (((handle->buf[1] & 0x20) == + 0) ? "left handed" : "right handed")); +#endif + /* set "lefty" orientation mode if "lefty bit" is _clear_ */ + if((handle->buf[1] & 0x20) == 0) + handle->leftymode4000 = 1; /* left handed mode */ + else + handle->leftymode4000 = 0; /* right handed mode */ + } + break; + + case 'C': /* Communications mode packet */ + case 'F': /* Spaceball sensitization packet */ + case 'P': /* Spaceball update rate packet */ + case 'M': /* Spaceball movement mode packet */ + case 'N': /* Null region packet */ + case '\r': /* carriage return at poweron */ + case '\v': /* XON at poweron */ + /* eat and ignore these packets */ + break; + + case '@': /* Reset packet */ +#ifdef DEBUG + printf("Spaceball reset: "); + for(j = 0; j < handle->packlen; j++) { + if(isprint(handle->buf[j])) + printf("%c", handle->buf[j]); + } + printf("\n"); +#endif + /* if we get a reset packet, we have to re-initialize */ + /* the device, and assume that its completely schizophrenic */ + /* at this moment, we must reset it again at this point */ + handle->resetoccured = 1; + sball_hwreset(handle); + break; + + + case 'E': /* Error packet, hardware/software problem */ + handle->erroroccured++; +#ifdef DEBUG + printf("\nSpaceball Error!! "); + printf("Error code: "); + for(j = 0; j < handle->packlen; j++) { + printf(" 0x%02x ", handle->buf[j]); + } + printf("\n"); +#endif + break; + + case 'Z': /* Zero packet (Spaceball 2003/3003/4000 FLX) */ + /* We just ignore these... */ + break; + + default: +#ifdef DEBUG + printf("Unknown packet (2): 0x%02x\n", handle->packtype); + printf(" char: "); + if(isprint(handle->packtype)) + printf("%c", handle->packtype); + else + printf(" (unprintable)"); + printf("\n"); +#endif + break; + } + + /* reset */ + handle->bufpos = 0; + handle->packtype = 0; + handle->packlen = 1; + packs++; + } + } + + return packs; +} + + +int sball_rezero(SBallHandle voidhandle) +{ + sballhandle *handle = voidhandle; + + char outbuf[200]; + + if(handle == NULL) + return -1; + + sprintf(outbuf, "\rZ\r"); + sball_comm_write(handle->commhandle, outbuf); + + return 0; +} + +int sball_init(SBallHandle voidhandle) +{ + sballhandle *handle = voidhandle; + + /*char outbuf[200]; */ + + if(handle == NULL) + return -1; + + sball_update(handle); + +#if 0 + sprintf(outbuf, "\r"); + sball_update(handle); + sball_comm_write(handle->commhandle, outbuf); + sball_rezero(handle); +#endif + + return 0; +} + + +void sball_set_nullregion(SBallHandle voidhandle, + int nulltx, int nullty, int nulltz, int nullrx, int nullry, int nullrz) +{ + sballhandle *handle = voidhandle; + + handle->nulltrans[0] = abs(nulltx); + handle->nulltrans[1] = abs(nullty); + handle->nulltrans[2] = abs(nulltz); + + handle->nullrot[0] = abs(nullrx); + handle->nullrot[1] = abs(nullry); + handle->nullrot[2] = abs(nullrz); + + handle->usenullregion = 1; +} + + +static int nullregion(int null, int val) +{ + if(abs(val) > null) { + return ((val > 0) ? (val - null) : (val + null)); + } + return 0; +} + +static void sball_do_nullregion(SBallHandle voidhandle) +{ + sballhandle *handle = voidhandle; + + handle->trans[0] = nullregion(handle->nulltrans[0], handle->trans[0]); + handle->trans[1] = nullregion(handle->nulltrans[1], handle->trans[1]); + handle->trans[2] = nullregion(handle->nulltrans[2], handle->trans[2]); + handle->rot[0] = nullregion(handle->nullrot[0], handle->rot[0]); + handle->rot[1] = nullregion(handle->nullrot[1], handle->rot[1]); + handle->rot[2] = nullregion(handle->nullrot[2], handle->rot[2]); +} + +int sball_getstatus(SBallHandle voidhandle, int *tx, int *ty, int *tz, + int *rx, int *ry, int *rz, int *buttons) +{ + sballhandle *handle = voidhandle; + + int events; + + if(handle == NULL) + return -1; + + events = sball_update(handle); /* check for new data */ + + /* perform null region processing */ + if(handle->usenullregion) + sball_do_nullregion(voidhandle); + + if(tx != NULL) + *tx = handle->trans[0]; + if(ty != NULL) + *ty = handle->trans[1]; + if(tz != NULL) + *tz = handle->trans[2]; + + if(rx != NULL) + *rx = handle->rot[0]; + if(ry != NULL) + *ry = handle->rot[1]; + if(rz != NULL) + *rz = handle->rot[2]; + + if(buttons != NULL) + *buttons = handle->buttons; + + /* no timer code yet */ + + return events; +} + +/* everything from this point to the end of file was added by + * John Tsiombikas for spacenavd integration. + */ +int sball_get_input(SBallHandle voidhandle, struct dev_input *inp) +{ + struct event *ev; + sballhandle *handle = voidhandle; + + /* read pending packets from the device and append them in the event list */ + sball_update(handle); + + /* if there are any events in the list, grab the first and return it */ + if((ev = handle->evhead)) { + handle->evhead = handle->evhead->next; + + *inp = ev->data; + free_event(ev); + return 1; + } + return 0; +} + +int sball_get_fd(SBallHandle voidhandle) +{ + sballhandle *sball = voidhandle; + + return sball_comm_fd(sball->commhandle); +} + +static struct event *alloc_event(void) +{ + struct event *ev; + + if(ev_free_list) { + ev = ev_free_list; + ev_free_list = ev->next; + } else { + ev = malloc(sizeof *ev); + evpool_size++; + } + return ev; +} + +static void free_event(struct event *ev) +{ + if(evpool_size > 512) { + free(ev); + evpool_size--; + } else { + ev->next = ev_free_list; + ev_free_list = ev; + } +} + +static void generate_motion_events(sballhandle *handle, int *prev_val, int *new_val, int timer) +{ + int i, pending = 0; + struct event *ev; + + for(i=0; i<6; i++) { + if(prev_val[i] == new_val[i]) { + continue; + } + + if((ev = alloc_event())) { + ev->data.type = INP_MOTION; + ev->data.idx = i; + ev->data.val = new_val[i]; + ev->next = 0; + + if(handle->evhead) { + handle->evtail->next = ev; + handle->evtail = ev; + } else { + handle->evhead = handle->evtail = ev; + } + pending = 1; + } + } + + if(pending) { + if((ev = alloc_event())) { + ev->data.type = INP_FLUSH; + ev->next = 0; + } + + if(handle->evhead) { + handle->evtail->next = ev; + handle->evtail = ev; + } else { + handle->evhead = handle->evtail = ev; + } + } +} + +static void generate_button_events(sballhandle *handle, int prevstate, int newstate) +{ + int i; + + for(i=0; i<16; i++) { + int newbit = (newstate >> i) & 1; + if(newbit != ((prevstate >> i) & 1)) { + /* state changed, trigger event */ + struct event *ev = alloc_event(); + if(!ev) continue; + + ev->data.type = INP_BUTTON; + ev->data.idx = i; + ev->data.val = newbit; + ev->next = 0; + + if(handle->evhead) { + handle->evtail->next = ev; + handle->evtail = ev; + } else { + handle->evhead = handle->evtail = ev; + } + } + } +} diff --git a/src/serial/sball.h b/src/serial/sball.h new file mode 100644 index 0000000..ee9763a --- /dev/null +++ b/src/serial/sball.h @@ -0,0 +1,177 @@ +/* +spacenavd - a free software replacement driver for 6dof space-mice. +Copyright (C) 2007-2010 John Tsiombikas + +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 3 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, see . + +This file incorporates work covered by the following copyright and +permission notice: + + Copyright 1997-2001 John E. Stone (j.stone@acm.org) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. 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. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +*/ + +#if !defined(SBALL_H) +#define SBALL_H 1 + +#include "event.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *SBallHandle; /* Handle type, used by all sball API functions */ + +/* Spaceball Button bit-masks */ +#define SBALL_BUTTON_1 1 /* bit 0 */ +#define SBALL_BUTTON_2 2 /* bit 1 */ +#define SBALL_BUTTON_3 4 /* bit 2 */ +#define SBALL_BUTTON_4 8 /* bit 3 */ +#define SBALL_BUTTON_5 16 /* bit 4 */ +#define SBALL_BUTTON_6 32 /* bit 5 */ +#define SBALL_BUTTON_7 64 /* bit 6 */ +#define SBALL_BUTTON_8 128 /* bit 7 */ +#define SBALL_BUTTON_9 256 /* bit 8 */ +#define SBALL_BUTTON_10 512 /* bit 9 */ +#define SBALL_BUTTON_11 1024 /* bit 10 */ +#define SBALL_BUTTON_12 2048 /* bit 11 */ + +/* The Spaceball 3003 and 3003 FLX only have "left" and "right" buttons */ +#define SBALL_BUTTON_LEFT 4096 /* bit 12 */ +#define SBALL_BUTTON_RIGHT 8192 /* bit 13 */ + +/* The Spaceball 2003A and 2003B have a dedicated pick button on the ball */ + +/* The Spaceball 2003 FLX uses "button 9" as the pick button. */ + +/* All of them return this as "button 9" in their encoded button data */ +#define SBALL_BUTTON_PICK 128 /* bit 8 */ + +/* On Spaceball 2003A and 2003B, the Rezero is "button 8" on the device */ + +/* On the newer devices, there are dedicated rezero buttons */ +#define SBALL_BUTTON_REZERO 16384 /* bit 14 */ + +/* The Spaceball 4000 FLX has a configurable palm rest which can be in */ + +/* either "left" or "right" handed mode. When it is configured in "left" */ + +/* handed mode, the "lefty" bit is set, and coordinate systems need to be */ + +/* inverted on one axis. */ +#define SBALL_MODE_LEFTY 32768 /* bit 15 */ + +/* + * sball_open() + * Open a named serial port which a Spaceball is attached to. + * Returns a handle which is used by all other sball API functions. + * If the serial port open fails, or the sball does not pass initialization + * tests, then a NULL is returned as the handle. + */ +SBallHandle sball_open(const char *sballname); + +/* + * sball_close() + * Closes down the Spaceball serial port, frees allocated resources and + * discards any unprocessed sball messages. + */ +int sball_close(SBallHandle voidhandle); + +/* + * sball_getstatus() + * Polls the Spaceball serial port for new packets, performs any optional + * postprocessing of Spaceball data such as null-region, scaling, and + * value clamping. The most recent values for translation, rotation and + * buttons are stored in the memory locations supplied by the caller. + * Returns the number of events processed. If the number of events returned + * is less than 1, either an error occured or there were no Spaceball + * events to process. + */ +int sball_getstatus(SBallHandle voidhandle, int *tx, int *ty, int *tz, int *rx, int *ry, int *rz, int *buttons); + +/* sball_get_input() - Added for spacenavd integration by John Tsiombikas. + * + * returns the first of any pending events through inp. + * returns 1 if it got an event, 0 if there where none pending + */ +int sball_get_input(SBallHandle voidhandle, struct dev_input *inp); + +/* sball_get_fd() - Added for spacenavd integration by John Tsiombikas. + * + * retreives the device file descriptor */ +int sball_get_fd(SBallHandle voidhandle); + +/* + * sball_rezero() + * Forces the Orb to re-zero itself at the present twist/position. + * All future event data is relative to this zero point. + */ +int sball_rezero(SBallHandle voidhandle); + +/* + * sball_init() + * Performs a software re-initialization of the Spaceball, clearing + * all unprocessed events. Initialization also forces the Orb to re-zero + * itself. + */ +int sball_init(SBallHandle voidhandle); + +/* + * sball_set_nullregion() + * Enables null-region processing on Spaceball output. + * The null-region is the area (centered at 0) around which + * each coordinate will report zero even when the Spaceball itself + * reports a number whose absolute value is less than the null region + * value for that coordinate. For example, if the null region on the + * X translation coordinate is set to 50, all sball_getstatus() would report + * 0 if X is less than 50 and greater than -50. If X is 51, sball_getstatus + * would report 1. If X is -51, sball_getstatus() would report -1. + * Null-regions help novice users gradually become accustomed to the + * incredible sensitivity of the Spaceball, and make some applications + * significantly easier to control. A resonable default nullregion for all + * six axes is 65. Null regions should be tunable by the user, since its + * likely that not all Spaceballs are quite identical, and it is guaranteed + * that users have varying levels of manual dexterity. + * Note that setting the null-region too high significantly reduces the + * dynamic range of the output values from the Spaceball. + */ +void sball_set_nullregion(SBallHandle voidhandle, int nulltx, int nullty, int nulltz, + int nullrx, int nullry, int nullrz); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/serial/sballserial.c b/src/serial/sballserial.c new file mode 100644 index 0000000..54662ec --- /dev/null +++ b/src/serial/sballserial.c @@ -0,0 +1,152 @@ +/* +spacenavd - a free software replacement driver for 6dof space-mice. +Copyright (C) 2007-2010 John Tsiombikas + +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 3 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, see . + +This file incorporates work covered by the following copyright and +permission notice: + + Copyright 1997-2001 John E. Stone (j.stone@acm.org) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. 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. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +*/ + +#define _POSIX_SOURCE 1 + +#include +#include +#include +#include +#include +#include +#include "sballserial.h" /* protos and types for this file */ + +typedef struct { + int fd; /* serial port device file descriptor */ +} commstruct; + +int sball_comm_open(const char *commname, SBallCommHandle * commhandleptr) +{ + struct termios sballtermio; + + commstruct *comm; + + *commhandleptr = NULL; + + comm = malloc(sizeof(commstruct)); + if(comm == NULL) + return -1; + + comm->fd = open(commname, O_RDWR | O_NONBLOCK | O_NOCTTY); + + if(comm->fd == -1) { + free(comm); + return -1; /* failed open of comm port */ + } + tcgetattr(comm->fd, &sballtermio); + +#if 0 + /* TIOCEXCL exclusive access by this process */ +#if defined(TIOCEXCL) + if(ioctl(comm->fd, TIOCEXCL) < 0) { + return -1; /* couldn't get exclusive use of port */ + } +#endif +#endif + + sballtermio.c_lflag = 0; + sballtermio.c_lflag = 0; + sballtermio.c_iflag = IGNBRK | IGNPAR; + sballtermio.c_oflag = 0; + sballtermio.c_cflag = CREAD | CS8 | CLOCAL | HUPCL; + sballtermio.c_cc[VEOL] = '\r'; + sballtermio.c_cc[VERASE] = 0; + sballtermio.c_cc[VKILL] = 0; + sballtermio.c_cc[VMIN] = 0; + sballtermio.c_cc[VTIME] = 0; + + /* use of baud rate in cflag is deprecated according to the */ + /* single unix spec, also doesn't work in IRIX > 6.2 */ + cfsetispeed(&sballtermio, B9600); + cfsetospeed(&sballtermio, B9600); + + tcsetattr(comm->fd, TCSAFLUSH, &sballtermio); + + *commhandleptr = (SBallCommHandle) comm; + + return 0; +} + +int sball_comm_write(SBallCommHandle commhandle, const char *buf) +{ + commstruct *comm = (commstruct *) commhandle; + + if(comm == NULL) + return -1; + + return write(comm->fd, buf, strlen(buf)); +} + +int sball_comm_read(SBallCommHandle commhandle, char *buf, int sz) +{ + commstruct *comm = (commstruct *) commhandle; + + if(comm == NULL) + return -1; + + return read(comm->fd, buf, sz); +} + +int sball_comm_close(SBallCommHandle * commhandleptr) +{ + commstruct *comm = (commstruct *) (*commhandleptr); + + if(comm == NULL) + return -1; + + close(comm->fd); + + free(*commhandleptr); + *commhandleptr = NULL; + + return 0; +} + +int sball_comm_fd(SBallCommHandle commhandle) +{ + return ((commstruct *) commhandle)->fd; +} + +/* end of unix code */ diff --git a/src/serial/sballserial.h b/src/serial/sballserial.h new file mode 100644 index 0000000..d627824 --- /dev/null +++ b/src/serial/sballserial.h @@ -0,0 +1,67 @@ +/* +spacenavd - a free software replacement driver for 6dof space-mice. +Copyright (C) 2007-2010 John Tsiombikas + +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 3 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, see . + +This file incorporates work covered by the following copyright and +permission notice: + + Copyright 1997-2001 John E. Stone (j.stone@acm.org) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. 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. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +*/ + +/* + * Machine/OS dependent serial port I/O routines. + * + * sball_comm_open() - open the serial port device for communication with + * the sball. Settings are 9600,N,8,1, non-blocking, + * no controlling tty. + * sball_comm_read() - nonblocking read of up to size bytes + * sball_comm_write() - blocking write of up to size bytes + * sball_comm_close() - close the serial port device + */ + +typedef void *SBallCommHandle; + +int sball_comm_open(const char *commname, SBallCommHandle * commhandleptr); + +int sball_comm_write(SBallCommHandle commhandle, const char *buf); + +int sball_comm_read(SBallCommHandle commhandle, char *buf, int sz); + +int sball_comm_close(SBallCommHandle * commhandleptr); + +int sball_comm_fd(SBallCommHandle commhandle); diff --git a/src/spnavd.c b/src/spnavd.c index 7a987b6..3802de2 100644 --- a/src/spnavd.c +++ b/src/spnavd.c @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 @@ -130,8 +130,6 @@ int main(int argc, char **argv) FD_SET(s, &rset); if(s > max_fd) max_fd = s; - - printf("listen to client: %d\n", s); } c = next_client(); } @@ -225,7 +223,7 @@ static void handle_events(fd_set *rset) struct dev_input inp; /* read an event from the device ... */ - if(read_dev(&inp) != -1) { + while(read_dev(&inp) != -1) { /* ... and process it, possibly dispatching a spacenav event to clients */ process_input(&inp); } diff --git a/src/spnavd.h b/src/spnavd.h index 3abe8a1..8f5bcd9 100644 --- a/src/spnavd.h +++ b/src/spnavd.h @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/xdetect.h b/src/xdetect.h index c2facba..e8f1175 100644 --- a/src/xdetect.h +++ b/src/xdetect.h @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 diff --git a/src/xdetect_linux.c b/src/xdetect_linux.c index 3c6fa10..bd60851 100644 --- a/src/xdetect_linux.c +++ b/src/xdetect_linux.c @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2009 John Tsiombikas +Copyright (C) 2007-2010 John Tsiombikas 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 @@ -124,7 +124,7 @@ int handle_xdet_events(fd_set *rset) } } sprintf(sock_file, "X%d", dpynum); - + if(ev->len > 0 && strcmp(ev->name, sock_file) == 0) { int i;