Fixed a bug introduced with the multi-device support patch. device->close()

would not be called when removing devices any more muldi-device patch was
applied). This would leave LEDs on when shutting down spacenavd.

Also simplified the code in some places



git-svn-id: svn+ssh://svn.code.sf.net/p/spacenav/code/trunk/spacenavd@156 ef983eb1-d774-4af8-acfd-baaf7b16a646
pull/1/head
John Tsiombikas 2013-06-22 17:15:55 +00:00
rodzic c17defa830
commit c12c505801
5 zmienionych plików z 104 dodań i 114 usunięć

Wyświetl plik

@ -1,6 +1,6 @@
/*
spacenavd - a free software replacement driver for 6dof space-mice.
Copyright (C) 2007-2012 John Tsiombikas <nuclear@member.fsf.org>
Copyright (C) 2007-2013 John Tsiombikas <nuclear@member.fsf.org>
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
@ -30,7 +30,6 @@ static struct device *add_device(void);
static struct device *dev_path_in_use(char const * dev_path);
static struct device *dev_list = NULL;
static struct device *dev_iter;
int init_devices(void)
{
@ -82,7 +81,7 @@ int init_devices(void)
}
}
for(i=0; i<8; i++) {
for(i=0; i<MAX_DEVICES; i++) {
free(dev_path[i]);
}
free(dev_path);
@ -96,59 +95,47 @@ int init_devices(void)
static struct device *add_device(void)
{
struct device *dev_new, *iter;
struct device *dev;
if((dev_new = malloc(sizeof *dev_new)) == NULL) {
return NULL;
if(!(dev = malloc(sizeof *dev))) {
return 0;
}
memset(dev, 0, sizeof *dev);
printf("adding device.\n");
dev_new->fd = -1;
dev_new->data = NULL;
dev_new->next = NULL;
dev->fd = -1;
dev->next = dev_list;
dev_list = dev;
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;
return dev_list;
}
void remove_device(struct device *dev)
{
struct device *iter = dev_list, *tmp;
struct device dummy;
struct device *iter;
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;
}
printf("removing device: %s\n", dev->name);
dummy.next = dev_list;
iter = &dummy;
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;
iter->next = dev->next;
break;
}
iter = iter->next;
}
dev_list = dummy.next;
remove_dev_event(dev);
if(dev->close) {
dev->close(dev);
}
free(dev);
}
static struct device *dev_path_in_use(char const *dev_path)
@ -165,9 +152,7 @@ static struct device *dev_path_in_use(char const *dev_path)
int get_device_fd(struct device *dev)
{
if(dev == NULL)
return -1;
return dev->fd;
return dev ? dev->fd : -1;
}
int get_device_index(struct device *dev)
@ -175,8 +160,9 @@ int get_device_index(struct device *dev)
struct device *iter = dev_list;
int index = 0;
while(iter) {
if(dev == iter)
if(dev == iter) {
return index;
}
index++;
iter = iter->next;
}
@ -185,25 +171,20 @@ int get_device_index(struct device *dev)
int read_device(struct device *dev, struct dev_input *inp)
{
if(dev->read == NULL)
if(dev->read == NULL) {
return -1;
return (dev->read(dev, inp));
}
return dev->read(dev, inp);
}
void set_device_led(struct device *dev, int state)
{
if(dev->set_led)
if(dev->set_led) {
dev->set_led(dev, state);
}
}
struct device *first_device(void)
struct device *get_devices(void)
{
return (dev_iter = dev_list);
}
struct device *next_device(void)
{
if(dev_iter)
dev_iter = dev_iter->next;
return dev_iter;
return dev_list;
}

Wyświetl plik

@ -1,6 +1,6 @@
/*
spacenavd - a free software replacement driver for 6dof space-mice.
Copyright (C) 2007-2012 John Tsiombikas <nuclear@member.fsf.org>
Copyright (C) 2007-2013 John Tsiombikas <nuclear@member.fsf.org>
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
@ -48,7 +48,6 @@ 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);
struct device *get_devices(void);
#endif /* SPNAV_DEV_H_ */

Wyświetl plik

@ -108,7 +108,6 @@ static void close_evdev(struct device *dev)
dev->set_led(dev, 0);
close(dev->fd);
dev->fd = -1;
remove_device(dev);
}
}

Wyświetl plik

@ -1,6 +1,6 @@
/*
spacenavd - a free software replacement driver for 6dof space-mice.
Copyright (C) 2007-2012 John Tsiombikas <nuclear@member.fsf.org>
Copyright (C) 2007-2013 John Tsiombikas <nuclear@member.fsf.org>
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
@ -82,28 +82,26 @@ static struct dev_event *add_dev_event(struct device *dev)
*/
void remove_dev_event(struct device *dev)
{
struct dev_event *iter = dev_ev_list, *tmp;
struct dev_event dummy;
struct dev_event *iter;
if(iter == NULL)
return;
if(iter->dev == dev) {
dev_ev_list = iter->next;
free(iter);
if((iter = dev_ev_list) == NULL)
return;
}
dummy.next = dev_ev_list;
iter = &dummy;
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);
struct dev_event *ev = iter->next;
iter->next = ev->next;
if(verbose) {
printf("removing pending device event of: %s\n", dev->path);
}
free(ev);
} else {
iter = iter->next;
}
}
dev_ev_list = dummy.next;
}
static struct dev_event *device_event_in_use(struct device *dev)

