Mercurial > remote-gamepad-server
view uinput.c @ 6:eafcd170dc6d
Add circle pad and c pad support, and provisional touch support.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 18 Aug 2015 02:07:48 +0100 |
parents | 73c20831be0a |
children | 6aa40a25de22 |
line wrap: on
line source
#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 "Nintendo 3DS" /* 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; // Circle pad dev.absmax[ABS_X] = PAD_MAX; dev.absmin[ABS_X] = -PAD_MAX; dev.absfuzz[ABS_X] = 4; dev.absflat[ABS_X] = 2; dev.absmax[ABS_Y] = PAD_MAX; dev.absmin[ABS_Y] = -PAD_MAX; dev.absfuzz[ABS_Y] = 4; dev.absflat[ABS_Y] = 2; // C pad dev.absmax[ABS_RX] = PAD_MAX; dev.absmin[ABS_RX] = -PAD_MAX; dev.absfuzz[ABS_RX] = 4; dev.absflat[ABS_RX] = 2; dev.absmax[ABS_RY] = PAD_MAX; dev.absmin[ABS_RY] = -PAD_MAX; dev.absfuzz[ABS_RY] = 4; dev.absflat[ABS_RY] = 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_TL2) ) return -1; if( ioctl(fd, UI_SET_KEYBIT, BTN_TR2) ) return -1; if( ioctl(fd, UI_SET_KEYBIT, BTN_START) ) return -1; if( ioctl(fd, UI_SET_KEYBIT, BTN_SELECT)) return -1; if( ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_UP)) return -1; if( ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_DOWN)) return -1; if( ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_LEFT)) return -1; if( ioctl(fd, UI_SET_KEYBIT, BTN_DPAD_RIGHT)) 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; if( ioctl(fd, UI_SET_ABSBIT, ABS_RX) ) return -1; if( ioctl(fd, UI_SET_ABSBIT, ABS_RY) ) 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); } }