summaryrefslogtreecommitdiff
path: root/rcm-server-keymap.c
diff options
context:
space:
mode:
Diffstat (limited to 'rcm-server-keymap.c')
-rw-r--r--rcm-server-keymap.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/rcm-server-keymap.c b/rcm-server-keymap.c
new file mode 100644
index 0000000..a5c194e
--- /dev/null
+++ b/rcm-server-keymap.c
@@ -0,0 +1,121 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#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;
+}
+