diff --git a/src/client.c b/src/client.c
index b879669..27d1931 100644
--- a/src/client.c
+++ b/src/client.c
@@ -35,24 +35,14 @@ struct client {
#endif
float sens; /* sensitivity */
+ int dev_idx; /* device index */
struct client *next;
};
-static struct client *client_list;
-static struct client *citer; /* iterator (used by first/next calls) */
-
-int init_clients(void)
-{
- if(!(client_list = malloc(sizeof *client_list))) {
- perror("failed to allocate client list");
- return -1;
- }
- client_list->next = 0;
- return 0;
-}
-
+static struct client *client_list = NULL;
+static struct client *client_iter; /* iterator (used by first/next calls) */
/* add a client to the list
* cdata points to the socket fd for new-protocol clients, or the
@@ -63,9 +53,9 @@ struct client *add_client(int type, void *cdata)
struct client *client;
#ifdef USE_X11
- if(!cdata || (type != CLIENT_UNIX && type != CLIENT_X11))
+ if(!cdata || (type != CLIENT_UNIX && type != CLIENT_X11))
#else
- if(!cdata || type != CLIENT_UNIX)
+ if(!cdata || type != CLIENT_UNIX)
#endif
{
return 0;
@@ -85,8 +75,14 @@ struct client *add_client(int type, void *cdata)
}
client->sens = 1.0f;
- client->next = client_list->next;
- client_list->next = client;
+ client->dev_idx = 0; /* default/first device */
+
+ if(client_list == NULL) {
+ client->next = NULL;
+ return (client_list = client);
+ }
+ client->next = client_list;
+ client_list = client;
return client;
}
@@ -95,6 +91,15 @@ void remove_client(struct client *client)
{
struct client *iter = client_list;
+ if(iter == NULL)
+ return;
+ if(iter == client) {
+ client_list = iter->next;
+ free(iter);
+ if((iter = client_list) == NULL)
+ return;
+ }
+
while(iter->next) {
if(iter->next == client) {
struct client *tmp = iter->next;
@@ -133,13 +138,24 @@ float get_client_sensitivity(struct client *client)
return client->sens;
}
+void set_client_device_index(struct client *client, int dev_idx)
+{
+ client->dev_idx = dev_idx;
+}
+
+int get_client_device_index(struct client *client)
+{
+ return client->dev_idx;
+}
+
struct client *first_client(void)
{
- return citer = client_list->next;
+ return (client_iter = client_list);
}
struct client *next_client(void)
{
- citer = citer->next;
- return citer;
+ if(client_iter)
+ client_iter = client_iter->next;
+ return client_iter;
}
diff --git a/src/client.h b/src/client.h
index 97cd1e3..ec9c7c6 100644
--- a/src/client.h
+++ b/src/client.h
@@ -34,8 +34,6 @@ enum {
struct client;
-int init_clients(void);
-
struct client *add_client(int type, void *cdata);
void remove_client(struct client *client);
@@ -48,6 +46,9 @@ Window get_client_window(struct client *client);
void set_client_sensitivity(struct client *client, float sens);
float get_client_sensitivity(struct client *client);
+void set_client_device_index(struct client *client, int dev_idx);
+int get_client_device_index(struct client *client);
+
/* these two can be used to iterate over all clients */
struct client *first_client(void);
struct client *next_client(void);
diff --git a/src/dev.c b/src/dev.c
index ada0e64..354f6b6 100644
--- a/src/dev.c
+++ b/src/dev.c
@@ -18,67 +18,192 @@ along with this program. If not, see .
#include "config.h"
#include
#include
+#include
+#include
#include "dev.h"
#include "dev_usb.h"
#include "dev_serial.h"
+#include "event.h" /* remove pending events upon device removal */
#include "spnavd.h"
-static struct device dev = {-1, 0};
+static struct device *add_device(void);
+static struct device *dev_path_in_use(char const * dev_path);
-int init_dev(void)
+static struct device *dev_list = NULL;
+static struct device *dev_iter;
+
+int init_devices(void)
{
- if(dev.fd != -1) {
- fprintf(stderr, "init_dev called, but device is already open\n");
- return -1;
+ struct device *dev_cur;
+ int i, device_added = 0;
+ char **dev_path;
+
+ /* try to open a serial device if specified in the config file */
+ if(cfg.serial_dev[0]) {
+ if(!dev_path_in_use(cfg.serial_dev)) {
+ dev_cur = add_device();
+ strcpy(dev_cur->path, cfg.serial_dev);
+ if(open_dev_serial(dev_cur) == -1) {
+ remove_device(dev_cur);
+ } else {
+ strcpy(dev_cur->name, "serial device");
+ printf("using device: %s\n", cfg.serial_dev);
+ device_added++;
+ }
+ }
}
- if(cfg.serial_dev[0]) {
- /* try to open a serial device if specified in the config file */
- printf("using device: %s\n", cfg.serial_dev);
+ dev_path = malloc(MAX_DEVICES * sizeof(char *));
+ for(i=0; ipath, dev_path[i]);
+ if(open_dev_usb(dev_cur) == -1) {
+ remove_device(dev_cur);
+ } else {
+ printf("using device: %s\n", dev_path[i]);
+ device_added++;
+ }
+ }
- if(open_dev_usb(&dev, dev_path) == -1) {
- return -1;
- }
+ for(i=0; i<8; i++) {
+ free(dev_path[i]);
+ }
+ free(dev_path);
+
+ if(!device_added) {
+ return -1;
}
return 0;
}
-void shutdown_dev(void)
+static struct device *add_device(void)
{
- if(dev.close) {
- dev.close(&dev);
+ struct device *dev_new, *iter;
+
+ if((dev_new = malloc(sizeof *dev_new)) == NULL) {
+ return NULL;
+ }
+
+ printf("adding device.\n");
+
+ dev_new->fd = -1;
+ dev_new->data = NULL;
+ dev_new->next = NULL;
+
+ if(dev_list == NULL)
+ return (dev_list = dev_new);
+
+ iter = dev_list;
+ while(iter->next) {
+ iter = iter->next;
+ }
+ iter->next = dev_new;
+ return dev_new;
+}
+
+void remove_device(struct device *dev)
+{
+ struct device *iter = dev_list, *tmp;
+
+ if(iter == NULL)
+ return;
+ if(iter == dev) {
+ if(verbose)
+ printf("removing device: %s\n", dev->path);
+ dev_list = iter->next;
+ free(iter);
+ if((iter = dev_list) == NULL)
+ return;
+ }
+
+ while(iter->next) {
+ if(iter->next == dev) {
+ if(verbose)
+ printf("removing device: %s\n", dev->path);
+ tmp = iter->next;
+ iter->next = iter->next->next;
+ remove_dev_event(dev);
+ if(tmp->fd >= 0) {
+ close(tmp->fd);
+ }
+ free(tmp);
+ } else {
+ iter = iter->next;
+ }
}
}
-int get_dev_fd(void)
+static struct device *dev_path_in_use(char const *dev_path)
{
- return dev.fd;
+ struct device *iter = dev_list;
+ while(iter) {
+ if(strcmp(iter->path, dev_path) == 0) {
+ return iter;
+ }
+ iter = iter->next;
+ }
+ return 0;
}
-int read_dev(struct dev_input *inp)
+int get_device_fd(struct device *dev)
{
- if(!dev.read) {
+ if(dev == NULL)
return -1;
- }
- return dev.read(&dev, inp);
+ return dev->fd;
}
-void set_led(int state)
+int get_device_index(struct device *dev)
{
- if(dev.set_led) {
- dev.set_led(&dev, state);
+ struct device *iter = dev_list;
+ int index = 0;
+ while(iter) {
+ if(dev == iter)
+ return index;
+ index++;
+ iter = iter->next;
}
+ return -1;
+}
+
+int read_device(struct device *dev, struct dev_input *inp)
+{
+ if(dev->read == NULL)
+ return -1;
+ return (dev->read(dev, inp));
+}
+
+void set_device_led(struct device *dev, int state)
+{
+ if(dev->set_led)
+ dev->set_led(dev, state);
+}
+
+struct device *first_device(void)
+{
+ return (dev_iter = dev_list);
+}
+
+struct device *next_device(void)
+{
+ if(dev_iter)
+ dev_iter = dev_iter->next;
+ return dev_iter;
}
diff --git a/src/dev.h b/src/dev.h
index 5e6ecbd..58d2c74 100644
--- a/src/dev.h
+++ b/src/dev.h
@@ -18,6 +18,7 @@ along with this program. If not, see .
#ifndef SPNAV_DEV_H_
#define SPNAV_DEV_H_
+#include
#include "config.h"
struct dev_input;
@@ -28,19 +29,26 @@ struct device {
int fd;
void *data;
char name[MAX_DEV_NAME];
+ char path[PATH_MAX];
void (*close)(struct device*);
int (*read)(struct device*, struct dev_input*);
void (*set_led)(struct device*, int);
+
+ struct device *next;
};
-int init_dev(void);
-void shutdown_dev(void);
-int get_dev_fd(void);
-#define is_dev_valid() (get_dev_fd() >= 0)
+int init_devices(void);
-int read_dev(struct dev_input *inp);
+void remove_device(struct device *dev);
-void set_led(int state);
+int get_device_fd(struct device *dev);
+#define is_device_valid(dev) (get_device_fd(dev) >= 0)
+int get_device_index(struct device *dev);
+int read_device(struct device *dev, struct dev_input *inp);
+void set_device_led(struct device *dev, int state);
+
+struct device *first_device(void);
+struct device *next_device(void);
#endif /* SPNAV_DEV_H_ */
diff --git a/src/dev_serial.c b/src/dev_serial.c
index 212ec57..0d02347 100644
--- a/src/dev_serial.c
+++ b/src/dev_serial.c
@@ -25,9 +25,9 @@ along with this program. If not, see .
static void close_dev_serial(struct device *dev);
static int read_dev_serial(struct device *dev, struct dev_input *inp);
-int open_dev_serial(struct device *dev, const char *devfile)
+int open_dev_serial(struct device *dev)
{
- if(!(dev->data = sball_open(devfile))) {
+ if(!(dev->data = sball_open(dev->path))) {
return -1;
}
dev->fd = sball_get_fd(dev->data);
diff --git a/src/dev_serial.h b/src/dev_serial.h
index 1bc3372..a8c3339 100644
--- a/src/dev_serial.h
+++ b/src/dev_serial.h
@@ -21,6 +21,6 @@ along with this program. If not, see .
struct device;
-int open_dev_serial(struct device *dev, const char *devfile);
+int open_dev_serial(struct device *dev);
#endif /* SPNAV_DEV_SERIAL_H_ */
diff --git a/src/dev_usb.h b/src/dev_usb.h
index 7e424b6..9261f55 100644
--- a/src/dev_usb.h
+++ b/src/dev_usb.h
@@ -20,7 +20,7 @@ along with this program. If not, see .
struct device;
-int open_dev_usb(struct device *dev, const char *path);
-const char *find_usb_device(void);
+int open_dev_usb(struct device *dev);
+void find_usb_devices(char **path, int str_n, int char_n);
#endif /* SPNAV_DEV_USB_H_ */
diff --git a/src/dev_usb_darwin.c b/src/dev_usb_darwin.c
index 3710525..1fd8def 100644
--- a/src/dev_usb_darwin.c
+++ b/src/dev_usb_darwin.c
@@ -23,12 +23,12 @@ along with this program. If not, see .
#include
#include "dev.h"
-int open_dev_usb(struct device *dev, const char *path)
+int open_dev_usb(struct device *dev)
{
return -1;
}
-const char *find_usb_device(void)
+void find_usb_devices(char **path, int str_n, int char_n);
{
static const int vendor_id = 1133; /* 3dconnexion */
static char dev_path[512];
@@ -47,7 +47,8 @@ const char *find_usb_device(void)
/* fetch... */
if(IOServiceGetMatchingServices(kIOMasterPortDefault, match_dict, &iter) != kIOReturnSuccess) {
fprintf(stderr, "failed to retrieve USB HID devices\n");
- return 0;
+ /* return 0; */
+ return;
}
dev = IOIteratorNext(iter);
@@ -56,7 +57,7 @@ const char *find_usb_device(void)
IOObjectRelease(dev);
IOObjectRelease(iter);
- return dev_path;
+ /* return dev_path;*/
}
#endif /* __APPLE__ && __MACH__ */
diff --git a/src/dev_usb_linux.c b/src/dev_usb_linux.c
index e883db5..9c71cab 100644
--- a/src/dev_usb_linux.c
+++ b/src/dev_usb_linux.c
@@ -22,6 +22,7 @@ along with this program. If not, see .
#include
#include
#include
+#include
#include
#include
#include
@@ -54,12 +55,12 @@ static int read_evdev(struct device *dev, struct dev_input *inp);
static void set_led_evdev(struct device *dev, int state);
-int open_dev_usb(struct device *dev, const char *path)
+int open_dev_usb(struct device *dev)
{
/*unsigned char evtype_mask[(EV_MAX + 7) / 8];*/
- if((dev->fd = open(path, O_RDWR)) == -1) {
- if((dev->fd = open(path, O_RDONLY)) == -1) {
+ if((dev->fd = open(dev->path, O_RDWR)) == -1) {
+ if((dev->fd = open(dev->path, O_RDONLY)) == -1) {
perror("failed to open device");
return -1;
}
@@ -107,6 +108,7 @@ static void close_evdev(struct device *dev)
dev->set_led(dev, 0);
close(dev->fd);
dev->fd = -1;
+ remove_device(dev);
}
}
@@ -126,11 +128,7 @@ static int read_evdev(struct device *dev, struct dev_input *inp)
if(rdbytes == -1) {
if(errno != EAGAIN) {
perror("read error");
- close(dev->fd);
- dev->fd = -1;
-
- /* restart hotplug detection */
- init_hotplug();
+ remove_device(dev);
}
return -1;
}
@@ -165,7 +163,6 @@ static int read_evdev(struct device *dev, struct dev_input *inp)
return -1;
}
}
-
return 0;
}
@@ -188,60 +185,97 @@ static void set_led_evdev(struct device *dev, int state)
}
#define PROC_DEV "/proc/bus/input/devices"
-const char *find_usb_device(void)
+void find_usb_devices(char **path, int str_n, int char_n)
{
- static char path[PATH_MAX];
+ int path_idx = 0;
int i, valid_vendor = 0, valid_str = 0;
+ int skip_section = 0, buf_used, buf_len;
char buf[1024];
+ char *buf_pos, *section_start, *next_section = 0, *cur_line, *next_line;
FILE *fp;
if(verbose) {
printf("Device detection, parsing " PROC_DEV "\n");
}
+ for(i=0; ievent.motion.data = (int*)&dev_ev->event.motion.x;
+ for(i=0; i<6; i++)
+ dev_ev->event.motion.data[i] = 0;
+ gettimeofday(&dev_ev->timeval, 0);
+ dev_ev->dev = dev;
+ dev_ev->next = NULL;
+
+ if(dev_ev_list == NULL)
+ return dev_ev_list = dev_ev;
+
+ iter = dev_ev_list;
+ while(iter->next) {
+ iter = iter->next;
+ }
+ iter->next = dev_ev;
+ return dev_ev;
+}
+
+/* remove_dev_event takes a device pointer as argument so that upon removal of
+ * a device the pending event (if any) can be removed.
+ */
+void remove_dev_event(struct device *dev)
+{
+ struct dev_event *iter = dev_ev_list, *tmp;
+
+ if(iter == NULL)
+ return;
+ if(iter->dev == dev) {
+ dev_ev_list = iter->next;
+ free(iter);
+ if((iter = dev_ev_list) == NULL)
+ return;
+ }
+
+ while(iter->next) {
+ if(iter->next->dev == dev) {
+ if(verbose)
+ printf("removing device event of: %s\n", dev->path);
+ tmp = iter->next;
+ iter->next = iter->next->next;
+ free(tmp);
+ } else {
+ iter = iter->next;
+ }
+ }
+}
+
+static struct dev_event *device_event_in_use(struct device *dev)
+{
+ struct dev_event *iter = dev_ev_list;
+ while(iter) {
+ if(iter->dev == dev) {
+ return iter;
+ }
+ iter = iter->next;
+ }
+ return NULL;
+}
/* process_input processes an device input event, and dispatches
* spacenav events to the clients by calling dispatch_event.
@@ -47,9 +124,10 @@ static int ev_pending;
* we get an INP_FLUSH event. Button events are dispatched immediately
* and they implicitly flush any pending motion event.
*/
-void process_input(struct dev_input *inp)
+void process_input(struct device *dev, struct dev_input *inp)
{
int sign;
+ struct dev_event *dev_ev;
switch(inp->type) {
case INP_MOTION:
@@ -62,10 +140,17 @@ void process_input(struct dev_input *inp)
inp->val = (int)((float)inp->val * cfg.sensitivity * (inp->idx < 3 ? cfg.sens_trans[inp->idx] : cfg.sens_rot[inp->idx - 3]));
- ev.type = EVENT_MOTION;
- ev.motion.data = (int*)&ev.motion.x;
- ev.motion.data[inp->idx] = sign * inp->val;
- ev_pending = 1;
+ dev_ev = device_event_in_use(dev);
+ if(verbose && dev_ev == NULL)
+ printf("adding dev event for device: %s\n", dev->path);
+ if(dev_ev == NULL && (dev_ev = add_dev_event(dev)) == NULL) {
+ fprintf(stderr, "failed to get dev_event\n");
+ break;
+ }
+ dev_ev->event.type = EVENT_MOTION;
+ dev_ev->event.motion.data = (int*)&dev_ev->event.motion.x;
+ dev_ev->event.motion.data[inp->idx] = sign * inp->val;
+ dev_ev->pending = 1;
break;
case INP_BUTTON:
@@ -82,26 +167,37 @@ void process_input(struct dev_input *inp)
break;
}
#endif
-
- if(ev_pending) {
- dispatch_event(&ev);
- ev_pending = 0;
+ dev_ev = device_event_in_use(dev);
+ if(dev_ev && dev_ev->pending) {
+ dispatch_event(dev_ev);
+ dev_ev->pending = 0;
}
inp->idx = cfg.map_button[inp->idx];
+ /* button events are not queued */
{
- union spnav_event bev;
- bev.type = EVENT_BUTTON;
- bev.button.press = inp->val;
- bev.button.bnum = inp->idx;
- dispatch_event(&bev);
+ struct dev_event dev_button_event;
+ dev_button_event.dev = dev;
+ dev_button_event.event.type = EVENT_BUTTON;
+ dev_button_event.event.button.press = inp->val;
+ dev_button_event.event.button.bnum = inp->idx;
+ dispatch_event(&dev_button_event);
}
+
+ /* to have them replace motion events in the queue uncomment next section */
+ /* dev_ev = add_dev_event(dev);
+ * dev_ev->event.type = EVENT_BUTTON;
+ * dev_ev->event.button.press = inp->val;
+ * dev_ev->event.button.bnum = inp->idx;
+ * dispatch_event(dev_ev);
+ */
break;
case INP_FLUSH:
- if(ev_pending) {
- dispatch_event(&ev);
- ev_pending = 0;
+ dev_ev = device_event_in_use(dev);
+ if(dev_ev && dev_ev->pending) {
+ dispatch_event(dev_ev);
+ dev_ev->pending = 0;
}
break;
@@ -110,47 +206,47 @@ void process_input(struct dev_input *inp)
}
}
-int in_deadzone(void)
+int in_deadzone(struct device *dev)
{
int i;
- if(!ev.motion.data) {
- ev.motion.data = &ev.motion.x;
- }
-
+ struct dev_event *dev_ev;
+ if((dev_ev = device_event_in_use(dev)) == NULL)
+ return -1;
for(i=0; i<6; i++) {
- if(ev.motion.data[i] != 0) {
+ if(dev_ev->event.motion.data[i] != 0)
return 0;
- }
}
return 1;
}
-void repeat_last_event(void)
+void repeat_last_event(struct device *dev)
{
- if(ev.type == EVENT_MOTION) {
- dispatch_event(&ev);
- }
+ struct dev_event *dev_ev;
+ if((dev_ev = device_event_in_use(dev)) == NULL)
+ return;
+ dispatch_event(dev_ev);
}
-static void dispatch_event(spnav_event *ev)
+static void dispatch_event(struct dev_event *dev_ev)
{
- struct client *c, *citer;
- static struct timeval prev_motion_time;
+ struct client *c, *client_iter;
+ int dev_idx;
- if(ev->type == EVENT_MOTION) {
+ if(dev_ev->event.type == EVENT_MOTION) {
struct timeval tv;
gettimeofday(&tv, 0);
- ev->motion.period = msec_dif(tv, prev_motion_time);
- prev_motion_time = tv;
+ dev_ev->event.motion.period = msec_dif(tv, dev_ev->timeval);
+ dev_ev->timeval = tv;
}
- citer = first_client();
- while(citer) {
- c = citer;
- citer = next_client();
-
- send_event(ev, c);
+ dev_idx = get_device_index(dev_ev->dev);
+ client_iter = first_client();
+ while(client_iter) {
+ c = client_iter;
+ client_iter = next_client();
+ if(get_client_device_index(c) <= dev_idx) /* use <= until API changes, else == */
+ send_event(&dev_ev->event, c);
}
}
diff --git a/src/event.h b/src/event.h
index da2d421..9cf382d 100644
--- a/src/event.h
+++ b/src/event.h
@@ -21,6 +21,7 @@ along with this program. If not, see .
#include "config.h"
#include
+#include "dev.h"
enum {
EVENT_MOTION,
@@ -47,8 +48,6 @@ typedef union spnav_event {
struct event_button button;
} spnav_event;
-
-
enum {
INP_MOTION,
INP_BUTTON,
@@ -62,14 +61,15 @@ struct dev_input {
int val;
};
+void remove_dev_event(struct device *dev);
-void process_input(struct dev_input *inp);
+void process_input(struct device *dev, struct dev_input *inp);
/* non-zero if the last processed motion event was in the deadzone */
-int in_deadzone(void);
+int in_deadzone(struct device *dev);
/* dispatches the last event */
-void repeat_last_event(void);
+void repeat_last_event(struct device *dev);
#endif /* EVENT_H_ */
diff --git a/src/hotplug_linux.c b/src/hotplug_linux.c
index a96ede1..ae485c4 100644
--- a/src/hotplug_linux.c
+++ b/src/hotplug_linux.c
@@ -92,12 +92,11 @@ int handle_hotplug(void)
char buf[512];
read(hotplug_fd, buf, sizeof buf);
- if(get_dev_fd() == -1) {
- if(init_dev() == -1) {
- return -1;
- }
- shutdown_hotplug();
- }
+ if(verbose)
+ printf("\nhandle_hotplug called\n");
+
+ if (init_devices() == -1)
+ return -1;
return 0;
}
diff --git a/src/spnavd.c b/src/spnavd.c
index d8caa05..0c675e9 100644
--- a/src/spnavd.c
+++ b/src/spnavd.c
@@ -91,10 +91,6 @@ int main(int argc, char **argv)
read_cfg("/etc/spnavrc", &cfg);
- if(init_clients() == -1) {
- return 1;
- }
-
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
signal(SIGSEGV, sig_handler);
@@ -102,9 +98,9 @@ int main(int argc, char **argv)
signal(SIGUSR1, sig_handler);
signal(SIGUSR2, sig_handler);
- if(init_dev() == -1) {
- init_hotplug();
- }
+ init_devices();
+ init_hotplug();
+
init_unix();
#ifdef USE_X11
init_x11();
@@ -115,12 +111,21 @@ int main(int argc, char **argv)
for(;;) {
fd_set rset;
int fd, max_fd = 0;
- struct client *c;
+ struct client *client_iter;
+ struct device *dev_iter;
FD_ZERO(&rset);
- /* set the device fd if it's open, otherwise set the hotplug fd */
- if((fd = get_dev_fd()) != -1 || (fd = get_hotplug_fd()) != -1) {
+ dev_iter = first_device();
+ while(dev_iter) {
+ if((fd = get_device_fd(dev_iter)) != -1) {
+ FD_SET(fd, &rset);
+ if(fd > max_fd) max_fd = fd;
+ }
+ dev_iter = next_device();
+ }
+
+ if((fd = get_hotplug_fd()) != -1) {
FD_SET(fd, &rset);
if(fd > max_fd) max_fd = fd;
}
@@ -132,16 +137,16 @@ int main(int argc, char **argv)
}
/* all the UNIX socket clients */
- c = first_client();
- while(c) {
- if(get_client_type(c) == CLIENT_UNIX) {
- int s = get_client_socket(c);
+ client_iter = first_client();
+ while(client_iter) {
+ if(get_client_type(client_iter) == CLIENT_UNIX) {
+ int s = get_client_socket(client_iter);
assert(s >= 0);
FD_SET(s, &rset);
if(s > max_fd) max_fd = s;
}
- c = next_client();
+ client_iter = next_client();
}
/* and the X server socket */
@@ -154,7 +159,8 @@ int main(int argc, char **argv)
do {
struct timeval tv, *timeout = 0;
- if(is_dev_valid() && cfg.repeat_msec >= 0 && !in_deadzone()) {
+ dev_iter = first_device();
+ if(is_device_valid(dev_iter) && cfg.repeat_msec >= 0 && !in_deadzone(dev_iter)) {
tv.tv_sec = cfg.repeat_msec / 1000;
tv.tv_usec = cfg.repeat_msec % 1000;
timeout = &tv;
@@ -166,8 +172,13 @@ int main(int argc, char **argv)
if(ret > 0) {
handle_events(&rset);
} else {
- if(cfg.repeat_msec >= 0 && !in_deadzone()) {
- repeat_last_event();
+ if(cfg.repeat_msec >= 0) {
+ dev_iter = first_device();
+ while(dev_iter) {
+ if(!in_deadzone(dev_iter))
+ repeat_last_event(dev_iter);
+ dev_iter = next_device();
+ }
}
}
}
@@ -176,11 +187,20 @@ int main(int argc, char **argv)
static void cleanup(void)
{
+ struct device *dev_iter, *tmp;
#ifdef USE_X11
close_x11(); /* call to avoid leaving garbage in the X server's root windows */
#endif
close_unix();
- shutdown_dev();
+
+ shutdown_hotplug();
+
+ dev_iter = first_device();
+ while(dev_iter) {
+ tmp = next_device();
+ remove_device(dev_iter);
+ dev_iter = tmp;
+ }
remove(PIDFILE);
}
@@ -263,6 +283,8 @@ static int find_running_daemon(void)
static void handle_events(fd_set *rset)
{
int dev_fd, hotplug_fd;
+ struct device *dev_iter;
+ struct dev_input inp;
/* handle anything coming through the UNIX socket */
handle_uevents(rset);
@@ -273,18 +295,19 @@ static void handle_events(fd_set *rset)
#endif
/* finally read any pending device input data */
- if((dev_fd = get_dev_fd()) != -1) {
- if(FD_ISSET(dev_fd, rset)) {
- struct dev_input inp;
-
+ dev_iter = first_device();
+ while(dev_iter) {
+ if((dev_fd = get_device_fd(dev_iter)) != -1 && FD_ISSET(dev_fd, rset)) {
/* read an event from the device ... */
- while(read_dev(&inp) != -1) {
+ while(read_device(dev_iter, &inp) != -1) {
/* ... and process it, possibly dispatching a spacenav event to clients */
- process_input(&inp);
+ process_input(dev_iter, &inp);
}
}
+ dev_iter = next_device();
+ }
- } else if((hotplug_fd = get_hotplug_fd()) != -1) {
+ if((hotplug_fd = get_hotplug_fd()) != -1) {
if(FD_ISSET(hotplug_fd, rset)) {
handle_hotplug();
}
@@ -297,13 +320,20 @@ static void handle_events(fd_set *rset)
static void sig_handler(int s)
{
int tmp;
+ struct device *dev_iter;
switch(s) {
case SIGHUP:
tmp = cfg.led;
read_cfg("/etc/spnavrc", &cfg);
- if(cfg.led != tmp && get_dev_fd() >= 0) {
- set_led(cfg.led);
+ dev_iter = first_device();
+ while(dev_iter) {
+ if(cfg.led != tmp && is_device_valid(dev_iter)) {
+ if(verbose)
+ printf("turn led %s, device: %s\n", cfg.led ? "on": "off", dev_iter->name);
+ set_device_led(dev_iter, cfg.led);
+ }
+ dev_iter = next_device();
}
break;
diff --git a/src/spnavd.h b/src/spnavd.h
index 8f5bcd9..7200b2e 100644
--- a/src/spnavd.h
+++ b/src/spnavd.h
@@ -25,6 +25,10 @@ along with this program. If not, see .
#define SOCK_NAME "/var/run/spnav.sock"
#define PIDFILE "/var/run/spnavd.pid"
#define LOGFILE "/var/log/spnavd.log"
+/* Multiple devices support */
+#ifndef MAX_DEVICES
+#define MAX_DEVICES 8
+#endif
struct cfg cfg;
int verbose;