kopia lustrzana https://github.com/FreeSpacenav/spacenavd
- client event mask (event type selection)
- added unique device ids (unique during spacenavd lifetime) - send device change events - added provision for configuration change eventspull/68/head
rodzic
881feaed74
commit
bea696f24f
|
@ -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-2022 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
|
||||
|
@ -62,6 +62,8 @@ struct client *add_client(int type, void *cdata)
|
|||
}
|
||||
/* default to protocol version 0 until the client changes it */
|
||||
client->proto = 0;
|
||||
/* evmask for proto-v0 clients is just input events */
|
||||
client->evmask = EVMASK_MOTION | EVMASK_BUTTON;
|
||||
|
||||
client->sens = 1.0f;
|
||||
client->dev = 0; /* default/first device */
|
||||
|
|
11
src/client.h
11
src/client.h
|
@ -31,6 +31,14 @@ enum {
|
|||
CLIENT_UNIX /* through the new UNIX domain socket */
|
||||
};
|
||||
|
||||
/* event selection (must match SPNAV_EVMASK* in libspnav/spnav.h) */
|
||||
enum {
|
||||
EVMASK_MOTION = 1,
|
||||
EVMASK_BUTTON = 2,
|
||||
EVMASK_DEV = 4,
|
||||
EVMASK_CFG = 8
|
||||
};
|
||||
|
||||
struct device;
|
||||
|
||||
struct client {
|
||||
|
@ -45,7 +53,8 @@ struct client {
|
|||
float sens; /* sensitivity */
|
||||
struct device *dev;
|
||||
|
||||
char name[32];
|
||||
char name[32]; /* client name (not unique) */
|
||||
unsigned int evmask; /* event selection mask */
|
||||
|
||||
char reqbuf[64];
|
||||
int reqbytes;
|
||||
|
|
41
src/dev.c
41
src/dev.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
spacenavd - a free software replacement driver for 6dof space-mice.
|
||||
Copyright (C) 2007-2020 John Tsiombikas <nuclear@member.fsf.org>
|
||||
Copyright (C) 2007-2022 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 "event.h" /* remove pending events upon device removal */
|
||||
#include "spnavd.h"
|
||||
#include "proto.h"
|
||||
#include "proto_unix.h"
|
||||
|
||||
#ifdef USE_X11
|
||||
#include "proto_x11.h"
|
||||
|
@ -37,12 +38,14 @@ static int match_usbdev(const struct usb_dev_info *devinfo);
|
|||
static int usbdevtype(unsigned int vid, unsigned int pid);
|
||||
|
||||
static struct device *dev_list = NULL;
|
||||
static unsigned short last_id;
|
||||
|
||||
int init_devices(void)
|
||||
{
|
||||
struct device *dev;
|
||||
int i, device_added = 0;
|
||||
struct usb_dev_info *usblist, *usbdev;
|
||||
spnav_event ev = {0};
|
||||
|
||||
/* try to open a serial device if specified in the config file */
|
||||
if(cfg.serial_dev[0]) {
|
||||
|
@ -56,6 +59,13 @@ int init_devices(void)
|
|||
logmsg(LOG_INFO, "using device: %s\n", cfg.serial_dev);
|
||||
device_added++;
|
||||
}
|
||||
|
||||
/* new serial device added, send device change event */
|
||||
ev.dev.type = EVENT_DEV;
|
||||
ev.dev.op = DEV_ADD;
|
||||
ev.dev.id = dev->id;
|
||||
ev.dev.devtype = dev->type;
|
||||
broadcast_event(&ev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +77,7 @@ int init_devices(void)
|
|||
for(i=0; i<usbdev->num_devfiles; i++) {
|
||||
if((dev = dev_path_in_use(usbdev->devfiles[i]))) {
|
||||
if(verbose) {
|
||||
logmsg(LOG_WARNING, "already using device: %s (%s)\n", dev->name, dev->path);
|
||||
logmsg(LOG_WARNING, "already using device: %s (%s) (id: %d)\n", dev->name, dev->path, dev->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -83,6 +93,15 @@ int init_devices(void)
|
|||
} else {
|
||||
logmsg(LOG_INFO, "using device: %s (%s)\n", dev->name, dev->path);
|
||||
device_added++;
|
||||
|
||||
/* new USB device added, send device change event */
|
||||
ev.dev.type = EVENT_DEV;
|
||||
ev.dev.op = DEV_ADD;
|
||||
ev.dev.id = dev->id;
|
||||
ev.dev.devtype = dev->type;
|
||||
ev.dev.usbid[0] = dev->usbid[0];
|
||||
ev.dev.usbid[1] = dev->usbid[1];
|
||||
broadcast_event(&ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -111,12 +130,13 @@ static struct device *add_device(void)
|
|||
}
|
||||
memset(dev, 0, sizeof *dev);
|
||||
|
||||
logmsg(LOG_INFO, "adding device.\n");
|
||||
|
||||
dev->fd = -1;
|
||||
dev->id = last_id++;
|
||||
dev->next = dev_list;
|
||||
dev_list = dev;
|
||||
|
||||
logmsg(LOG_INFO, "adding device (id: %d).\n", dev->id);
|
||||
|
||||
return dev_list;
|
||||
}
|
||||
|
||||
|
@ -124,8 +144,9 @@ void remove_device(struct device *dev)
|
|||
{
|
||||
struct device dummy;
|
||||
struct device *iter;
|
||||
spnav_event ev;
|
||||
|
||||
logmsg(LOG_INFO, "removing device: %s\n", dev->name);
|
||||
logmsg(LOG_INFO, "removing device: %s (id: %d)\n", dev->name, dev->id);
|
||||
|
||||
dummy.next = dev_list;
|
||||
iter = &dummy;
|
||||
|
@ -144,6 +165,16 @@ void remove_device(struct device *dev)
|
|||
if(dev->close) {
|
||||
dev->close(dev);
|
||||
}
|
||||
|
||||
/* send device change event to clients */
|
||||
ev.dev.type = EVENT_DEV;
|
||||
ev.dev.op = DEV_RM;
|
||||
ev.dev.id = dev->id;
|
||||
ev.dev.devtype = dev->type;
|
||||
ev.dev.usbid[0] = dev->usbid[0];
|
||||
ev.dev.usbid[1] = dev->usbid[1];
|
||||
broadcast_event(&ev);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ struct dev_input;
|
|||
#define MAX_DEV_NAME 256
|
||||
|
||||
struct device {
|
||||
int id;
|
||||
int fd;
|
||||
void *data;
|
||||
char name[MAX_DEV_NAME];
|
||||
|
|
12
src/event.c
12
src/event.c
|
@ -304,6 +304,18 @@ static void dispatch_event(struct dev_event *dev_ev)
|
|||
}
|
||||
}
|
||||
|
||||
void broadcast_event(spnav_event *ev)
|
||||
{
|
||||
struct client *c;
|
||||
|
||||
c = first_client();
|
||||
while(c) {
|
||||
/* event masks will be checked at the protocol level (send_uevent) */
|
||||
send_event(ev, c);
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void send_event(spnav_event *ev, struct client *c)
|
||||
{
|
||||
switch(get_client_type(c)) {
|
||||
|
|
28
src/event.h
28
src/event.h
|
@ -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-2022 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
|
||||
|
@ -25,9 +25,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
enum {
|
||||
EVENT_MOTION,
|
||||
EVENT_BUTTON /* includes both press and release */
|
||||
EVENT_BUTTON, /* includes both press and release */
|
||||
|
||||
/* protocol v1 events */
|
||||
EVENT_DEV, /* device change */
|
||||
EVENT_CFG /* configuration change */
|
||||
};
|
||||
|
||||
enum { DEV_ADD, DEV_RM };
|
||||
|
||||
struct event_motion {
|
||||
int type;
|
||||
int x, y, z;
|
||||
|
@ -42,10 +48,26 @@ struct event_button {
|
|||
int bnum;
|
||||
};
|
||||
|
||||
struct event_dev {
|
||||
int type;
|
||||
int op;
|
||||
int id;
|
||||
int devtype;
|
||||
int usbid[2];
|
||||
};
|
||||
|
||||
struct event_cfg {
|
||||
int type;
|
||||
int cfg;
|
||||
int data[6];
|
||||
};
|
||||
|
||||
typedef union spnav_event {
|
||||
int type;
|
||||
struct event_motion motion;
|
||||
struct event_button button;
|
||||
struct event_dev dev;
|
||||
struct event_cfg cfg;
|
||||
} spnav_event;
|
||||
|
||||
enum {
|
||||
|
@ -71,5 +93,7 @@ int in_deadzone(struct device *dev);
|
|||
/* dispatches the last event */
|
||||
void repeat_last_event(struct device *dev);
|
||||
|
||||
/* broadcasts an event to all clients */
|
||||
void broadcast_event(spnav_event *ev);
|
||||
|
||||
#endif /* EVENT_H_ */
|
||||
|
|
12
src/proto.h
12
src/proto.h
|
@ -4,6 +4,16 @@
|
|||
/* maximum supported protocol version */
|
||||
#define MAX_PROTO_VER 1
|
||||
|
||||
enum {
|
||||
UEV_MOTION,
|
||||
UEV_PRESS,
|
||||
UEV_RELEASE,
|
||||
UEV_DEV,
|
||||
UEV_CFG,
|
||||
|
||||
MAX_UEV
|
||||
};
|
||||
|
||||
struct reqresp {
|
||||
int type;
|
||||
int data[7];
|
||||
|
@ -23,6 +33,8 @@ enum {
|
|||
REQ_SET_NAME = REQ_BASE,/* set client name: Q[0-6] name - R[6] status */
|
||||
REQ_SET_SENS, /* set client sensitivity: Q[0] float - R[6] status */
|
||||
REQ_GET_SENS, /* get client sensitivity: R[0] float R[6] status */
|
||||
REQ_SET_EVMASK, /* set event mask: Q[0] mask - R[6] status */
|
||||
REQ_GET_EVMASK, /* get event mask: R[0] mask R[6] status */
|
||||
|
||||
/* device queries */
|
||||
REQ_DEV_NAME = 0x2000, /* get device name: R[0] length R[6] status followed
|
||||
|
|
|
@ -35,12 +35,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
UEV_TYPE_MOTION,
|
||||
UEV_TYPE_PRESS,
|
||||
UEV_TYPE_RELEASE
|
||||
};
|
||||
|
||||
static int lsock = -1;
|
||||
|
||||
|
||||
|
@ -111,7 +105,9 @@ void send_uevent(spnav_event *ev, struct client *c)
|
|||
|
||||
switch(ev->type) {
|
||||
case EVENT_MOTION:
|
||||
data[0] = UEV_TYPE_MOTION;
|
||||
if(!(c->evmask & EVMASK_MOTION)) break;
|
||||
|
||||
data[0] = UEV_MOTION;
|
||||
|
||||
motion_mul = get_client_sensitivity(c);
|
||||
for(i=0; i<6; i++) {
|
||||
|
@ -122,10 +118,31 @@ void send_uevent(spnav_event *ev, struct client *c)
|
|||
break;
|
||||
|
||||
case EVENT_BUTTON:
|
||||
data[0] = ev->button.press ? UEV_TYPE_PRESS : UEV_TYPE_RELEASE;
|
||||
if(!(c->evmask & EVMASK_BUTTON)) break;
|
||||
|
||||
data[0] = ev->button.press ? UEV_PRESS : UEV_RELEASE;
|
||||
data[1] = ev->button.bnum;
|
||||
break;
|
||||
|
||||
case EVENT_DEV:
|
||||
if(!(c->evmask & EVMASK_DEV)) break;
|
||||
|
||||
data[0] = UEV_DEV;
|
||||
data[1] = ev->dev.op;
|
||||
data[2] = ev->dev.id;
|
||||
data[3] = ev->dev.devtype;
|
||||
data[4] = ev->dev.usbid[0];
|
||||
data[5] = ev->dev.usbid[1];
|
||||
break;
|
||||
|
||||
case EVENT_CFG:
|
||||
if(!(c->evmask & EVMASK_CFG)) break;
|
||||
|
||||
data[0] = UEV_CFG;
|
||||
data[1] = ev->cfg.cfg;
|
||||
memcpy(data + 2, ev->cfg.data, sizeof ev->cfg.data);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -194,6 +211,11 @@ int handle_uevents(fd_set *rset)
|
|||
msg = REQ_TAG | REQ_CHANGE_PROTO | MAX_PROTO_VER;
|
||||
}
|
||||
write(s, &msg, sizeof msg);
|
||||
|
||||
if(c->proto > 0) {
|
||||
/* set default event mask for proto-v1 clients */
|
||||
c->evmask = EVMASK_MOTION | EVMASK_BUTTON | EVMASK_DEV;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -276,6 +298,16 @@ static int handle_request(struct client *c, struct reqresp *req)
|
|||
sendresp(c, req, 0);
|
||||
break;
|
||||
|
||||
case REQ_SET_EVMASK:
|
||||
c->evmask = req->data[0];
|
||||
sendresp(c, req, 0);
|
||||
break;
|
||||
|
||||
case REQ_GET_EVMASK:
|
||||
req->data[0] = c->evmask;
|
||||
sendresp(c, req, 0);
|
||||
break;
|
||||
|
||||
case REQ_DEV_NAME:
|
||||
if((dev = get_client_device(c))) {
|
||||
req->data[0] = strlen(dev->name);
|
||||
|
|
Ładowanie…
Reference in New Issue