2012-12-03 16:12:48 -05:00
|
|
|
/*
|
|
|
|
* Status:
|
|
|
|
*
|
|
|
|
* - Can map keys from some keyboard to keys on a joystick.
|
|
|
|
*
|
|
|
|
* Does not:
|
|
|
|
* - Have a nice mapping file format / datastructures YET.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2012-12-03 14:16:19 -05:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
2012-12-03 17:06:12 -05:00
|
|
|
#include <signal.h>
|
2012-12-03 14:16:19 -05:00
|
|
|
|
|
|
|
#include <linux/input.h>
|
|
|
|
#include <linux/uinput.h>
|
|
|
|
|
2012-12-04 14:05:00 -05:00
|
|
|
#include "custom_map.h"
|
|
|
|
|
2012-12-03 14:16:19 -05:00
|
|
|
#define UINPUT_PATH "/dev/uinput"
|
|
|
|
|
2012-12-03 16:12:48 -05:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2012-12-04 14:05:00 -05:00
|
|
|
static int js[JOYCOUNT];
|
2012-12-03 16:12:48 -05:00
|
|
|
|
2012-12-03 14:16:19 -05:00
|
|
|
/* TODO:
|
2012-12-03 16:12:48 -05:00
|
|
|
* - Add file parsing / reading
|
|
|
|
* - Add proper datastructures to keep track
|
2012-12-03 14:16:19 -05:00
|
|
|
*/
|
|
|
|
|
2012-12-03 17:06:12 -05:00
|
|
|
void free_js(int sig) {
|
|
|
|
int j;
|
2012-12-04 14:13:43 -05:00
|
|
|
|
|
|
|
(void) sig;
|
2012-12-04 14:05:00 -05:00
|
|
|
for(j = 0; j < JOYCOUNT; j++) {
|
2012-12-03 17:06:12 -05:00
|
|
|
printf("Freeing joystick: %d\n", j);
|
|
|
|
if (ioctl(js[j], UI_DEV_DESTROY) < 0) {
|
|
|
|
perror("Error freeing joystick");
|
|
|
|
}
|
|
|
|
close(js[j]);
|
|
|
|
}
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2012-12-03 14:16:19 -05:00
|
|
|
int main(int argc, char** argv) {
|
2012-12-04 17:58:07 -05:00
|
|
|
int j, nowrite;
|
2012-12-03 17:06:12 -05:00
|
|
|
int in; /* fds */
|
2012-12-03 14:16:19 -05:00
|
|
|
struct input_event e, je;
|
|
|
|
struct uinput_user_dev uidev;
|
|
|
|
|
2012-12-03 16:12:48 -05:00
|
|
|
|
2012-12-04 14:13:43 -05:00
|
|
|
(void)argc;
|
|
|
|
(void)argv;
|
|
|
|
|
|
|
|
(void)get_key_num;
|
|
|
|
|
2012-12-03 17:06:12 -05:00
|
|
|
if(signal(SIGINT, free_js)) {
|
|
|
|
printf("Atexit registration failed\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2012-12-03 16:12:48 -05:00
|
|
|
/* Open input and uinput */
|
2012-12-03 14:16:19 -05:00
|
|
|
in = open(INPUT_PATH, O_RDONLY);
|
|
|
|
if(in < 0) {
|
|
|
|
perror("open in");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2012-12-04 14:05:00 -05:00
|
|
|
for(j = 0; j < JOYCOUNT; j++) {
|
2012-12-03 18:07:34 -05:00
|
|
|
/* Memset because we are already setting the absmax/absmin */
|
|
|
|
memset(&uidev, '\0', sizeof(struct uinput_user_dev));
|
2012-12-03 17:06:12 -05:00
|
|
|
js[j] = open(UINPUT_PATH, O_WRONLY | O_NONBLOCK);
|
|
|
|
if (js[j] < 0) {
|
|
|
|
perror("open js[j]");
|
|
|
|
return 1;
|
|
|
|
}
|
2012-12-03 14:16:19 -05:00
|
|
|
|
2012-12-03 17:06:12 -05:00
|
|
|
/* Register device opts */
|
|
|
|
if (ioctl(js[j], UI_SET_EVBIT, EV_ABS) < 0) {
|
|
|
|
perror("ioctl EV_ABS");
|
2012-12-03 16:12:48 -05:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2012-12-03 17:06:12 -05:00
|
|
|
if (ioctl(js[j], UI_SET_EVBIT, EV_KEY) < 0) {
|
|
|
|
perror("ioctl EV_KEY");
|
2012-12-03 16:12:48 -05:00
|
|
|
return 1;
|
|
|
|
}
|
2012-12-03 14:16:19 -05:00
|
|
|
|
2012-12-04 17:58:07 -05:00
|
|
|
#define H_CONFIGURE_JOYSTICKS
|
|
|
|
#include "custom_map.h"
|
2012-12-03 14:16:19 -05:00
|
|
|
|
2012-12-03 17:06:12 -05:00
|
|
|
/* Allocate device info */
|
2012-12-04 14:05:00 -05:00
|
|
|
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "key2joy:%d", j);
|
2012-12-03 14:16:19 -05:00
|
|
|
|
2012-12-03 17:06:12 -05:00
|
|
|
uidev.id.bustype = BUS_USB;
|
|
|
|
uidev.id.vendor = 0x42;
|
|
|
|
uidev.id.product = 0xbebe;
|
|
|
|
uidev.id.version = 1;
|
2012-12-03 14:16:19 -05:00
|
|
|
|
2012-12-03 17:06:12 -05:00
|
|
|
if (write(js[j], &uidev, sizeof(uidev)) < 0) {
|
|
|
|
perror("write");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ioctl(js[j], UI_DEV_CREATE)) {
|
|
|
|
perror("ioctl create");
|
|
|
|
return 1;
|
|
|
|
}
|
2012-12-03 14:16:19 -05:00
|
|
|
}
|
|
|
|
|
2012-12-03 16:12:48 -05:00
|
|
|
/* Do it! */
|
2012-12-03 14:16:19 -05:00
|
|
|
while (1) {
|
|
|
|
if (read(in, &e, sizeof(struct input_event))) {
|
|
|
|
printf("Event: (Type: %d, Code: %d, Value %d)\n", e.type, e.code, e.value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-03 16:12:48 -05:00
|
|
|
memset(&je, '\0', sizeof(struct input_event));
|
|
|
|
nowrite = 0;
|
2012-12-03 17:06:12 -05:00
|
|
|
j = 0;
|
2012-12-03 16:12:48 -05:00
|
|
|
|
2012-12-04 13:57:30 -05:00
|
|
|
|
2012-12-03 17:12:40 -05:00
|
|
|
/* Only catch keys and ignore auto-repeat (value == 2) */
|
|
|
|
if (e.type == EV_KEY && e.value != 2) {
|
2012-12-03 16:12:48 -05:00
|
|
|
switch(e.code) {
|
2012-12-04 13:57:30 -05:00
|
|
|
|
2012-12-04 14:05:00 -05:00
|
|
|
#define H_IN_CASE
|
2012-12-04 13:57:30 -05:00
|
|
|
#include "custom_map.h"
|
|
|
|
|
2012-12-03 16:12:48 -05:00
|
|
|
default:
|
|
|
|
nowrite = 1;
|
|
|
|
}
|
|
|
|
if (nowrite == 0) {
|
2012-12-04 18:13:19 -05:00
|
|
|
printf("Writing %d to %d\n", e.code, j);
|
2012-12-03 17:06:12 -05:00
|
|
|
if(write(js[j], &je, sizeof(struct input_event)) < 0) {
|
2012-12-03 16:12:48 -05:00
|
|
|
perror("EV_ABS Write event");
|
|
|
|
return -1;
|
|
|
|
}
|
2012-12-03 14:16:19 -05:00
|
|
|
}
|
|
|
|
}
|
2012-12-03 16:12:48 -05:00
|
|
|
|
|
|
|
/* Synchronisation events */
|
2012-12-03 14:16:19 -05:00
|
|
|
if (e.type == EV_SYN) {
|
|
|
|
memset(&je, '\0', sizeof(struct input_event));
|
|
|
|
printf("SYN event\n");
|
|
|
|
|
|
|
|
je.type = EV_SYN;
|
|
|
|
je.code = 0;
|
|
|
|
je.value = 0;
|
|
|
|
|
2012-12-03 17:06:12 -05:00
|
|
|
if (write(js[j], &je, sizeof(struct input_event)) < 0) {
|
2012-12-03 14:16:19 -05:00
|
|
|
perror("SYN write event");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|