#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "utils.h" #include "rcm-server.h" #include "rcm-server-keymap.h" struct keymap * find_keymap_by_name(struct device *dev, const char *name) { struct keymap *keymap; list_for_each_entry(keymap, &dev->keymaps, list) if (!strcmp(keymap->name, name)) return keymap; return NULL; } static struct keymap * keymap_read(int dfd, const char *name) { int fd; struct keymap *keymap; unsigned i; if (dfd < 0 || !name) return NULL; fd = openat(dfd, name, O_RDONLY); if (fd < 0) return NULL; keymap = zmalloc(sizeof(*keymap) + (8 * 3) * sizeof(struct keycode)); if (!keymap) { close(fd); return NULL; } keymap->name = strdup(name); if (!keymap->name) { close(fd); free(keymap); return NULL; } keymap->cols = 3; keymap->rows = 8; for (i = 0; i < (keymap->cols * keymap->rows); i++) { keymap->keycodes[i].name = "key-1-2"; keymap->keycodes[i].value = "KEY_COFFEE"; } /* FIXME: Actually read the keymap :) */ close(fd); return keymap; } static int keymaps_load_dir(struct device *device, const char *path) { DIR *dir; int dfd; struct dirent *dent; struct keymap *keymap; dir = opendir(path); if (!dir) return -1; dfd = dirfd(dir); if (dfd < 0) { closedir(dir); return -1; } while ((dent = readdir(dir))) { switch (dent->d_type) { case DT_REG: case DT_LNK: case DT_UNKNOWN: keymap = keymap_read(dfd, dent->d_name); if (keymap) list_add(&keymap->list, &device->keymaps); break; default: break; } } if (closedir(dir) < 0) return -1; return 0; } int keymaps_load(struct device *device) { char pdpath[strlen("./keymaps/per-device/") + strlen(device->name) + 1]; sprintf(pdpath, "./keymaps/per-device/%s", device->name); printf("Loading per-device keymaps...\n"); keymaps_load_dir(device, pdpath); printf("Loading default keymaps...\n"); keymaps_load_dir(device, "./keymaps/default"); return 0; }