Skip to content

Commit 41209d7

Browse files
committed
- Added UNIX-socket alternative communication method (not working correctly yet).
- Restructured the daemon code, broken up the huge main loop into two functions. git-svn-id: svn+ssh://svn.code.sf.net/p/spacenav/code/libspnav@5 ef983eb1-d774-4af8-acfd-baaf7b16a646
1 parent 9fbbba1 commit 41209d7

1 file changed

Lines changed: 124 additions & 7 deletions

File tree

spnav.c

Lines changed: 124 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ OF SUCH DAMAGE.
3030
#include <errno.h>
3131
#include <unistd.h>
3232
#include <sys/types.h>
33+
#include <sys/time.h>
3334
#include <sys/socket.h>
3435
#include <sys/un.h>
36+
#include <sys/select.h>
3537
#include "spnav.h"
3638

3739
#ifdef USE_X11
@@ -55,8 +57,17 @@ enum {
5557
#define IS_OPEN (sock)
5658
#endif
5759

60+
struct event_node {
61+
spnav_event event;
62+
struct event_node *next;
63+
};
64+
65+
/* only used for non-X mode, with spnav_remove_events */
66+
static struct event_node *ev_queue, *ev_queue_tail;
67+
5868
static int sock;
5969

70+
6071
int spnav_open(void)
6172
{
6273
int s;
@@ -66,7 +77,12 @@ int spnav_open(void)
6677
return -1;
6778
}
6879

69-
if((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
80+
if(!(ev_queue = malloc(sizeof *ev_queue))) {
81+
return -1;
82+
}
83+
ev_queue_tail = ev_queue;
84+
85+
if((s = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
7086
return -1;
7187
}
7288

@@ -75,6 +91,7 @@ int spnav_open(void)
7591
strcpy(addr.sun_path, "/tmp/spacenav_usock");
7692

7793
if(connect(s, (struct sockaddr*)&addr, sizeof addr) == -1) {
94+
perror("connect failed");
7895
return -1;
7996
}
8097

@@ -118,6 +135,12 @@ int spnav_close(void)
118135
}
119136

120137
if(sock) {
138+
while(ev_queue) {
139+
void *tmp = ev_queue;
140+
ev_queue = ev_queue->next;
141+
free(tmp);
142+
}
143+
121144
close(sock);
122145
sock = 0;
123146
return 0;
@@ -238,25 +261,90 @@ int spnav_fd(void)
238261
return sock ? sock : -1;
239262
}
240263

264+
static int event_pending(int s)
265+
{
266+
fd_set rd_set;
267+
struct timeval tv;
268+
269+
if(ev_queue->next) {
270+
return 1;
271+
}
272+
273+
FD_ZERO(&rd_set);
274+
FD_SET(s, &rd_set);
275+
276+
/* don't block, just poll */
277+
tv.tv_sec = tv.tv_usec = 0;
278+
279+
if(select(s + 1, &rd_set, 0, 0, &tv) > 0) {
280+
return 1;
281+
}
282+
return 0;
283+
}
284+
285+
static int read_event(int s, spnav_event *event)
286+
{
287+
int i, rd;
288+
int data[8];
289+
290+
/* if we have a queued event, deliver that one */
291+
if(ev_queue->next) {
292+
struct event_node *node = ev_queue->next;
293+
ev_queue->next = ev_queue->next->next;
294+
295+
memcpy(event, &node->event, sizeof *event);
296+
free(node);
297+
return event->type;
298+
}
299+
300+
/* otherwise read one from the connection */
301+
do {
302+
rd = read(s, data, sizeof data);
303+
} while(rd == -1 && errno == EINTR);
304+
305+
if(rd == -1) {
306+
return 0;
307+
}
308+
309+
if(data[0] < 0 || data[0] > 2) {
310+
return 0;
311+
}
312+
event->type = data[0] ? SPNAV_EVENT_BUTTON : SPNAV_EVENT_MOTION;
313+
314+
if(event->type == SPNAV_EVENT_MOTION) {
315+
event->motion.data = &event->motion.x;
316+
for(i=0; i<6; i++) {
317+
event->motion.data[i] = data[i + 1];
318+
}
319+
event->motion.period = data[7];
320+
} else {
321+
event->button.press = data[0] == 1 ? 1 : 0;
322+
event->button.bnum = data[1];
323+
}
324+
325+
return event->type;
326+
}
327+
241328

242329
int spnav_wait_event(spnav_event *event)
243330
{
244331
#ifdef USE_X11
245332
if(dpy) {
246333
for(;;) {
247-
int evtype;
248334
XEvent xev;
249335
XNextEvent(dpy, &xev);
250336

251-
if((evtype = spnav_x11_event(&xev, event)) > 0) {
252-
return evtype;
337+
if(spnav_x11_event(&xev, event) > 0) {
338+
return event->type;
253339
}
254340
}
255341
}
256342
#endif
257343

258344
if(sock) {
259-
/* TODO implement event reception from the UNIX socket */
345+
if(read_event(sock, event) > 0) {
346+
return event->type;
347+
}
260348
}
261349
return 0;
262350
}
@@ -276,7 +364,11 @@ int spnav_poll_event(spnav_event *event)
276364
#endif
277365

278366
if(sock) {
279-
/* TODO implement event reception from the UNIX socket */
367+
if(event_pending(sock)) {
368+
if(read_event(sock, event) > 0) {
369+
return event->type;
370+
}
371+
}
280372
}
281373
return 0;
282374
}
@@ -301,6 +393,21 @@ static Bool match_events(Display *dpy, XEvent *xev, char *arg)
301393
}
302394
#endif
303395

396+
static int enqueue_event(spnav_event *event)
397+
{
398+
struct event_node *node;
399+
if(!(node = malloc(sizeof *node))) {
400+
return -1;
401+
}
402+
403+
memcpy(&node->event, event, sizeof node->event);
404+
node->next = 0;
405+
406+
ev_queue_tail->next = node;
407+
ev_queue_tail = node;
408+
return 0;
409+
}
410+
304411
int spnav_remove_events(int type)
305412
{
306413
int rm_count = 0;
@@ -317,7 +424,17 @@ int spnav_remove_events(int type)
317424
#endif
318425

319426
if(sock) {
320-
/* TODO */
427+
while(event_pending(sock)) {
428+
spnav_event event;
429+
430+
read_event(sock, &event);
431+
if(event.type != type) {
432+
enqueue_event(&event);
433+
} else {
434+
rm_count++;
435+
}
436+
}
437+
return rm_count;
321438
}
322439
return 0;
323440
}

0 commit comments

Comments
 (0)