10 #include <sys/types.h>
11 #include <sys/socket.h>
13 #include <sys/select.h>
15 #define SPNAV_SOCK_PATH "/var/run/spnav.sock"
16 #define IS_OPEN (sock != -1)
20 struct event_node *next;
23 /* only used for non-X mode, with spnav_remove_events */
24 static struct event_node *ev_queue, *ev_queue_tail;
26 /* AF_UNIX socket used for alternative communication with daemon */
29 static int conn_unix(int s, const char *path)
31 struct sockaddr_un addr;
33 memset(&addr, 0, sizeof addr);
34 addr.sun_family = AF_UNIX;
35 strncpy(addr.sun_path, path, sizeof(addr.sun_path));
37 return connect(s, (struct sockaddr*)&addr, sizeof addr);
49 if(!(ev_queue = malloc(sizeof *ev_queue))) {
53 ev_queue_tail = ev_queue;
55 if((s = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
59 if(conn_unix(s, SPNAV_SOCK_PATH) == -1) {
60 perror("failed to connect");
69 void sball_shutdown(void)
78 ev_queue = ev_queue->next;
87 int sball_getdev(void)
92 /* Checks both the event queue and the daemon socket for pending events.
93 * In either case, it returns immediately with true/false values (doesn't block).
95 int sball_pending(void)
105 FD_SET(sock, &rd_set);
107 /* don't block, just poll */
108 tv.tv_sec = tv.tv_usec = 0;
110 if(select(sock + 1, &rd_set, 0, 0, &tv) > 0) {
117 /* If there are events waiting in the event queue, dequeue one and
118 * return that, otherwise read one from the daemon socket.
119 * This might block unless we called event_pending() first and it returned true.
121 static int read_event(int s, sball_event *event)
126 /* if we have a queued event, deliver that one */
128 struct event_node *node = ev_queue->next;
129 ev_queue->next = ev_queue->next->next;
131 /* dequeued the last event, must update tail pointer */
132 if(ev_queue_tail == node) {
133 ev_queue_tail = ev_queue;
136 memcpy(event, &node->event, sizeof *event);
141 /* otherwise read one from the connection */
143 rd = read(s, data, sizeof data);
144 } while(rd == -1 && errno == EINTR);
150 if(data[0] < 0 || data[0] > 2) {
153 event->type = data[0] ? SBALL_EV_BUTTON : SBALL_EV_MOTION;
155 if(event->type == SBALL_EV_MOTION) {
157 event->motion.motion[i] = data[i + 1];
159 event->motion.motion[2] = -event->motion.motion[2];
160 event->motion.motion[5] = -event->motion.motion[5];
162 event->button.pressed = data[0] == 1 ? 1 : 0;
163 event->button.id = data[1];
170 int sball_getevent(sball_event *ev)
173 if(read_event(sock, ev) > 0) {
180 #else /* not __unix__ */
187 void sball_shutdown(void)
191 int sball_getdev(void)
196 int sball_pending(void)
201 int sball_getevent(sball_event *ev)
203 return SBALL_EV_NONE;