Example #1
0
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;
}
Example #2
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);
}
Example #3
0
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;
}
Example #4
0
/* 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);
	}
Example #5
0
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;
}
Example #6
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;
}
Example #9
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;
}
Example #10
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;
}
Example #11
0
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();
}
Example #12
0
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;
}
Example #13
0
File: iod.c Project: Yomin/neobox
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");
    }
}
Example #14
0
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;
}
Example #15
0
/****************************************************************************
 *
 * @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;
                        }
                    }
                }
            }
        }

    }
}
Example #16
0
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;
}
Example #17
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);
}
Example #18
0
	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;
		}
	}
Example #19
0
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;
}
Example #20
0
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();
        }
    }
}
Example #21
0
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();
    }
}
Example #22
0
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;
}
Example #24
0
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;
}
Example #25
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;
}
Example #26
0
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;
}
Example #27
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
}
Example #28
0
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);
		}
	}
}
Example #30
0
/*
 * 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);
}