#include #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 }