kopia lustrzana https://github.com/FreeSpacenav/spacenavd
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-baaf7b16a646pull/1/head
rodzic
c17defa830
commit
c12c505801
93
src/dev.c
93
src/dev.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
28
src/event.c
28
src/event.c
|
@ -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)
|
||||
|
|
91
src/spnavd.c
91
src/spnavd.c
|
@ -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;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue