diff --git a/genkeys.sh b/genkeys.sh new file mode 100644 index 0000000..2c0e4a0 --- /dev/null +++ b/genkeys.sh @@ -0,0 +1 @@ +echo '#include ' | gcc -E -dM - | grep '#define KEY_' | cut -f2 -d" " | sed 's/KEY_.*/DEF_KEY(&)/' > def_keys.h diff --git a/map.c b/map.c index 2a4a129..8b313da 100644 --- a/map.c +++ b/map.c @@ -1,3 +1,16 @@ +/* + * Status: + * + * - Can map keys from some keyboard to keys on a joystick. + * + * Does not: + * - Show up as a joystick device? + * - Emulate multiple joysticks + * - Have a nice mapping file format / datastructures YET. + * + */ + + #include #include #include @@ -14,18 +27,72 @@ /*#define INPUT_PATH "/dev/input/by-path/platform-i8042-serio-0-event-kbd"*/ #define UINPUT_PATH "/dev/uinput" +/* Reverse mapping, for later use */ +static const struct _key_to_str { + char *name; + int num; +} key_map[] = { +#define DEF_KEY(NAME) \ + {#NAME,NAME}, + #include "def_keys.h" + {NULL, -1} +}; + +static int get_key_num(char* name) +{ + int i = 0; + + while (key_map[i].name) { + if (!strcmp(key_map[i].name, name)) + return key_map[i].num; + + i++; + } + + return -1; +} + + /* TODO: * - Use atexit() to free joysticks - * - Make joysticks static - * - * + * - Add file parsing / reading + * - Add proper datastructures to keep track */ int main(int argc, char** argv) { - int in, uin; + int i, nowrite; + int in, uin; /* fds */ struct input_event e, je; struct uinput_user_dev uidev; + /* + * KEY_LEFT -> ABS_HAT0X + * KEY_RIGHT -> ABS_HAT0X + * KEY_UP -> ABS_HAT0Y + * KEY_DOWN -> ABS_HAT0Y + * + * KEY_LEFTCTRL -> BTN_0 + * KEY_LEFTALT -> BTN_1 + * KEY_SPACE -> BTN_2 + * + * KEY_1 -> BTN_3 + */ + + int abskeyevs[] = { + ABS_HAT0X, + ABS_HAT0Y, + 0 + }; + + int evkeys[] = { + BTN_0, + BTN_1, + BTN_2, + BTN_3, + 0 + }; + + /* Open input and uinput */ in = open(INPUT_PATH, O_RDONLY); if(in < 0) { perror("open in"); @@ -38,7 +105,7 @@ int main(int argc, char** argv) { return 2; } - /* Create devices */ + /* Register device opts */ if (ioctl(uin, UI_SET_EVBIT, EV_ABS) < 0) { perror("ioctl EV_ABS"); return 1; @@ -50,11 +117,26 @@ int main(int argc, char** argv) { } /* Every ``button'' needs to be registered */ - if (ioctl(uin, UI_SET_ABSBIT, ABS_HAT0Y) < 0) { - perror("ioctl ABS_"); - return 1; + i = 0; + while(abskeyevs[i] != 0) { + if (ioctl(uin, UI_SET_ABSBIT, abskeyevs[i]) < 0) { + perror("ioctl dynamic"); + return 1; + } + i++; } + i = 0; + while(evkeys[i] != 0) { + if (ioctl(uin, UI_SET_KEYBIT, evkeys[i]) < 0) { + perror("ioctl dynamic 2"); + return 1; + } + i++; + } + + + /* Allocate device info */ memset(&uidev, '\0', sizeof(struct uinput_user_dev)); snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "key2joy:1"); @@ -73,23 +155,46 @@ int main(int argc, char** argv) { return 1; } + /* Do it! */ while (1) { - printf("in: %d, uin: %d\n", in, uin); if (read(in, &e, sizeof(struct input_event))) { printf("Event: (Type: %d, Code: %d, Value %d)\n", e.type, e.code, e.value); } - if (e.type == EV_KEY && e.code == KEY_UP) { - memset(&je, '\0', sizeof(struct input_event)); - je.type = EV_ABS; - je.code = ABS_HAT0Y; - je.value = -e.value; - if(write(uin, &je, sizeof(struct input_event)) < 0) { - perror("EV_ABS Write event"); - return -1; + memset(&je, '\0', sizeof(struct input_event)); + nowrite = 0; + + if (e.type == EV_KEY) { + switch(e.code) { + case KEY_UP: + je.type = EV_ABS; je.code = ABS_HAT0Y; je.value = -e.value; break; + case KEY_DOWN: + je.type = EV_ABS; je.code = ABS_HAT0Y; je.value = e.value; break; + case KEY_LEFT: + je.type = EV_ABS; je.code = ABS_HAT0X; je.value = -e.value; break; + case KEY_RIGHT: + je.type = EV_ABS; je.code = ABS_HAT0X; je.value = e.value; break; + case KEY_LEFTCTRL: + je.type = EV_KEY; je.code = BTN_0; je.value = e.value; break; + case KEY_LEFTALT: + je.type = EV_KEY; je.code = BTN_1; je.value = e.value; break; + case KEY_SPACE: + je.type = EV_KEY; je.code = BTN_2; je.value = e.value; break; + case KEY_1: + je.type = EV_KEY; je.code = BTN_3; je.value = e.value; break; + default: + nowrite = 1; + } + if (nowrite == 0) { + if(write(uin, &je, sizeof(struct input_event)) < 0) { + perror("EV_ABS Write event"); + return -1; + } } } + + /* Synchronisation events */ if (e.type == EV_SYN) { memset(&je, '\0', sizeof(struct input_event)); printf("SYN event\n"); @@ -103,7 +208,6 @@ int main(int argc, char** argv) { return -1; } } - printf("---\n"); }