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;