diff --git a/Makefile.in b/Makefile.in index 7f57910..76127c6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,5 +1,5 @@ -src = $(sort $(wildcard src/*.c) $(wildcard src/serial/*.c) $(wildcard src/magellan/*.c)) -hdr = $(wildcard src/*.h) $(wildcard src/serial/*.h) $(wildcard src/magellan/*.h) +src = $(sort $(wildcard src/*.c)) +hdr = $(wildcard src/*.h) obj = $(src:.c=.o) dep = $(obj:.o=.d) bin = spacenavd diff --git a/src/dev_serial.c b/src/dev_serial.c index 0d02347..d5cff28 100644 --- a/src/dev_serial.c +++ b/src/dev_serial.c @@ -1,6 +1,6 @@ /* spacenavd - a free software replacement driver for 6dof space-mice. -Copyright (C) 2007-2012 John Tsiombikas +Copyright (C) 2007-2020 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 @@ -15,40 +15,648 @@ 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 "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "dev_serial.h" #include "dev.h" #include "event.h" -#include "serial/sball.h" + +#if defined(__i386__) || defined(__ia64__) || defined(WIN32) || \ + (defined(__alpha__) || defined(__alpha)) || \ + defined(__arm__) || \ + (defined(__mips__) && defined(__MIPSEL__)) || \ + defined(__SYMBIAN32__) || \ + defined(__x86_64__) || \ + defined(__LITTLE_ENDIAN__) +#define SBALL_LITTLE_ENDIAN +#else +#define SBALL_BIG_ENDIAN +#endif + +#define INP_BUF_SZ 256 + +#define EVQUEUE_SZ 64 + +enum { + SB4000 = 1, + FLIPXY = 2 +}; + +struct sball { + int fd; + unsigned int flags; + int nbuttons; + + char buf[INP_BUF_SZ]; + int len; + + short mot[6]; + unsigned int keystate, keymask; + + struct termios saved_term; + int saved_mstat; + + struct dev_input evqueue[EVQUEUE_SZ]; + int evq_rd, evq_wr; + + int (*parse)(struct sball*, int, char*, int); +}; + static void close_dev_serial(struct device *dev); static int read_dev_serial(struct device *dev, struct dev_input *inp); +static int stty_sball(struct sball *sb); +static int stty_mag(struct sball *sb); +static void stty_save(struct sball *sb); +static void stty_restore(struct sball *sb); + +static int proc_input(struct sball *sb); + +static int mag_parsepkt(struct sball *sb, int id, char *data, int len); +static int sball_parsepkt(struct sball *sb, int id, char *data, int len); + +static int guess_num_buttons(const char *verstr); + +static void make_printable(char *buf, int len); +static int read_timeout(int fd, char *buf, int bufsz, long tm_usec); + +static void enqueue_motion(struct sball *sb, int axis, int val); +static void gen_button_events(struct sball *sb, unsigned int prev); + + int open_dev_serial(struct device *dev) { - if(!(dev->data = sball_open(dev->path))) { - return -1; - } - dev->fd = sball_get_fd(dev->data); + int fd, sz; + char buf[128]; + struct sball *sb = 0; + if((fd = open(dev->path, O_RDWR | O_NOCTTY | O_NONBLOCK)) == -1) { + fprintf(stderr, "sball_open: failed to open device: %s: %s\n", dev->path, strerror(errno)); + return 0; + } + + if(!(sb = calloc(1, sizeof *sb))) { + fprintf(stderr, "sball_open: failed to allocate sball object\n"); + goto err; + } + dev->data = sb; + dev->fd = sb->fd = fd; dev->close = close_dev_serial; dev->read = read_dev_serial; - return 0; + + stty_save(sb); + + if(stty_sball(sb) == -1) { + goto err; + } + write(fd, "\r@RESET\r", 8); + + if((sz = read_timeout(fd, buf, sizeof buf - 1, 2000000)) > 0 && strstr(buf, "\r@1")) { + /* we got a response, so it's a spaceball */ + make_printable(buf, sz); + printf("Spaceball detected: %s\n", buf); + + sb->nbuttons = guess_num_buttons(buf); + sb->keymask = 0xffff >> (16 - sb->nbuttons); + printf("%d buttons\n", sb->nbuttons); + + /* set binary mode and enable automatic data packet sending. also request + * a key event to find out as soon as possible if this is a 4000flx with + * 12 buttons + */ + write(fd, "\rCB\rMSSV\rk\r", 11); + + sb->parse = sball_parsepkt; + return 0; + } + + /* try as a magellan spacemouse */ + if(stty_mag(sb) == -1) { + goto err; + } + write(fd, "vQ\r", 3); + + if((sz = read_timeout(fd, buf, sizeof buf - 1, 250000)) > 0 && buf[0] == 'v') { + make_printable(buf, sz); + printf("Magellan SpaceMouse detected:\n%s\n", buf); + + sb->nbuttons = guess_num_buttons(buf); + sb->keymask = 0xffff >> (16 - sb->nbuttons); + printf("%d buttons\n", sb->nbuttons); + + /* set 3D mode, not-dominant-axis, pass through motion and button packets */ + write(fd, "m3\r", 3); + + sb->parse = mag_parsepkt; + return 0; + } + +err: + stty_restore(sb); + close(fd); + free(sb); + return -1; } static void close_dev_serial(struct device *dev) { if(dev->data) { - sball_close(dev->data); + stty_restore(dev->data); + close(dev->fd); } dev->data = 0; } static int read_dev_serial(struct device *dev, struct dev_input *inp) { - if(!dev->data || !sball_get_input(dev->data, inp)) { + int sz; + struct sball *sb = dev->data; + + if(!sb) return -1; + + while((sz = read(sb->fd, sb->buf + sb->len, INP_BUF_SZ - sb->len - 1)) > 0) { + sb->len += sz; + proc_input(sb); + } + + /* if we fill the input buffer, make a last attempt to parse it, and discard + * it so we can receive more + */ + if(sb->len >= INP_BUF_SZ) { + proc_input(sb); + sb->len = 0; + } + + if(sb->evq_rd != sb->evq_wr) { + *inp = sb->evqueue[sb->evq_rd]; + sb->evq_rd = (sb->evq_rd + 1) & (EVQUEUE_SZ - 1); + return 0; + } + return -1; +} + +/* Labtec spaceball: 9600 8n1 XON/XOFF + * Can't use canonical mode to assemble input into lines for the spaceball, + * because binary data received for motion events can include newlines which + * would be eaten up by the line discipline. Therefore we'll rely on VTIME=1 to + * hopefully get more than 1 byte at a time. Alternatively we could request + * printable reports, but I don't feel like implementing that. + */ +static int stty_sball(struct sball *sb) +{ + int mstat; + struct termios term; + + term = sb->saved_term; + term.c_oflag = 0; + term.c_lflag = 0; + term.c_cc[VMIN] = 0; + term.c_cc[VTIME] = 1; + + term.c_cflag = CLOCAL | CREAD | CS8 | HUPCL; + term.c_iflag = IGNBRK | IGNPAR | IXON | IXOFF; + + cfsetispeed(&term, B9600); + cfsetospeed(&term, B9600); + + if(tcsetattr(sb->fd, TCSAFLUSH, &term) == -1) { + perror("sball_open: tcsetattr"); return -1; } + tcflush(sb->fd, TCIOFLUSH); + + mstat = sb->saved_mstat | TIOCM_DTR | TIOCM_RTS; + ioctl(sb->fd, TIOCMGET, &mstat); + return 0; +} + +/* Logicad magellan spacemouse: 9600 8n2 CTS/RTS + * Since the magellan devices don't seem to send any newlines, we can rely on + * canonical mode to feed us nice whole lines at a time. + */ +static int stty_mag(struct sball *sb) +{ + int mstat; + struct termios term; + + term = sb->saved_term; + term.c_oflag = 0; + term.c_lflag = ICANON; + term.c_cc[VMIN] = 0; + term.c_cc[VTIME] = 0; + term.c_cc[VEOF] = 0; + term.c_cc[VEOL] = '\r'; + term.c_cc[VEOL2] = 0; + term.c_cc[VERASE] = 0; + term.c_cc[VKILL] = 0; + + term.c_cflag = CLOCAL | CREAD | CS8 | CSTOPB | HUPCL; +#ifdef CCTS_OFLOW + term.c_cflag |= CCTS_OFLOW; +#elif defined(CRTSCTS) + term.c_cflag |= CRTSCTS; +#endif + term.c_iflag = IGNBRK | IGNPAR; + + cfsetispeed(&term, B9600); + cfsetospeed(&term, B9600); + + if(tcsetattr(sb->fd, TCSAFLUSH, &term) == -1) { + perror("sball_open: tcsetattr"); + return -1; + } + tcflush(sb->fd, TCIOFLUSH); + + mstat = sb->saved_mstat | TIOCM_DTR | TIOCM_RTS; + ioctl(sb->fd, TIOCMGET, &mstat); + return 0; +} + +static void stty_save(struct sball *sb) +{ + tcgetattr(sb->fd, &sb->saved_term); + ioctl(sb->fd, TIOCMGET, &sb->saved_mstat); +} + +static void stty_restore(struct sball *sb) +{ + tcsetattr(sb->fd, TCSAFLUSH, &sb->saved_term); + tcflush(sb->fd, TCIOFLUSH); + ioctl(sb->fd, TIOCMSET, &sb->saved_mstat); +} + + +static int proc_input(struct sball *sb) +{ + int sz; + char *bptr = sb->buf; + char *start = sb->buf; + char *end = sb->buf + sb->len; + + /* see if we have a CR in the buffer */ + while(bptr < end) { + if(*bptr == '\r') { + *bptr = 0; + sb->parse(sb, *start, start + 1, bptr - start - 1); + start = ++bptr; + } else { + bptr++; + } + } + + sz = start - sb->buf; + if(sz > 0) { + memmove(sb->buf, start, sz); + sb->len -= sz; + } return 0; } + +static int mag_parsepkt(struct sball *sb, int id, char *data, int len) +{ + int i, prev, motion_pending = 0; + unsigned int prev_key; + + /*printf("magellan packet: %c - %s (%d bytes)\n", (char)id, data, len);*/ + + switch(id) { + case 'd': + if(len != 24) { + fprintf(stderr, "magellan: invalid data packet, expected 24 bytes, got: %d\n", len); + return -1; + } + for(i=0; i<6; i++) { + prev = sb->mot[i]; + sb->mot[i] = ((((int)data[0] & 0xf) << 12) | (((int)data[1] & 0xf) << 8) | + (((int)data[2] & 0xf) << 4) | (data[3] & 0xf)) - 0x8000; + data += 4; + + if(sb->mot[i] != prev) { + enqueue_motion(sb, i, sb->mot[i]); + motion_pending++; + } + } + if(motion_pending) { + enqueue_motion(sb, -1, 0); + } + break; + + case 'k': + if(len < 3) { + fprintf(stderr, "magellan: invalid keyboard pakcet, expected 3 bytes, got: %d\n", len); + return -1; + } + prev_key = sb->keystate; + sb->keystate = (data[0] & 0xf) | ((data[1] & 0xf) << 4) | (((unsigned int)data[2] & 0xf) << 8); + if(len > 3) { + sb->keystate |= ((unsigned int)data[3] & 0xf) << 12; + } + + if(sb->keystate != prev_key) { + gen_button_events(sb, prev_key); + } + break; + + case 'e': + if(data[0] == 1) { + fprintf(stderr, "magellan error: illegal command: %c%c\n", data[1], data[2]); + } else if(data[0] == 2) { + fprintf(stderr, "magellan error: framing error\n"); + } else { + fprintf(stderr, "magellan error: unknown device error\n"); + } + return -1; + + default: + break; + } + return 0; +} + +static int sball_parsepkt(struct sball *sb, int id, char *data, int len) +{ + int i, prev, motion_pending = 0; + char c, *rd, *wr; + unsigned int prev_key; + + /* decode data packet, replacing escaped values with the correct ones */ + rd = wr = data; + while(rd < data + len) { + if((c = *rd++) == '^') { + switch(*rd++) { + case 'Q': + *wr++ = 0x11; /* XON */ + break; + case 'S': + *wr++ = 0x13; /* XOFF */ + break; + case 'M': + *wr++ = 13; /* CR */ + break; + case '^': + *wr++ = '^'; + break; + default: + fprintf(stderr, "sball decode: ignoring invalid escape code: %xh\n", (unsigned int)c); + } + } else { + *wr++ = c; + } + } + len = wr - data; /* update the decoded length */ + + switch(id) { + case 'D': + if(len != 14) { + fprintf(stderr, "sball: invalid data packet, expected 14 bytes, got: %d\n", len); + return -1; + } + +#ifndef SBALL_BIG_ENDIAN + rd = data; + for(i=0; i<6; i++) { + rd += 2; + c = rd[0]; + rd[0] = rd[1]; + rd[1] = c; + } +#endif + + for(i=0; i<6; i++) { + char *dest = (char*)(sb->mot + i); + data += 2; + prev = sb->mot[i]; + *dest++ = data[0]; + *dest++ = data[1]; + + if(sb->mot[i] != prev) { + enqueue_motion(sb, i, sb->mot[i]); + motion_pending++; + } + } + if(motion_pending) { + enqueue_motion(sb, -1, 0); + } + break; + + case 'K': + if(len != 2) { + fprintf(stderr, "sball: invalid key packet, expected 2 bytes, got: %d\n", len); + return -1; + } + if(sb->flags & SB4000) break; /* ignore K packets from spaceball 4000 devices */ + + prev_key = sb->keystate; + /* data[1] bits 0-3 -> buttons 0,1,2,3 + * data[1] bits 4,5 (3003 L/R) -> buttons 0, 1 + * data[0] bits 0-2 -> buttons 4,5,6 + * data[0] bit 4 is (2003 pick) -> button 7 + */ + sb->keystate = ((data[1] & 0xf) | ((data[1] >> 4) & 3) | ((data[0] & 7) << 4) | + ((data[0] & 0x10) << 3)) & sb->keymask; + + if(sb->keystate != prev_key) { + gen_button_events(sb, prev_key); + } + break; + + case '.': + if(len != 2) { + fprintf(stderr, "sball: invalid sb4k key packet, expected 2 bytes, got: %d\n", len); + return -1; + } + /* spaceball 4000 key packet */ + if(!(sb->flags & SB4000)) { + printf("Switching to spaceball 4000flx/5000flx-a mode (12 buttons) \n"); + sb->flags |= SB4000; + sb->nbuttons = 12; /* might have guessed 8 before */ + sb->keymask = 0xfff; + } + /* update orientation flag (actually don't bother) */ + /* + if(data[0] & 0x20) { + sb->flags |= FLIPXY; + } else { + sb->flags &= ~FLIPXY; + } + */ + + prev_key = sb->keystate; + /* data[1] bits 0-5 -> buttons 0,1,2,3,4,5 + * data[1] bit 7 -> button 6 + * data[0] bits 0-4 -> buttons 7,8,9,10,11 + */ + sb->keystate = (data[1] & 0x3f) | ((data[1] & 0x80) >> 1) | ((data[0] & 0x1f) << 7); + if(sb->keystate != prev_key) { + gen_button_events(sb, prev_key); + } + break; + + case 'E': + fprintf(stderr, "sball: error:"); + for(i=0; i 0) { + tv.tv_sec = usec / 1000000; + tv.tv_usec = usec % 1000000; + + FD_ZERO(&rdset); + FD_SET(fd, &rdset); + if((res = select(fd + 1, &rdset, 0, 0, &tv)) > 0 && FD_ISSET(fd, &rdset)) { + sz += read(fd, buf + sz, bufsz - sz); + buf[sz] = 0; + tm_usec = usec = 128000; /* wait 128ms for the rest of the message to appear */ + gettimeofday(&tv0, 0); + continue; + } + if(res == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) { + break; + } + gettimeofday(&tv, 0); + usec = tm_usec - ((tv.tv_sec - tv0.tv_sec) * 1000000 + (tv.tv_usec - tv0.tv_usec)); + } + + return sz > 0 ? sz : -1; +} + +static void enqueue_motion(struct sball *sb, int axis, int val) +{ + struct dev_input *inp = sb->evqueue + sb->evq_wr; + + sb->evq_wr = (sb->evq_wr + 1) & (EVQUEUE_SZ - 1); + + if(axis >= 0) { + inp->type = INP_MOTION; + inp->idx = axis; + inp->val = val; + } else { + inp->type = INP_FLUSH; + } +} + +static void gen_button_events(struct sball *sb, unsigned int prev) +{ + int i; + unsigned int bit = 1; + unsigned int diff = sb->keystate ^ prev; + struct dev_input *inp; + + for(i=0; i<16; i++) { + if(diff & bit) { + inp = sb->evqueue + sb->evq_wr; + sb->evq_wr = (sb->evq_wr + 1) & (EVQUEUE_SZ - 1); + + inp->type = INP_BUTTON; + inp->idx = i; + inp->val = sb->keystate & bit ? 1 : 0; + } + bit <<= 1; + } +} diff --git a/src/magellan/serialconstants.h b/src/magellan/serialconstants.h deleted file mode 100644 index 4eb3592..0000000 --- a/src/magellan/serialconstants.h +++ /dev/null @@ -1,28 +0,0 @@ - -/* -serialmagellan - decoding serial magellan spaceball data. -Copyright (C) 2010 Thomas Anderson - -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 SERIAL_CONSTANTS_H_ -#define SERIAL_CONSTANTS_H_ - -#define MAXPACKETSIZE 16 -#define VERSION_STRING_MAX 512 -#define DEVICE_NAME_MAX 64 -#define MAXREADSIZE 512 - -#endif diff --git a/src/magellan/smag.c b/src/magellan/smag.c deleted file mode 100644 index 4789e65..0000000 --- a/src/magellan/smag.c +++ /dev/null @@ -1,423 +0,0 @@ -/* -serial magellan device support for spacenavd - -Copyright (C) 2012 John Tsiombikas -Copyright (C) 2010 Thomas Anderson - -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 -#include -#include -#include -#include -#include -#include "magellan/smag.h" -#include "magellan/smag_comm.h" -#include "magellan/smag_event.h" -#include "magellan/serialconstants.h" - -static void gen_disp_events(int *newval); -static void proc_disp_packet(void); -static void gen_button_event(int button, int new_state); -static void read_copy(void); -static void proc_disp_packet(void); -static void proc_bn_k_packet(void); -static void proc_bn_c_packet(void); -static void proc_bn_n_packet(void); -static void proc_bn_q_packet(void); -static void clean_input(); - - -static int dev_fd; - -struct input_struct { - char rbuf[MAXREADSIZE]; - int rbuf_sz; - char packet_buf[MAXPACKETSIZE]; - int packet_buf_pos; - struct smag_event *evhead; - struct smag_event *evtail; -} input; - -static int first_byte_parity[16] = { - 0xE0, 0xA0, 0xA0, 0x60, 0xA0, 0x60, 0x60, 0xA0, - 0x90, 0x50, 0x50, 0x90, 0xD0, 0x90, 0x90, 0x50 -}; - -static int second_byte_parity[64] = { - 0x80, 0x40, 0x40, 0x80, 0x40, 0x80, 0x80, 0x40, - 0x40, 0x80, 0x80, 0x40, 0x80, 0x40, 0x40, 0x80, - 0x40, 0x80, 0x80, 0x40, 0x80, 0x40, 0x40, 0x80, - 0x80, 0x40, 0x40, 0x80, 0xC0, 0x80, 0x80, 0x40, - 0xC0, 0x80, 0x80, 0x40, 0x80, 0x40, 0x40, 0x80, - 0x80, 0x40, 0x40, 0x80, 0x40, 0x80, 0x80, 0x40, - 0x80, 0x40, 0x40, 0x80, 0x40, 0x80, 0x80, 0x40, - 0x40, 0x80, 0x80, 0x40, 0x80, 0x40, 0x00, 0x80 -}; - -void smag_init_device(int fd) -{ - smag_write(fd, "", 0); - smag_write(fd, "\r\rm0", 4); - smag_write(fd, "pAA", 3); - smag_write(fd, "q00", 3); /*default translation and rotation */ - smag_write(fd, "nM", 2); /*zero radius. 0-15 defaults to 13 */ - smag_write(fd, "z", 1); /*zero device */ - smag_write(fd, "c33", 3); /*set translation, rotation on and dominant axis off */ - smag_write(fd, "l2\r\0", 4); - smag_write(fd, "\r\r", 2); - smag_write(fd, "l300", 4); - smag_write(fd, "b9", 2); /*these are beeps */ - smag_write(fd, "b9", 2); - - usleep(SMAG_DELAY_USEC); - tcflush(fd, TCIOFLUSH); - clean_input(); -} - -static void read_copy(void) -{ - int i; - - for(i=0; i 0) { - read_copy(); - } - ev = input.evhead; - if(ev) { - input.evhead = input.evhead->next; - - *inp = ev->data; - free_event(ev); - return 1; - } - return 0; -} - -int get_fd_smag() -{ - return dev_fd; -} - -void get_version_string(int fd, char *buf, int sz) -{ - int bytesrd; - char tmpbuf[MAXREADSIZE]; - - smag_write(fd, "\r\rm0", 4); - smag_write(fd, "", 0); - smag_write(fd, "\r\rm0", 4); - smag_write(fd, "c03", 3); - smag_write(fd, "z", 1); - smag_write(fd, "Z", 1); - smag_write(fd, "l000", 4); - usleep(SMAG_DELAY_USEC); - tcflush(fd, TCIOFLUSH); - clean_input(); - smag_write(fd, "vQ", 2); - - bytesrd = smag_read(fd, tmpbuf, MAXREADSIZE); - if(bytesrd > 0 && bytesrd < sz) { - strcpy(buf, tmpbuf); - } - clean_input(); -} - - -static void gen_disp_events(int *newval) -{ - int i, pending; - static int oldval[6] = {0, 0, 0, 0, 0, 0}; - struct smag_event *newev; - - pending = 0; - for(i=0; i<6; i++) { - if(newval[i] == oldval[i]) { - continue; - } - oldval[i] = newval[i]; - - newev = alloc_event(); - if(newev) { - newev->data.type = INP_MOTION; - newev->data.idx = i; - newev->data.val = newval[i]; - newev->next = 0; - - if(input.evhead) { - input.evtail->next = newev; - input.evtail = newev; - } else - input.evhead = input.evtail = newev; - pending = 1; - } - } - - if(pending) { - newev = alloc_event(); - if(newev) { - newev->data.type = INP_FLUSH; - newev->next = 0; - } - - if(input.evhead) { - input.evtail->next = newev; - input.evtail = newev; - } else { - input.evhead = input.evtail = newev; - } - } -} - -static void proc_disp_packet(void) -{ - int i, last_bytes, offset, values[6]; - short int accum_last, number, accum_last_adj; - - accum_last = offset = 0; - - for(i=1; i<13; i+=2) { - /*first byte check */ - unsigned char low, up; - - low = input.packet_buf[i] & 0x0F; - up = input.packet_buf[i] & 0xF0; - if(up != first_byte_parity[low]) { - fprintf(stderr, "bad first packet\n"); - return; - } - - /*second byte check */ - low = input.packet_buf[i + 1] & 0x3F; - up = input.packet_buf[i + 1] & 0xC0; - if(up != second_byte_parity[low]) { - fprintf(stderr, "bad second packet\n"); - return; - } - - number = (short int)((input.packet_buf[i] << 6 & 0x03C0) | (input.packet_buf[i + 1] & 0x3F)); - if(number > 512) { - number -= 1024; - } - accum_last += number; - - if(number < 0) { - offset += ((int)(number + 1) / 64) - 1; - } else { - offset += (int)number / 64; - } - /*printf("%8i ", number); */ - values[(i + 1) / 2 - 1] = number; - } - - /*last byte of packet is a sum of 6 numbers and a factor of 64. use as a packet check. - still not sure what the second to last byte is for. */ - accum_last_adj = accum_last & 0x003F; - accum_last_adj += offset; - if(accum_last_adj < 0) { - accum_last_adj += 64; - } - if(accum_last_adj > 63) { - accum_last_adj -= 64; - } - - last_bytes = (short int)(input.packet_buf[14] & 0x3F); - - if(accum_last_adj != last_bytes) { - printf(" bad packet\n"); - return; - } - gen_disp_events(values); - return; -} - -static void gen_button_event(int button, int new_state) -{ - struct smag_event *newev = alloc_event(); - - if(!newev) { - return; - } - - newev->data.type = INP_BUTTON; - newev->data.idx = button; - newev->data.val = new_state; - newev->next = 0; - - if(input.evhead) { - input.evtail->next = newev; - input.evtail = newev; - } else { - input.evhead = input.evtail = newev; - } -} - -static void proc_bn_k_packet(void) -{ - static char old_state[5] = { 0, 0, 0, 0, 0 }; - - if(input.packet_buf[1] != old_state[1]) { - if((input.packet_buf[1] & 0x01) != (old_state[1] & 0x01)) { - gen_button_event(0, input.packet_buf[1] & 0x01); - } - if((input.packet_buf[1] & 0x02) != (old_state[1] & 0x02)) { - gen_button_event(1, input.packet_buf[1] & 0x02); - } - if((input.packet_buf[1] & 0x04) != (old_state[1] & 0x04)) { - gen_button_event(2, input.packet_buf[1] & 0x04); - } - if((input.packet_buf[1] & 0x08) != (old_state[1] & 0x08)) { - gen_button_event(3, input.packet_buf[1] & 0x08); - } - } - - if(input.packet_buf[2] != old_state[2]) { - if((input.packet_buf[2] & 0x01) != (old_state[2] & 0x01)) { - gen_button_event(4, input.packet_buf[2] & 0x01); - } - if((input.packet_buf[2] & 0x02) != (old_state[2] & 0x02)) { - gen_button_event(5, input.packet_buf[2] & 0x02); - } - if((input.packet_buf[2] & 0x04) != (old_state[2] & 0x04)) { - gen_button_event(6, input.packet_buf[2] & 0x04); - } - if((input.packet_buf[2] & 0x08) != (old_state[2] & 0x08)) { - gen_button_event(7, input.packet_buf[2] & 0x08); - } - } - - /*skipping asterisk button. asterisk function come in through other packets. */ - /*magellan plus has left and right (10, 11) buttons not magellan classic */ - /*not sure if we need to filter out lower button events for magellan classic */ - - if(input.packet_buf[3] != old_state[3]) { - /* - if (input.packet_buf[3] & 0x01) - printf("button asterisk "); - */ - if((input.packet_buf[3] & 0x02) != (old_state[3] & 0x02)) { - gen_button_event(8, input.packet_buf[3] & 0x02); /*left button */ - } - if((input.packet_buf[3] & 0x04) != (old_state[3] & 0x04)) { - gen_button_event(9, input.packet_buf[3] & 0x04); /*right button */ - } - } - - strcpy(old_state, input.packet_buf); -} - -static void proc_bn_c_packet(void) -{ - /*these are implemented at device and these signals are to keep the driver in sync */ - if(input.packet_buf[1] & 0x02) { - printf("translation is on "); - } else { - printf("translation is off "); - } - - if(input.packet_buf[1] & 0x01) { - printf("rotation is on "); - } else { - printf("rotation is off "); - } - - if(input.packet_buf[1] & 0x04) { - printf("dominant axis is on "); - } else { - printf("dominant axis is off "); - } - - printf("\n"); - /*printf("%s\n", input.packet_buf); */ -} - -static void proc_bn_n_packet(void) -{ - int radius; - - radius = (int)input.packet_buf[1] & 0x0F; - printf("zero radius set to %i\n", radius); -} - -static void proc_bn_q_packet(void) -{ - /* this has no effect on the device numbers. Driver is to implement any scale of numbers */ - int rotation, translation; - - rotation = (int)input.packet_buf[1] & 0x07; - translation = (int)input.packet_buf[2] & 0x07; - printf("rotation = %i translation = %i\n", rotation, translation); -} - - -static void clean_input(void) -{ - memset(input.rbuf, 0x00, MAXREADSIZE); - input.rbuf_sz = 0; - memset(input.packet_buf, 0x00, MAXPACKETSIZE); - input.packet_buf_pos = 0; -} diff --git a/src/magellan/smag.h b/src/magellan/smag.h deleted file mode 100644 index c5a22a5..0000000 --- a/src/magellan/smag.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -serial magellan device support for spacenavd - -Copyright (C) 2012 John Tsiombikas -Copyright (C) 2010 Thomas Anderson - -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 "event.h" - -int open_smag(const char *devfile); -int close_smag(); -int read_smag(struct dev_input *inp); -int get_fd_smag(); - -void get_version_string(int fd, char *buf, int sz); - -void smag_init_device(int fd); -void clearInput(void); -void readCopy(void); diff --git a/src/magellan/smag_comm.c b/src/magellan/smag_comm.c deleted file mode 100644 index e65a287..0000000 --- a/src/magellan/smag_comm.c +++ /dev/null @@ -1,153 +0,0 @@ -/* -serial magellan device support for spacenavd - -Copyright (C) 2012 John Tsiombikas -Copyright (C) 2010 Thomas Anderson - -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include "magellan/smag_comm.h" - - -int smag_open_device(const char *fname) -{ - return open(fname, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY); -} - -int smag_set_port_spaceball(int fd) -{ - int status; - struct termios term; - - if(tcgetattr(fd, &term) == -1) { - perror("error tcgetattr"); - return -1; - } - - term.c_cflag = CREAD | CS8 | CLOCAL | HUPCL; - term.c_iflag |= IGNBRK | IGNPAR; - term.c_oflag = 0; - term.c_lflag = 0; - term.c_cc[VMIN] = 1; - term.c_cc[VTIME] = 0; - - cfsetispeed(&term, 9600); - cfsetospeed(&term, 9600); - if(tcsetattr(fd, TCSANOW, &term) == -1) { - perror("error tcsetattr"); - return -1; - } - - if(ioctl(fd, TIOCMGET, &status) == -1) { - perror("error TIOMCGET"); - return -1; - } - status |= TIOCM_DTR; - status |= TIOCM_RTS; - if(ioctl(fd, TIOCMSET, &status) == -1) { - perror("error TIOCMSET"); - return -1; - } - return 0; -} - -int smag_set_port_magellan(int fd) -{ - int status; - struct termios term; - - if(tcgetattr(fd, &term) == -1) { - perror("error tcgetattr"); - return -1; - } - - term.c_cflag = CS8 | CSTOPB | CRTSCTS | CREAD | HUPCL | CLOCAL; - term.c_iflag |= IGNBRK | IGNPAR; - term.c_oflag = 0; - term.c_lflag = 0; - term.c_cc[VMIN] = 1; - term.c_cc[VTIME] = 0; - - cfsetispeed(&term, 9600); - cfsetospeed(&term, 9600); - if(tcsetattr(fd, TCSANOW, &term) == -1) { - perror("error tcsetattr"); - return -1; - } - - if(ioctl(fd, TIOCMGET, &status) == -1) { - perror("error TIOCMGET"); - return -1; - } - status |= TIOCM_DTR; - status |= TIOCM_RTS; - if(ioctl(fd, TIOCMSET, &status) == -1) { - perror("error TIOCMSET"); - return -1; - } - return 0; -} - -#define LONG_DELAY 150000 - -void smag_write(int fd, const char *buf, int sz) -{ - int i; - - for(i=0; i -Copyright (C) 2010 Thomas Anderson - -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 SMAG_COMM_H_ -#define SMAG_COMM_H_ - -#define SMAG_DELAY_USEC 2000 - -int smag_open_device(const char *fname); -int smag_set_port_spaceball(int fd); -int smag_set_port_magellan(int fd); -void smag_write(int fd, const char *buf, int sz); -int smag_read(int fd, char *buf, int sz); -int smag_wait_read(int fd, char *buf, int sz, int wait_sec); - -#endif diff --git a/src/magellan/smag_detect.c b/src/magellan/smag_detect.c deleted file mode 100644 index d8a826f..0000000 --- a/src/magellan/smag_detect.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -serial magellan device support for spacenavd - -Copyright (C) 2012 John Tsiombikas -Copyright (C) 2010 Thomas Anderson - -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 -#include -#include -#include "magellan/smag.h" -#include "magellan/smag_detect.h" -#include "magellan/serialconstants.h" -#include "magellan/smag_comm.h" - -/*swap out /r for /n for string printing*/ -static void make_printable(char *str) -{ - while(*str) { - if(*str == '\r') { - *str = '\n'; - } - str++; - } -} - -int smag_detect(const char *fname, char *buf, int sz) -{ - int fd, bytesrd, pos; - char tmpbuf[MAXREADSIZE]; - - if((fd = smag_open_device(fname)) == -1) { - fprintf(stderr, "%s: couldn't open device file: %s\n", __func__, fname); - return -1; - } - if(smag_set_port_spaceball(fd) == -1) { - close(fd); - fprintf(stderr, "%s: couldn't setup port\n", __func__); - return -1; - } - - /* first look for spaceball. should have data after open and port setup. - * I was hoping that using the select inside serialWaitRead would allow me - * to get rid of the following sleep. Removing the sleep causes port to freeze. - */ - sleep(1); - - bytesrd = 0; - pos = 0; - - while((pos = smag_wait_read(fd, tmpbuf + bytesrd, MAXREADSIZE - bytesrd, 1)) > 0) { - bytesrd += pos; - } - if(bytesrd > 0) { - smag_write(fd, "hm", 2); - while((pos = smag_wait_read(fd, tmpbuf + bytesrd, MAXREADSIZE - bytesrd, 1)) > 0) { - bytesrd += pos; - } - - smag_write(fd, "\"", 1); - while((pos = smag_wait_read(fd, tmpbuf + bytesrd, MAXREADSIZE - bytesrd, 1)) > 0) { - bytesrd += pos; - } - - make_printable(tmpbuf); - strncpy(buf, tmpbuf, sz); - if(bytesrd < sz) { - fprintf(stderr, "%s: buffer overrun\n", __func__); - return -1; - } - } - - /*now if we are here we don't have a spaceball and now we need to check for a magellan */ - close(fd); - pos = 0; - - if((fd = smag_open_device(fname)) == -1) { - return -1; - } - if(smag_set_port_magellan(fd) == -1) { - return -1; - } - sleep(1); - - smag_init_device(fd); - get_version_string(fd, tmpbuf, MAXREADSIZE); - - make_printable(tmpbuf); - strncpy(buf, tmpbuf, sz); - close(fd); - return 0; -} diff --git a/src/magellan/smag_detect.h b/src/magellan/smag_detect.h deleted file mode 100644 index 9a52e80..0000000 --- a/src/magellan/smag_detect.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -serial magellan device support for spacenavd - -Copyright (C) 2012 John Tsiombikas -Copyright (C) 2010 Thomas Anderson - -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 SMAG_DETECT_H_ -#define SMAG_DETECT_H_ - -int smag_detect(const char *fname, char *buf, int sz); - -#endif /* SMAG_DETECT_H_ */ diff --git a/src/magellan/smag_event.c b/src/magellan/smag_event.c deleted file mode 100644 index 5f2ae68..0000000 --- a/src/magellan/smag_event.c +++ /dev/null @@ -1,49 +0,0 @@ -/* -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 -#include "smag_event.h" - -static int evpool_size; -static struct smag_event *ev_free_list; - -struct smag_event *alloc_event(void) -{ - struct smag_event *ev; - - if(ev_free_list) { - ev = ev_free_list; - ev_free_list = ev->next; - } else { - if((ev = malloc(sizeof *ev))) { - evpool_size++; - } - } - return ev; -} - -void free_event(struct smag_event *ev) -{ - if(evpool_size > 512) { - free(ev); - evpool_size--; - } else { - ev->next = ev_free_list; - ev_free_list = ev; - } -} diff --git a/src/magellan/smag_event.h b/src/magellan/smag_event.h deleted file mode 100644 index b642692..0000000 --- a/src/magellan/smag_event.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -serial magellan device support for spacenavd - -Copyright (C) 2012 John Tsiombikas -Copyright (C) 2010 Thomas Anderson - -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 SMAG_EVENT_H_ -#define SMAG_EVENT_H_ - -#include "event.h" - -struct smag_event { - struct dev_input data; - struct smag_event *next; -}; - -struct smag_event *alloc_event(void); -void free_event(struct smag_event *ev); - -#endif /* SMAG_EVENT_H_ */ diff --git a/src/serial/sball.c b/src/serial/sball.c deleted file mode 100644 index c7a8554..0000000 --- a/src/serial/sball.c +++ /dev/null @@ -1,747 +0,0 @@ -/* -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; -static 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 { - if((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 deleted file mode 100644 index ee9763a..0000000 --- a/src/serial/sball.h +++ /dev/null @@ -1,177 +0,0 @@ -/* -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 deleted file mode 100644 index 54662ec..0000000 --- a/src/serial/sballserial.c +++ /dev/null @@ -1,152 +0,0 @@ -/* -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 deleted file mode 100644 index d627824..0000000 --- a/src/serial/sballserial.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -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);