From 75aea89e557d02e73bfe5ddba90f66b765fe0fb2 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 21 Mar 2022 08:53:15 +0200 Subject: [PATCH] - added client event type selection (evmask) - added new types of events (dev/cfg) for proto v1 --- proto.h | 12 ++++++++++++ spnav.c | 36 +++++++++++++++++++++++++++++++----- spnav.h | 40 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/proto.h b/proto.h index 0dd086d..61ea90a 100644 --- a/proto.h +++ b/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 diff --git a/spnav.c b/spnav.c index b82fa5f..9f50a95 100644 --- a/spnav.c +++ b/spnav.c @@ -390,20 +390,46 @@ static int read_event(int s, spnav_event *event) return 0; } - if(data[0] < 0 || data[0] > 2) { + return proc_event(data, event); +} + +static int proc_event(int *data, spnav_event *event) +{ + if(data[0] < 0 || data[0] >= MAX_UEV) { return 0; } - event->type = data[0] ? SPNAV_EVENT_BUTTON : SPNAV_EVENT_MOTION; + if(data[0] == UEV_PRESS || data[0] == UEV_RELEASE) { + event->type = SPNAV_EVENT_BUTTON; + } else { + event->type = data[0]; + } - if(event->type == SPNAV_EVENT_MOTION) { + switch(event->type) { + case SPNAV_EVENT_MOTION: event->motion.data = &event->motion.x; for(i=0; i<6; i++) { event->motion.data[i] = data[i + 1]; } event->motion.period = data[7]; - } else { - event->button.press = data[0] == 1 ? 1 : 0; + break; + + case SPNAV_EVENT_BUTTON: + event->button.press = data[0] == UEV_PRESS ? 1 : 0; event->button.bnum = data[1]; + break; + + case SPNAV_EVENT_DEV: + event->dev.op = data[1]; + event->dev.id = data[2]; + event->dev.devtype = data[3]; + event->dev.usbid[0] = data[4]; + event->dev.usbid[1] = data[5]; + break; + + case SPNAV_EVENT_CFG: + event->cfg.cfg = data[1]; + memcpy(event->cfg.data, data + 2, sizeof event->cfg.data); + break; } return event->type; diff --git a/spnav.h b/spnav.h index e481e41..a437897 100644 --- a/spnav.h +++ b/spnav.h @@ -36,11 +36,16 @@ OF SUCH DAMAGE. enum { SPNAV_EVENT_ANY, /* used by spnav_remove_events() */ SPNAV_EVENT_MOTION, - SPNAV_EVENT_BUTTON /* includes both press and release */ + SPNAV_EVENT_BUTTON, /* includes both press and release */ + + SPNAV_EVENT_DEV = 4,/* add/remove device event */ + SPNAV_EVENT_CFG /* configuration change event */ }; +enum { SPNAV_DEV_ADD, SPNAV_DEV_RM }; + struct spnav_event_motion { - int type; + int type; /* SPNAV_EVENT_MOTION */ int x, y, z; int rx, ry, rz; unsigned int period; @@ -48,15 +53,31 @@ struct spnav_event_motion { }; struct spnav_event_button { - int type; + int type; /* SPNAV_EVENT_BUTTON */ int press; int bnum; }; +struct spnav_event_dev { + int type; /* SPNAV_EVENT_DEV */ + int op; /* SPNAV_DEV_ADD / SPNAV_DEV_RM */ + int id; + int devtype; /* see spnav_dev_type() */ + int usbid[2]; /* USB id if it's a USB device, 0:0 if it's a serial device */ +}; + +struct spnav_event_cfg { + int type; /* SPNAV_EVENT_CFG */ + int cfg; /* same as protocol REQ_GCFG* enum */ + int data[6]; /* same as protocol response data 0-5 */ +}; + typedef union spnav_event { int type; struct spnav_event_motion motion; struct spnav_event_button button; + struct spnav_event_dev dev; + struct spnav_event_cfg cfg; } spnav_event; @@ -146,6 +167,19 @@ int spnav_protocol(void); /* Set client name */ int spnav_client_name(const char *name); +/* Select the types of events the client is interested in receiving */ +enum { + SPNAV_EVMASK_MOTION = 1, /* 6dof motion events */ + SPNAV_EVMASK_BUTTON = 2, /* button events */ + SPNAV_EVMASK_DEV = 4, /* device change events */ + SPNAV_EVMASK_CFG = 8, /* configuration change events */ + + SPNAV_EVMASK_INPUT = SPNAV_EVMASK_MOTION | SPNAV_EVMASK_BUTTON, + SPNAV_EVMASK_DEFAULT = SPNAV_EVMASK_INPUT | SPNAV_EVMASK_DEV, + SPNAV_EVMASK_ALL = 0xffff +}; +int spnav_evmask(unsigned int mask); + /* TODO multi-device support and device selection not implemented yet int spnav_num_devices(void); int spnav_select_device(int dev);