config: Add k: and m: device matching prefixes

master
Raheman Vaiya 4 years ago
parent f2774494d7
commit 77e43a18ae
  1. BIN
      data/keyd-application-mapper.1.gz
  2. BIN
      data/keyd.1.gz
  3. 4
      docs/keyd.scdoc
  4. 46
      src/config.c
  5. 15
      src/config.h
  6. 30
      src/daemon.c

Binary file not shown.

Binary file not shown.

@ -118,6 +118,10 @@ of _[global]_ (see _GLOBALS_).
Config errors will appear in the log output and can be accessed in the usual Config errors will appear in the log output and can be accessed in the usual
way using your system's service manager (e.g sudo journalctl -eu keyd). way using your system's service manager (e.g sudo journalctl -eu keyd).
If a vendor/product pair matches more than one device type, the prefix k: may
be used to exclusively match keyboards and the prefix m: may be used to
exclusively match mice. (E.g m:046d:b01d)
Note: All keyboards defined within a given config file will share the Note: All keyboards defined within a given config file will share the
same state. This is useful for linking separate input devices together same state. This is useful for linking separate input devices together
(e.g foot pedals). (e.g foot pedals).

@ -758,12 +758,34 @@ static void parse_id_section(struct config *config, struct ini_section *section)
if (!strcmp(s, "*")) { if (!strcmp(s, "*")) {
config->wildcard = 1; config->wildcard = 1;
} else { } else {
if (sscanf(s, "-%hx:%hx", &vendor, &product) == 2) { if (sscanf(s, "m:%hx:%hx", &vendor, &product) == 2) {
assert(config->nr_excluded_ids < ARRAY_SIZE(config->excluded_ids)); assert(config->nr_ids < ARRAY_SIZE(config->ids));
config->excluded_ids[config->nr_excluded_ids++] = (vendor << 16 | product); config->ids[config->nr_ids].product = product;
config->ids[config->nr_ids].vendor = vendor;
config->ids[config->nr_ids].flags = ID_MOUSE;
config->nr_ids++;
} else if (sscanf(s, "k:%hx:%hx", &vendor, &product) == 2) {
assert(config->nr_ids < ARRAY_SIZE(config->ids));
config->ids[config->nr_ids].product = product;
config->ids[config->nr_ids].vendor = vendor;
config->ids[config->nr_ids].flags = ID_KEYBOARD;
config->nr_ids++;
} else if (sscanf(s, "-%hx:%hx", &vendor, &product) == 2) {
assert(config->nr_ids < ARRAY_SIZE(config->ids));
config->ids[config->nr_ids].product = product;
config->ids[config->nr_ids].vendor = vendor;
config->ids[config->nr_ids].flags = ID_EXCLUDED;
config->nr_ids++;
} else if (sscanf(s, "%hx:%hx", &vendor, &product) == 2) { } else if (sscanf(s, "%hx:%hx", &vendor, &product) == 2) {
assert(config->nr_ids < ARRAY_SIZE(config->ids)); assert(config->nr_ids < ARRAY_SIZE(config->ids));
config->ids[config->nr_ids++] = (vendor << 16 | product); config->ids[config->nr_ids].product = product;
config->ids[config->nr_ids].vendor = vendor;
config->ids[config->nr_ids].flags = ID_KEYBOARD | ID_MOUSE;
config->nr_ids++;
} }
else { else {
warn("%s is not a valid device id", s); warn("%s is not a valid device id", s);
@ -871,19 +893,19 @@ int config_parse(struct config *config, const char *path)
return 0; return 0;
} }
int config_check_match(struct config *config, uint32_t id) int config_check_match(struct config *config, uint16_t vendor, uint16_t product, uint8_t flags)
{ {
size_t i; size_t i;
for (i = 0; i < config->nr_ids; i++) { for (i = 0; i < config->nr_ids; i++) {
if (config->ids[i] == id) if (config->ids[i].product == product && config->ids[i].vendor == vendor) {
return 2; if (config->ids[i].flags & ID_EXCLUDED) {
} return 0;
} else if (config->ids[i].flags & flags) {
for (i = 0; i < config->nr_excluded_ids; i++) return 2;
if (config->excluded_ids[i] == id) { }
return 0;
} }
}
return config->wildcard ? 1 : 0; return config->wildcard ? 1 : 0;
} }

@ -20,6 +20,9 @@
#define PATH_MAX 1024 #define PATH_MAX 1024
#endif #endif
#define ID_EXCLUDED 1
#define ID_MOUSE 2
#define ID_KEYBOARD 4
enum op { enum op {
OP_KEYSEQUENCE = 1, OP_KEYSEQUENCE = 1,
@ -110,11 +113,15 @@ struct config {
char aliases[256][32]; char aliases[256][32];
uint8_t wildcard; uint8_t wildcard;
uint32_t ids[64]; struct {
uint32_t excluded_ids[64]; uint16_t product;
uint16_t vendor;
uint8_t flags;
} ids[64];
size_t nr_ids; size_t nr_ids;
size_t nr_excluded_ids;
size_t nr_layers; size_t nr_layers;
size_t nr_macros; size_t nr_macros;
size_t nr_descriptors; size_t nr_descriptors;
@ -135,6 +142,6 @@ int config_parse(struct config *config, const char *path);
int config_add_entry(struct config *config, const char *exp); int config_add_entry(struct config *config, const char *exp);
int config_get_layer_index(const struct config *config, const char *name); int config_get_layer_index(const struct config *config, const char *name);
int config_check_match(struct config *config, uint32_t id); int config_check_match(struct config *config, uint16_t vendor, uint16_t product, uint8_t flags);
#endif #endif

@ -152,40 +152,46 @@ static void load_configs()
closedir(dh); closedir(dh);
} }
static int lookup_config_ent(uint32_t id, struct config_ent **match) static struct config_ent *lookup_config_ent(uint16_t vendor,
uint16_t product,
uint8_t flags)
{ {
struct config_ent *ent = configs; struct config_ent *ent = configs;
struct config_ent *match = NULL;
int rank = 0; int rank = 0;
*match = NULL;
while (ent) { while (ent) {
int r = config_check_match(&ent->config, id); int r = config_check_match(&ent->config, vendor, product, flags);
if (r > rank) { if (r > rank) {
*match = ent; match = ent;
rank = r; rank = r;
} }
ent = ent->next; ent = ent->next;
} }
return rank; /* The wildcard should not match mice. */
if (rank == 1 && (flags == ID_MOUSE))
return NULL;
else
return match;
} }
static void manage_device(struct device *dev) static void manage_device(struct device *dev)
{ {
int match; uint8_t flags = 0;
uint32_t id = dev->vendor_id << 16 | dev->product_id; struct config_ent *ent;
struct config_ent *ent = NULL;
if (!strcmp(dev->name, VKBD_NAME)) if (!strcmp(dev->name, VKBD_NAME))
return; return;
match = lookup_config_ent(id, &ent); if (dev->capabilities & CAP_KEYBOARD)
flags |= ID_KEYBOARD;
if (dev->capabilities & (CAP_MOUSE|CAP_MOUSE_ABS))
flags |= ID_MOUSE;
if ((match && dev->capabilities & CAP_KEYBOARD) || if ((ent = lookup_config_ent(dev->vendor_id, dev->product_id, flags))) {
(match == 2 && dev->capabilities & (CAP_MOUSE | CAP_MOUSE_ABS))) {
if (device_grab(dev)) { if (device_grab(dev)) {
warn("Failed to grab %s", dev->path); warn("Failed to grab %s", dev->path);
dev->data = NULL; dev->data = NULL;

Loading…
Cancel
Save