aboutsummaryrefslogtreecommitdiffhomepage
path: root/uinput.c
diff options
context:
space:
mode:
Diffstat (limited to 'uinput.c')
-rw-r--r--uinput.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/uinput.c b/uinput.c
new file mode 100644
index 0000000..e14ce59
--- /dev/null
+++ b/uinput.c
@@ -0,0 +1,180 @@
+#include <linux/input.h>
+
+#include "minimonster.h"
+#include "uinput.h"
+
+int init() {
+
+ backend uinput = {
+ .name = BACKEND_NAME,
+ .conf = backend_configure,
+ .create = backend_instance,
+ .conf_instance = backend_configure_instance,
+ .channel = backend_channel,
+ .handle = backend_set,
+ .process = backend_handle,
+ .start = backend_start,
+ .shutdown = backend_shutdown
+ };
+
+ if (mm_backend_register(uinput)) {
+ fprintf(stderr, "Failed to register uinput backend\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int backend_configure(char* option, char* value) {
+ fprintf(stderr, "Not implemented\n");
+ return 1;
+}
+
+static int backend_configure_instance(instance* inst, char* option, char* value) {
+ uinput_instance* data = (uinput_instance*) inst->impl;
+
+ if (!strcmp(option, "device")) {
+ if (data->device_path) {
+ free(data->device_path);
+ }
+ data->device_path = strdup(value);
+
+ if (!data->device_path) {
+ fprintf(stderr, "Failed to allocate memory\n");
+ return 1;
+ }
+ } else if (!strcmp(option, "name")) {
+ if (data->name) {
+ free(data->name);
+ }
+
+ data->name = strdup(option);
+
+ if (data->name) {
+ fprintf(stderr, "Failed to allocate memory\n");
+ return 1;
+ }
+ } else {
+ fprintf(stderr, "Unkown configuration parameter %s for uinput backend\n", option);
+ return 1;
+ }
+ return 0;
+}
+
+static channel* backend_channel(instance* inst, char* spec) {
+ uinput_instance* data = (uinput_instance*) inst->impl;
+ char* next = spec;
+ // type
+ unsigned long type = strtoul(spec, &next, 10);
+
+ if (spec == next) {
+ fprintf(stderr, "Cannot parse type\n");
+ return NULL;
+ }
+
+ if (type >= EV_MAX) {
+ fprintf(stderr, "Type is out of range\n");
+ return NULL;
+ }
+
+ if (next[0] != '.') {
+ fprintf(stderr, "Cannot parse code. Unknown character %c\n", next[0]);
+ return NULL;
+ }
+
+ spec = next + 1;
+
+ unsigned long code = strtoul(spec, &next, 10);
+
+ if (spec == next) {
+ fprintf(stderr, "Cannot parse code\n");
+ return NULL;
+ }
+
+ if (type == EV_SYN && code >= SYN_MAX) {
+ fprintf(stderr, "Code is out of range. Limit for SYN is %d\n", SYN_MAX);
+ } else if (type == EV_KEY && code >= KEY_MAX) {
+ fprintf(stderr, "Code is out of range. Limit for KEY is %d\n", KEY_MAX);
+ return NULL;
+ } else if (type == EV_REL && code >= REL_MAX) {
+ fprintf(stderr, "Code is out of range. Limit for REL is %d\n", REL_MAX);
+ return NULL;
+ } else if (type == EV_ABS && code >= ABS_MAX) {
+ fprintf(stderr, "Code is out of range. Limit for ABS is %d\n", ABS_MAX);
+ return NULL;
+ } else if (type == EV_SW && code >= SW_MAX) {
+ fprintf(stderr, "Code is out of range. Limit for SW is %d\n", SW_MAX);
+ return NULL;
+ } else if (type == EV_MSC && code >= MSC_MAX) {
+ fprintf(stderr, "Code is out of range. Limit for MSC is %d\n", MSC_MAX);
+ return NULL;
+ } else if (type == EV_LED && code >= LED_MAX) {
+ fprintf(stderr, "Code is out of range. Limit for LED is %d\n", LED_MAX);
+ return NULL;
+ } else if (type == EV_REP && code >= REP_MAX) {
+ fprintf(stderr, "Code is out of range. Limit for REP is %d\n", REP_MAX);
+ return NULL;
+ } else if (type == EV_SND && code >= SND_MAX) {
+ fprintf(stderr, "Code is out of range. Limit for SND is %d\n", SND_MAX);
+ }
+
+ if (next[0] != '.') {
+ fprintf(stderr, "Cannot parse value. Unknown character %c\n", next[0]);
+ return NULL;
+ }
+
+ spec = next + 1;
+
+ long value = strtol(spec, &next, 10);
+
+ if (spec == next) {
+ fprintf(stderr, "Cannot parse value\n");
+ return NULL;
+ }
+
+ if (type == EV_KEY && (value != 0 || value != 1)) {
+ fprintf(stderr, "Value of KEY is out of range. Only values 0 and 1 are supported for KEY.");
+ return NULL;
+ }
+
+ // find event
+ unsigned u;
+ for (u = 0; u < data.size_events) {
+ if (data->events[u].type == type
+ && data->events[u].code == code
+ && data->events[u].value == value) {
+ break;
+ }
+ }
+
+ if (u == data->size_events) {
+ data->events = realloc(data->channel, (u + 1) * sizeof(struct input_event));
+
+ if (!data->events) {
+ fprintf(stderr, "Failed to allocate memory\n");
+ return NULL;
+ }
+
+ data->events[u].type = (uint16_t) type;
+ data->events[u].code = (uint16_t) code;
+ data->events[u].value = (int32_t) value;
+ data->size_events++;
+ }
+ return mm_channel(inst, u, 1);
+}
+
+static instance* backend_instance() {
+ // TODO impl
+}
+
+static int backend_handle(size_t num, managed_fd* fds) {
+ //TODO impl
+}
+
+static int backend_start() {
+ //TODO impl
+}
+
+static int backend_shutdown() {
+ //TODO impl
+}