From b5833b21c01741aff1bb8060fd9c72288494d0de Mon Sep 17 00:00:00 2001 From: Gustavo Nunes Goretkin Date: Sun, 21 Jan 2024 22:02:07 -0500 Subject: [PATCH] Add a device id to most events --- src/client.c | 5 +++++ src/client.h | 3 +++ src/dev.c | 6 +++--- src/dev.h | 2 +- src/event.c | 37 ++++++++++++++++++++----------------- src/event.h | 3 ++- src/proto.h | 7 +++++++ src/proto_unix.c | 22 ++++++++++++++++------ src/proto_unix.h | 2 +- 9 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/client.c b/src/client.c index 5e711b6..1ad1ce0 100644 --- a/src/client.c +++ b/src/client.c @@ -152,6 +152,11 @@ struct device *get_client_device(struct client *client) return client->dev ? client->dev : get_devices(); } +int is_client_multidev(struct client *client) +{ + return 0; +} + struct client *first_client(void) { client_iter = client_list; diff --git a/src/client.h b/src/client.h index 13132a6..99fe545 100644 --- a/src/client.h +++ b/src/client.h @@ -85,6 +85,9 @@ float get_client_sensitivity(struct client *client); void set_client_device(struct client *client, struct device *dev); struct device *get_client_device(struct client *client); +/* if client has has enabled multi-device mode, then return 1, otherwise 0*/ +int is_client_multidev(struct client *client); + /* these two can be used to iterate over all clients */ struct client *first_client(void); struct client *next_client(void); diff --git a/src/dev.c b/src/dev.c index 802676d..4a2d0da 100644 --- a/src/dev.c +++ b/src/dev.c @@ -151,7 +151,7 @@ void init_devices_serial(void) ev.dev.op = DEV_ADD; ev.dev.id = dev->id; ev.dev.devtype = dev->type; - broadcast_event(&ev); + broadcast_event(NULL, &ev); } } } @@ -216,7 +216,7 @@ int init_devices_usb(void) ev.dev.devtype = dev->type; ev.dev.usbid[0] = dev->usbid[0]; ev.dev.usbid[1] = dev->usbid[1]; - broadcast_event(&ev); + broadcast_event(NULL, &ev); break; } } @@ -290,7 +290,7 @@ void remove_device(struct device *dev) ev.dev.devtype = dev->type; ev.dev.usbid[0] = dev->usbid[0]; ev.dev.usbid[1] = dev->usbid[1]; - broadcast_event(&ev); + broadcast_event(NULL, &ev); free(dev); } diff --git a/src/dev.h b/src/dev.h index 19c3526..2d2ca5a 100644 --- a/src/dev.h +++ b/src/dev.h @@ -26,7 +26,7 @@ struct dev_input; #define MAX_DEV_NAME 256 struct device { - int id; + int id; /* "spnav_dev_id" : sequential ID generated by `add_device` */ int fd; void *data; char name[MAX_DEV_NAME]; diff --git a/src/event.c b/src/event.c index f67c6f6..459c4db 100644 --- a/src/event.c +++ b/src/event.c @@ -54,8 +54,8 @@ static int dom_axis_thres = 2; static struct dev_event *add_dev_event(struct device *dev); static struct dev_event *device_event_in_use(struct device *dev); static void handle_button_action(int act, int val); -static void dispatch_event(struct dev_event *dev); -static void send_event(spnav_event *ev, struct client *c); +static void dispatch_event(struct device *dev, struct dev_event *dev_ev); +static void send_event(struct device *dev, spnav_event *ev, struct client *c); static unsigned int msec_dif(struct timeval tv1, struct timeval tv2); static struct dev_event *dev_ev_list = NULL; @@ -162,7 +162,7 @@ void process_input(struct device *dev, struct dev_input *inp) ev.type = EVENT_RAWAXIS; ev.axis.idx = inp->idx; ev.axis.value = inp->val; - broadcast_event(&ev); + broadcast_event(dev, &ev); if(abs(inp->val) < cfg.dead_threshold[inp->idx] ) { inp->val = 0; @@ -215,7 +215,7 @@ void process_input(struct device *dev, struct dev_input *inp) ev.type = EVENT_RAWBUTTON; ev.button.press = inp->val; ev.button.bnum = inp->idx; - broadcast_event(&ev); + broadcast_event(dev, &ev); /* check to see if the button has been bound to an action */ if(cfg.bnact[inp->idx] > 0) { @@ -240,7 +240,7 @@ void process_input(struct device *dev, struct dev_input *inp) #endif dev_ev = device_event_in_use(dev); if(dev_ev && dev_ev->pending) { - dispatch_event(dev_ev); + dispatch_event(dev, dev_ev); dev_ev->pending = 0; } inp->idx = cfg.map_button[inp->idx]; @@ -252,7 +252,7 @@ void process_input(struct device *dev, struct dev_input *inp) dev_button_event.event.type = EVENT_BUTTON; dev_button_event.event.button.press = inp->val; dev_button_event.event.button.bnum = inp->idx; - dispatch_event(&dev_button_event); + dispatch_event(dev, &dev_button_event); } /* to have them replace motion events in the queue uncomment next section */ @@ -260,14 +260,14 @@ void process_input(struct device *dev, struct dev_input *inp) * dev_ev->event.type = EVENT_BUTTON; * dev_ev->event.button.press = inp->val; * dev_ev->event.button.bnum = inp->idx; - * dispatch_event(dev_ev); + * dispatch_event(dev, dev_ev); */ break; case INP_FLUSH: dev_ev = device_event_in_use(dev); if(dev_ev && dev_ev->pending) { - dispatch_event(dev_ev); + dispatch_event(dev, dev_ev); dev_ev->pending = 0; } break; @@ -330,10 +330,10 @@ void repeat_last_event(struct device *dev) struct dev_event *dev_ev; if((dev_ev = device_event_in_use(dev)) == NULL) return; - dispatch_event(dev_ev); + dispatch_event(dev, dev_ev); } -static void dispatch_event(struct dev_event *dev_ev) +static void dispatch_event(struct device *dev, struct dev_event *dev_ev) { struct client *c, *client_iter; struct device *client_dev; @@ -353,22 +353,25 @@ static void dispatch_event(struct dev_event *dev_ev) /* if the client has selected a single device to get input from, then * don't send the event if it originates from a different device + * as of January 2024, there is no protocol mechanism for a client to + * select a single device. + * However, clients may select to receive events from all devices. */ client_dev = get_client_device(c); - if(!client_dev || client_dev == dev_ev->dev) { - send_event(&dev_ev->event, c); + if(!client_dev || client_dev == dev_ev->dev || is_client_multidev(c)) { + send_event(dev, &dev_ev->event, c); } } } -void broadcast_event(spnav_event *ev) +void broadcast_event(struct device *maybe_dev, 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); + send_event(maybe_dev, ev, c); c = c->next; } } @@ -380,10 +383,10 @@ void broadcast_cfg_event(int cfg, int val) ev.type = EVENT_CFG; ev.cfg.cfg = cfg; ev.cfg.data[0] = val; - broadcast_event(&ev); + broadcast_event(NULL, &ev); } -static void send_event(spnav_event *ev, struct client *c) +static void send_event(struct device *dev, spnav_event *ev, struct client *c) { switch(get_client_type(c)) { #ifdef USE_X11 @@ -393,7 +396,7 @@ static void send_event(spnav_event *ev, struct client *c) #endif case CLIENT_UNIX: - send_uevent(ev, c); + send_uevent(dev, ev, c); break; default: diff --git a/src/event.h b/src/event.h index bbd5447..62ad8ba 100644 --- a/src/event.h +++ b/src/event.h @@ -104,7 +104,8 @@ int in_deadzone(struct device *dev); void repeat_last_event(struct device *dev); /* broadcasts an event to all clients */ -void broadcast_event(spnav_event *ev); +/* if event corresponds to a specific device, `maybe_dev` is not null */ +void broadcast_event(struct device *maybe_dev, spnav_event *ev); void broadcast_cfg_event(int cfg, int val); diff --git a/src/proto.h b/src/proto.h index a852f7f..3657dfd 100644 --- a/src/proto.h +++ b/src/proto.h @@ -21,9 +21,16 @@ enum { UEV_RAWAXIS, UEV_RAWBUTTON, + UEV_MOTION_MULTIDEV, + UEV_PRESS_MULTIDEV, + UEV_RELEASE_MULTIDEV, + UEV_RAWAXIS_MULTIDEV, + UEV_RAWBUTTON_MULTIDEV, MAX_UEV }; + + struct reqresp { int32_t type; int32_t data[7]; diff --git a/src/proto_unix.c b/src/proto_unix.c index 20a3334..2f0fe81 100644 --- a/src/proto_unix.c +++ b/src/proto_unix.c @@ -99,7 +99,7 @@ int get_unix_socket(void) return lsock; } -void send_uevent(spnav_event *ev, struct client *c) +void send_uevent(struct device *maybe_dev, spnav_event *ev, struct client *c) { int i; int32_t data[8] = {0}; @@ -107,24 +107,32 @@ void send_uevent(spnav_event *ev, struct client *c) if(lsock == -1) return; + int send_multi_device_event = 0; + if(maybe_dev != NULL && is_client_multidev(c)) { + int spnav_dev_id = maybe_dev->id; + data[7] = spnav_dev_id; + send_multi_device_event = 1; + } switch(ev->type) { case EVENT_MOTION: if(!(c->evmask & EVMASK_MOTION)) return; - data[0] = UEV_MOTION; + data[0] = send_multi_device_event ? UEV_MOTION_MULTIDEV: UEV_MOTION; motion_mul = get_client_sensitivity(c); for(i=0; i<6; i++) { float val = (float)ev->motion.data[i] * motion_mul; data[i + 1] = (int32_t)val; } - data[7] = ev->motion.period; + if(!send_multi_device_event) { + data[7] = ev->motion.period; + } break; case EVENT_RAWAXIS: if(!(c->evmask & EVMASK_RAWAXIS)) return; - data[0] = UEV_RAWAXIS; + data[0] = send_multi_device_event ? UEV_RAWAXIS_MULTIDEV : UEV_RAWAXIS; data[1] = ev->axis.idx; data[2] = ev->axis.value; break; @@ -132,7 +140,9 @@ void send_uevent(spnav_event *ev, struct client *c) case EVENT_BUTTON: if(!(c->evmask & EVMASK_BUTTON)) return; - data[0] = ev->button.press ? UEV_PRESS : UEV_RELEASE; + data[0] = send_multi_device_event ? + (ev->button.press ? UEV_PRESS_MULTIDEV : UEV_RELEASE_MULTIDEV): + (ev->button.press ? UEV_PRESS : UEV_RELEASE); data[1] = ev->button.bnum; data[2] = ev->button.press; break; @@ -140,7 +150,7 @@ void send_uevent(spnav_event *ev, struct client *c) case EVENT_RAWBUTTON: if(!(c->evmask & EVMASK_RAWBUTTON)) return; - data[0] = UEV_RAWBUTTON; + data[0] = send_multi_device_event ? UEV_RAWBUTTON_MULTIDEV : UEV_RAWBUTTON; data[1] = ev->button.bnum; data[2] = ev->button.press; break; diff --git a/src/proto_unix.h b/src/proto_unix.h index 045b379..411fc64 100644 --- a/src/proto_unix.h +++ b/src/proto_unix.h @@ -27,7 +27,7 @@ int init_unix(void); void close_unix(void); int get_unix_socket(void); -void send_uevent(spnav_event *ev, struct client *c); +void send_uevent(struct device *dev, spnav_event *ev, struct client *c); int handle_uevents(fd_set *rset);