7e5101ac46dfc9a97e331bcc8e0d45198bf79dc8
[sball] / src / sball.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <termios.h>
8
9 struct sball {
10         int fd;
11 };
12
13 static int stty_sball(int fd);
14 static int stty_mag(int fd);
15
16 struct sball *sball_open(const char *dev)
17 {
18         int fd;
19         struct sball *sb = 0;
20
21         if((fd = open(dev, O_RDWR | | O_NOCTTY | O_NONBLOCK)) == -1) {
22                 fprintf(stderr, "sball_open: failed to open device: %s: %s\n", dev, strerror(errno));
23                 return 0;
24         }
25
26         if(!(sb = malloc(sizeof *sb))) {
27                 fprintf(stderr, "sball_open: failed to allocate sball object\n");
28                 goto err;
29         }
30         sb->fd = fd;
31
32         if(stty_sball(fd) == -1) {
33                 goto err;
34         }
35
36         /* set detect receiver function pointer */
37
38         return sb;
39
40 err:
41         close(fd);
42         free(sb);
43         return 0;
44 }
45
46 void sball_close(struct sball *sb)
47 {
48         if(!sb) return;
49         close(sb->fd);
50 }
51
52
53 /* Labtec spaceball: 9600 8n1 XON/XOFF */
54 static int stty_sball(int fd)
55 {
56         struct termios term;
57
58         if(tcgetattr(fd, &term) == -1) {
59                 perror("sball_open: tcgetattr");
60                 return -1;
61         }
62
63         term.c_oflag = 0;
64         term.c_lflag = 0;
65         term.c_cc[VMIN] = 0;
66         term.c_cc[VTIME] = 0;
67
68         term.c_cflag = CLOCAL | CREAD | CS8 | HUPCL;
69         term.c_iflag = IGNBRK | IGNPAR | IXON | IXOFF;
70
71         csetispeed(&term, B9600);
72         csetospeed(&term, B9600);
73
74         if(tcsetattr(fd, TCSANOW, &term) == -1) {
75                 perror("sball_open: tcsetattr");
76                 return -1;
77         }
78
79         return 0;
80 }
81
82 /* Logicad magellan spacemouse: 9600 8n2 CTS/RTS */
83 static int stty_mag(int fd)
84 {
85         struct termios term;
86
87         if(tcgetattr(fd, &term) == -1) {
88                 perror("sball_open: tcgetattr");
89                 return -1;
90         }
91
92         term.c_oflag = 0;
93         term.c_lflag = 0;
94         term.c_cc[VMIN] = 0;
95         term.c_cc[VTIME] = 0;
96
97         term.c_cflag = CLOCAL | CREAD | CS8 | CSTOPB | HUPCL | CRTSCTS;
98         term.c_iflag = IGNBRK | IGNPAR |;
99
100         csetispeed(&term, B9600);
101         csetospeed(&term, B9600);
102
103         if(tcsetattr(fd, TCSANOW, &term) == -1) {
104                 perror("sball_open: tcsetattr");
105                 return -1;
106         }
107
108         return 0;
109 }