- client event mask (event type selection)

- added unique device ids (unique during spacenavd lifetime)
- send device change events
- added provision for configuration change events
pull/68/head
John Tsiombikas 2022-03-21 08:50:36 +02:00
rodzic 881feaed74
commit bea696f24f
8 zmienionych plików z 140 dodań i 17 usunięć

Wyświetl plik

@ -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 */

Wyświetl plik

@ -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;

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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];

Wyświetl plik

@ -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)) {

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-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_ */

Wyświetl plik

@ -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

Wyświetl plik

@ -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);