Mercurial > remote-gamepad-server
diff uinput.c @ 0:e70ea46d6073
Initial import from http://wouhanegaine.free.fr/dev/DSPad02b_neo07.zip
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sun, 22 Feb 2015 01:38:06 +0100 |
parents | |
children | f362b20de51e |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/uinput.c @@ -0,0 +1,134 @@ +#include "uinput.h" +#include "ds.h" +#include "service.h" + +#include <stdio.h> +#include <fcntl.h> +#include <string.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdbool.h> + + +#define DS_NAME "NintendoDS Wireless Gamepad" + +/* Not found these values... but it's not important! */ +#define DS_VENDOR 0xdead +#define DS_PRODUCT 0xbeef +#define DS_VERSION 0x00 + + + +/* + Create a new uinput device + Returns: file descriptor (-1 if error) + */ +int init_uinput_device(void){ + struct uinput_user_dev dev; + int fd = -1; + + if(uinput_dev == NULL){ + fd = open("/dev/uinput", O_RDWR); + + if(fd < 0) + fd = open("/dev/misc/uinput", O_RDWR); + + if(fd < 0) + fd = open("/dev/input/uinput", O_RDWR); + } + else fd = open(uinput_dev, O_RDWR); //from xml + + if(fd < 0){ + fprintf(stderr, " [%d] Unable to open uinput device ; hint: 'modprobe uinput' ?!\n", curdev); + return -1; + } + + + + memset(&dev, 0, sizeof(dev)); + strncpy(dev.name, DS_NAME, UINPUT_MAX_NAME_SIZE); + dev.id.bustype = 0; + dev.id.vendor = DS_VENDOR; + dev.id.product = DS_PRODUCT; + dev.id.version = DS_VERSION; + + dev.absmax[ABS_X] = DS_MAX_X; + dev.absmin[ABS_X] = DS_MIN_X; + dev.absfuzz[ABS_X] = 4; + dev.absflat[ABS_X] = 2; + + dev.absmax[ABS_Y] = DS_MAX_Y; + dev.absmin[ABS_Y] = DS_MIN_Y; + dev.absfuzz[ABS_X] = 4; + dev.absflat[ABS_X] = 2; + + + if(write(fd, &dev, sizeof(dev)) < (ssize_t)sizeof(dev)){ + fprintf(stderr, " [%d] Registering device at uinput failed\n", curdev); + return -1; + } + + /* Keys [01] (found in <linux/input.h>) */ + if( ioctl(fd, UI_SET_EVBIT, EV_KEY) ) return -1; + if( ioctl(fd, UI_SET_KEYBIT, BTN_A) ) return -1; + if( ioctl(fd, UI_SET_KEYBIT, BTN_B) ) return -1; + if( ioctl(fd, UI_SET_KEYBIT, BTN_X) ) return -1; + if( ioctl(fd, UI_SET_KEYBIT, BTN_Y) ) return -1; + if( ioctl(fd, UI_SET_KEYBIT, BTN_TL) ) return -1; + if( ioctl(fd, UI_SET_KEYBIT, BTN_TR) ) return -1; + if( ioctl(fd, UI_SET_KEYBIT, BTN_START) ) return -1; + if( ioctl(fd, UI_SET_KEYBIT, BTN_SELECT)) return -1; + + /* D-Pad [-0xFFFF - 0xFFFF] */ + if( ioctl(fd, UI_SET_EVBIT, EV_ABS) ) return -1; + if( ioctl(fd, UI_SET_ABSBIT, ABS_X) ) return -1; + if( ioctl(fd, UI_SET_ABSBIT, ABS_Y) ) return -1; + + + /* Register device */ + if( ioctl(fd, UI_DEV_CREATE) ) return -1; + + return fd; +} + + +/* + Send an event into the uinput device + Returns: TRUE, FALSE +*/ +int do_uinput(int fd, unsigned short key, int pressed, unsigned short event_type){ + struct input_event event; + memset(&event, 0 , sizeof(event)); + + event.type = event_type; + event.code = key; + event.value = pressed; + + if(write(fd,&event,sizeof(event)) != sizeof(event)){ + fprintf(stderr, " [%d] Writing event to uinput driver failed ; Aborting\n", curdev); + return false; + } + return true; +} + + +/* + Synchonize events +*/ +void flush_uinput(int fd){ + struct input_event event; + memset(&event, 0 , sizeof(event)); + + event.type = EV_SYN; + event.code = SYN_REPORT; + + if(fd){ + if(write(fd, &event, sizeof(event) != sizeof(event))) + fprintf(stderr, " [%d] Flushing uinput failed\n", curdev); + } +} + + + + +