aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJan Düpmeier <j.duepmeier@googlemail.com>2017-11-07 11:13:34 +0100
committerJan Düpmeier <j.duepmeier@googlemail.com>2017-11-07 11:13:34 +0100
commit4265dc5892f4cec2aabf76b4922231d2878cc7ea (patch)
tree95e5537f5760a7867a27e952a5cae9af12d52842
parentb9e141a7ea3f52e354c2096aaa5f935556b9f734 (diff)
downloadmidimonster-4265dc5892f4cec2aabf76b4922231d2878cc7ea.tar.gz
midimonster-4265dc5892f4cec2aabf76b4922231d2878cc7ea.tar.bz2
midimonster-4265dc5892f4cec2aabf76b4922231d2878cc7ea.zip
skel, configure_instance and channel for uinput
-rw-r--r--uinput.c180
-rw-r--r--uinput.h24
2 files changed, 204 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
+}
diff --git a/uinput.h b/uinput.h
new file mode 100644
index 0000000..8c4925a
--- /dev/null
+++ b/uinput.h
@@ -0,0 +1,24 @@
+#include <sys/types.h>
+#include <linux/input.h>
+
+#include "midimonster.h"
+
+int init();
+static int backend_configure(char* option, char* value);
+static int backend_configure_instance(instance* instance, char* option, char* value);
+static instance* backend_instance();
+static channel* backend_channel(instance* instance, char* spec);
+static int backend_set(instance* inst, size_t num, channel** c, channel_value* v);
+static int backend_handle(size_t num, managed_fd* fds);
+static int backend_start();
+static int backend_shutdown();
+
+/* uinput_instance */
+typedef struct {
+ char* device_path;
+ char* name;
+ int fd_in;
+ int fd_out;
+ size_t size_events;
+ struct input_event* events;
+} uinput_instance;