From e87cbc9ad5bc6bc3e958eb72b515ec9e32cad585 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Fri, 24 Jul 2009 02:52:07 +0000 Subject: [PATCH] forgot to add the new xdetect files git-svn-id: svn+ssh://svn.code.sf.net/p/spacenav/code/trunk/spacenavd@89 ef983eb1-d774-4af8-acfd-baaf7b16a646 --- init_script | 2 +- src/xdetect.h | 31 ++++++++++ src/xdetect_linux.c | 147 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 src/xdetect.h create mode 100644 src/xdetect_linux.c diff --git a/init_script b/init_script index 9d39929..05dddb1 100755 --- a/init_script +++ b/init_script @@ -31,6 +31,6 @@ stop) ;; reload|restart|force-reload) - $0 stop && $0 start + $0 stop && sleep 1 && $0 start ;; esac diff --git a/src/xdetect.h b/src/xdetect.h new file mode 100644 index 0000000..c2facba --- /dev/null +++ b/src/xdetect.h @@ -0,0 +1,31 @@ +/* +spacenavd - a free software replacement driver for 6dof space-mice. +Copyright (C) 2007-2009 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 XDETECT_H_ +#define XDETECT_H_ + +#include "config.h" + +int xdet_start(void); +void xdet_stop(void); + +int xdet_get_fd(void); + +int handle_xdet_events(fd_set *rset); + +#endif /* XDETECT_H_ */ diff --git a/src/xdetect_linux.c b/src/xdetect_linux.c new file mode 100644 index 0000000..c190fa4 --- /dev/null +++ b/src/xdetect_linux.c @@ -0,0 +1,147 @@ +/* +spacenavd - a free software replacement driver for 6dof space-mice. +Copyright (C) 2007-2009 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 "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "proto_x11.h" +#include "spnavd.h" + +/* TODO implement fallback to polling if inotify is not available */ + +static int fd = -1; +static int watch_tmp = -1, watch_x11 = -1; + +int xdet_start(void) +{ + if((fd = inotify_init()) == -1) { + perror("failed to create inotify queue"); + return -1; + } + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + + if((watch_x11 = inotify_add_watch(fd, "/tmp/.X11-unix", IN_CREATE)) == -1) { + if((watch_tmp = inotify_add_watch(fd, "/tmp", IN_CREATE)) == -1) { + perror("failed to watch /tmp for file events"); + close(fd); + fd = -1; + return -1; + } + } + + if(verbose) { + printf("waiting for X socket file to appear\n"); + } + + return fd; +} + +/* this is called by init_x11 if it's successful */ +void xdet_stop(void) +{ + if(fd != -1) { + if(verbose) { + printf("stopping X watch\n"); + } + + close(fd); + fd = watch_tmp = watch_x11 = -1; + } +} + +int xdet_get_fd(void) +{ + return fd; +} + +int handle_xdet_events(fd_set *rset) +{ + char buf[512]; + struct inotify_event *ev = (struct inotify_event*)buf; + ssize_t res; + + if(fd == -1 || !FD_ISSET(fd, rset)) { + return -1; + } + + for(;;) { + if((res = read(fd, buf, sizeof buf)) <= 0) { + if(res == 0) { + /* kernels before 2.6.14 returned 0 for not enough space */ + errno = EINVAL; + } + if(errno == EINTR) continue; + if(errno != EAGAIN) { + perror("failed to read inotify event"); + } + return -1; + } + + if(ev->wd == watch_tmp) { + if(watch_x11 != -1) { + inotify_rm_watch(fd, watch_tmp); + continue; + } + + if(ev->len > 0 && strcmp(ev->name, ".X11-unix") == 0) { + if((watch_x11 = inotify_add_watch(fd, "/tmp/.X11-unix", IN_CREATE)) == -1) { + perror("failed to add /tmp/.X11-unix to the watch queue"); + continue; + } + } + + } else if(ev->wd == watch_x11) { + char *dpystr, sock_file[64]; + int dpynum = 0; + + if((dpystr = getenv("DISPLAY"))) { + char *tmp = strchr(dpystr, ':'); + if(tmp && isdigit(tmp[1])) { + dpynum = atoi(tmp + 1); + } + } + sprintf(sock_file, "X%d", dpynum); + + if(ev->len > 0 && strcmp(ev->name, sock_file) == 0) { + int i; + + if(verbose) { + printf("found X socket, will now attempt to connect to the X server\n"); + } + + /* poll for approximately 30 seconds (well a bit more than that) */ + for(i=0; i<30; i++) { + sleep(1); + if(init_x11() != -1) { + return 0; /* success */ + } + } + + fprintf(stderr, "found X socket yet failed to connect\n"); + } + } + } + + return -1; +}