int main (int argc, char *argv[]) { struct input_event ev[64]; int fd, rd, value, size = sizeof (struct input_event); char name[256] = "Unknown"; const char *device = NULL; if(daemon(0,0)){ printf("Could not start as daemon\n"); return -1; } device = "/dev/naga_keyboard"; //Open Device if ((fd = open (device, O_RDONLY)) == -1){ printf ("%s is not a vaild device.\n", device); return -1; } //Print Device Name ioctl (fd, EVIOCGNAME (sizeof (name)), name); printf ("Reading From : %s (%s)\n", device, name); init(); while (1){ if ((rd = read (fd, ev, size * 64)) < size) perror_exit ("read()"); value = ev[0].value; if (value != ' ' && ev[1].value == 1 && ev[1].type == 1){ // Only read the key press event printf ("Code[%d]\n", (ev[1].code)); docode(ev[1].code); } } return 0; }
int main() { int mouseFD = -1; int i; char deviceName[64]; char fullPath[128]; fprintf(stderr, "Try to find the device ( %s ).\n", TOUCH_PANEL_DEVICE_NAME); for(i=0; i<10; i++) { memset(deviceName, 0, 64); memset(fullPath, 0, 128); sprintf(fullPath,"/dev/input/event%d",i); mouseFD = open(fullPath,O_RDONLY | O_NDELAY); if(mouseFD==-1) continue; if(ioctl(mouseFD, EVIOCGNAME(64), deviceName) < 0) { close(mouseFD); continue; } // Get the device name, matching... fprintf(stderr,"Current device -> %s, name -> %s, Result -> ", fullPath, deviceName); if(strcasestr(deviceName, TOUCH_PANEL_DEVICE_NAME)) { fprintf(stderr,"Have found touch panal device %s\n",fullPath); close(mouseFD); goto findok; } else { fprintf(stderr,"no touch panel device found!\n"); close(mouseFD); } } goto notfind; findok: printf("%s", fullPath); exit(0); notfind: exit(1); }
static int is_gpio_keys(char *path) { char buf[256]; int fd; int ret; fd = open(path, O_RDONLY); if (fd < 0){ perror("open"); return FALSE; } ret = ioctl(fd, EVIOCGNAME(sizeof(buf)), buf); close(fd); if (ret < 0) return FALSE; ret = strcmp(buf, sw[sw_index].driver); if (ret != 0) return FALSE; return TRUE; }
/* another option to this mess (as the hashing thing doesn't seem to work out * is to move identification/etc. to another level and just let whatever device * node generator is active populate with coherent names. and use a hash of that * name as the ID */ static bool identify(int fd, const char* path, char* label, size_t label_sz, unsigned short* dnum) { if (-1 == ioctl(fd, EVIOCGNAME(label_sz), label)){ debug_print("input/identify: bad EVIOCGNAME, setting unknown\n"); snprintf(label, label_sz, "unknown"); } else verbose_print( "input/identify(%d): %s name resolved to %s", fd, path, label); struct input_id nodeid; if (-1 == ioctl(fd, EVIOCGID, &nodeid)){ debug_print( "input/identify(%d): no EVIOCGID, reason:%s", fd, strerror(errno)); return false; } /* * first, check if any other subsystem knows about this one and ignore if so */ if (arcan_led_known(nodeid.vendor, nodeid.product)){ debug_print( "led subsys know %d, %d\n", (int)nodeid.vendor, (int)nodeid.product); arcan_led_init(); return false; } /* didn't find much on how unique eviocguniq actually was, nor common lengths * or what not so just mix them in a buffer, hash and let unsigned overflow * modulo take us down to 16bit */ size_t bpl = sizeof(long) * 8; size_t nbits = ((EV_MAX)-1) / bpl + 1; char buf[12 + nbits * sizeof(long)]; char bbuf[sizeof(buf)]; memset(buf, '\0', sizeof(buf)); memset(bbuf, '\0', sizeof(bbuf)); /* some test devices here answered to the ioctl and returned full empty UNIQs, * do something to lower the likelihood of collisions */ unsigned long hash = 5381; if (-1 == ioctl(fd, EVIOCGUNIQ(sizeof(buf)), buf) || memcmp(buf, bbuf, sizeof(buf)) == 0){ size_t llen = strlen(label); for (size_t i = 0; i < llen; i++) hash = ((hash << 5) + hash) + label[i]; llen = strlen(path); for (size_t i = 0; i < llen; i++) hash = ((hash << 5) + hash) + path[i]; buf[11] ^= nodeid.vendor >> 8; buf[10] ^= nodeid.vendor; buf[9] ^= nodeid.product >> 8; buf[8] ^= nodeid.product; buf[7] ^= nodeid.version >> 8; buf[6] ^= nodeid.version; /* even this point has a few collisions, particularly some keyboards and mice * that don't respond to CGUNIQ and expose multiple- subdevices but with * different button/axis count */ ioctl(fd, EVIOCGBIT(0, EV_MAX), &buf); }
int EventHub::open_device(const char *deviceName) { int version; int fd; struct pollfd *new_mFDs; device_t **new_devices; char **new_device_names; char name[80]; char location[80]; char idstr[80]; struct input_id id; LOGV("Opening device: %s", deviceName); AutoMutex _l(mLock); fd = open(deviceName, O_RDWR); if(fd < 0) { LOGE("could not open %s, %s\n", deviceName, strerror(errno)); return -1; } if(ioctl(fd, EVIOCGVERSION, &version)) { LOGE("could not get driver version for %s, %s\n", deviceName, strerror(errno)); return -1; } if(ioctl(fd, EVIOCGID, &id)) { LOGE("could not get driver id for %s, %s\n", deviceName, strerror(errno)); return -1; } name[sizeof(name) - 1] = '\0'; location[sizeof(location) - 1] = '\0'; idstr[sizeof(idstr) - 1] = '\0'; if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { //fprintf(stderr, "could not get device name for %s, %s\n", deviceName, strerror(errno)); name[0] = '\0'; } // check to see if the device is on our excluded list List<String8>::iterator iter = mExcludedDevices.begin(); List<String8>::iterator end = mExcludedDevices.end(); for ( ; iter != end; iter++) { const char* test = *iter; if (strcmp(name, test) == 0) { LOGI("ignoring event id %s driver %s\n", deviceName, test); close(fd); return -1; } } if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) { //fprintf(stderr, "could not get location for %s, %s\n", deviceName, strerror(errno)); location[0] = '\0'; } if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) { //fprintf(stderr, "could not get idstring for %s, %s\n", deviceName, strerror(errno)); idstr[0] = '\0'; } int devid = 0; while (devid < mNumDevicesById) { if (mDevicesById[devid].device == NULL) { break; } devid++; } if (devid >= mNumDevicesById) { device_ent* new_devids = (device_ent*)realloc(mDevicesById, sizeof(mDevicesById[0]) * (devid + 1)); if (new_devids == NULL) { LOGE("out of memory"); return -1; } mDevicesById = new_devids; mNumDevicesById = devid+1; mDevicesById[devid].device = NULL; mDevicesById[devid].seq = 0; } mDevicesById[devid].seq = (mDevicesById[devid].seq+(1<<SEQ_SHIFT))&SEQ_MASK; if (mDevicesById[devid].seq == 0) { mDevicesById[devid].seq = 1<<SEQ_SHIFT; } new_mFDs = (pollfd*)realloc(mFDs, sizeof(mFDs[0]) * (mFDCount + 1)); new_devices = (device_t**)realloc(mDevices, sizeof(mDevices[0]) * (mFDCount + 1)); if (new_mFDs == NULL || new_devices == NULL) { LOGE("out of memory"); return -1; } mFDs = new_mFDs; mDevices = new_devices; #if 0 LOGI("add device %d: %s\n", mFDCount, deviceName); LOGI(" bus: %04x\n" " vendor %04x\n" " product %04x\n" " version %04x\n", id.bustype, id.vendor, id.product, id.version); LOGI(" name: \"%s\"\n", name); LOGI(" location: \"%s\"\n" " id: \"%s\"\n", location, idstr); LOGI(" version: %d.%d.%d\n", version >> 16, (version >> 8) & 0xff, version & 0xff); #endif device_t* device = new device_t(devid|mDevicesById[devid].seq, deviceName, name); if (device == NULL) { LOGE("out of memory"); return -1; } mFDs[mFDCount].fd = fd; mFDs[mFDCount].events = POLLIN; // figure out the kinds of events the device reports // See if this is a keyboard, and classify it. Note that we only // consider up through the function keys; we don't want to include // ones after that (play cd etc) so we don't mistakenly consider a // controller to be a keyboard. uint8_t key_bitmask[(KEY_MAX+7)/8]; memset(key_bitmask, 0, sizeof(key_bitmask)); LOGV("Getting keys..."); if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) { //LOGI("MAP\n"); //for (int i=0; i<((KEY_MAX+7)/8); i++) { // LOGI("%d: 0x%02x\n", i, key_bitmask[i]); //} for (int i=0; i<((BTN_MISC+7)/8); i++) { if (key_bitmask[i] != 0) { device->classes |= CLASS_KEYBOARD; break; } } if ((device->classes & CLASS_KEYBOARD) != 0) { device->keyBitmask = new uint8_t[sizeof(key_bitmask)]; if (device->keyBitmask != NULL) { memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask)); } else { delete device; LOGE("out of memory allocating key bitmask"); return -1; } } } // See if this is a trackball. if (test_bit(BTN_MOUSE, key_bitmask)) { uint8_t rel_bitmask[(REL_MAX+7)/8]; memset(rel_bitmask, 0, sizeof(rel_bitmask)); LOGV("Getting relative controllers..."); if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0) { if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) { if (test_bit(BTN_LEFT, key_bitmask) && test_bit(BTN_RIGHT, key_bitmask)) device->classes |= CLASS_MOUSE; else device->classes |= CLASS_TRACKBALL; } } } uint8_t abs_bitmask[(ABS_MAX+7)/8]; memset(abs_bitmask, 0, sizeof(abs_bitmask)); LOGV("Getting absolute controllers..."); ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask); // Is this a new modern multi-touch driver? if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask) && test_bit(ABS_MT_POSITION_X, abs_bitmask) && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) { device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT; // Is this an old style single-touch driver? } else if (test_bit(BTN_TOUCH, key_bitmask) && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) { device->classes |= CLASS_TOUCHSCREEN; #ifdef HAVE_TSLIB mTS->fd = fd; //Configure here LOGV("Device name = %s, fd = %d", deviceName,fd); LOGV("tslib: calling ts_config from eventhub\n"); if(ts_config(mTS)) { LOGE("Error in Configuring tslib. Device Name = %s \n", deviceName); } #endif } #ifdef EV_SW // figure out the switches this device reports uint8_t sw_bitmask[(SW_MAX+7)/8]; memset(sw_bitmask, 0, sizeof(sw_bitmask)); if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) { for (int i=0; i<EV_SW; i++) { //LOGI("Device 0x%x sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask)); if (test_bit(i, sw_bitmask)) { if (mSwitches[i] == 0) { mSwitches[i] = device->id; } } } } #endif if ((device->classes&CLASS_KEYBOARD) != 0) { char tmpfn[sizeof(name)]; char keylayoutFilename[300]; // a more descriptive name device->name = name; // replace all the spaces with underscores strcpy(tmpfn, name); for (char *p = strchr(tmpfn, ' '); p && *p; p = strchr(tmpfn, ' ')) *p = '_'; // find the .kl file we need for this device const char* root = getenv("ANDROID_ROOT"); snprintf(keylayoutFilename, sizeof(keylayoutFilename), "%s/usr/keylayout/%s.kl", root, tmpfn); bool defaultKeymap = false; if (access(keylayoutFilename, R_OK)) { snprintf(keylayoutFilename, sizeof(keylayoutFilename), "%s/usr/keylayout/%s", root, "qwerty.kl"); defaultKeymap = true; } device->layoutMap->load(keylayoutFilename); // tell the world about the devname (the descriptive name) if (!mHaveFirstKeyboard && !defaultKeymap && strstr(name, "-keypad")) { // the built-in keyboard has a well-known device ID of 0, // this device better not go away. mHaveFirstKeyboard = true; mFirstKeyboardId = device->id; property_set("hw.keyboards.0.devname", name); } else { // ensure mFirstKeyboardId is set to -something-. if (mFirstKeyboardId == 0) { mFirstKeyboardId = device->id; } } char propName[100]; sprintf(propName, "hw.keyboards.%u.devname", device->id); property_set(propName, name); // 'Q' key support = cheap test of whether this is an alpha-capable kbd if (hasKeycode(device, kKeyCodeQ)) { device->classes |= CLASS_ALPHAKEY; } // See if this has a DPAD. if (hasKeycode(device, kKeyCodeDpadUp) && hasKeycode(device, kKeyCodeDpadDown) && hasKeycode(device, kKeyCodeDpadLeft) && hasKeycode(device, kKeyCodeDpadRight) && hasKeycode(device, kKeyCodeDpadCenter)) { device->classes |= CLASS_DPAD; } LOGI("New keyboard: device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n", device->id, name, propName, keylayoutFilename); } // If the device isn't recognized as something we handle, don't monitor it. if (device->classes == 0) { LOGV("Dropping device %s %p, id = %d\n", deviceName, device, devid); close(fd); delete device; return -1; } LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n", deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes); LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n", deviceName, device, mFDCount, devid, device->classes); mDevicesById[devid].device = device; device->next = mOpeningDevices; mOpeningDevices = device; mDevices[mFDCount] = device; mFDCount++; return 0; }
/* * Opens an input device */ EAPI Ecore_Fb_Input_Device * ecore_fb_input_device_open(const char *dev) { Ecore_Fb_Input_Device *device; unsigned long event_type_bitmask[EV_CNT / 32 + 1]; int event_type; int fd; if(!dev) return NULL; device = calloc(1, sizeof(Ecore_Fb_Input_Device)); if(!device) return NULL; if((fd = open(dev, O_RDONLY, O_NONBLOCK)) < 0) { fprintf(stderr, "[ecore_fb_li:device_open] %s %s", dev, strerror(errno)); goto error_open; } /* query capabilities */ if(ioctl(fd, EVIOCGBIT(0, EV_MAX), event_type_bitmask) < 0) { fprintf(stderr,"[ecore_fb_li:device_open] query capabilities %s %s", dev, strerror(errno)); goto error_caps; } /* query name */ device->info.name = calloc(256, sizeof(char)); if(ioctl(fd, EVIOCGNAME(sizeof(char) * 256), device->info.name) < 0) { fprintf(stderr, "[ecore_fb_li:device_open] get name %s %s", dev, strerror(errno)); strcpy(device->info.name, "Unknown"); } device->fd = fd; device->info.dev = strdup(dev); /* common */ device->mouse.threshold = CLICK_THRESHOLD_DEFAULT; /* set info */ for(event_type = 0; event_type < EV_MAX; event_type++) { if(!test_bit(event_type, event_type_bitmask)) continue; switch(event_type) { case EV_SYN : break; case EV_KEY: device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS; break; case EV_REL: device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_RELATIVE; break; case EV_ABS: device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE; break; case EV_MSC: case EV_LED: case EV_SND: case EV_REP: case EV_FF : case EV_FF_STATUS: case EV_PWR: default: break; } } _ecore_fb_li_devices = eina_list_append(_ecore_fb_li_devices, device); return device; error_caps: close(fd); error_open: free(device); return NULL; }
/* Main function, contains kernel driver event loop */ int main(int argc, char **argv) { char* devname = 0; int doDaemonize = 1; int doWait = 0; int clickMode = 2; int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--debug") == 0) { doDaemonize = 0; debugMode = 1; } else if (strcmp(argv[i], "--wait") == 0) { doWait = 1; } else if (strcmp(argv[i], "--click=first") == 0) { clickMode = 0; } else if (strcmp(argv[i], "--click=second") == 0) { clickMode = 1; } else if (strcmp(argv[i], "--click=center") == 0) { clickMode = 2; } else { devname = argv[i]; } } initGestures(clickMode); if (doDaemonize) { daemonize(); } if (doWait) { /* Wait until all necessary things are loaded */ sleep(10); } /* Connect to X server */ if ((display = XOpenDisplay(NULL)) == NULL) { fprintf(stderr, "Couldn't connect to X server\n"); exit(1); } /* Read X data */ screenNum = DefaultScreen(display); root = RootWindow(display, screenNum); // realDisplayWidth = DisplayWidth(display, screenNum); // realDisplayHeight = DisplayHeight(display, screenNum); WM_CLASS = XInternAtom(display, "WM_CLASS", 0); /* Get notified about new windows */ XSelectInput(display, root, StructureNotifyMask | SubstructureNotifyMask); //TODO load blacklist and profiles from file(s) /* Device file name */ if (devname == 0) { devname = "/dev/twofingtouch"; } /* Try to read from device file */ int fileDesc; if ((fileDesc = open(devname, O_RDONLY)) < 0) { perror("twofing"); return 1; } fd_set fileDescSet; FD_ZERO(&fileDescSet); int eventQueueDesc = XConnectionNumber(display); while (1) { /* Perform initialization at beginning and after module has been re-loaded */ int rd, i; struct input_event ev[64]; char name[256] = "Unknown"; /* Read device name */ ioctl(fileDesc, EVIOCGNAME(sizeof(name)), name); printf("Input device name: \"%s\"\n", name); //TODO activate again? //XSetErrorHandler(invalidWindowHandler); int opcode, event, error; if (!XQueryExtension(display, "RANDR", &opcode, &event, &error)) { printf("X RANDR extension not available.\n"); XCloseDisplay(display); exit(1); } /* Which version of XRandR? We support 1.3 */ int major = 1, minor = 3; if (!XRRQueryVersion(display, &major, &minor)) { printf("XRandR version not available.\n"); XCloseDisplay(display); exit(1); } else if(!(major>1 || (major == 1 && minor >= 3))) { printf("XRandR 1.3 not available. Server supports %d.%d\n", major, minor); XCloseDisplay(display); exit(1); } /* XInput Extension available? */ if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) { printf("X Input extension not available.\n"); XCloseDisplay(display); exit(1); } /* Which version of XI2? We support 2.1 */ major = 2; minor = 1; if (XIQueryVersion(display, &major, &minor) == BadRequest) { printf("XI 2.1 not available. Server supports %d.%d\n", major, minor); XCloseDisplay(display); exit(1); } screenWidth = XDisplayWidth(display, screenNum); screenHeight = XDisplayHeight(display, screenNum); int n; XIDeviceInfo *info = XIQueryDevice(display, XIAllDevices, &n); if (!info) { printf("No XInput devices available\n"); exit(1); } /* Go through input devices and look for that with the same name as the given device */ int devindex; for (devindex = 0; devindex < n; devindex++) { if (info[devindex].use == XIMasterPointer || info[devindex].use == XIMasterKeyboard) continue; if (strcmp(info[devindex].name, name) == 0) { deviceID = info[devindex].deviceid; break; } } if (deviceID == -1) { printf("Input device not found in XInput device list.\n"); exit(1); } XIFreeDeviceInfo(info); if(debugMode) printf("XInput device id is %i.\n", deviceID); /* Prepare by reading calibration */ readCalibrationData(1); /* Receive device property change events */ XIEventMask device_mask2; unsigned char mask_data2[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; device_mask2.deviceid = deviceID; device_mask2.mask_len = sizeof(mask_data2); device_mask2.mask = mask_data2; XISetMask(device_mask2.mask, XI_PropertyEvent); XISetMask(device_mask2.mask, XI_ButtonPress); //XISetMask(device_mask2.mask, XI_TouchBegin); //XISetMask(device_mask2.mask, XI_TouchUpdate); //XISetMask(device_mask2.mask, XI_TouchEnd); XISelectEvents(display, root, &device_mask2, 1); /* Recieve events when screen size changes */ XRRSelectInput(display, root, RRScreenChangeNotifyMask); /* Receive touch events */ /* Needed for XTest to work correctly */ XTestGrabControl(display, True); /* Needed for some reason to receive events */ /* XGrabPointer(display, root, False, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); XUngrabPointer(display, CurrentTime);*/ grab(display, deviceID); printf("Reading input from device ... (interrupt to exit)\n"); /* We perform raw event reading here as X touch events don't seem too reliable */ int currentSlot = 0; /* If we use the legacy protocol, we collect all data of one finger into tempFingerInfo and set it to the correct slot once MT_SYNC occurs. */ FingerInfo tempFingerInfo = { .rawX=0, .rawY=0, .rawZ=0, .id = -1, .slotUsed = 0, .setThisTime = 0 }; while (1) { FD_SET(fileDesc, &fileDescSet); FD_SET(eventQueueDesc, &fileDescSet); select(MAX(fileDesc, eventQueueDesc) + 1, &fileDescSet, NULL, NULL, getEasingStepTimeVal()); checkEasingStep(); if(FD_ISSET(fileDesc, &fileDescSet)) { rd = read(fileDesc, ev, sizeof(struct input_event) * 64); if (rd < (int) sizeof(struct input_event)) { printf("Data stream stopped\n"); break; } for (i = 0; i < rd / sizeof(struct input_event); i++) { if (ev[i].type == EV_SYN) { if (0 == ev[i].code) { // Ev_Sync event end /* All finger data received, so process now. */ if(useLegacyProtocol) { /* Clear slots not set this time */ int i; for(i = 0; i < 2; i++) { if(fingerInfos[i].setThisTime) { fingerInfos[i].setThisTime = 0; } else { /* Clear slot */ fingerInfos[i].slotUsed = 0; } } tempFingerInfo.slotUsed = 0; } processFingers(); } else if (2 == ev[i].code) { // MT_Sync : Multitouch event end if(!useLegacyProtocol) { /* This messsage indicates we use legacy protocol, so switch */ useLegacyProtocol = 1; currentSlot = -1; tempFingerInfo.slotUsed = 0; if(debugMode) printf("Switch to legacy protocol.\n"); } else { if(tempFingerInfo.slotUsed) { /* Finger info for one finger collected in tempFingerInfo, so save it to fingerInfos. */ /* Look for slot to put the data into by looking at the tracking ids */ int index = -1; int i; for(i = 0; i < 2; i++) { if(fingerInfos[i].slotUsed && fingerInfos[i].id == tempFingerInfo.id) { index = i; break; } } if(index == -1) { for(i = 0; i < 2; i++) { if(!fingerInfos[i].slotUsed) { /* "Empty" slot, so we can add it. */ index = i; fingerInfos[i].id = tempFingerInfo.id; fingerInfos[i].slotUsed = 1; break; } } } if(index != -1) { /* Copy temporary data to slot */ fingerInfos[index].setThisTime = 1; fingerInfos[index].rawX = tempFingerInfo.rawX; fingerInfos[index].rawY = tempFingerInfo.rawY; fingerInfos[index].rawZ = tempFingerInfo.rawZ; } } } } } else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) { } else if (ev[i].code == 47) { currentSlot = ev[i].value; if(currentSlot < 0 || currentSlot > 1) currentSlot = -1; } else { /* Set finger info values for current finger */ if (ev[i].code == 57) { /* ABS_MT_TRACKING_ID */ if(currentSlot != -1) { if(ev[i].value == -1) { fingerInfos[currentSlot].slotUsed = 0; } else { fingerInfos[currentSlot].id = ev[i].value; fingerInfos[currentSlot].slotUsed = 1; } } else if(useLegacyProtocol) { tempFingerInfo.id = ev[i].value; tempFingerInfo.slotUsed = 1; } }; if (ev[i].code == 53) { if(currentSlot != -1) { fingerInfos[currentSlot].rawX = ev[i].value; } else if(useLegacyProtocol) { tempFingerInfo.rawX = ev[i].value; } }; if (ev[i].code == 54) { if(currentSlot != -1) { fingerInfos[currentSlot].rawY = ev[i].value; } else if(useLegacyProtocol) { tempFingerInfo.rawY = ev[i].value; } }; if (ev[i].code == 58) { if(currentSlot != -1) { fingerInfos[currentSlot].rawZ = ev[i].value; } else if(useLegacyProtocol) { tempFingerInfo.rawZ = ev[i].value; } }; } } } if(FD_ISSET(eventQueueDesc, &fileDescSet)) { handleXEvent(); } } /* Stream stopped, probably because module has been unloaded */ close(fileDesc); /* Clean up */ releaseButton(); ungrab(display, deviceID); /* Wait until device file is there again */ while ((fileDesc = open(devname, O_RDONLY)) < 0) { sleep(1); } } }
static int vk_init(struct ev *e) { char vk_path[PATH_MAX] = "/sys/board_properties/virtualkeys."; char vks[2048], *ts = NULL; ssize_t len; int vk_fd; int i; e->vk_count = 0; len = strlen(vk_path); len = ioctl(e->fd->fd, EVIOCGNAME(sizeof(e->deviceName)), e->deviceName); if (len <= 0) { printf("Unable to query event object.\n"); return -1; } #ifdef _EVENT_LOGGING printf("Event object: %s\n", e->deviceName); #endif // Blacklist these "input" devices if (strcmp(e->deviceName, "bma250") == 0 || strcmp(e->deviceName, "bma150") == 0 || strcmp(e->deviceName, "accelerometer") == 0) { e->ignored = 1; } strcat(vk_path, e->deviceName); // Some devices split the keys from the touchscreen e->vk_count = 0; vk_fd = open(vk_path, O_RDONLY); if (vk_fd >= 0) { len = read(vk_fd, vks, sizeof(vks)-1); close(vk_fd); if (len <= 0) return -1; vks[len] = '\0'; /* Parse a line like: keytype:keycode:centerx:centery:width:height:keytype2:keycode2:centerx2:... */ for (ts = vks, e->vk_count = 1; *ts; ++ts) { if (*ts == ':') ++e->vk_count; } if (e->vk_count % 6) { printf("minui: %s is %d %% 6\n", vk_path, e->vk_count % 6); } e->vk_count /= 6; if (e->vk_count <= 0) return -1; e->down = DOWN_NOT; } ioctl(e->fd->fd, EVIOCGABS(ABS_X), &e->p.xi); ioctl(e->fd->fd, EVIOCGABS(ABS_Y), &e->p.yi); e->p.synced = 0; #ifdef _EVENT_LOGGING printf("EV: ST minX: %d maxX: %d minY: %d maxY: %d\n", e->p.xi.minimum, e->p.xi.maximum, e->p.yi.minimum, e->p.yi.maximum); #endif ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_X), &e->mt_p.xi); ioctl(e->fd->fd, EVIOCGABS(ABS_MT_POSITION_Y), &e->mt_p.yi); e->mt_p.synced = 0; #ifdef _EVENT_LOGGING printf("EV: MT minX: %d maxX: %d minY: %d maxY: %d\n", e->mt_p.xi.minimum, e->mt_p.xi.maximum, e->mt_p.yi.minimum, e->mt_p.yi.maximum); #endif e->vks = malloc(sizeof(*e->vks) * e->vk_count); for (i = 0; i < e->vk_count; ++i) { char *token[6]; int j; for (j = 0; j < 6; ++j) { token[j] = vk_strtok_r((i||j)?NULL:vks, ":", &ts); } if (strcmp(token[0], "0x01") != 0) { /* Java does string compare, so we do too. */ printf("minui: %s: ignoring unknown virtual key type %s\n", vk_path, token[0]); continue; } e->vks[i].scancode = strtol(token[1], NULL, 0); e->vks[i].centerx = strtol(token[2], NULL, 0); e->vks[i].centery = strtol(token[3], NULL, 0); e->vks[i].width = strtol(token[4], NULL, 0); e->vks[i].height = strtol(token[5], NULL, 0); } return 0; }
/* * list_input_devices - Show a human-readable list of all input devices * the current user has permissions to read from. * Add info wether this probably can be "muted" in X11 if requested */ int list_input_devices () { int i, fd; char buf[sizeof(EVDEVNAME)+8]; struct input_id device_info; char namebuf[256]; char *xinlist; FILE *pf; char *p, *q; char x11 = 0; if ( NULL == ( xinlist = malloc ( 4096 ) ) ) { printf ( "Memory alloc error\n" ); return 1; } bzero ( xinlist, 4096 ); if ( NULL != ( pf = popen ("xinput --list --name-only", "r" ) ) ) { if ( 1 > fread ( xinlist, 1, 4095, pf ) ) { printf ( "\tx11-mutable information not available.\n" ); } fclose ( pf ); } printf ( "List of available input devices:\n"); printf ( "num\tVendor/Product, Name, -x compatible (x/-)\n" ); for ( i = 0; i < MAXEVDEVS; ++i ) { sprintf ( buf, EVDEVNAME, i ); fd = open ( buf, O_RDONLY ); if ( fd < 0 ) { if ( errno == ENOENT ) { i = MAXEVDEVS ; break; } if ( errno == EACCES ) { printf ( "%2d:\t[permission denied]\n", i ); } continue; } if ( ioctl ( fd, EVIOCGID, &device_info ) < 0 ) { close(fd); continue; } if ( ioctl ( fd, EVIOCGNAME(sizeof(namebuf)-4), namebuf+2) < 0 ) { close(fd); continue; } namebuf[sizeof(namebuf)-4] = 0; x11 = 0; p = xinlist; while ( ( p != NULL ) && ( *p != 0 ) ) { if ( NULL == ( q = strchr ( p, 0x0a ) ) ) { break; } *q = 0; if ( strcmp ( p, namebuf + 2 ) == 0 ) { x11 = 1; } *q = 0x0a; while ( (*q > 0) && (*q <= 0x20 ) ) { ++q; } p = q; } printf("%2d\t[%04hx:%04hx.%04hx] '%s' (%s)", i, device_info.vendor, device_info.product, device_info.version, namebuf + 2, x11 ? "+" : "-"); printf("\n"); close ( fd ); } free ( xinlist ); return 0; }
/* * initevents () - opens all required event files * or only the ones specified by evdevmask, if evdevmask != 0 * try to disable in X11 if mutex11 is set to 1 * returns number of successfully opened event file nodes, or <1 for error */ int initevents ( unsigned int evdevmask, int mutex11 ) { int i, j, k; char buf[sizeof(EVDEVNAME)+8]; char *xinlist = NULL; FILE *pf; char *p, *q; if ( mutex11 ) { if ( NULL == ( xinlist = malloc ( 4096 ) ) ) { printf ( "Memory alloc error\n" ); return 0; } bzero ( xinlist, 4096 ); if ( NULL != ( pf = popen ("xinput --list --short", "r" ) ) ) { if ( 1 > fread ( xinlist, 1, 3800, pf ) ) { printf ( "\tx11-mutable information not available.\n" ); free ( xinlist ); xinlist = NULL; } } fclose ( pf ); } for ( i = 0; i < MAXEVDEVS; ++i ) { eventdevs[i] = -1; x11handles[i] = -1; } for ( i = j = 0; j < MAXEVDEVS; ++j ) { if ( ( evdevmask != 0 ) && ( ( evdevmask & ( 1 << j ) ) == 0 ) ) { continue; } sprintf ( buf, EVDEVNAME, j ); eventdevs[i] = open ( buf, O_RDONLY ); if ( 0 <= eventdevs[i] ) { fprintf ( stdout, "Opened %s as event device [counter %d]\n", buf, i ); if ( ( mutex11 > 0 ) && ( xinlist != NULL ) ) { k = -1; xinlist[3801] = 0; if ( ioctl(eventdevs[i], EVIOCGNAME(256),xinlist+3801) >= 0 ) { p = xinlist; xinlist[4056] = 0; if ( strlen(xinlist+3801) < 4 ) // min lenght for name p = xinlist + 4056; while ( (*p != 0) && ( NULL != ( p = strstr ( p, xinlist+3801 ) ) ) ) { q = p + strlen(xinlist+3801); while ( *q == ' ' ) ++q; if ( strncmp ( q, "\tid=", 4 ) == 0 ) { k = atoi ( q + 4 ); p = xinlist + 4056; } else { p = q; } } } if ( k >= 0 ) { sprintf ( xinlist+3801, "xinput set-int-prop %d \"Device "\ "Enabled\" 8 0", k ); if ( system ( xinlist + 3801 ) ) { fprintf ( stderr, "Failed to x11-mute.\n" ); } x11handles[i] = k; } } ++i; } } if ( xinlist != NULL ) { free ( xinlist ); } return i; }
void CRCInput::open() { close(); fd_tdt_rc_event_driver = -1; for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) { if ((fd_rc[i] = ::open(RC_EVENT_DEVICE[i], O_RDONLY)) == -1) perror(RC_EVENT_DEVICE[i]); else { char name[80]; ioctl(fd_rc[i], EVIOCGNAME(sizeof(name)), name); if(!strcmp("TDT RC event driver", name)) fd_tdt_rc_event_driver = fd_rc[i]; fcntl(fd_rc[i], F_SETFL, O_NONBLOCK); } } if (fd_tdt_rc_event_driver < 0) fd_tdt_rc_event_driver = fd_rc[0]; //+++++++++++++++++++++++++++++++++++++++ #ifdef KEYBOARD_INSTEAD_OF_REMOTE_CONTROL fd_keyb = STDIN_FILENO; fd_tdt_rc_event_driver = STDIN_FILENO; #else fd_keyb = 0; #endif /* KEYBOARD_INSTEAD_OF_REMOTE_CONTROL */ /* ::open("/dev/dbox/rc0", O_RDONLY); if (fd_keyb<0) { perror("/dev/stdin"); exit(-1); } */ #ifdef KEYBOARD_INSTEAD_OF_REMOTE_CONTROL ::fcntl(fd_keyb, F_SETFL, O_NONBLOCK); struct termio new_termio; ::ioctl(STDIN_FILENO, TCGETA, &orig_termio); saved_orig_termio = true; new_termio = orig_termio; new_termio.c_lflag &= ~ICANON; // new_termio.c_lflag &= ~(ICANON|ECHO); new_termio.c_cc[VMIN ] = 1; new_termio.c_cc[VTIME] = 0; ::ioctl(STDIN_FILENO, TCSETA, &new_termio); #else //fcntl(fd_keyb, F_SETFL, O_NONBLOCK ); //+++++++++++++++++++++++++++++++++++++++ #endif /* KEYBOARD_INSTEAD_OF_REMOTE_CONTROL */ open_click(); calculateMaxFd(); }
int main(void) { TEST_NULL_ARG(EVIOCGVERSION); TEST_NULL_ARG(EVIOCGEFFECTS); TEST_NULL_ARG(EVIOCGID); TEST_NULL_ARG(EVIOCGKEYCODE); TEST_NULL_ARG(EVIOCSKEYCODE); TEST_NULL_ARG(EVIOCSFF); # ifdef EVIOCGKEYCODE_V2 TEST_NULL_ARG(EVIOCGKEYCODE_V2); # endif # ifdef EVIOCSKEYCODE_V2 TEST_NULL_ARG(EVIOCSKEYCODE_V2); # endif # ifdef EVIOCGREP TEST_NULL_ARG(EVIOCGREP); # endif # ifdef EVIOCSREP TEST_NULL_ARG(EVIOCSREP); # endif # ifdef EVIOCSCLOCKID TEST_NULL_ARG(EVIOCSCLOCKID); # endif TEST_NULL_ARG(EVIOCGNAME(0)); TEST_NULL_ARG(EVIOCGPHYS(0)); TEST_NULL_ARG(EVIOCGUNIQ(0)); TEST_NULL_ARG(EVIOCGKEY(0)); TEST_NULL_ARG(EVIOCGLED(0)); # ifdef EVIOCGMTSLOTS TEST_NULL_ARG(EVIOCGMTSLOTS(0)); # endif # ifdef EVIOCGPROP TEST_NULL_ARG(EVIOCGPROP(0)); # endif TEST_NULL_ARG(EVIOCGSND(0)); # ifdef EVIOCGSW TEST_NULL_ARG(EVIOCGSW(0)); # endif TEST_NULL_ARG(EVIOCGABS(ABS_X)); TEST_NULL_ARG(EVIOCSABS(ABS_X)); TEST_NULL_ARG(EVIOCGBIT(EV_SYN, 0)); TEST_NULL_ARG(EVIOCGBIT(EV_KEY, 1)); TEST_NULL_ARG(EVIOCGBIT(EV_REL, 2)); TEST_NULL_ARG(EVIOCGBIT(EV_ABS, 3)); TEST_NULL_ARG(EVIOCGBIT(EV_MSC, 4)); # ifdef EV_SW TEST_NULL_ARG(EVIOCGBIT(EV_SW, 5)); # endif TEST_NULL_ARG(EVIOCGBIT(EV_LED, 6)); TEST_NULL_ARG(EVIOCGBIT(EV_SND, 7)); TEST_NULL_ARG(EVIOCGBIT(EV_REP, 8)); TEST_NULL_ARG(EVIOCGBIT(EV_FF, 9)); TEST_NULL_ARG(EVIOCGBIT(EV_PWR, 10)); TEST_NULL_ARG(EVIOCGBIT(EV_FF_STATUS, 11)); ioctl(-1, EVIOCGBIT(EV_MAX, 42), 0); printf("ioctl(-1, EVIOCGBIT(%#x /* EV_??? */, 42), NULL)" " = -1 EBADF (%m)\n", EV_MAX); ioctl(-1, EVIOCRMFF, lmagic); printf("ioctl(-1, EVIOCRMFF, %d) = -1 EBADF (%m)\n", (int) lmagic); ioctl(-1, EVIOCGRAB, lmagic); printf("ioctl(-1, EVIOCGRAB, %lu) = -1 EBADF (%m)\n", lmagic); # ifdef EVIOCREVOKE ioctl(-1, EVIOCREVOKE, lmagic); printf("ioctl(-1, EVIOCREVOKE, %lu) = -1 EBADF (%m)\n", lmagic); # endif const unsigned int size = get_page_size(); void *const page = tail_alloc(size); fill_memory(page, size); int *const val_int = tail_alloc(sizeof(*val_int)); *val_int = magic; # ifdef EVIOCSCLOCKID ioctl(-1, EVIOCSCLOCKID, val_int); printf("ioctl(-1, EVIOCSCLOCKID, [%u]) = -1 EBADF (%m)\n", *val_int); # endif int *pair_int = tail_alloc(sizeof(*pair_int) * 2); pair_int[0] = 0xdeadbeef; pair_int[1] = 0xbadc0ded; # ifdef EVIOSGREP ioctl(-1, EVIOCSREP, pair_int); printf("ioctl(-1, EVIOCSREP, [%u, %u]) = -1 EBADF (%m)\n", pair_int[0], pair_int[1]); # endif pair_int[1] = 1; ioctl(-1, EVIOCSKEYCODE, pair_int); printf("ioctl(-1, EVIOCSKEYCODE, [%u, %s]) = -1 EBADF (%m)\n", pair_int[0], "KEY_ESC"); # ifdef EVIOCSKEYCODE_V2 struct input_keymap_entry *const ike = tail_alloc(sizeof(*ike)); fill_memory(ike, sizeof(*ike)); ike->keycode = 2; ioctl(-1, EVIOCSKEYCODE_V2, ike); printf("ioctl(-1, EVIOCSKEYCODE_V2, {flags=%" PRIu8 ", len=%" PRIu8 ", ", ike->flags, ike->len); # if VERBOSE printf("index=%" PRIu16 ", keycode=%s, scancode=[", ike->index, "KEY_1"); unsigned int i; for (i = 0; i < ARRAY_SIZE(ike->scancode); ++i) { if (i > 0) printf(", "); printf("%" PRIx8, ike->scancode[i]); } printf("]"); # else printf("..."); # endif errno = EBADF; printf("}) = -1 EBADF (%m)\n"); # endif struct ff_effect *const ffe = tail_alloc(sizeof(*ffe)); fill_memory(ffe, sizeof(*ffe)); ffe->type = FF_CONSTANT; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "FF_CONSTANT"); # if VERBOSE printf(", constant={level=%hd", ffe->u.constant.level); print_envelope(&ffe->u.constant.envelope); printf("}"); # else printf("..."); # endif errno = EBADF; printf("}) = -1 EBADF (%m)\n"); # if VERBOSE ffe->type = FF_RAMP; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "FF_RAMP"); printf(", ramp={start_level=%hd, end_level=%hd", ffe->u.ramp.start_level, ffe->u.ramp.end_level); print_envelope(&ffe->u.ramp.envelope); errno = EBADF; printf("}}) = -1 EBADF (%m)\n"); ffe->type = FF_PERIODIC; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "FF_PERIODIC"); printf(", periodic={waveform=%hu, period=%hu, magnitude=%hd" ", offset=%hd, phase=%hu", ffe->u.periodic.waveform, ffe->u.periodic.period, ffe->u.periodic.magnitude, ffe->u.periodic.offset, ffe->u.periodic.phase); print_envelope(&ffe->u.periodic.envelope); printf(", custom_len=%u, custom_data=%p}", ffe->u.periodic.custom_len, ffe->u.periodic.custom_data); errno = EBADF; printf("}) = -1 EBADF (%m)\n"); ffe->type = FF_RUMBLE; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "FF_RUMBLE"); printf(", rumble={strong_magnitude=%hu, weak_magnitude=%hu}", ffe->u.rumble.strong_magnitude, ffe->u.rumble.weak_magnitude); errno = EBADF; printf("}) = -1 EBADF (%m)\n"); ffe->type = 0xff; ioctl(-1, EVIOCSFF, ffe); print_ffe_common(ffe, "0xff /* FF_??? */"); errno = EBADF; printf("}) = -1 EBADF (%m)\n"); # endif ioctl(-1, _IOC(_IOC_READ, 0x45, 0x1, 0xff), lmagic); printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", "_IOC(_IOC_READ, 0x45, 0x1, 0xff)", lmagic); ioctl(-1, _IOC(_IOC_WRITE, 0x45, 0x1, 0xff), lmagic); printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", "_IOC(_IOC_WRITE, 0x45, 0x1, 0xff)", lmagic); ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, 0x45, 0xfe, 0xff), lmagic); printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", "_IOC(_IOC_READ|_IOC_WRITE, 0x45, 0xfe, 0xff)", lmagic); ioctl(-1, _IOC(_IOC_READ|_IOC_WRITE, 0x45, 0, 0), lmagic); printf("ioctl(-1, %s, %#lx) = -1 EBADF (%m)\n", "_IOC(_IOC_READ|_IOC_WRITE, 0x45, 0, 0)", lmagic); puts("+++ exited with 0 +++"); return 0; }
void print_info(int fd) { char buf[100]; int version; struct input_id id; char evtype[(EV_MAX+7)/8]; int i; if(ioctl(fd, EVIOCGNAME(100), buf) == -1) { if(errno == ENOTTY) // sim return; perror("Failed to get device name"); } else printf("Device: %s\n", buf); if(ioctl(fd, EVIOCGID, &id) == -1) perror("Failed to get device id"); else { switch(id.bustype) { case BUS_PCI: printf("Bustype PCI "); break; case BUS_ISAPNP: printf("Bustype ISAPNP "); break; case BUS_USB: printf("Bustype USB "); break; case BUS_HIL: printf("Bustype HIL "); break; case BUS_BLUETOOTH: printf("Bustype BLUETOOTH "); break; case BUS_VIRTUAL: printf("Bustype VIRTUAL "); break; case BUS_ISA: printf("Bustype ISA "); break; case BUS_I8042: printf("Bustype I8042 "); break; case BUS_XTKBD: printf("Bustype XTKBD "); break; case BUS_RS232: printf("Bustype RS232 "); break; case BUS_GAMEPORT: printf("Bustype GAMEPORT "); break; case BUS_PARPORT: printf("Bustype PARPORT "); break; case BUS_AMIGA: printf("Bustype AMIGA "); break; case BUS_ADB: printf("Bustype ADB "); break; case BUS_I2C: printf("Bustype I2C "); break; case BUS_HOST: printf("Bustype HOST "); break; case BUS_GSC: printf("Bustype GSC "); break; case BUS_ATARI: printf("Bustype ATARI "); break; case BUS_SPI: printf("Bustype SPI "); break; default: printf("Bustype unknown(%04hx) ", id.bustype); } printf("Vendor %04hx ", id.vendor); printf("Product %04hx ", id.product); printf("Version %04hx\n", id.version); } if(ioctl(fd, EVIOCGVERSION, &version) == -1) perror("Failed to get driver version"); else printf("Driver: %i.%i.%i\n", version>>16, (version>>8) & 0xff, version & 0xff); if(ioctl(fd, EVIOCGBIT(0, EV_MAX), &evtype) == -1) perror("Failed to get event types"); else { printf("Events: "); for(i=0; i<EV_MAX; i++) if(evtype[i/8] & (1<<(i%8))) printf("%s ", strevent(i)); printf("\n"); } }
static struct orng_device_info * read_devinfo(struct orng_device_info *devinfo, int with_scancodes, int fd) { int i; char buf[1024]; __u32 sc; __u16 j; int res = 0; __u32 nsc; memset(devinfo, 0, sizeof(*devinfo)); /* device identifier */ if (ioctl(fd, EVIOCGID, &devinfo->id) < 0) { fprintf(stderr, "ioctl(EVIOCGID): %s\n", strerror(errno)); goto err_ioctl; } /* event bits */ if (ioctl(fd, EVIOCGBIT(0, sizeof(devinfo->evbit)), devinfo->evbit) < 0) { fprintf(stderr, "ioctl(EVIOCGBIT(0)): %s\n", strerror(errno)); goto err_ioctl; } /* keys */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_KEY)) { if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(devinfo->keybit)), devinfo->keybit) < 0) { fprintf(stderr, "ioctl(EVIOCGBIT(EV_KEY)): %s\n", strerror(errno)); goto err_ioctl; } /* key state */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_KEY)) { if (ioctl(fd, EVIOCGKEY(sizeof(devinfo->key)), devinfo->key) < 0) { fprintf(stderr, "ioctl(EVIOCGKEY(%zu)): %s\n", sizeof(buf), strerror(errno)); goto err_ioctl; } } /* read mapping between scan codes and key codes */ if (with_scancodes) { nsc = 1ul<<((CHAR_BIT*sizeof(devinfo->keymap[0][0]))-1); for (sc = 0, j = 0; sc < nsc; ++sc) { int map[2] = {sc, 0}; int res = ioctl(fd, EVIOCGKEYCODE, map); if (res < 0) { if (errno != EINVAL) { fprintf(stderr, "ioctl: %s\n", strerror(errno)); goto err_ioctl; } } else { /* save mapping */ devinfo->keymap[j][0] = map[0]; /* scan code */ devinfo->keymap[j][1] = map[1]; /* key code */ ++j; if (j >= sizeof(devinfo->keymap)/sizeof(devinfo->keymap[0])) { break; } } } } } /* relative positioning */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_REL)) { if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(devinfo->relbit)), devinfo->relbit) < 0) { fprintf(stderr, "ioctl(EVIOCGBIT(EV_REL)): %s\n", strerror(errno)); goto err_ioctl; } } /* absolute positioning */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_ABS)) { if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(devinfo->absbit)), devinfo->absbit) < 0) { fprintf(stderr, "ioctl(EVIOCGBIT(EV_ABS)): %s\n", strerror(errno)); goto err_ioctl; } /* limits */ for (i = 0; i <= ABS_MAX; ++i) { if (TEST_ARRAY_BIT(devinfo->absbit, i)) { if (ioctl(fd, EVIOCGABS(i), devinfo->absinfo+i) < 0) { fprintf(stderr, "ioctl(EVIOCGABS(%d)): %s\n", i, strerror(errno)); goto err_ioctl; } } } } /* misc */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_MSC)) { if (ioctl(fd, EVIOCGBIT(EV_MSC, sizeof(devinfo->mscbit)), devinfo->mscbit) < 0) { fprintf(stderr, "ioctl(EVIOCGBIT(EV_MSC)): %s\n", strerror(errno)); goto err_ioctl; } } /* LEDs */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_LED)) { if (ioctl(fd, EVIOCGBIT(EV_LED, sizeof(devinfo->ledbit)), devinfo->ledbit) < 0) { fprintf(stderr, "ioctl(EVIOCGBIT(EV_LED)): %s\n", strerror(errno)); goto err_ioctl; } /* LED state */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_LED)) { if (ioctl(fd, EVIOCGLED(sizeof(devinfo->led)), devinfo->led) < 0) { fprintf(stderr, "ioctl(EVIOCGLED(%zu)): %s\n", sizeof(buf), strerror(errno)); goto err_ioctl; } } } /* sound */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_SND)) { if (ioctl(fd, EVIOCGBIT(EV_SND, sizeof(devinfo->sndbit)), devinfo->sndbit) < 0) { fprintf(stderr, "ioctl(EVIOCGBIT(EV_SND)): %s\n", strerror(errno)); goto err_ioctl; } /* sound state */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_SW)) { if (ioctl(fd, EVIOCGSND(sizeof(devinfo->snd)), devinfo->snd) < 0) { fprintf(stderr, "ioctl(EVIOCGSND(%zu)): %s\n", sizeof(buf), strerror(errno)); goto err_ioctl; } } } /* force feedback */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_FF)) { if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(devinfo->ffbit)), devinfo->ffbit) < 0) { fprintf(stderr, "ioctl(EVIOCGBIT(EV_FF)): %s\n", strerror(errno)); goto err_ioctl; } } /* switches */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_SW)) { if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(devinfo->swbit)), devinfo->swbit) < 0) { fprintf(stderr, "ioctl(EVIOCGBIT(EV_SW)): %s\n", strerror(errno)); goto err_ioctl; } /* switch state */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_SW)) { if (ioctl(fd, EVIOCGSW(sizeof(devinfo->sw)), devinfo->sw) < 0) { fprintf(stderr, "ioctl(EVIOCGSW(%zu)): %s\n", sizeof(buf), strerror(errno)); goto err_ioctl; } } } /* auto repeat */ if (TEST_ARRAY_BIT(devinfo->evbit, EV_REP)) { if (ioctl(fd, EVIOCGREP, devinfo->rep) < 0) { fprintf(stderr, "ioctl(EVIOCGREP): %s\n", strerror(errno)); goto err_ioctl; } } /* name */ memset(buf, 0, sizeof(buf)); do { res = ioctl(fd, EVIOCGNAME(sizeof(buf)), buf); } while ((res < 0) && (errno == EINTR)); if (res >= 0) { devinfo->name = strndup(buf, sizeof(buf)-1); if (!devinfo->name) { fprintf(stderr, "strdup: %s\n", strerror(errno)); goto err_strdup_name; } } else if (errno != ENOENT) { fprintf(stderr, "ioctl(EVIOCGPHYS(%lu)): %s\n", (unsigned long)sizeof(buf), strerror(errno)); goto err_ioctl; } /* physical location */ memset(buf, 0, sizeof(buf)); do { res = ioctl(fd, EVIOCGPHYS(sizeof(buf)), buf); } while ((res < 0) && (errno == EINTR)); if (res >= 0) { devinfo->phys = strndup(buf, sizeof(buf)-1); if (!devinfo->phys) { fprintf(stderr, "strdup: %s\n", strerror(errno)); goto err_strdup_phys; } } else if (errno != ENOENT) { fprintf(stderr, "ioctl(EVIOCGPHYS(%lu)): %s\n", (unsigned long)sizeof(buf), strerror(errno)); goto err_ioctl; } /* unique identifier */ memset(buf, 0, sizeof(buf)); do { res = ioctl(fd, EVIOCGUNIQ(sizeof(buf)), buf); } while ((res < 0) && (errno == EINTR)); if (res >= 0) { devinfo->uniq = strndup(buf, sizeof(buf)-1); if (!devinfo->uniq) { fprintf(stderr, "strdup: %s\n", strerror(errno)); goto err_strdup_uniq; } } else if (errno != ENOENT) { fprintf(stderr, "ioctl(EVIOCGUNIQ(%lu)): %s\n", (unsigned long)sizeof(buf), strerror(errno)); goto err_ioctl; } return devinfo; err_strdup_uniq: free(devinfo->phys); err_strdup_phys: err_ioctl_gphys: free(devinfo->name); err_strdup_name: err_ioctl: return NULL; }
/**************************************************************************** * * @brief * Fukncija koja se treba kreirati kao poseban thread, a predstavlja beskonacnu petlju koja se vrti, * i u slucaju pritiska dugmeta na daljinskom upravljacu aktivira se odgovarajuca callback funkcija. * * * * *****************************************************************************/ void* remoteControlThread(void* nn) { const char* dev = "/dev/input/event0"; char deviceName[20]; struct input_event* eventBuf; uint32_t eventCnt; uint32_t i; uint32_t service_number = 1; uint32_t tmp_number; uint32_t tmp_number2; inputFileDesc = open(dev, O_RDWR); if (inputFileDesc == -1) { printf("Error while opening device (%s) !", strerror(errno)); return; } ioctl(inputFileDesc, EVIOCGNAME(sizeof (deviceName)), deviceName); printf("RC device opened succesfully [%s]\n", deviceName); eventBuf = malloc(NUM_EVENTS * sizeof (struct input_event)); if (!eventBuf) { printf("Error allocating memory !"); return; } tmp_number = service_number; while (NON_STOP) { if (getKeys(NUM_EVENTS, (uint8_t*) eventBuf, &eventCnt)) { printf("Error while reading input events !"); return; } for (i = 0; i < eventCnt; i++) { if (eventBuf[i].value == 1 && eventBuf[i].type == 1) { tmp_number2 = service_number; switch (eventBuf[i].code) { case REMOTE_BTN_PROGRAM_PLUS: if (sectionNumberCallback(service_number + 1) == NO_ERROR) { service_number++; } break; case REMOTE_BTN_PROGRAM_MINUS: if (sectionNumberCallback(service_number - 1) == NO_ERROR) { service_number--; } break; case REMOTE_BTN_VOLUME_PLUS: if (volumeCallback != NULL) { volumeCallback(VOLUME_PLUS); } break; case REMOTE_BTN_VOLUME_MINUS: if (volumeCallback != NULL) { volumeCallback(VOLUME_MINUS); } break; case REMOTE_BTN_MUTE: printf(" MUTE\n"); if (volumeCallback != NULL) { volumeCallback(VOLUME_MUTE); } break; case REMOTE_BTN_INFO: if (infoCallback != NULL) { infoCallback(1); } break; case REMOTE_BTN_EXIT: free(eventBuf); return; default: tmp_number = remoteCheckServiceNumberCode(eventBuf[i].code); if (tmp_number != -1) { // printf("****Service number: %d tmp_number\n", service_number); if (sectionNumberCallback(tmp_number) == NO_ERROR) { service_number = tmp_number; } } } } } } }
int main(int argc,char* argv[]) { int fd; int read_num = 0, opt = 0; fprintf(stderr,"input device test v0.1\n"); fprintf(stderr,"This program was compiled at %s %s\n",__DATE__,__TIME__); fprintf(stderr,"Author: [email protected]\n"); while ((opt = getopt(argc, argv, "hr:")) != -1) { switch (opt) { case 'r': read_num = atoi(optarg); break; case 'h': default: usage(argv[0]); return 0; } } if (optind >= argc) { usage(argv[0]); return -1; } char devpath[256] = "\0"; if(argv[optind][0] != '/'){ strcpy(devpath,"/dev/input/"); } strcat(devpath,argv[optind]); printf("event driver: %s\n", devpath); // if((file = open(str, O_RDWR|O_NONBLOCK)) < 0) if((fd = open(devpath, O_RDWR)) < 0) { perror("device can not open"); return -2; } //Listing 1. Sample EVIOCGVERSION Function /* ioctl() accesses the underlying driver */ int version = 0; if (ioctl(fd, EVIOCGVERSION, &version)) { perror("EVIOCGVERSION"); } /* the EVIOCGVERSION ioctl() returns an int */ /* so we unpack it and display it */ printf("\tversion is %d.%d.%d\n", version >> 16, (version >> 8) & 0xff, version & 0xff); //Listing 3. Sample EVIOCGID ioctl /* suck out some device information */ struct input_id device_info; if(ioctl(fd, EVIOCGID, &device_info)) { perror("EVIOCGVERSION"); } /* the EVIOCGID ioctl() returns input_devinfo * structure - see <linux/input.h> * So we work through the various elements, * displaying each of them */ printf("\tvendor %04hx product %04hx version %04hx", device_info.vendor, device_info.product, device_info.version); switch ( device_info.bustype) { case BUS_PCI : printf(" is on a PCI bus\n"); break; case BUS_USB : printf(" is on a Universal Serial Bus\n"); break; case BUS_I2C : printf(" is on BUS_I2C\n"); break; default: printf(" is on an unknow bus %x\n",(unsigned int)device_info.bustype); break; } //Listing 4. get name char name[256]= "Unknown"; if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) { perror("EVIOCGNAME"); } printf("\tname is %s\n", name); //Listing 5. Using EVIOCGPHYS for Topology Information char phys[256]= "\0"; if(ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys) < 0) { //perror("EVIOCGPHYS "); } printf("\tphys is %s\n", phys); //Listing 6. Finding a Unique Identifier char uniq[256]= "\0"; if(ioctl(fd, EVIOCGUNIQ(sizeof(uniq)), uniq) < 0) { //perror("EVIOCGUNIQ"); } printf("\tidentity is %s\n", uniq); printf("\n"); //Listing 7. Determining Features with EVIOCGBIT unsigned char evtype_b[(EV_MAX >> 3) +1]; memset(evtype_b, 0, sizeof(evtype_b)); if (ioctl(fd, EVIOCGBIT(0, EV_MAX), evtype_b) < 0) { perror("EVIOCGBIT"); } printf("Supported event types %x:\n",evtype_b[0]); int yalv = 0; for (yalv = 0; yalv < EV_MAX; yalv++) { if (test_bit(yalv, evtype_b)) { /* the bit is set in the event types list */ printf(" Event type 0x%02x ", yalv); switch ( yalv) { case EV_SYN : printf(" (Synch Events)\n"); break; case EV_KEY : printf(" (Keys or Buttons)\n"); break; case EV_REL : printf(" (Relative Axes)\n"); break; case EV_ABS : printf(" (Absolute Axes)\n"); break; case EV_MSC : printf(" (Miscellaneous)\n"); break; case EV_LED : printf(" (LEDs)\n"); break; case EV_SND : printf(" (Sounds)\n"); break; case EV_REP : printf(" (Repeat)\n"); break; case EV_FF : case EV_FF_STATUS: printf(" (Force Feedback)\n"); break; case EV_PWR: printf(" (Power Management)\n"); break; default: printf(" (Unknown: 0x%04hx)\n", yalv); } } } //Listing 11. Using EVIOCGLED unsigned char led_b[64]; memset(led_b, 0, sizeof(led_b)); if(ioctl(fd, EVIOCGLED(sizeof(led_b)), led_b)<0){ perror("EVIOCGLED"); return -11; } for (yalv = 0; yalv < LED_MAX; yalv++) { if (test_bit(yalv, led_b)) { /* the bit is set in the LED state */ printf(" LED 0x%02x ", yalv); switch ( yalv) { case LED_NUML : printf(" (Num Lock)\n"); break; case LED_CAPSL : printf(" (Caps Lock)\n"); break; /* other LEDs not shown here*/ default: printf(" (Unknown LED: 0x%04hx)\n", yalv); } } } printf("\n"); //Listing 8. Checking for Busy Spots /* how many bytes were read */ size_t rb; /* the events (up to 64 at once) */ struct input_event ev[64]; while(read_num-- > 0){ rb=read(fd,ev,sizeof(struct input_event)*64); if (rb < (int) sizeof(struct input_event)) { perror("evtest: short read"); return -10; } for (yalv = 0; yalv < (int) (rb / sizeof(struct input_event)); yalv++) { printf("%ld.%06ld ",ev[yalv].time.tv_sec,ev[yalv].time.tv_usec); printf("type %d code %03d 0x%03x value %d\n", ev[yalv].type, ev[yalv].code,ev[yalv].code,ev[yalv].value); if (0 == ev[yalv].type) printf("\n"); } //printf("\n"); } close(fd); return 0; }
void Gamepad_detectDevices() { unsigned int numPaths; char ** gamepadPaths; bool duplicate; unsigned int pathIndex, gamepadIndex; struct stat statBuf; struct Gamepad_device * deviceRecord; struct Gamepad_devicePrivate * deviceRecordPrivate; int fd; char name[128]; char * description; int evKeyBits[(KEY_CNT - 1) / sizeof(int) * 8 + 1]; int evAbsBits[(ABS_CNT - 1) / sizeof(int) * 8 + 1]; int bit; struct input_id id; if (!inited) { return; } gamepadPaths = findGamepadPaths(&numPaths); pthread_mutex_lock(&devicesMutex); for (pathIndex = 0; pathIndex < numPaths; pathIndex++) { duplicate = false; for (gamepadIndex = 0; gamepadIndex < numDevices; gamepadIndex++) { if (!strcmp(((struct Gamepad_devicePrivate *) devices[gamepadIndex]->privateData)->path, gamepadPaths[pathIndex])) { duplicate = true; break; } } if (duplicate) { free(gamepadPaths[pathIndex]); continue; } if (!stat(gamepadPaths[pathIndex], &statBuf)) { deviceRecord = (Gamepad_device*)malloc(sizeof(struct Gamepad_device)); deviceRecord->deviceID = nextDeviceID++; deviceRecord->eventDispatcher = EventDispatcher_create(deviceRecord); devices = (Gamepad_device**)realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1)); devices[numDevices++] = deviceRecord; fd = open(gamepadPaths[pathIndex], O_RDONLY, 0); deviceRecordPrivate = (Gamepad_devicePrivate*)malloc(sizeof(struct Gamepad_devicePrivate)); deviceRecordPrivate->fd = fd; deviceRecordPrivate->path = gamepadPaths[pathIndex]; memset(deviceRecordPrivate->buttonMap, 0xFF, sizeof(deviceRecordPrivate->buttonMap)); memset(deviceRecordPrivate->axisMap, 0xFF, sizeof(deviceRecordPrivate->axisMap)); deviceRecord->privateData = deviceRecordPrivate; if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) > 0) { description = (char*)malloc(strlen(name + 1)); strcpy(description, name); } else { description = (char*)malloc(strlen(gamepadPaths[pathIndex] + 1)); strcpy(description, gamepadPaths[pathIndex]); } deviceRecord->description = description; if (!ioctl(fd, EVIOCGID, &id)) { deviceRecord->vendorID = id.vendor; deviceRecord->productID = id.product; } else { deviceRecord->vendorID = deviceRecord->productID = 0; } memset(evKeyBits, 0, sizeof(evKeyBits)); memset(evAbsBits, 0, sizeof(evAbsBits)); ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evKeyBits)), evKeyBits); ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evAbsBits)), evAbsBits); deviceRecord->numAxes = 0; for (bit = 0; bit < ABS_CNT; bit++) { if (test_bit(bit, evAbsBits)) { if (ioctl(fd, EVIOCGABS(bit), &deviceRecordPrivate->axisInfo[bit]) < 0 || deviceRecordPrivate->axisInfo[bit].minimum == deviceRecordPrivate->axisInfo[bit].maximum) { continue; } deviceRecordPrivate->axisMap[bit] = deviceRecord->numAxes; deviceRecord->numAxes++; } } deviceRecord->numButtons = 0; for (bit = BTN_MISC; bit < KEY_CNT; bit++) { if (test_bit(bit, evKeyBits)) { deviceRecordPrivate->buttonMap[bit - BTN_MISC] = deviceRecord->numButtons; deviceRecord->numButtons++; } } deviceRecord->axisStates = (float*)calloc(sizeof(float), deviceRecord->numAxes); deviceRecord->buttonStates = (bool*)calloc(sizeof(bool), deviceRecord->numButtons); Gamepad_eventDispatcher()->dispatchEvent(Gamepad_eventDispatcher(), GAMEPAD_EVENT_DEVICE_ATTACHED, deviceRecord); pthread_create(&deviceRecordPrivate->thread, NULL, deviceThread, deviceRecord); } } pthread_mutex_unlock(&devicesMutex); }
int input_evdev_init(EvdevController* controller, const char* device, const char* custom_mapping_fname = NULL) { load_libevdev(); char name[256] = "Unknown"; printf("evdev: Trying to open device at '%s'\n", device); int fd = open(device, O_RDWR); if (fd >= 0) { fcntl(fd, F_SETFL, O_NONBLOCK); if(ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) { perror("evdev: ioctl"); return -2; } else { printf("evdev: Found '%s' at '%s'\n", name, device); controller->fd = fd; const char* mapping_fname; if(custom_mapping_fname != NULL) { mapping_fname = custom_mapping_fname; } else { #if defined(TARGET_PANDORA) mapping_fname = "controller_pandora.cfg"; #elif defined(TARGET_GCW0) mapping_fname = "controller_gcwz.cfg"; #else if (strcmp(name, "Microsoft X-Box 360 pad") == 0 || strcmp(name, "Xbox 360 Wireless Receiver") == 0 || strcmp(name, "Xbox 360 Wireless Receiver (XBOX)") == 0) { mapping_fname = "controller_xpad.cfg"; } else if (strstr(name, "Xbox Gamepad (userspace driver)") != NULL) { mapping_fname = "controller_xboxdrv.cfg"; } else if (strstr(name, "keyboard") != NULL || strstr(name, "Keyboard") != NULL) { mapping_fname = "keyboard.cfg"; } else { mapping_fname = "controller_generic.cfg"; } #endif } if(loaded_mappings.count(string(mapping_fname)) == 0) { FILE* mapping_fd = NULL; if(mapping_fname[0] == '/') { // Absolute mapping mapping_fd = fopen(mapping_fname, "r"); } else { // Mapping from ~/.reicast/mappings/ size_t size_needed = snprintf(NULL, 0, EVDEV_MAPPING_PATH, mapping_fname) + 1; char* mapping_path = (char*)malloc(size_needed); sprintf(mapping_path, EVDEV_MAPPING_PATH, mapping_fname); mapping_fd = fopen(get_readonly_data_path(mapping_path).c_str(), "r"); free(mapping_path); } if(mapping_fd != NULL) { printf("evdev: reading mapping file: '%s'\n", mapping_fname); loaded_mappings.insert(std::make_pair(string(mapping_fname), load_mapping(mapping_fd))); fclose(mapping_fd); } else { printf("evdev: unable to open mapping file '%s'\n", mapping_fname); perror("evdev"); return -3; } } controller->mapping = &loaded_mappings[string(mapping_fname)]; printf("evdev: Using '%s' mapping\n", controller->mapping->name); controller->init(); return 0; } } else { perror("evdev: open"); return -1; } }
evio_handle evio_open(const char *devpath) { evio *evp = NULL; int fd; if ((fd = open(devpath, O_RDONLY, 0)) < 0) { printf("Failed to open device '%s' ...\n", devpath); return NULL; } evp = (evio *) calloc(1, sizeof(evio)); evp->fd = fd; strncpy(evp->devpath, devpath, sizeof(evp->devpath)); if (ioctl(evp->fd, EVIOCGNAME(sizeof(evp->devname)), evp->devname) < 0) { printf("Error) EVIOCGNAME ...\n"); free(evp); return NULL; } if ((ioctl(evp->fd, EVIOCGBIT(0, sizeof(evp->evbit)), evp->evbit) < 0) || (ioctl(evp->fd, EVIOCGBIT(EV_KEY, sizeof(evp->keybit)), evp->keybit) < 0) || (ioctl(evp->fd, EVIOCGBIT(EV_ABS, sizeof(evp->absbit)), evp->absbit) < 0) || (ioctl(evp->fd, EVIOCGBIT(EV_REL, sizeof(evp->relbit)), evp->relbit) < 0)) { printf("Error) ioctl() calls ...\n"); free(evp); return NULL; } /* * classify device as joystick, spaceball, or something else * see if it has buttons and absolute x/y position at a minimum */ if (EVIO_TESTBIT(EV_KEY, evp->evbit) && EVIO_TESTBIT(EV_ABS, evp->evbit) && EVIO_TESTBIT(ABS_X, evp->absbit) && EVIO_TESTBIT(ABS_Y, evp->absbit) && EVIO_TESTBIT(ABS_RX, evp->absbit) && EVIO_TESTBIT(ABS_RY, evp->absbit)) { evp->devjoystick = EVENTIO_JOYSTICK_LOGIF310; } if (!evp->devjoystick && EVIO_TESTBIT(EV_KEY, evp->evbit) && EVIO_TESTBIT(EV_ABS, evp->evbit) && EVIO_TESTBIT(ABS_X, evp->absbit) && EVIO_TESTBIT(ABS_Y, evp->absbit) && EVIO_TESTBIT(ABS_Z, evp->absbit) && EVIO_TESTBIT(ABS_RZ, evp->absbit)) { evp->devjoystick = EVENTIO_JOYSTICK_NYKO; } if (!evp->devjoystick && EVIO_TESTBIT(EV_KEY, evp->evbit) && EVIO_TESTBIT(EV_ABS, evp->evbit) && EVIO_TESTBIT(ABS_X, evp->absbit) && EVIO_TESTBIT(ABS_Y, evp->absbit)) { evp->devjoystick = EVENTIO_JOYSTICK_STD; } /* see if it has buttons and relative x/y/z rx/ry/rz at a minimum */ if (!evp->devjoystick && EVIO_TESTBIT(EV_KEY, evp->evbit) && EVIO_TESTBIT(EV_REL, evp->evbit) && EVIO_TESTBIT(REL_X, evp->relbit) && EVIO_TESTBIT(REL_Y, evp->relbit) && EVIO_TESTBIT(REL_Z, evp->relbit) && EVIO_TESTBIT(REL_RX, evp->relbit) && EVIO_TESTBIT(REL_RY, evp->relbit) && EVIO_TESTBIT(REL_RZ, evp->relbit)) { evp->devspaceball = EVENTIO_SPACEBALL_STD; } /* query device ID info */ if (ioctl(evp->fd, EVIOCGID, &evp->devid) < 0) { printf("Error) EVIOCGID ...\n"); free(evp); return NULL; } fcntl(evp->fd, F_SETFL, O_NONBLOCK); /* set device to non-blocking I/O */ return evp; }
void QInputDeviceScanner::scan() { for( int index = 0; index < MAX_INPUT_DEVICES; index++ ) { QString devInput = QString("/dev/input"); QString devEvent = devInput + "/event" + QString::number(index); QFile fileEvent; fileEvent.setFileName(devEvent); if( fileEvent.open(QIODevice::ReadOnly) ) { char name[256] = "Unknown"; char phys[256] = ""; if( ::ioctl(fileEvent.handle(), EVIOCGNAME(sizeof(name)), name) < 0 ) { // qWarning("Cannot get the name of device"); } if( ::ioctl(fileEvent.handle(), EVIOCGPHYS(sizeof(phys)), phys) < 0 ) { // qWarning("Cannot get the physical location"); } QString deviceName = QString(name); QString devicePhys = QString(phys); if( devicePhys.startsWith("usb-dev") ) { unsigned long evbit[NBITS(EV_MAX + 1)]; if( ::ioctl(fileEvent.handle(), EVIOCGBIT(0, sizeof(evbit)), evbit) >= 0 ) { if( IS_BIT_SET(EV_REL, evbit) ) { qDebug() << QString("Found Mouse: ") << devEvent; m_listOfMouse.append(devEvent); } else if( IS_BIT_SET(EV_KEY, evbit) && ! IS_BIT_SET(EV_REL, evbit) && ! IS_BIT_SET(EV_ABS, evbit) ) { qDebug() << QString("Found Keyboard: ") << devEvent; m_listOfKeyboard.append(devEvent); } } } else if(deviceName.contains("M-RCU - Builtin")) { qDebug() << QString("Found Motion: ") << devEvent; m_listOfMotion.append(devEvent); } fileEvent.close(); } } }
static void ljoy_scan(bool configure) { int fd; ALLEGRO_JOYSTICK_LINUX *joy, **joypp; int num; ALLEGRO_USTR *device_name; unsigned i; /* Clear mark bits. */ for (i = 0; i < _al_vector_size(&joysticks); i++) { joypp = _al_vector_ref(&joysticks, i); joy = *joypp; joy->marked = false; } device_name = al_ustr_new(""); /* This is a big number, but there can be gaps and other unrelated event * device files. Perhaps it would be better to use glob() here. */ for (num = 0; num < 32; num++) { if (!ljoy_detect_device_name(num, device_name)) continue; joy = ljoy_by_device_name(device_name); if (joy) { ALLEGRO_DEBUG("Device %s still exists\n", al_cstr(device_name)); joy->marked = true; continue; } /* Try to open the device. The device must be opened in O_RDWR mode to * allow writing of haptic effects! The haptic driver for linux * reuses the joystick driver's fd. */ fd = open(al_cstr(device_name), O_RDWR|O_NONBLOCK); if (fd == -1) { ALLEGRO_WARN("Failed to open device %s\n", al_cstr(device_name)); continue; } /* The device must have at least one joystick-related axis, and one * joystick-related button. Some devices, such as mouse pads, have ABS_X * and ABS_Y axes like a joystick but not joystick-related buttons. By * checking for both axes and buttons, such devices can be excluded. */ if (!have_joystick_button(fd) || !have_joystick_axis(fd)) { ALLEGRO_DEBUG("Device %s not a joystick\n", al_cstr(device_name)); close(fd); continue; } ALLEGRO_DEBUG("Device %s is new\n", al_cstr(device_name)); joy = ljoy_allocate_structure(); joy->fd = fd; joy->device_name = al_ustr_dup(device_name); joy->config_state = LJOY_STATE_BORN; joy->marked = true; config_needs_merging = true; if (ioctl(fd, EVIOCGNAME(sizeof(joy->name)), joy->name) < 0) strcpy(joy->name, "Unknown"); /* Map Linux input API axis and button numbers to ours, and fill in * information. */ if (!fill_joystick_axes(joy, fd) || !fill_joystick_buttons(joy, fd)) { ALLEGRO_ERROR("fill_joystick_info failed %s\n", al_cstr(device_name)); inactivate_joy(joy); close(fd); continue; } /* Register the joystick with the fdwatch subsystem. */ _al_unix_start_watching_fd(joy->fd, ljoy_process_new_data, joy); } al_ustr_free(device_name); /* Schedule unmarked structures to be inactivated. */ for (i = 0; i < _al_vector_size(&joysticks); i++) { joypp = _al_vector_ref(&joysticks, i); joy = *joypp; if (joy->config_state == LJOY_STATE_ALIVE && !joy->marked) { ALLEGRO_DEBUG("Device %s to be inactivated\n", al_cstr(joy->device_name)); joy->config_state = LJOY_STATE_DYING; config_needs_merging = true; } } /* Generate a configure event if necessary. * Even if we generated one before that the user hasn't responded to, * we don't know if the user received it so always generate it. */ if (config_needs_merging && configure) { ljoy_generate_configure_event(); } }
int main(int argc, char *argv[]) { int opt, j, ret; int fd; int options = 0; #define OPT_INFO 1 #define OPT_GRAB 2 #define OPT_LONG 4 #define OPT_INITIAL 0x08 #define OPT_QUIT 0x10 char *device; struct pollfd pollfd = { .events = POLLIN, }; struct input_event evs[16]; /* parse program options */ while ((opt = getopt_long(argc, argv, optstring, long_opts, NULL)) != -1) switch (opt) { case 'V': fprintf(stderr, "%s: %s\n", NAME, VERSION); return 0; case 'i': options |= OPT_INFO; break; case '0': if (options & OPT_INITIAL) options |= OPT_QUIT; options |= OPT_INITIAL; break; case 'g': options |= OPT_GRAB; break; case 'l': options |= OPT_LONG; if (optarg) { double dtime = strtod(optarg, NULL); if (dtime > 0.001) { tlong.tv_sec = lround(floor(dtime)); tlong.tv_usec = lround(dtime * 1e6) % 1000000; } } break; case 'm': if (inputeventloadmap(optarg) < 0) elog(1, errno, "load map from '%s'", optarg); break; default: fprintf(stderr, "%s: option '%c' unrecognised\n", NAME, opt); case '?': fputs(help_msg, stderr); exit(1); } device = argv[optind]; if (!device) { fprintf(stderr, "No device given\n"); fputs(help_msg, stderr); exit(1); } if (options & OPT_LONG) { keytimes = malloc(sizeof(*keytimes) * KEY_CNT); if (!keytimes) elog(1, errno, "malloc keycache\n"); } fd = open(device, O_RDONLY); if (fd < 0) elog(1, errno, "open %s\n", device); /* show info when requested */ if (options & OPT_INFO) { char name[64]; char phys[64]; struct input_id id; if (ioctl(fd, EVIOCGID, &id) < 0) elog(1, errno, "ioctl %s EVIOCGID\n", device); if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0) elog(1, errno, "ioctl %s EVIOCGNAME\n", device); if (ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys) < 0) elog(1, errno, "ioctl %s EVIOCGPHYS\n", device); printf("### %s\n", device); printf("name: %s\n", name); printf("phys: %s\n", phys); printf("bus: %u\n", id.bustype); printf("vendor: 0x%04x\n", id.vendor); printf("product: 0x%04x\n", id.product); printf("version: %u\n", id.version); return 0; } if (options & OPT_GRAB) { int value = 1; if (ioctl(fd, EVIOCGRAB, &value) < 0) elog(1, errno, "Grab %s failed\n", device); } if (argv[++optind]) { /* fork child process */ int pp[2]; if (pipe(pp) < 0) elog(1, errno, "pipe() failed\n"); ret = fork(); if (ret < 0) elog(1, errno, "fork() failed\n"); else if (!ret) { dup2(pp[0], STDIN_FILENO); close(pp[0]); close(pp[1]); close(fd); execvp(argv[optind], argv+optind); elog(1, errno, "execvp %s ...", argv[optind]); } dup2(pp[1], STDOUT_FILENO); close(pp[0]); close(pp[1]); } if (options & OPT_INITIAL) { char state[KEY_CNT/8+1]; int j; if (ioctl(fd, EVIOCGKEY(sizeof(state)), state) < 0) elog(1, errno, "ioctl %s EVIOCGKEY\n", device); for (j = 0; j < KEY_CNT; ++j) { if (state[j/8] & (1 << (j % 8))) printf("i %s 1\n", inputeventtostr(EV_KEY, j)); } if (ioctl(fd, EVIOCGSW(sizeof(state)), state) < 0) elog(1, errno, "ioctl %s EVIOCGKEY\n", device); for (j = 0; j < SW_CNT; ++j) { if (state[j/8] & (1 << (j % 8))) printf("i %s 1\n", inputeventtostr(EV_SW, j)); } if (options & OPT_QUIT) return 0; fflush(stdout); } /* prepare main loop */ pollfd.fd = fd; while (1) { libt_flush(); ret = poll(&pollfd, 1, libt_get_waittime()); if (ret < 0) elog(1, errno, "poll"); if (!ret) continue; ret = read(fd, evs, sizeof(evs)); if (ret < 0) elog(1, errno, "read input"); for (j = 0; j < ret/sizeof(*evs); ++j) { if ((options & OPT_LONG) && (evs[j].type == EV_KEY) && !evs[j].value && !libt_timeout_exist(keytimeout, (void *)(long)evs[j].code)) /* long press detection timeout has already passed */ continue; if ((evs[j].type == EV_KEY) && keytimes && (evs[j].code < KEY_CNT)) { /* do longpress detection */ if (evs[j].value == 1) { keytimes[evs[j].code] = evs[j].time; libt_add_timeout(dtlong, keytimeout, (void *)(long)evs[j].code); } else if (!evs[j].value && libt_timeout_exist(keytimeout, (void *)(long)evs[j].code)) /* no long press detected yet */ libt_remove_timeout(keytimeout, (void *)(long)evs[j].code); else /* long press detected, or autorepeat */ continue; } printf("%lu.%06lu %s %i\n", evs[j].time.tv_sec, evs[j].time.tv_usec, inputeventtostr(evs[j].type, evs[j].code), evs[j].value); } fflush(stdout); } return 0; }
status_t EvdevDeviceNode::queryProperties() { char buffer[80]; if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGNAME(sizeof(buffer) - 1), buffer)) < 1) { ALOGV("could not get device name for %s.", mPath.c_str()); } else { buffer[sizeof(buffer) - 1] = '\0'; mName = buffer; } int driverVersion; if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGVERSION, &driverVersion))) { ALOGE("could not get driver version for %s. err=%d", mPath.c_str(), errno); return -errno; } struct input_id inputId; if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGID, &inputId))) { ALOGE("could not get device input id for %s. err=%d", mPath.c_str(), errno); return -errno; } mBusType = inputId.bustype; mVendorId = inputId.vendor; mProductId = inputId.product; mVersion = inputId.version; if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGPHYS(sizeof(buffer) - 1), buffer)) < 1) { ALOGV("could not get location for %s.", mPath.c_str()); } else { buffer[sizeof(buffer) - 1] = '\0'; mLocation = buffer; } if (TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGUNIQ(sizeof(buffer) - 1), buffer)) < 1) { ALOGV("could not get unique id for %s.", mPath.c_str()); } else { buffer[sizeof(buffer) - 1] = '\0'; mUniqueId = buffer; } ALOGV("add device %s", mPath.c_str()); ALOGV(" bus: %04x\n" " vendor: %04x\n" " product: %04x\n" " version: %04x\n", mBusType, mVendorId, mProductId, mVersion); ALOGV(" name: \"%s\"\n" " location: \"%s\"\n" " unique_id: \"%s\"\n" " descriptor: (TODO)\n" " driver: v%d.%d.%d", mName.c_str(), mLocation.c_str(), mUniqueId.c_str(), driverVersion >> 16, (driverVersion >> 8) & 0xff, (driverVersion >> 16) & 0xff); TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_KEY, sizeof(mKeyBitmask)), mKeyBitmask)); TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_ABS, sizeof(mAbsBitmask)), mAbsBitmask)); TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_REL, sizeof(mRelBitmask)), mRelBitmask)); TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_SW, sizeof(mSwBitmask)), mSwBitmask)); TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_LED, sizeof(mLedBitmask)), mLedBitmask)); TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGBIT(EV_FF, sizeof(mFfBitmask)), mFfBitmask)); TEMP_FAILURE_RETRY(ioctl(mFd, EVIOCGPROP(sizeof(mPropBitmask)), mPropBitmask)); queryAxisInfo(); return OK; }
status_t EventHub::openDeviceLocked(const char *devicePath) { char buffer[80]; ALOGV("Opening device: %s", devicePath); int fd = open(devicePath, O_RDWR); if(fd < 0) { LOGE("could not open %s, %s\n", devicePath, strerror(errno)); return -1; } InputDeviceIdentifier identifier; // Get device name. if(ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) { //fprintf(stderr, "could not get device name for %s, %s\n", devicePath, strerror(errno)); } else { buffer[sizeof(buffer) - 1] = '\0'; identifier.name.setTo(buffer); } // Check to see if the device is on our excluded list for (size_t i = 0; i < mExcludedDevices.size(); i++) { const String8& item = mExcludedDevices.itemAt(i); if (identifier.name == item) { LOGI("ignoring event id %s driver %s\n", devicePath, item.string()); close(fd); return -1; } } // Get device driver version. int driverVersion; if(ioctl(fd, EVIOCGVERSION, &driverVersion)) { LOGE("could not get driver version for %s, %s\n", devicePath, strerror(errno)); close(fd); return -1; } // Get device identifier. struct input_id inputId; if(ioctl(fd, EVIOCGID, &inputId)) { LOGE("could not get device input id for %s, %s\n", devicePath, strerror(errno)); close(fd); return -1; } identifier.bus = inputId.bustype; identifier.product = inputId.product; identifier.vendor = inputId.vendor; identifier.version = inputId.version; // Get device physical location. if(ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) { //fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno)); } else { buffer[sizeof(buffer) - 1] = '\0'; identifier.location.setTo(buffer); } // Get device unique id. if(ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) { //fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno)); } else { buffer[sizeof(buffer) - 1] = '\0'; identifier.uniqueId.setTo(buffer); } // Make file descriptor non-blocking for use with poll(). if (fcntl(fd, F_SETFL, O_NONBLOCK)) { LOGE("Error %d making device file descriptor non-blocking.", errno); close(fd); return -1; } // Allocate device. (The device object takes ownership of the fd at this point.) int32_t deviceId = mNextDeviceId++; Device* device = new Device(fd, deviceId, String8(devicePath), identifier); #if 0 LOGI("add device %d: %s\n", deviceId, devicePath); LOGI(" bus: %04x\n" " vendor %04x\n" " product %04x\n" " version %04x\n", identifier.bus, identifier.vendor, identifier.product, identifier.version); LOGI(" name: \"%s\"\n", identifier.name.string()); LOGI(" location: \"%s\"\n", identifier.location.string()); LOGI(" unique id: \"%s\"\n", identifier.uniqueId.string()); LOGI(" driver: v%d.%d.%d\n", driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff); #endif // Load the configuration file for the device. loadConfigurationLocked(device); // Figure out the kinds of events the device reports. ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(device->keyBitmask)), device->keyBitmask); ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(device->absBitmask)), device->absBitmask); ioctl(fd, EVIOCGBIT(EV_REL, sizeof(device->relBitmask)), device->relBitmask); ioctl(fd, EVIOCGBIT(EV_SW, sizeof(device->swBitmask)), device->swBitmask); ioctl(fd, EVIOCGBIT(EV_LED, sizeof(device->ledBitmask)), device->ledBitmask); ioctl(fd, EVIOCGPROP(sizeof(device->propBitmask)), device->propBitmask); // See if this is a keyboard. Ignore everything in the button range except for // joystick and gamepad buttons which are handled like keyboards for the most part. bool haveKeyboardKeys = containsNonZeroByte(device->keyBitmask, 0, sizeof_bit_array(BTN_MISC)) || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(KEY_OK), sizeof_bit_array(KEY_MAX + 1)); bool haveGamepadButtons = containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_MISC), sizeof_bit_array(BTN_MOUSE)) || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_JOYSTICK), sizeof_bit_array(BTN_DIGI)); if (haveKeyboardKeys || haveGamepadButtons) { device->classes |= INPUT_DEVICE_CLASS_KEYBOARD; } // See if this is a cursor device such as a trackball or mouse. if (test_bit(BTN_MOUSE, device->keyBitmask) && test_bit(REL_X, device->relBitmask) && test_bit(REL_Y, device->relBitmask)) { device->classes |= INPUT_DEVICE_CLASS_CURSOR; } // See if this is a touch pad. // Is this a new modern multi-touch driver? if (test_bit(ABS_MT_POSITION_X, device->absBitmask) && test_bit(ABS_MT_POSITION_Y, device->absBitmask)) { // Some joysticks such as the PS3 controller report axes that conflict // with the ABS_MT range. Try to confirm that the device really is // a touch screen. if (test_bit(BTN_TOUCH, device->keyBitmask) || !haveGamepadButtons) { device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT; } // Is this an old style single-touch driver? } else if (test_bit(BTN_TOUCH, device->keyBitmask) && test_bit(ABS_X, device->absBitmask) && test_bit(ABS_Y, device->absBitmask)) { device->classes |= INPUT_DEVICE_CLASS_TOUCH; } // See if this device is a joystick. // Assumes that joysticks always have gamepad buttons in order to distinguish them // from other devices such as accelerometers that also have absolute axes. if (haveGamepadButtons) { uint32_t assumedClasses = device->classes | INPUT_DEVICE_CLASS_JOYSTICK; for (int i = 0; i <= ABS_MAX; i++) { if (test_bit(i, device->absBitmask) && (getAbsAxisUsage(i, assumedClasses) & INPUT_DEVICE_CLASS_JOYSTICK)) { device->classes = assumedClasses; break; } } } // Check whether this device has switches. for (int i = 0; i <= SW_MAX; i++) { if (test_bit(i, device->swBitmask)) { device->classes |= INPUT_DEVICE_CLASS_SWITCH; break; } } // Configure virtual keys. if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) { // Load the virtual keys for the touch screen, if any. // We do this now so that we can make sure to load the keymap if necessary. status_t status = loadVirtualKeyMapLocked(device); if (!status) { device->classes |= INPUT_DEVICE_CLASS_KEYBOARD; } } // Load the key map. // We need to do this for joysticks too because the key layout may specify axes. status_t keyMapStatus = NAME_NOT_FOUND; if (device->classes & (INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_JOYSTICK)) { // Load the keymap for the device. keyMapStatus = loadKeyMapLocked(device); } // Configure the keyboard, gamepad or virtual keyboard. if (device->classes & INPUT_DEVICE_CLASS_KEYBOARD) { // Register the keyboard as a built-in keyboard if it is eligible. if (!keyMapStatus && mBuiltInKeyboardId == -1 && isEligibleBuiltInKeyboard(device->identifier, device->configuration, &device->keyMap)) { mBuiltInKeyboardId = device->id; } // 'Q' key support = cheap test of whether this is an alpha-capable kbd if (hasKeycodeLocked(device, AKEYCODE_Q)) { device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; } // See if this device has a DPAD. if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) && hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) && hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) && hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) && hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) { device->classes |= INPUT_DEVICE_CLASS_DPAD; } // See if this device has a gamepad. for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]); i++) { if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) { device->classes |= INPUT_DEVICE_CLASS_GAMEPAD; break; } } } // If the device isn't recognized as something we handle, don't monitor it. if (device->classes == 0) { ALOGV("Dropping device: id=%d, path='%s', name='%s'", deviceId, devicePath, device->identifier.name.string()); delete device; return -1; } // Determine whether the device is external or internal. if (isExternalDeviceLocked(device)) { device->classes |= INPUT_DEVICE_CLASS_EXTERNAL; } // Register with epoll. struct epoll_event eventItem; memset(&eventItem, 0, sizeof(eventItem)); eventItem.events = EPOLLIN; eventItem.data.u32 = deviceId; if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) { LOGE("Could not add device fd to epoll instance. errno=%d", errno); delete device; return -1; } LOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, " "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s", deviceId, fd, devicePath, device->identifier.name.string(), device->classes, device->configurationFile.string(), device->keyMap.keyLayoutFile.string(), device->keyMap.keyCharacterMapFile.string(), toString(mBuiltInKeyboardId == deviceId)); mDevices.add(deviceId, device); device->next = mOpeningDevices; mOpeningDevices = device; return 0; }
static unsigned char send_device_info(IEContext* ctx, unsigned int reply_id) { dterm_mark_t msg; dterm_t dt; int len = 0; char name[256]; char topology[256]; char uniq_id[256]; struct input_id id; // Get device id. if (ioctl(ctx->mDescriptor, EVIOCGID, &id) < 0) { return IEDRV_RES_IO_ERROR; } if ((len = ioctl(ctx->mDescriptor, EVIOCGNAME(sizeof(name) - 1), name)) < 0) { return IEDRV_RES_IO_ERROR; } name[len] = 0; if ((len = ioctl(ctx->mDescriptor, EVIOCGPHYS(sizeof(topology) - 1), topology)) < 0) { return IEDRV_RES_IO_ERROR; } topology[len] = 0; if ((len = ioctl(ctx->mDescriptor, EVIOCGUNIQ(sizeof(uniq_id) - 1), uniq_id)) < 0) uniq_id[0] = 0; uniq_id[len] = 0; dterm_init(&dt); dterm_tuple_begin(&dt, &msg); { dterm_mark_t prop; dterm_atom(&dt, ie_device_info); dterm_port(&dt, ctx->mDport); dterm_int(&dt, reply_id); // // Setup { id, Bustype, Vendor, Product, Version, Name} // dterm_tuple_begin(&dt, &prop); { dterm_atom(&dt, ie_drv_dev_id); dterm_string(&dt, uniq_id, strlen(uniq_id)); dterm_string(&dt, name, strlen(name)); dterm_atom(&dt, *bus_atoms[id.bustype]); dterm_int(&dt, id.vendor); dterm_int(&dt, id.product); dterm_int(&dt, id.version); dterm_string(&dt, topology, strlen(topology)); // // Setup [{ capability, [ { Cap, [X] }, { Cap, [Y] }, ...}, ...] // add_cap(&dt, ctx->mDescriptor); dterm_tuple_end(&dt, &prop); } } dterm_tuple_end(&dt, &msg); driver_output_term(ctx->mPort, dterm_data(&dt), dterm_used_size(&dt)); dterm_finish(&dt); return IEDRV_RES_OK; }
static int SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item) { int ret, i; char name[64]; struct input_absinfo abs_info; if (!item->is_touchscreen) return 0; item->touchscreen_data = SDL_calloc(1, sizeof(*item->touchscreen_data)); if (item->touchscreen_data == NULL) return SDL_OutOfMemory(); ret = ioctl(item->fd, EVIOCGNAME(sizeof(name)), name); if (ret < 0) { SDL_free(item->touchscreen_data); return SDL_SetError("Failed to get evdev touchscreen name"); } item->touchscreen_data->name = SDL_strdup(name); if (item->touchscreen_data->name == NULL) { SDL_free(item->touchscreen_data); return SDL_OutOfMemory(); } ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_X), &abs_info); if (ret < 0) { SDL_free(item->touchscreen_data->name); SDL_free(item->touchscreen_data); return SDL_SetError("Failed to get evdev touchscreen limits"); } item->touchscreen_data->min_x = abs_info.minimum; item->touchscreen_data->max_x = abs_info.maximum; item->touchscreen_data->range_x = abs_info.maximum - abs_info.minimum; ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_Y), &abs_info); if (ret < 0) { SDL_free(item->touchscreen_data->name); SDL_free(item->touchscreen_data); return SDL_SetError("Failed to get evdev touchscreen limits"); } item->touchscreen_data->min_y = abs_info.minimum; item->touchscreen_data->max_y = abs_info.maximum; item->touchscreen_data->range_y = abs_info.maximum - abs_info.minimum; ret = ioctl(item->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info); if (ret < 0) { SDL_free(item->touchscreen_data->name); SDL_free(item->touchscreen_data); return SDL_SetError("Failed to get evdev touchscreen limits"); } item->touchscreen_data->max_slots = abs_info.maximum + 1; item->touchscreen_data->slots = SDL_calloc( item->touchscreen_data->max_slots, sizeof(*item->touchscreen_data->slots)); if (item->touchscreen_data->slots == NULL) { SDL_free(item->touchscreen_data->name); SDL_free(item->touchscreen_data); return SDL_OutOfMemory(); } for(i = 0; i < item->touchscreen_data->max_slots; i++) { item->touchscreen_data->slots[i].tracking_id = -1; } ret = SDL_AddTouch(item->fd, /* I guess our fd is unique enough */ item->touchscreen_data->name); if (ret < 0) { SDL_free(item->touchscreen_data->slots); SDL_free(item->touchscreen_data->name); SDL_free(item->touchscreen_data); return ret; } return 0; }
void X11_InitTouch(_THIS) { #ifdef SDL_INPUT_LINUXEV FILE *fd; fd = fopen("/proc/bus/input/devices","r"); char c; int i = 0; char line[256]; char tstr[256]; int vendor = -1,product = -1,event = -1; while(!feof(fd)) { if(fgets(line,256,fd) <=0) continue; if(line[0] == '\n') { if(vendor == 1386) { /*printf("Wacom... Assuming it is a touch device\n");*/ /*sprintf(tstr,"/dev/input/event%i",event);*/ /*printf("At location: %s\n",tstr);*/ SDL_Touch touch; touch.pressure_max = 0; touch.pressure_min = 0; touch.id = event; touch.driverdata = SDL_malloc(sizeof(EventTouchData)); EventTouchData* data = (EventTouchData*)(touch.driverdata); data->x = -1; data->y = -1; data->pressure = -1; data->finger = 0; data->up = SDL_FALSE; data->eventStream = open(tstr, O_RDONLY | O_NONBLOCK); ioctl (data->eventStream, EVIOCGNAME (sizeof (tstr)), tstr); int abs[5]; ioctl(data->eventStream,EVIOCGABS(0),abs); touch.x_min = abs[1]; touch.x_max = abs[2]; touch.native_xres = touch.x_max - touch.x_min; ioctl(data->eventStream,EVIOCGABS(ABS_Y),abs); touch.y_min = abs[1]; touch.y_max = abs[2]; touch.native_yres = touch.y_max - touch.y_min; ioctl(data->eventStream,EVIOCGABS(ABS_PRESSURE),abs); touch.pressure_min = abs[1]; touch.pressure_max = abs[2]; touch.native_pressureres = touch.pressure_max - touch.pressure_min; SDL_AddTouch(&touch, tstr); } vendor = -1; product = -1; event = -1; } else if(line[0] == 'I') { i = 1; while(line[i]) { sscanf(&line[i],"Vendor=%x",&vendor); sscanf(&line[i],"Product=%x",&product); i++; } } else if(line[0] == 'H') { i = 1; while(line[i]) { sscanf(&line[i],"event%d",&event); i++; } } } close(fd); #endif }
int main(int argc, char* argv[]) { bcm_host_init(); // get an EGL display connection display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!display) { printf("Failed to get display\n"); return 1; } // initialize the EGL display connection //EGLBoolean result; if (!eglInitialize(display, NULL, NULL)) { printf("Failed to initialize EGL\n"); return 1; } // get an appropriate EGL frame buffer configuration static const EGLint attributeList[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; EGLConfig config; EGLint numConfig; if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig)) { printf("Failed to choose EGL config\n"); return 1; } // get an appropriate EGL frame buffer configuration if (!eglBindAPI(EGL_OPENGL_ES_API)) { printf("Failed to bind OpenGL ES API\n"); return 1; } // create an EGL rendering context static const EGLint contextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); if (context == EGL_NO_CONTEXT) { printf("Failed to create EGL context\n"); return 1; } // create an EGL window surface uint32_t screenWidth; uint32_t screenHeight; int32_t success = graphics_get_display_size(0, &screenWidth, &screenHeight); if (success == -1) { printf("Failed to get display size\n"); return 1; } VC_RECT_T dstRect; dstRect.x = 0; dstRect.y = 0; dstRect.width = screenWidth; dstRect.height = screenHeight; VC_RECT_T srcRect; srcRect.x = 0; srcRect.y = 0; srcRect.width = screenWidth; srcRect.height = screenHeight; DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0); DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0); DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay, 0, &dstRect, 0, &srcRect, DISPMANX_PROTECTION_NONE, 0, 0, DISPMANX_NO_ROTATE); static EGL_DISPMANX_WINDOW_T nativewindow; nativewindow.element = dispmanElement; nativewindow.width = screenWidth; nativewindow.height = screenHeight; vc_dispmanx_update_submit_sync(dispmanUpdate); surface = eglCreateWindowSurface(display, config, &nativewindow, NULL); if (surface == EGL_NO_SURFACE) { printf("Failed to create EGL window surface\n"); return 1; } // connect the context to the surface if (!eglMakeCurrent(display, surface, surface, context)) { printf("Failed to set current EGL context\n"); return 1; } // input struct InputDeviceRPI { enum DeviceClass { CLASS_KEYBOARD = 1, CLASS_MOUSE = 2, CLASS_TOUCHPAD = 4, CLASS_GAMEPAD = 8 }; uint32_t deviceClass = 0; int fd = 0; }; int maxFd = 0; std::vector<InputDeviceRPI> inputDevices; uint32_t mouseX = 0; uint32_t mouseY = 0; char TEMP[256]; glob_t g; int result = glob("/dev/input/event*", GLOB_NOSORT, NULL, &g); if (result == GLOB_NOMATCH) { printf("No event devices found\n"); return 1; } else if (result) { printf("Could not read /dev/input/event*\n"); return 1; } for (size_t i = 0; i < g.gl_pathc; i++) { InputDeviceRPI inputDevice; inputDevice.fd = open(g.gl_pathv[i], O_RDONLY); if (inputDevice.fd == -1) { printf("Failed to open device file descriptor\n"); continue; } if (ioctl(inputDevice.fd, EVIOCGRAB, (void *)1) == -1) { printf("Failed to get grab device\n"); } memset(TEMP, 0, sizeof(TEMP)); if (ioctl(inputDevice.fd, EVIOCGNAME(sizeof(TEMP) - 1), TEMP) == -1) { printf("Failed to get device name\n"); } else { printf("Got device: %s\n", TEMP); } unsigned long eventBits[BITS_TO_LONGS(EV_CNT)]; unsigned long absBits[BITS_TO_LONGS(ABS_CNT)]; unsigned long relBits[BITS_TO_LONGS(REL_CNT)]; unsigned long keyBits[BITS_TO_LONGS(KEY_CNT)]; if (ioctl(inputDevice.fd, EVIOCGBIT(0, sizeof(eventBits)), eventBits) == -1 || ioctl(inputDevice.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) == -1 || ioctl(inputDevice.fd, EVIOCGBIT(EV_REL, sizeof(relBits)), relBits) == -1 || ioctl(inputDevice.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) == -1) { printf("Failed to get device event bits\n"); } if (bit_is_set(eventBits, EV_KEY) && ( bit_is_set(keyBits, KEY_1) || bit_is_set(keyBits, KEY_2) || bit_is_set(keyBits, KEY_3) || bit_is_set(keyBits, KEY_4) || bit_is_set(keyBits, KEY_5) || bit_is_set(keyBits, KEY_6) || bit_is_set(keyBits, KEY_7) || bit_is_set(keyBits, KEY_8) || bit_is_set(keyBits, KEY_9) || bit_is_set(keyBits, KEY_0) )) { printf("Keyboard\n"); inputDevice.deviceClass = InputDeviceRPI::CLASS_KEYBOARD; } if (bit_is_set(eventBits, EV_ABS) && bit_is_set(absBits, ABS_X) && bit_is_set(absBits, ABS_Y)) { if (bit_is_set(keyBits, BTN_STYLUS) || bit_is_set(keyBits, BTN_TOOL_PEN)) { printf("Tablet\n"); inputDevice.deviceClass |= InputDeviceRPI::CLASS_TOUCHPAD; } else if (bit_is_set(keyBits, BTN_TOOL_FINGER) && !bit_is_set(keyBits, BTN_TOOL_PEN)) { printf("Touchpad\n"); inputDevice.deviceClass |= InputDeviceRPI::CLASS_TOUCHPAD; } else if (bit_is_set(keyBits, BTN_MOUSE)) { printf("Mouse\n"); inputDevice.deviceClass |= InputDeviceRPI::CLASS_MOUSE; } else if (bit_is_set(keyBits, BTN_TOUCH)) { printf("Touchscreen\n"); inputDevice.deviceClass |= InputDeviceRPI::CLASS_TOUCHPAD; } } else if (bit_is_set(eventBits, EV_REL) && bit_is_set(relBits, REL_X) && bit_is_set(relBits, REL_Y)) { if (bit_is_set(keyBits, BTN_MOUSE)) { printf("Mouse\n"); inputDevice.deviceClass |= InputDeviceRPI::CLASS_MOUSE; } } if (bit_is_set(keyBits, BTN_JOYSTICK)) { printf("Joystick\n"); inputDevice.deviceClass = InputDeviceRPI::CLASS_GAMEPAD; } if (bit_is_set(keyBits, BTN_GAMEPAD)) { printf("Gamepad\n"); inputDevice.deviceClass = InputDeviceRPI::CLASS_GAMEPAD; } if (inputDevice.fd > maxFd) { maxFd = inputDevice.fd; } inputDevices.push_back(inputDevice); } globfree(&g); fd_set rfds; struct timeval tv; for(;;) { FD_ZERO(&rfds); for (const InputDeviceRPI& inputDevice : inputDevices) { FD_SET(inputDevice.fd, &rfds); } tv.tv_sec = 0; tv.tv_usec = 0; int retval = select(maxFd + 1, &rfds, NULL, NULL, &tv); if (retval == -1) { printf("Select failed\n"); return 1; } else if (retval > 0) { for (const InputDeviceRPI& inputDevice : inputDevices) { if (FD_ISSET(inputDevice.fd, &rfds)) { ssize_t bytesRead = read(inputDevice.fd, TEMP, sizeof(TEMP)); if (bytesRead == -1) { printf("Failed to read input"); } printf("Got input, read %d bytes\n", bytesRead); for (ssize_t i = 0; i < bytesRead - static_cast<ssize_t>(sizeof(input_event)) + 1; i += sizeof(input_event)) { input_event* event = reinterpret_cast<input_event*>(TEMP + i); if (inputDevice.deviceClass & InputDeviceRPI::CLASS_KEYBOARD) { printf("Timestamp: %d.%d, type: %d", (uint32_t)event->time.tv_sec, (uint32_t)event->time.tv_usec, event->type); switch (event->type) { case EV_SYN: printf(", EV_SYN"); break; case EV_KEY: printf(", EV_KEY"); break; case EV_MSC: printf(", EV_MSC"); break; case EV_REP: printf(", EV_REP"); break; } printf(", value: %d, key: %d\n", event->value, event->code); if (event->type == EV_KEY && event->code == KEY_ESC) { return 0; } } if (inputDevice.deviceClass & InputDeviceRPI::CLASS_MOUSE) { printf("Timestamp: %d.%d, type: %d", (uint32_t)event->time.tv_sec, (uint32_t)event->time.tv_usec, event->type); switch (event->type) { case EV_SYN: printf(", EV_SYN"); break; case EV_KEY: printf(", EV_KEY"); break; case EV_MSC: printf(", EV_MSC"); break; case EV_REL: printf(", EV_REL"); break; } printf(", value: %d, key: %d\n", event->value, event->code); } } } } } glClearColor(1.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glFlush(); eglSwapBuffers(display, surface); } for (const InputDeviceRPI& inputDevice : inputDevices) { if (ioctl(inputDevice.fd, EVIOCGRAB, (void*)0) == -1) { printf("Failed to release device\n"); } if (close(inputDevice.fd) == -1) { printf("Failed to close file descriptor\n"); } } if (!eglDestroySurface(display, surface)) { printf("Failed to destroy EGL surface\n"); } if (!eglDestroyContext(display, context)) { printf("Failed to destroy EGL context\n"); } if (!eglTerminate(display)) { printf("Failed to terminate EGL\n"); } bcm_host_deinit(); return 0; }
void joystick_linux::open_joystick(const char *p_path) { int joy_num = get_free_joy_slot(); int fd = open(p_path, O_RDONLY | O_NONBLOCK); if (fd != -1 && joy_num != -1) { unsigned long evbit[NBITS(EV_MAX)] = { 0 }; unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) { return; } //check if the device supports basic gamepad events, prevents certain keyboards from //being detected as joysticks if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) && ((test_bit(ABS_X, absbit) || test_bit(ABS_Y, absbit)) || (test_bit(BTN_A, keybit) || test_bit(BTN_THUMBL, keybit))))) { close(fd); return; } char uid[128]; char namebuf[128]; String name = ""; input_id inpid; if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) >= 0) { name = namebuf; } if (ioctl(fd, EVIOCGID, &inpid) < 0) { close(fd); return; } joysticks[joy_num].reset(); Joystick &joy = joysticks[joy_num]; joy.fd = fd; joy.devpath = String(p_path); setup_joystick_properties(joy_num); sprintf(uid, "%04x%04x", __bswap_16(inpid.bustype), 0); if (inpid.vendor && inpid.product && inpid.version) { uint16_t vendor = __bswap_16(inpid.vendor); uint16_t product = __bswap_16(inpid.product); uint16_t version = __bswap_16(inpid.version); sprintf(uid + String(uid).length(), "%04x%04x%04x%04x%04x%04x", vendor,0,product,0,version,0); input->joy_connection_changed(joy_num, true, name, uid); } else { String uidname = uid; int uidlen = MIN(name.length(), 11); for (int i=0; i<uidlen; i++) { uidname = uidname + _hex_str(name[i]); } uidname += "00"; input->joy_connection_changed(joy_num, true, name, uidname); } } }
/* * Fill device information. * Queries the input device and tries to classify it. */ void CLinuxInputDevice::GetInfo(int fd) { unsigned int num_keys = 0; unsigned int num_ext_keys = 0; unsigned int num_buttons = 0; unsigned int num_rels = 0; unsigned int num_abs = 0; unsigned long evbit[NBITS(EV_CNT)]; unsigned long keybit[NBITS(KEY_CNT)]; /* get device name */ bzero(m_deviceName, sizeof(m_deviceName)); ioctl(fd, EVIOCGNAME(sizeof(m_deviceName)-1), m_deviceName); if (strncmp(m_deviceName, "D-Link Boxee D-Link Boxee Receiver", strlen("D-Link Boxee D-Link Boxee Receiver")) == 0) { m_bSkipNonKeyEvents = true; } else { m_bSkipNonKeyEvents = false; } CLog::Log(LOGINFO, "opened device '%s' (file name %s), m_bSkipNonKeyEvents %d\n", m_deviceName, m_fileName.c_str(), m_bSkipNonKeyEvents); /* get event type bits */ ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit); if (test_bit( EV_KEY, evbit )) { int i; /* get keyboard bits */ ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit); /** count typical keyboard keys only */ for (i = KEY_Q; i <= KEY_M; i++) if (test_bit( i, keybit )) num_keys++; for (i = KEY_OK; i < KEY_CNT; i++) if (test_bit( i, keybit )) num_ext_keys++; for (i = BTN_MOUSE; i < BTN_JOYSTICK; i++) if (test_bit( i, keybit )) num_buttons++; } #ifndef HAS_INTELCE unsigned long relbit[NBITS(REL_CNT)]; unsigned long absbit[NBITS(ABS_CNT)]; if (test_bit( EV_REL, evbit )) { int i; /* get bits for relative axes */ ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit); for (i = 0; i < REL_CNT; i++) if (test_bit( i, relbit )) num_rels++; } if (test_bit( EV_ABS, evbit )) { int i; /* get bits for absolute axes */ ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit); for (i = 0; i < ABS_PRESSURE; i++) if (test_bit( i, absbit )) num_abs++; /* test if it is a multi-touch type B device */ if (test_bit(ABS_MT_SLOT, absbit)) m_deviceType |= LI_DEVICE_MULTITOUCH; } /* Mouse, Touchscreen or Smartpad ? */ if ((test_bit( EV_KEY, evbit ) && (test_bit( BTN_TOUCH, keybit ) || test_bit( BTN_TOOL_FINGER, keybit ))) || ((num_rels >= 2 && num_buttons) || (num_abs == 2 && (num_buttons == 1)))) m_deviceType |= LI_DEVICE_MOUSE; else if (num_abs && num_buttons) /* Or a Joystick? */ m_deviceType |= LI_DEVICE_JOYSTICK; #endif /* A Keyboard, do we have at least some letters? */ if (num_keys > 20) { m_deviceType |= LI_DEVICE_KEYBOARD; m_deviceCaps |= LI_CAPS_KEYS; m_deviceMinKeyCode = 0; m_deviceMaxKeyCode = 127; } /* A Remote Control? */ if (num_ext_keys) { m_deviceType |= LI_DEVICE_REMOTE; m_deviceCaps |= LI_CAPS_KEYS; } /* Buttons */ if (num_buttons) { m_deviceCaps |= LI_CAPS_BUTTONS; m_deviceMaxKeyCode = num_buttons - 1; } /* Axes */ if (num_rels || num_abs) { m_deviceCaps |= LI_CAPS_AXES; m_deviceMaxAxis = std::max(num_rels, num_abs) - 1; } /* Decide which primary input device to be. */ if (m_deviceType & LI_DEVICE_KEYBOARD) m_devicePreferredId = LI_DEVICE_KEYBOARD; else if (m_deviceType & LI_DEVICE_MULTITOUCH) { m_devicePreferredId = LI_DEVICE_MULTITOUCH; CGenericTouchInputHandler::GetInstance().RegisterHandler(&CGenericTouchActionHandler::GetInstance()); } else if (m_deviceType & LI_DEVICE_REMOTE) m_devicePreferredId = LI_DEVICE_REMOTE; else if (m_deviceType & LI_DEVICE_JOYSTICK) m_devicePreferredId = LI_DEVICE_JOYSTICK; else if (m_deviceType & LI_DEVICE_MOUSE) m_devicePreferredId = LI_DEVICE_MOUSE; else m_devicePreferredId = LI_DEVICE_NONE; //printf("type: %d\n", m_deviceType); //printf("caps: %d\n", m_deviceCaps); //printf("pref: %d\n", m_devicePreferredId); }