kopia lustrzana https://github.com/FreeSpacenav/spacenavd
Code cleanup.
- separated hotplug functionality from device driver for USB devices - factored out common code to minimize redundancy for different platforms (linux/freebsd) - created an internal "device" data type to allow handling both USB and serial devices transparently without conditions everywhere. Also fixed a minor performance bug. If there is no device plugged in, the repeat interval is ignored. git-svn-id: svn+ssh://svn.code.sf.net/p/spacenav/code/trunk/spacenavd@139 ef983eb1-d774-4af8-acfd-baaf7b16a646pull/1/head
rodzic
0f5d96c69f
commit
3b5d37fb34
|
@ -133,7 +133,7 @@ if [ "$DBG" = 'yes' ]; then
|
|||
fi
|
||||
|
||||
if [ "$OPT" = 'yes' ]; then
|
||||
echo 'opt = -O3' >>Makefile
|
||||
echo 'opt = -O2' >>Makefile
|
||||
fi
|
||||
|
||||
if [ "$X11" = 'yes' ]; then
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2011 John Tsiombikas <nuclear@member.fsf.org>
|
||||
Copyright (C) 2007-2012 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
|
||||
|
@ -15,52 +15,42 @@ 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "dev.h"
|
||||
#include "cfgfile.h"
|
||||
#include "spnavd.h"
|
||||
#include "dev_usb.h"
|
||||
#include "dev_serial.h"
|
||||
#include "spnavd.h"
|
||||
|
||||
static int dev_fd = -1;
|
||||
static int dev_is_serial;
|
||||
|
||||
int init_hotplug(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void shutdown_hotplug(void)
|
||||
{
|
||||
}
|
||||
|
||||
int get_hotplug_fd(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int handle_hotplug(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static struct device dev = {-1, 0};
|
||||
|
||||
int init_dev(void)
|
||||
{
|
||||
if(dev.fd != -1) {
|
||||
fprintf(stderr, "init_dev called, but device is already open\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if((dev_fd = open_dev_serial(cfg.serial_dev)) == -1) {
|
||||
if(open_dev_serial(&dev, cfg.serial_dev) == -1) {
|
||||
return -1;
|
||||
}
|
||||
dev_is_serial = 1;
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "USB devices aren't currently supported on this platform\n");
|
||||
return -1;
|
||||
const char *dev_path;
|
||||
|
||||
if(!(dev_path = find_usb_device())) {
|
||||
fprintf(stderr, "failed to find the spaceball device file\n");
|
||||
return -1;
|
||||
}
|
||||
printf("using device: %s\n", dev_path);
|
||||
|
||||
if(open_dev_usb(&dev, dev_path) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -68,25 +58,27 @@ int init_dev(void)
|
|||
|
||||
void shutdown_dev(void)
|
||||
{
|
||||
if(dev_is_serial) {
|
||||
close_dev_serial();
|
||||
} else {
|
||||
/* TODO */
|
||||
if(dev.close) {
|
||||
dev.close(&dev);
|
||||
}
|
||||
}
|
||||
|
||||
int get_dev_fd(void)
|
||||
{
|
||||
return dev_fd;
|
||||
return dev.fd;
|
||||
}
|
||||
|
||||
int read_dev(struct dev_input *inp)
|
||||
{
|
||||
return dev_is_serial ? read_dev_serial(inp) : -1;
|
||||
if(!dev.read) {
|
||||
return -1;
|
||||
}
|
||||
return dev.read(&dev, inp);
|
||||
}
|
||||
|
||||
void set_led(int state)
|
||||
{
|
||||
if(dev.set_led) {
|
||||
dev.set_led(&dev, state);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __FreeBSD__ */
|
28
src/dev.h
28
src/dev.h
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2010 John Tsiombikas <nuclear@member.fsf.org>
|
||||
Copyright (C) 2007-2012 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
|
||||
|
@ -15,28 +15,32 @@ 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DEV_H_
|
||||
#define DEV_H_
|
||||
#ifndef SPNAV_DEV_H_
|
||||
#define SPNAV_DEV_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "event.h"
|
||||
|
||||
/* device hotplug detection */
|
||||
int init_hotplug(void);
|
||||
void shutdown_hotplug(void);
|
||||
int get_hotplug_fd(void);
|
||||
struct dev_input;
|
||||
|
||||
int handle_hotplug(void);
|
||||
#define MAX_DEV_NAME 256
|
||||
|
||||
struct device {
|
||||
int fd;
|
||||
void *data;
|
||||
char name[MAX_DEV_NAME];
|
||||
|
||||
void (*close)(struct device*);
|
||||
int (*read)(struct device*, struct dev_input*);
|
||||
void (*set_led)(struct device*, int);
|
||||
};
|
||||
|
||||
/* device handling */
|
||||
int init_dev(void);
|
||||
void shutdown_dev(void);
|
||||
int get_dev_fd(void);
|
||||
#define is_dev_valid() (get_dev_fd() >= 0)
|
||||
|
||||
int read_dev(struct dev_input *inp);
|
||||
|
||||
void set_led(int state);
|
||||
|
||||
#endif /* DEV_H_ */
|
||||
#endif /* SPNAV_DEV_H_ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2010 John Tsiombikas <nuclear@member.fsf.org>
|
||||
Copyright (C) 2007-2012 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
|
||||
|
@ -16,27 +16,38 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "dev_serial.h"
|
||||
#include "dev.h"
|
||||
#include "event.h"
|
||||
#include "serial/sball.h"
|
||||
|
||||
static void *dev;
|
||||
static void close_dev_serial(struct device *dev);
|
||||
static int read_dev_serial(struct device *dev, struct dev_input *inp);
|
||||
|
||||
int open_dev_serial(const char *devfile)
|
||||
int open_dev_serial(struct device *dev, const char *devfile)
|
||||
{
|
||||
if(!(dev = sball_open(devfile))) {
|
||||
if(!(dev->data = sball_open(devfile))) {
|
||||
return -1;
|
||||
}
|
||||
return sball_get_fd(dev);
|
||||
dev->fd = sball_get_fd(dev->data);
|
||||
|
||||
dev->close = close_dev_serial;
|
||||
dev->read = read_dev_serial;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void close_dev_serial(void)
|
||||
static void close_dev_serial(struct device *dev)
|
||||
{
|
||||
sball_close(dev);
|
||||
if(dev->data) {
|
||||
sball_close(dev->data);
|
||||
}
|
||||
dev->data = 0;
|
||||
}
|
||||
|
||||
int read_dev_serial(struct dev_input *inp)
|
||||
static int read_dev_serial(struct device *dev, struct dev_input *inp)
|
||||
{
|
||||
if(!sball_get_input(dev, inp)) {
|
||||
if(!dev->data || !sball_get_input(dev->data, inp)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2010 John Tsiombikas <nuclear@member.fsf.org>
|
||||
Copyright (C) 2007-2012 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
|
||||
|
@ -16,13 +16,11 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DEV_SERIAL_H_
|
||||
#define DEV_SERIAL_H_
|
||||
#ifndef SPNAV_DEV_SERIAL_H_
|
||||
#define SPNAV_DEV_SERIAL_H_
|
||||
|
||||
#include "event.h"
|
||||
struct device;
|
||||
|
||||
int open_dev_serial(const char *devfile);
|
||||
void close_dev_serial(void);
|
||||
int read_dev_serial(struct dev_input *inp);
|
||||
int open_dev_serial(struct device *dev, const char *devfile);
|
||||
|
||||
#endif /* DEV_SERIAL_H_ */
|
||||
#endif /* SPNAV_DEV_SERIAL_H_ */
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2012 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
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SPNAV_DEV_USB_H_
|
||||
#define SPNAV_DEV_USB_H_
|
||||
|
||||
struct device;
|
||||
|
||||
int open_dev_usb(struct device *dev, const char *path);
|
||||
const char *find_usb_device(void);
|
||||
|
||||
#endif /* SPNAV_DEV_USB_H_ */
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2012 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
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
int open_dev_usb(struct device *dev, const char *path)
|
||||
{
|
||||
return -1; /* TODO */
|
||||
}
|
||||
|
||||
const char *find_usb_device(void)
|
||||
{
|
||||
return 0; /* TODO */
|
||||
}
|
||||
|
||||
#endif /* __FreeBSD__ */
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2011 John Tsiombikas <nuclear@member.fsf.org>
|
||||
Copyright (C) 2007-2012 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
|
||||
|
@ -15,35 +15,23 @@ 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* TODO: break this up into dev_serial, dev_usb_linux, dev_usb_freebsd, dev_usb_libhid etc */
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef USE_NETLINK
|
||||
#include <linux/netlink.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/input.h>
|
||||
#include "dev.h"
|
||||
#include "cfgfile.h"
|
||||
#include "spnavd.h"
|
||||
#include "dev_serial.h"
|
||||
|
||||
#define DEV_POLL_INTERVAL 30
|
||||
#include "event.h"
|
||||
#include "hotplug.h"
|
||||
|
||||
#define IS_DEV_OPEN(dev) ((dev)->fd >= 0)
|
||||
|
||||
/* sometimes the rotation events are missing from linux/input.h */
|
||||
#ifndef REL_RX
|
||||
|
@ -56,202 +44,92 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define REL_RZ 5
|
||||
#endif
|
||||
|
||||
/* apparently some old versions of input.h doesn't define EV_SYN */
|
||||
/* apparently some old versions of input.h do not define EV_SYN */
|
||||
#ifndef EV_SYN
|
||||
#define EV_SYN 0
|
||||
#endif
|
||||
|
||||
static int open_dev_usb(const char *path);
|
||||
static int read_dev_usb(struct dev_input *inp);
|
||||
static char *get_dev_path(void);
|
||||
static int con_hotplug(void);
|
||||
static void poll_timeout(int sig);
|
||||
static void close_evdev(struct device *dev);
|
||||
static int read_evdev(struct device *dev, struct dev_input *inp);
|
||||
static void set_led_evdev(struct device *dev, int state);
|
||||
|
||||
static int dev_fd = -1;
|
||||
static char dev_name[128];
|
||||
static unsigned char evtype_mask[(EV_MAX + 7) / 8];
|
||||
#define TEST_BIT(b, ar) (ar[b / 8] & (1 << (b % 8)))
|
||||
|
||||
static int hotplug_fd = -1;
|
||||
static int poll_time, poll_pipe;
|
||||
#define MAX_POLL_TIME 30
|
||||
|
||||
static int dev_is_serial;
|
||||
|
||||
/* hotplug stuff */
|
||||
|
||||
int init_hotplug(void)
|
||||
int open_dev_usb(struct device *dev, const char *path)
|
||||
{
|
||||
if((hotplug_fd = con_hotplug()) == -1) {
|
||||
int pfd[2];
|
||||
/*unsigned char evtype_mask[(EV_MAX + 7) / 8];*/
|
||||
|
||||
if(verbose) {
|
||||
printf("hotplug failed will resort to polling\n");
|
||||
}
|
||||
|
||||
if(pipe(pfd) == -1) {
|
||||
perror("failed to open polling self-pipe");
|
||||
if((dev->fd = open(path, O_RDWR)) == -1) {
|
||||
if((dev->fd = open(path, O_RDONLY)) == -1) {
|
||||
perror("failed to open device");
|
||||
return -1;
|
||||
}
|
||||
poll_pipe = pfd[1];
|
||||
hotplug_fd = pfd[0];
|
||||
|
||||
poll_time = 1;
|
||||
signal(SIGALRM, poll_timeout);
|
||||
alarm(poll_time);
|
||||
fprintf(stderr, "opened device read-only, LEDs won't work\n");
|
||||
}
|
||||
|
||||
return hotplug_fd;
|
||||
}
|
||||
|
||||
void shutdown_hotplug(void)
|
||||
{
|
||||
if(hotplug_fd != -1) {
|
||||
close(hotplug_fd);
|
||||
hotplug_fd = -1;
|
||||
if(ioctl(dev->fd, EVIOCGNAME(sizeof dev->name), dev->name) == -1) {
|
||||
perror("EVIOCGNAME ioctl failed\n");
|
||||
strcpy(dev->name, "unknown");
|
||||
}
|
||||
printf("device name: %s\n", dev->name);
|
||||
|
||||
if(poll_pipe != -1) {
|
||||
close(poll_pipe);
|
||||
poll_pipe = -1;
|
||||
}
|
||||
}
|
||||
/*if(ioctl(dev->fd, EVIOCGBIT(0, sizeof(evtype_mask)), evtype_mask) == -1) {
|
||||
perror("EVIOCGBIT ioctl failed\n");
|
||||
close(dev->fd);
|
||||
return -1;
|
||||
}*/
|
||||
|
||||
int get_hotplug_fd(void)
|
||||
{
|
||||
return hotplug_fd;
|
||||
}
|
||||
|
||||
int handle_hotplug(void)
|
||||
{
|
||||
char buf[512];
|
||||
read(hotplug_fd, buf, sizeof buf);
|
||||
|
||||
if(dev_fd == -1) {
|
||||
if(init_dev() == -1) {
|
||||
return -1;
|
||||
if(cfg.grab_device) {
|
||||
int grab = 1;
|
||||
/* try to grab the device */
|
||||
if(ioctl(dev->fd, EVIOCGRAB, &grab) == -1) {
|
||||
perror("failed to grab the spacenav device");
|
||||
}
|
||||
shutdown_hotplug();
|
||||
}
|
||||
|
||||
/* set non-blocking */
|
||||
fcntl(dev->fd, F_SETFL, fcntl(dev->fd, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
if(cfg.led) {
|
||||
set_led_evdev(dev, 1);
|
||||
}
|
||||
|
||||
/* fill the device function pointers */
|
||||
dev->close = close_evdev;
|
||||
dev->read = read_evdev;
|
||||
dev->set_led = set_led_evdev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int con_hotplug(void)
|
||||
static void close_evdev(struct device *dev)
|
||||
{
|
||||
int s = -1;
|
||||
|
||||
#ifdef USE_NETLINK
|
||||
struct sockaddr_nl addr;
|
||||
|
||||
if((s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)) == -1) {
|
||||
perror("failed to open hotplug netlink socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof addr);
|
||||
addr.nl_family = AF_NETLINK;
|
||||
addr.nl_pid = getpid();
|
||||
addr.nl_groups = -1;
|
||||
|
||||
if(bind(s, (struct sockaddr*)&addr, sizeof addr) == -1) {
|
||||
perror("failed to bind to hotplug netlink socket");
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
#endif /* USE_NETLINK */
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static void poll_timeout(int sig)
|
||||
{
|
||||
signal(sig, poll_timeout);
|
||||
|
||||
if(sig == SIGALRM) {
|
||||
if(poll_pipe != -1) {
|
||||
write(poll_pipe, &sig, 1);
|
||||
poll_time *= 2;
|
||||
alarm(poll_time);
|
||||
}
|
||||
if(IS_DEV_OPEN(dev)) {
|
||||
dev->set_led(dev, 0);
|
||||
close(dev->fd);
|
||||
dev->fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* device handling */
|
||||
|
||||
int init_dev(void)
|
||||
static int read_evdev(struct device *dev, struct dev_input *inp)
|
||||
{
|
||||
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);
|
||||
|
||||
if((dev_fd = open_dev_serial(cfg.serial_dev)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
dev_is_serial = 1;
|
||||
|
||||
} else {
|
||||
char *dev_path;
|
||||
if(!(dev_path = get_dev_path())) {
|
||||
fprintf(stderr, "failed to find the spaceball device file\n");
|
||||
return -1;
|
||||
}
|
||||
printf("using device: %s\n", dev_path);
|
||||
|
||||
if((dev_fd = open_dev_usb(dev_path)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
dev_is_serial = 0;
|
||||
|
||||
printf("device name: %s\n", dev_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void shutdown_dev(void)
|
||||
{
|
||||
if(dev_is_serial) {
|
||||
close_dev_serial();
|
||||
} else {
|
||||
if(dev_fd != -1) {
|
||||
set_led(0);
|
||||
close(dev_fd);
|
||||
}
|
||||
}
|
||||
dev_fd = -1;
|
||||
}
|
||||
|
||||
int get_dev_fd(void)
|
||||
{
|
||||
return dev_fd;
|
||||
}
|
||||
|
||||
int read_dev(struct dev_input *inp)
|
||||
{
|
||||
return dev_is_serial ? read_dev_serial(inp) : read_dev_usb(inp);
|
||||
}
|
||||
|
||||
static int read_dev_usb(struct dev_input *inp)
|
||||
{
|
||||
struct input_event iev;
|
||||
struct input_event iev; /* linux evdev event */
|
||||
int rdbytes;
|
||||
|
||||
if(dev_fd == -1) {
|
||||
if(!IS_DEV_OPEN(dev))
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
rdbytes = read(dev_fd, &iev, sizeof iev);
|
||||
rdbytes = read(dev->fd, &iev, sizeof iev);
|
||||
} while(rdbytes == -1 && errno == EINTR);
|
||||
|
||||
/* disconnect? */
|
||||
if(rdbytes == -1) {
|
||||
if(errno != EAGAIN) {
|
||||
perror("read error");
|
||||
close(dev_fd);
|
||||
dev_fd = -1;
|
||||
close(dev->fd);
|
||||
dev->fd = -1;
|
||||
|
||||
/* restart hotplug detection */
|
||||
init_hotplug();
|
||||
}
|
||||
return -1;
|
||||
|
@ -289,70 +167,30 @@ static int read_dev_usb(struct dev_input *inp)
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void set_led(int state)
|
||||
static void set_led_evdev(struct device *dev, int state)
|
||||
{
|
||||
struct input_event ev;
|
||||
|
||||
if(dev_fd == -1) {
|
||||
fprintf(stderr, "set_led failed, invalid dev_fd\n");
|
||||
if(!IS_DEV_OPEN(dev))
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ev, 0, sizeof ev);
|
||||
ev.type = EV_LED;
|
||||
ev.code = LED_MISC;
|
||||
ev.value = state;
|
||||
|
||||
if(write(dev_fd, &ev, sizeof ev) == -1) {
|
||||
if(write(dev->fd, &ev, sizeof ev) == -1) {
|
||||
fprintf(stderr, "failed to turn LED %s\n", state ? "on" : "off");
|
||||
}
|
||||
}
|
||||
|
||||
static int open_dev_usb(const char *path)
|
||||
{
|
||||
if((dev_fd = open(path, O_RDWR)) == -1) {
|
||||
if((dev_fd = open(path, O_RDONLY)) == -1) {
|
||||
perror("failed to open device");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, "opened device read-only, LEDs won't work\n");
|
||||
}
|
||||
|
||||
if(ioctl(dev_fd, EVIOCGNAME(sizeof(dev_name)), dev_name) == -1) {
|
||||
perror("EVIOCGNAME ioctl failed\n");
|
||||
strcpy(dev_name, "unknown");
|
||||
}
|
||||
|
||||
if(ioctl(dev_fd, EVIOCGBIT(0, sizeof(evtype_mask)), evtype_mask) == -1) {
|
||||
perror("EVIOCGBIT ioctl failed\n");
|
||||
close(dev_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(cfg.grab_device) {
|
||||
int grab = 1;
|
||||
/* try to grab the device */
|
||||
if(ioctl(dev_fd, EVIOCGRAB, &grab) == -1) {
|
||||
perror("failed to grab the spacenav device");
|
||||
}
|
||||
}
|
||||
|
||||
/* set non-blocking */
|
||||
fcntl(dev_fd, F_SETFL, fcntl(dev_fd, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
if(cfg.led) {
|
||||
set_led(1);
|
||||
}
|
||||
return dev_fd;
|
||||
}
|
||||
|
||||
|
||||
#define PROC_DEV "/proc/bus/input/devices"
|
||||
static char *get_dev_path(void)
|
||||
const char *find_usb_device(void)
|
||||
{
|
||||
static char path[128];
|
||||
static char path[PATH_MAX];
|
||||
int i, valid_vendor = 0, valid_str = 0;
|
||||
char buf[1024];
|
||||
FILE *fp;
|
||||
|
@ -462,4 +300,5 @@ static char *get_dev_path(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* __linux__ */
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2012 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
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SPNAV_HOTPLUG_H_
|
||||
#define SPNAV_HOTPLUG_H_
|
||||
|
||||
int init_hotplug(void);
|
||||
void shutdown_hotplug(void);
|
||||
int get_hotplug_fd(void);
|
||||
int handle_hotplug(void);
|
||||
|
||||
#endif /* SPNAV_HOTPLUG_H_ */
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2012 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
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
/* TODO: implement */
|
||||
|
||||
int init_hotplug(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void shutdown_hotplug(void)
|
||||
{
|
||||
}
|
||||
|
||||
int get_hotplug_fd(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int handle_hotplug(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* __FreeBSD__ */
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2012 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
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef USE_NETLINK
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/netlink.h>
|
||||
#endif
|
||||
|
||||
#include "hotplug.h"
|
||||
#include "dev.h"
|
||||
#include "spnavd.h"
|
||||
#include "cfgfile.h"
|
||||
|
||||
static int con_hotplug(void);
|
||||
static void poll_timeout(int sig);
|
||||
|
||||
static int hotplug_fd = -1;
|
||||
static int poll_time, poll_pipe;
|
||||
|
||||
int init_hotplug(void)
|
||||
{
|
||||
if(hotplug_fd != -1) {
|
||||
fprintf(stderr, "WARNING: calling init_hotplug while hotplug is running!\n");
|
||||
return hotplug_fd;
|
||||
}
|
||||
|
||||
if((hotplug_fd = con_hotplug()) == -1) {
|
||||
int pfd[2];
|
||||
|
||||
if(verbose) {
|
||||
printf("hotplug failed will resort to polling\n");
|
||||
}
|
||||
|
||||
if(pipe(pfd) == -1) {
|
||||
perror("failed to open polling self-pipe");
|
||||
return -1;
|
||||
}
|
||||
poll_pipe = pfd[1];
|
||||
hotplug_fd = pfd[0];
|
||||
|
||||
poll_time = 1;
|
||||
signal(SIGALRM, poll_timeout);
|
||||
alarm(poll_time);
|
||||
}
|
||||
|
||||
return hotplug_fd;
|
||||
}
|
||||
|
||||
void shutdown_hotplug(void)
|
||||
{
|
||||
if(hotplug_fd != -1) {
|
||||
close(hotplug_fd);
|
||||
hotplug_fd = -1;
|
||||
}
|
||||
|
||||
if(poll_pipe != -1) {
|
||||
close(poll_pipe);
|
||||
poll_pipe = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int get_hotplug_fd(void)
|
||||
{
|
||||
return hotplug_fd;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int con_hotplug(void)
|
||||
{
|
||||
int s = -1;
|
||||
|
||||
#ifdef USE_NETLINK
|
||||
struct sockaddr_nl addr;
|
||||
|
||||
if((s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)) == -1) {
|
||||
perror("failed to open hotplug netlink socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof addr);
|
||||
addr.nl_family = AF_NETLINK;
|
||||
addr.nl_pid = getpid();
|
||||
addr.nl_groups = -1;
|
||||
|
||||
if(bind(s, (struct sockaddr*)&addr, sizeof addr) == -1) {
|
||||
perror("failed to bind to hotplug netlink socket");
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
#endif /* USE_NETLINK */
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static void poll_timeout(int sig)
|
||||
{
|
||||
signal(sig, poll_timeout);
|
||||
|
||||
if(sig == SIGALRM) {
|
||||
if(poll_pipe != -1) {
|
||||
write(poll_pipe, &sig, 1);
|
||||
poll_time *= 2;
|
||||
alarm(poll_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* __linux__ */
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2010 John Tsiombikas <nuclear@member.fsf.org>
|
||||
Copyright (C) 2007-2012 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
|
||||
|
@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <sys/select.h>
|
||||
#include "spnavd.h"
|
||||
#include "dev.h"
|
||||
#include "hotplug.h"
|
||||
#include "client.h"
|
||||
#include "proto_unix.h"
|
||||
#ifdef USE_X11
|
||||
|
@ -144,7 +145,7 @@ int main(int argc, char **argv)
|
|||
|
||||
do {
|
||||
struct timeval tv, *timeout = 0;
|
||||
if(cfg.repeat_msec >= 0 && !in_deadzone()) {
|
||||
if(is_dev_valid() && cfg.repeat_msec >= 0 && !in_deadzone()) {
|
||||
tv.tv_sec = cfg.repeat_msec / 1000;
|
||||
tv.tv_usec = cfg.repeat_msec % 1000;
|
||||
timeout = &tv;
|
||||
|
|
Ładowanie…
Reference in New Issue