config: Add k: and m: device matching prefixes

master
Raheman Vaiya 3 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
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
same state. This is useful for linking separate input devices together
(e.g foot pedals).

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

@ -20,6 +20,9 @@
#define PATH_MAX 1024
#endif
#define ID_EXCLUDED 1
#define ID_MOUSE 2
#define ID_KEYBOARD 4
enum op {
OP_KEYSEQUENCE = 1,
@ -110,11 +113,15 @@ struct config {
char aliases[256][32];
uint8_t wildcard;
uint32_t ids[64];
uint32_t excluded_ids[64];
struct {
uint16_t product;
uint16_t vendor;
uint8_t flags;
} ids[64];
size_t nr_ids;
size_t nr_excluded_ids;
size_t nr_layers;
size_t nr_macros;
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_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

@ -152,40 +152,46 @@ static void load_configs()
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 *match = NULL;
int rank = 0;
*match = NULL;
while (ent) {
int r = config_check_match(&ent->config, id);
int r = config_check_match(&ent->config, vendor, product, flags);
if (r > rank) {
*match = ent;
match = ent;
rank = r;
}
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)
{
int match;
uint32_t id = dev->vendor_id << 16 | dev->product_id;
struct config_ent *ent = NULL;
uint8_t flags = 0;
struct config_ent *ent;
if (!strcmp(dev->name, VKBD_NAME))
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) ||
(match == 2 && dev->capabilities & (CAP_MOUSE | CAP_MOUSE_ABS))) {
if ((ent = lookup_config_ent(dev->vendor_id, dev->product_id, flags))) {
if (device_grab(dev)) {
warn("Failed to grab %s", dev->path);
dev->data = NULL;

Loading…
Cancel
Save