Wyświetl plik

@ -1,6 +1,6 @@
/*
spacenavd - a free software replacement driver for 6dof space-mice.
Copyright (C) 2007-2012 John Tsiombikas <nuclear@member.fsf.org>
Copyright (C) 2007-2013 John Tsiombikas <nuclear@member.fsf.org>
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
@ -112,17 +112,17 @@ int main(int argc, char **argv)
fd_set rset;
int fd, max_fd = 0;
struct client *client_iter;
struct device *dev_iter;
struct device *dev;
FD_ZERO(&rset);
dev_iter = first_device();
while(dev_iter) {
if((fd = get_device_fd(dev_iter)) != -1) {
dev = get_devices();
while(dev) {
if((fd = get_device_fd(dev)) != -1) {
FD_SET(fd, &rset);
if(fd > max_fd) max_fd = fd;
}
dev_iter = next_device();
dev = dev->next;
}
if((fd = get_hotplug_fd()) != -1) {
@ -158,12 +158,21 @@ int main(int argc, char **argv)
#endif
do {
/* if there is at least one device out of the deadzone and repeat is enabled
* wait for only as long as specified in cfg.repeat_msec
*/
struct timeval tv, *timeout = 0;
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;
if(cfg.repeat_msec >= 0) {
dev = get_devices();
while(dev) {
if(is_device_valid(dev) && !in_deadzone(dev)) {
tv.tv_sec = cfg.repeat_msec / 1000;
tv.tv_usec = cfg.repeat_msec % 1000;
timeout = &tv;
break;
}
dev = dev->next;
}
}
ret = select(max_fd + 1, &rset, 0, 0, timeout);
@ -173,11 +182,12 @@ int main(int argc, char **argv)
handle_events(&rset);
} else {
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();
dev = get_devices();
while(dev) {
if(!in_deadzone(dev)) {
repeat_last_event(dev);
}
dev = dev->next;
}
}
}
@ -187,7 +197,8 @@ int main(int argc, char **argv)
static void cleanup(void)
{
struct device *dev_iter, *tmp;
struct device *dev;
#ifdef USE_X11
close_x11(); /* call to avoid leaving garbage in the X server's root windows */
#endif
@ -195,12 +206,13 @@ static void cleanup(void)
shutdown_hotplug();
dev_iter = first_device();
while(dev_iter) {
tmp = next_device();
remove_device(dev_iter);
dev_iter = tmp;
dev = get_devices();
while(dev) {
struct device *tmp = dev;
dev = dev->next;
remove_device(tmp);
}
remove(PIDFILE);
}
@ -283,7 +295,7 @@ static int find_running_daemon(void)
static void handle_events(fd_set *rset)
{
int dev_fd, hotplug_fd;
struct device *dev_iter;
struct device *dev;
struct dev_input inp;
/* handle anything coming through the UNIX socket */
@ -295,16 +307,16 @@ static void handle_events(fd_set *rset)
#endif
/* finally read any pending device input data */
dev_iter = first_device();
while(dev_iter) {
if((dev_fd = get_device_fd(dev_iter)) != -1 && FD_ISSET(dev_fd, rset)) {
dev = get_devices();
while(dev) {
if((dev_fd = get_device_fd(dev)) != -1 && FD_ISSET(dev_fd, rset)) {
/* read an event from the device ... */
while(read_device(dev_iter, &inp) != -1) {
while(read_device(dev, &inp) != -1) {
/* ... and process it, possibly dispatching a spacenav event to clients */
process_input(dev_iter, &inp);
process_input(dev, &inp);
}
}
dev_iter = next_device();
dev = dev->next;
}
if((hotplug_fd = get_hotplug_fd()) != -1) {
@ -319,21 +331,22 @@ static void handle_events(fd_set *rset)
*/
static void sig_handler(int s)
{
int tmp;
struct device *dev_iter;
int prev_led = cfg.led;
switch(s) {
case SIGHUP:
tmp = cfg.led;
read_cfg("/etc/spnavrc", &cfg);
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);
if(cfg.led != prev_led) {
struct device *dev = get_devices();
while(dev) {
if(is_device_valid(dev)) {
if(verbose) {
printf("turn led %s, device: %s\n", cfg.led ? "on": "off", dev->name);
}
set_device_led(dev, cfg.led);
}
dev = dev->next;
}
dev_iter = next_device();
}
break;