diff --git a/src/porting/common/input_linux.cc b/src/porting/common/input_linux.cc new file mode 100644 index 00000000..5caa4d37 --- /dev/null +++ b/src/porting/common/input_linux.cc @@ -0,0 +1,194 @@ +#if 1//ndef HAVE_INPUT_H +#include +#else +#define EV_SYN 0x00 +#define EV_KEY 0x01 +#define EV_REL 0x02 +#define EV_ABS 0x03 +#define EV_MSC 0x04 +#define EV_SW 0x05 +#define EV_LED 0x11 +#define EV_SND 0x12 +#define EV_REP 0x14 +#define EV_FF 0x15 +#endif +#ifdef HAVE_POLL_H +#include +#endif +#ifdef HAVE_EPOLL_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + int maxfd; + int nfd; + int inotify; + int pipe[2]; + int fds[128]; + std::mapkeymap; +} INPUTDEVICE; + +static INPUTDEVICE dev= {0,0}; + +INT InputInit() { + if(dev.pipe[0]>0) + return 0; + pipe(dev.pipe); + dev.nfd=0; + dev.fds[dev.nfd++]=dev.pipe[0]; + dev.maxfd=dev.pipe[0]; + int rc=fcntl(dev.pipe[0],F_SETFL,O_NONBLOCK); + struct dirent **namelist=nullptr; + LOGD("cplusplus=%di nfd=%d fcntl=%d fd[0]=%d input_event.size=%d %d",__cplusplus,dev.nfd,rc,dev.fds[0],sizeof(struct input_event),sizeof(struct timeval)); + int nf=scandir("/dev/input",&namelist,[&dev](const struct dirent * ent)->int{ + char fname[256]; + int fd=-1; + snprintf(fname,sizeof(fname),"/dev/input/%s",ent->d_name); + if(ent->d_type!=DT_DIR) { + fd=open(fname,O_RDWR); + LOGD("%s fd=%d",fname,fd); + if(fd>0) { + dev.maxfd=std::max(dev.maxfd,fd); + dev.fds[dev.nfd++]=fd; + } + } + return fd>0; + },nullptr); + free(namelist); + LOGD("maxfd=%d numfd=%d\r\n",dev.maxfd,nf+1); + return 0; +} + +#define SET_BIT(array,bit) ((array)[(bit)/8] |= (1<<((bit)%8))) + +INT InputGetDeviceInfo(int device,INPUTDEVICEINFO*devinfo) { + int rc1,rc2; + memset(devinfo,0,sizeof(INPUTDEVICEINFO)); + struct input_id id; + rc1=ioctl(device, EVIOCGNAME(sizeof(devinfo->name) - 1),devinfo->name); + rc2=ioctl(device, EVIOCGID, &id); + + for(int i=0,j=0; iaxis+j++; + a->axis = i; + a->fuzz = info.fuzz; + a->flat = info.flat; + a->minimum= info.minimum; + a->maximum= info.maximum; + a->resolution=info.resolution; + LOGI_IF(a->maximum-a->minimum||1,"dev %d axis[%d]=[%d,%d,%d]",device,a->axis, a->minimum,a->maximum,a->resolution); + } + } + devinfo->product=id.product; + devinfo->vendor=id.vendor; + ioctl(device, EVIOCGBIT(EV_KEY, sizeof(devinfo->keyBitMask)), devinfo->keyBitMask); + ioctl(device, EVIOCGBIT(EV_ABS, sizeof(devinfo->absBitMask)), devinfo->absBitMask); + ioctl(device, EVIOCGBIT(EV_REL, sizeof(devinfo->relBitMask)), devinfo->relBitMask); + ioctl(device, EVIOCGBIT(EV_SW, sizeof(devinfo->swBitMask)), devinfo->swBitMask); + ioctl(device, EVIOCGBIT(EV_LED, sizeof(devinfo->ledBitMask)), devinfo->ledBitMask); + ioctl(device, EVIOCGBIT(EV_FF, sizeof(devinfo->ffBitMask)), devinfo->ffBitMask); + ioctl(device, EVIOCGPROP(sizeof(devinfo->propBitMask)), devinfo->propBitMask); + switch(device) { + case INJECTDEV_TOUCH: + strcpy(devinfo->name,"Touch-Inject"); + devinfo->vendor=INJECTDEV_TOUCH>>16; + devinfo->product=INJECTDEV_TOUCH&0xFF; + SET_BIT(devinfo->absBitMask,ABS_X); + SET_BIT(devinfo->absBitMask,ABS_Y); + SET_BIT(devinfo->keyBitMask,BTN_TOUCH); + break; + case INJECTDEV_MOUSE: + strcpy(devinfo->name,"Touch-Inject"); + devinfo->vendor=INJECTDEV_MOUSE>>16; + devinfo->product=INJECTDEV_MOUSE&0xFF; + SET_BIT(devinfo->relBitMask,REL_X); + SET_BIT(devinfo->relBitMask,REL_Y); + break; + case INJECTDEV_KEY: + strcpy(devinfo->name,"qwerty"); + devinfo->vendor=INJECTDEV_KEY>>16; + devinfo->product=INJECTDEV_KEY&0xFF; + SET_BIT(devinfo->keyBitMask,BTN_MISC); + SET_BIT(devinfo->keyBitMask,KEY_OK); + break; + default: + break; + } + return 0; +} + +INT InputInjectEvents(const INPUTEVENT*es,UINT count,DWORD timeout) { + const char*evtnames[]= {"SYN","KEY","REL","ABS","MSC","SW"}; + struct timespec tv; + INPUTEVENT*events=(INPUTEVENT*)malloc(count*sizeof(INPUTEVENT)); + memcpy(events,es,count*sizeof(INPUTEVENT)); + + if(dev.pipe[1]>0) { + int rc=write(dev.pipe[1],events,count*sizeof(INPUTEVENT)); + LOGV_IF(count&&(es->type<=EV_SW),"pipe=%d %s,%x,%x write=%d",dev.pipe[1],evtnames[es->type],es->code,es->value,rc); + } + free(events); + return count; +} + +INT InputGetEvents(INPUTEVENT*outevents,UINT max,DWORD timeout) { + int rc,count=0; + struct timeval tv; + struct input_event events[64]; + INPUTEVENT*e=outevents; + fd_set rfds; + static const char*type2name[]= {"SYN","KEY","REL","ABS","MSC","SW"}; + tv.tv_usec=(timeout%1000)*1000;//1000L*timeout; + tv.tv_sec=timeout/1000; + FD_ZERO(&rfds); + for(int i=0; itv_sec = events[j].time.tv_sec; + e->tv_usec= events[j].time.tv_usec; + e->type = events[j].type; + e->code = events[j].code; + e->value= events[j].value; + e->device=dev.fds[i]; + LOGV_IF(e->typetype],e->type,e->code,e->value,e->tv_sec,e->tv_usec,events[j].time.tv_sec,events[j].time.tv_usec); + } + } else { //for pipe + rc=read(dev.fds[i],e, (max-count)*sizeof(INPUTEVENT)); + e+=rc/sizeof(INPUTEVENT); + count+=rc/sizeof(INPUTEVENT); + } + LOGV_IF(rc,"fd %d read %d bytes ispipe=%d",dev.fds[i],rc,dev.fds[i]==dev.pipe[0]); + } + return e-outevents; +} +