コード例 #1
0
ファイル: input.c プロジェクト: gvalkov/python-evdev
static PyObject *
ioctl_EVIOCG_bits(PyObject *self, PyObject *args)
{
    int max, fd, evtype, ret;

    ret = PyArg_ParseTuple(args, "ii", &fd, &evtype);
    if (!ret) return NULL;

    switch (evtype) {
    case EV_LED:
        max = LED_MAX; break;
    case EV_SND:
        max = SND_MAX; break;
    case EV_KEY:
        max = KEY_MAX; break;
    case EV_SW:
        max = SW_MAX; break;
    default:
        return NULL;
    }

    char bytes[(max+7)/8];
    memset(bytes, 0, sizeof bytes);

    switch (evtype) {
    case EV_LED:
        ret = ioctl(fd, EVIOCGLED(sizeof(bytes)), &bytes);
        break;
    case EV_SND:
        ret = ioctl(fd, EVIOCGSND(sizeof(bytes)), &bytes);
        break;
    case EV_KEY:
        ret = ioctl(fd, EVIOCGKEY(sizeof(bytes)), &bytes);
        break;
    case EV_SW:
        ret = ioctl(fd, EVIOCGSW(sizeof(bytes)), &bytes);
        break;
    }

    if (ret == -1)
        return NULL;

    PyObject* res = PyList_New(0);
    for (int i=0; i<max; i++) {
        if (test_bit(bytes, i)) {
            PyList_Append(res, Py_BuildValue("i", i));
        }
    }

    return res;
}
コード例 #2
0
void QEvdevKeyboardHandler::unloadKeymap()
{
    qCDebug(qLcEvdevKey) << "Unload current keymap and restore built-in";

    if (m_keymap && m_keymap != s_keymap_default)
        delete [] m_keymap;
    if (m_keycompose && m_keycompose != s_keycompose_default)
        delete [] m_keycompose;

    m_keymap = s_keymap_default;
    m_keymap_size = sizeof(s_keymap_default) / sizeof(s_keymap_default[0]);
    m_keycompose = s_keycompose_default;
    m_keycompose_size = sizeof(s_keycompose_default) / sizeof(s_keycompose_default[0]);

    // reset state, so we could switch keymaps at runtime
    m_modifiers = 0;
    memset(m_locks, 0, sizeof(m_locks));
    m_composing = 0;
    m_dead_unicode = 0xffff;

    //Set locks according to keyboard leds
    quint16 ledbits[1];
    memset(ledbits, 0, sizeof(ledbits));
    if (::ioctl(m_fd, EVIOCGLED(sizeof(ledbits)), ledbits) < 0) {
        qWarning("evdevkeyboard: Failed to query led states");
        switchLed(LED_NUML,false);
        switchLed(LED_CAPSL, false);
        switchLed(LED_SCROLLL,false);
    } else {
        //Capslock
        if ((ledbits[0]&0x02) > 0)
            m_locks[0] = 1;
        //Numlock
        if ((ledbits[0]&0x01) > 0)
            m_locks[1] = 1;
        //Scrollock
        if ((ledbits[0]&0x04) > 0)
            m_locks[2] = 1;
        qCDebug(qLcEvdevKey, "numlock=%d , capslock=%d, scrolllock=%d", m_locks[1], m_locks[0], m_locks[2]);
    }
}
コード例 #3
0
ファイル: main.c プロジェクト: largeriver/tests
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;
}
コード例 #4
0
/*
 * Open the device, fill out information about it,
 * allocate and fill private data, start input thread.
 */
bool CLinuxInputDevice::Open()
{
  int fd, ret;
  unsigned long ledbit[NBITS(LED_CNT)];

  /* open device */
  fd = open(m_fileName.c_str(), O_RDWR | O_NONBLOCK);
  if (fd < 0)
  {
    CLog::Log(LOGERROR, "CLinuxInputDevice: could not open device: %s\n", m_fileName.c_str());
    return false;
  }

  /* grab device */
  ret = ioctl(fd, EVIOCGRAB, 1);
  if (ret && errno != EINVAL)
  {
    CLog::Log(LOGERROR, "CLinuxInputDevice: could not grab device: %s\n", m_fileName.c_str());
    close(fd);
    return false;
  }

  // Set the socket to non-blocking
  int opts = 0;
  if ((opts = fcntl(fd, F_GETFL)) < 0)
  {
    CLog::Log(LOGERROR, "CLinuxInputDevice %s: fcntl(F_GETFL) failed: %s", __FUNCTION__ , strerror(errno));
    close(fd);
    return false;
  }

  opts = (opts | O_NONBLOCK);
  if (fcntl(fd, F_SETFL, opts) < 0)
  {
    CLog::Log(LOGERROR, "CLinuxInputDevice %s: fcntl(F_SETFL) failed: %s", __FUNCTION__, strerror(errno));
    close(fd);
    return false;
  }

  /* fill device info structure */
  GetInfo(fd);

  if (m_deviceType & LI_DEVICE_KEYBOARD)
    SetupKeyboardAutoRepeat(fd);

  m_fd = fd;
  m_vt_fd = -1;

  if (m_deviceMinKeyCode >= 0 && m_deviceMaxKeyCode >= m_deviceMinKeyCode)
  {
    if (m_vt_fd < 0)
      m_vt_fd = open("/dev/tty0", O_RDWR | O_NOCTTY);
 
    if (m_vt_fd < 0)
      m_vt_fd = open("/dev/tty1", O_RDWR | O_NOCTTY);

    if (m_vt_fd < 0)
      CLog::Log(LOGWARNING, "no keymap support (requires /dev/tty0 - CONFIG_VT)");
  }

  /* check if the device has LEDs */
  ret = ioctl(fd, EVIOCGBIT(EV_LED, sizeof(ledbit)), ledbit);
  if (ret < 0)
	  CLog::Log(LOGWARNING, "DirectFB/linux_input: could not get LED bits" );
  else
    m_hasLeds = test_bit( LED_SCROLLL, ledbit ) || test_bit( LED_NUML, ledbit )
        || test_bit( LED_CAPSL, ledbit );

  if (m_hasLeds)
  {
    /* get LED state */
    ret = ioctl(fd, EVIOCGLED(sizeof(m_ledState)), m_ledState);
    if (ret < 0)
    {
      CLog::Log(LOGERROR, "DirectFB/linux_input: could not get LED state");
      goto driver_open_device_error;
    }

    /* turn off LEDs */
    SetLed(LED_SCROLLL, 0);
    SetLed(LED_NUML, 0);
    SetLed(LED_CAPSL, 0);
  }

  return true;

driver_open_device_error:

  ioctl(fd, EVIOCGRAB, 0);
  if (m_vt_fd >= 0)
  {
    close(m_vt_fd);
    m_vt_fd = -1;
  }
  close(fd);
  m_fd = -1;

  return false;
}
コード例 #5
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;
}
コード例 #6
0
ファイル: mkdevinfo.c プロジェクト: AlanHuang/orangutan
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;
}
コード例 #7
0
ファイル: getevent.c プロジェクト: MoKee/android_system_core
static int print_possible_events(int fd, int print_flags)
{
    uint8_t *bits = NULL;
    ssize_t bits_size = 0;
    const char* label;
    int i, j, k;
    int res, res2;
    struct label* bit_labels;
    const char *bit_label;

    printf("  events:\n");
    for(i = EV_KEY; i <= EV_MAX; i++) { // skip EV_SYN since we cannot query its available codes
        int count = 0;
        while(1) {
            res = ioctl(fd, EVIOCGBIT(i, bits_size), bits);
            if(res < bits_size)
                break;
            bits_size = res + 16;
            bits = realloc(bits, bits_size * 2);
            if(bits == NULL)
                err(1, "failed to allocate buffer of size %d\n", (int)bits_size);
        }
        res2 = 0;
        switch(i) {
            case EV_KEY:
                res2 = ioctl(fd, EVIOCGKEY(res), bits + bits_size);
                label = "KEY";
                bit_labels = key_labels;
                break;
            case EV_REL:
                label = "REL";
                bit_labels = rel_labels;
                break;
            case EV_ABS:
                label = "ABS";
                bit_labels = abs_labels;
                break;
            case EV_MSC:
                label = "MSC";
                bit_labels = msc_labels;
                break;
            case EV_LED:
                res2 = ioctl(fd, EVIOCGLED(res), bits + bits_size);
                label = "LED";
                bit_labels = led_labels;
                break;
            case EV_SND:
                res2 = ioctl(fd, EVIOCGSND(res), bits + bits_size);
                label = "SND";
                bit_labels = snd_labels;
                break;
            case EV_SW:
                res2 = ioctl(fd, EVIOCGSW(bits_size), bits + bits_size);
                label = "SW ";
                bit_labels = sw_labels;
                break;
            case EV_REP:
                label = "REP";
                bit_labels = rep_labels;
                break;
            case EV_FF:
                label = "FF ";
                bit_labels = ff_labels;
                break;
            case EV_PWR:
                label = "PWR";
                bit_labels = NULL;
                break;
            case EV_FF_STATUS:
                label = "FFS";
                bit_labels = ff_status_labels;
                break;
            default:
                res2 = 0;
                label = "???";
                bit_labels = NULL;
        }
        for(j = 0; j < res; j++) {
            for(k = 0; k < 8; k++)
                if(bits[j] & 1 << k) {
                    char down;
                    if(j < res2 && (bits[j + bits_size] & 1 << k))
                        down = '*';
                    else
                        down = ' ';
                    if(count == 0)
                        printf("    %s (%04x):", label, i);
                    else if((count & (print_flags & PRINT_LABELS ? 0x3 : 0x7)) == 0 || i == EV_ABS)
                        printf("\n               ");
                    if(bit_labels && (print_flags & PRINT_LABELS)) {
                        bit_label = get_label(bit_labels, j * 8 + k);
                        if(bit_label)
                            printf(" %.20s%c%*s", bit_label, down, (int) (20 - strlen(bit_label)), "");
                        else
                            printf(" %04x%c                ", j * 8 + k, down);
                    } else {
                        printf(" %04x%c", j * 8 + k, down);
                    }
                    if(i == EV_ABS) {
                        struct input_absinfo abs;
                        if(ioctl(fd, EVIOCGABS(j * 8 + k), &abs) == 0) {
                            printf(" : value %d, min %d, max %d, fuzz %d, flat %d, resolution %d",
                                abs.value, abs.minimum, abs.maximum, abs.fuzz, abs.flat,
                                abs.resolution);
                        }
                    }
                    count++;
                }
        }
        if(count)
            printf("\n");
    }
    free(bits);
    return 0;
}
コード例 #8
0
ファイル: usb_stick.c プロジェクト: Fokker/paparazzi-1
int init_hid_device(char* device_name)
{
  int cnt;
  unsigned long buttons,axes;
  unsigned long key_bits[32],abs_bits[32],led_bits[32];
  //	unsigned long ff_bits[32];
  int valbuf[16];
  char name[MAX_NAME_LENGTH] = "Unknown";

  stick_button_count = 0;
  stick_axis_count = 0;

  /* Detect device mode, event interface or joystick */
  if (strstr( device_name, "event" ) == 0 ) {
    dbgprintf(stderr," Using Joystick interface\n");
    event_mode = STICK_MODE_JOYSTICK;
  } else {
    dbgprintf(stderr," Using Event interface\n");
    event_mode = STICK_MODE_EVENT;
  }

  /* Open event device read only (with write permission for ff) */
  stick_device_handle = open(device_name,O_RDONLY|O_NONBLOCK);
  if (stick_device_handle<0) {
    dbgprintf(stderr,"ERROR: can not open %s (%s) [%s:%d]\n",
        device_name,strerror(errno),__FILE__,__LINE__);
    return(1);
  }

  /* LED testing */

//  led_test( );


  /* Which buttons has the device? */
  memset(key_bits,0,32*sizeof(unsigned long));
  memset(led_bits,0,32*sizeof(unsigned long));
  if (event_mode == STICK_MODE_EVENT ) {
    if (ioctl(stick_device_handle,EVIOCGBIT(EV_KEY,32*sizeof(unsigned long)),key_bits)<0) {
      dbgprintf(stderr,"ERROR: can not get key bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
    //read LED count
    if (ioctl(stick_device_handle,EVIOCGLED(32*sizeof(led_bits)),led_bits)<0) {
      dbgprintf(stderr,"ERROR: can not get LED bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
    dbgprintf(stderr,"LEDs: %X",*led_bits);


  } else {
    if (ioctl(stick_device_handle,JSIOCGBUTTONS,&buttons)<0) {
      dbgprintf(stderr,"ERROR: can not get key bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
  }

  /* Store buttons */
  if (stick_init_param.button_count > 0) {
    for (cnt = 0; cnt < MIN(stick_init_param.button_count,BUTTON_COUNT); cnt++) {
      if (!TEST_BIT(stick_init_param.button_code[cnt], key_bits)) {
        dbgprintf(stderr,"ERROR: no suitable custom button %d found [%s:%d]\n",cnt,__FILE__,__LINE__);
        return 1;
      }
    }
    stick_button_count = stick_init_param.button_count;
    memcpy(button_code,stick_init_param.button_code,BUTTON_COUNT*sizeof(int));
  }
  else {
    if (event_mode == STICK_MODE_EVENT) {
      for (cnt = MIN_BUTTON_CODE; cnt < MAX_BUTTON_CODE; cnt++) {
        if (TEST_BIT(cnt, key_bits)) {
          button_code[stick_button_count++] = cnt;
          dbgprintf(stderr,"Available button: %d (0x%x)\n",cnt,cnt);
        }
        if (stick_button_count == BUTTON_COUNT) break;
      }
    } else {
      for (cnt = 0; cnt < buttons; cnt++) {
        button_code[stick_button_count++] = cnt;
        dbgprintf(stderr,"Available button: %d (0x%x)\n",cnt,cnt);
        if (stick_button_count == BUTTON_COUNT) break;
      }
    }

    if (stick_button_count == 0) {
      dbgprintf(stderr,"ERROR: no suitable buttons found [%s:%d]\n",__FILE__,__LINE__);
    }
  }

  /* Which axis has the device? */
  memset(abs_bits,0,32*sizeof(unsigned long));
  if (event_mode == STICK_MODE_EVENT ) {
    if (ioctl(stick_device_handle,EVIOCGBIT(EV_ABS,32*sizeof(unsigned long)),abs_bits)<0) {
      dbgprintf(stderr,"ERROR: can not get abs bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
  } else {
    if (ioctl(stick_device_handle,JSIOCGAXES,&axes)<0) {
      dbgprintf(stderr,"ERROR: can not get abs bits (%s) [%s:%d]\n",
          strerror(errno),__FILE__,__LINE__);
      return(1);
    }
  }

  /* Store axis */
  if (stick_init_param.axis_count > 0) {
    for (cnt = 0; cnt < MIN(stick_init_param.axis_count,AXIS_COUNT); cnt++) {
      if (!TEST_BIT(stick_init_param.axis_code[cnt], abs_bits)) {
        dbgprintf(stderr,"ERROR: no suitable custom axis %d found [%s:%d]\n",cnt,__FILE__,__LINE__);
        return 1;
      }
    }
    stick_axis_count = stick_init_param.axis_count;
    memcpy(axis_code,stick_init_param.axis_code,AXIS_COUNT*sizeof(int));
  }
  else {
    if(event_mode == STICK_MODE_EVENT) {
      for (cnt = MIN_ABS_CODE; cnt < MAX_ABS_CODE; cnt++) {
        if (TEST_BIT(cnt, abs_bits)) {
          axis_code[stick_axis_count++] = cnt;
          dbgprintf(stderr,"Available axis: %d (0x%x)\n",cnt,cnt);
        }
        if (stick_axis_count == AXIS_COUNT) break;
      }
    } else {
      for (cnt = 0; cnt < axes; cnt++) {
        axis_code[stick_axis_count++] = cnt;
        dbgprintf(stderr,"Available axis: %d (0x%x)\n",cnt,cnt);
        if (stick_axis_count == AXIS_COUNT) break;
      }
    }

    // at least 2 axis are needed in auto detection
    if (stick_axis_count < 2) {
      dbgprintf(stderr,"ERROR: no suitable axis found [%s:%d]\n",__FILE__,__LINE__);
      return(1);
    }
  }

  /* Axis param */
  for (cnt = 0; cnt < stick_axis_count; cnt++)
  {
    if (event_mode == STICK_MODE_EVENT ) {
      /* get axis value range */
      if (ioctl(stick_device_handle,EVIOCGABS(axis_code[cnt]),valbuf)<0) {
        dbgprintf(stderr,"ERROR: can not get axis %d value range (%s) [%s:%d]\n",
            cnt,strerror(errno),__FILE__,__LINE__);
        return(1);
      }
      axis_min[cnt]=valbuf[1];
      axis_max[cnt]=valbuf[2];
    } else {
      // with joystick interface, all axes are signed 16 bit with full range
      axis_min[cnt]=-32768;
      axis_max[cnt]=32768;
    }

    if (axis_min[cnt]>=axis_max[cnt]) {
      dbgprintf(stderr,"ERROR: bad axis %d value range (%d,%d) [%s:%d]\n",
          cnt,axis_min[cnt],axis_max[cnt],__FILE__,__LINE__);
      return(1);
    }
    dbgprintf(stderr,"Axis %d : parameters = [%d,%d]\n",
        cnt,axis_min[cnt],axis_max[cnt]);
  }

  //--------------------------------------------------
  // force feedback, TBD feature
  //--------------------------------------------------
#if 0
  /* Now get some information about force feedback */
  memset(ff_bits,0,32*sizeof(unsigned long));
  if (ioctl(device_handle,EVIOCGBIT(EV_FF ,32*sizeof(unsigned long)),ff_bits)<0) {
    dbgprintf(stderr,"ERROR: can not get ff bits (%s) [%s:%d]\n",
        strerror(errno),__FILE__,__LINE__);
    return(1);
  }

  /* force feedback supported? */
  if (!TEST_BIT(FF_CONSTANT,ff_bits)) {
    dbgprintf(stderr,"ERROR: device (or driver) has no force feedback support [%s:%d]\n",
        __FILE__,__LINE__);
    return(1);
  }

  /* Switch off auto centering */
  memset(&event,0,sizeof(event));
  event.type=EV_FF;
  event.code=FF_AUTOCENTER;
  event.value=0;
  if (write(device_handle,&event,sizeof(event))!=sizeof(event)) {
    dbgprintf(stderr,"ERROR: failed to disable auto centering (%s) [%s:%d]\n",
        strerror(errno),__FILE__,__LINE__);
    return(1);
  }

  /* Initialize constant force effect */
  memset(&effect,0,sizeof(effect));
  effect.type=FF_CONSTANT;
  effect.id=-1;
  effect.trigger.button=0;
  effect.trigger.interval=0;
  effect.replay.length=0xffff;
  effect.replay.delay=0;
  effect.u.constant.level=0;
  effect.direction=0xC000;
  effect.u.constant.envelope.attack_length=0;
  effect.u.constant.envelope.attack_level=0;
  effect.u.constant.envelope.fade_length=0;
  effect.u.constant.envelope.fade_level=0;

  /* Upload effect */
  if (ioctl(device_handle,EVIOCSFF,&effect)==-1) {
    dbgprintf(stderr,"ERROR: uploading effect failed (%s) [%s:%d]\n",
        strerror(errno),__FILE__,__LINE__);
    return(1);
  }

  /* Start effect */
  memset(&event,0,sizeof(event));
  event.type=EV_FF;
  event.code=effect.id;
  event.value=1;
  if (write(device_handle,&event,sizeof(event))!=sizeof(event)) {
    dbgprintf(stderr,"ERROR: starting effect failed (%s) [%s:%d]\n",
        strerror(errno),__FILE__,__LINE__);
    return(1);
  }
#endif

  if (event_mode == STICK_MODE_EVENT ) {
    ioctl(stick_device_handle, EVIOCGNAME(sizeof(name)), name);
  } else {
    ioctl(stick_device_handle, JSIOCGNAME(MAX_NAME_LENGTH), name);
  }
  printf("Input device name: \"%s\" on device \"%s\"\n", name, device_name);

  return(0);
}
コード例 #9
0
ファイル: input.c プロジェクト: jcmvbkbc/trinity-xtensa
static void input_sanitise(const struct ioctl_group *grp, int childno)
{
	unsigned int u, r;

	pick_random_ioctl(grp, childno);

	switch (shm->syscall[childno].a2) {
	case EVIOCGNAME(0):
		u = rand();
		shm->syscall[childno].a2 = EVIOCGNAME(u);
		break;
	case EVIOCGPHYS(0):
		u = rand();
		shm->syscall[childno].a2 = EVIOCGPHYS(u);
		break;
	case EVIOCGUNIQ(0):
		u = rand();
		shm->syscall[childno].a2 = EVIOCGUNIQ(u);
		break;
#ifdef EVIOCGPROP
	case EVIOCGPROP(0):
		u = rand();
		shm->syscall[childno].a2 = EVIOCGPROP(u);
		break;
#endif
#ifdef EVIOCGMTSLOTS
	case EVIOCGMTSLOTS(0):
		u = rand();
		shm->syscall[childno].a2 = EVIOCGMTSLOTS(u);
		break;
#endif
	case EVIOCGKEY(0):
		u = rand();
		shm->syscall[childno].a2 = EVIOCGKEY(u);
		break;
	case EVIOCGLED(0):
		u = rand();
		shm->syscall[childno].a2 = EVIOCGLED(u);
		break;
	case EVIOCGSND(0):
		u = rand();
		shm->syscall[childno].a2 = EVIOCGSND(u);
		break;
	case EVIOCGSW(0):
		u = rand();
		shm->syscall[childno].a2 = EVIOCGSW(u);
		break;
	case EVIOCGBIT(0,0):
		u = rand();
		r = rand();
		if (u % 10) u %= EV_CNT;
		if (r % 10) r /= 4;
		shm->syscall[childno].a2 = EVIOCGBIT(u, r);
		break;
	case EVIOCGABS(0):
		u = rand();
		if (u % 10) u %= ABS_CNT;
		shm->syscall[childno].a2 = EVIOCGABS(u);
		break;
	case EVIOCSABS(0):
		u = rand();
		if (u % 10) u %= ABS_CNT;
		shm->syscall[childno].a2 = EVIOCSABS(u);
		break;
	default:
		break;
	}
}
コード例 #10
0
ファイル: input.c プロジェクト: jcmvbkbc/trinity-xtensa
#endif
	IOCTL(EVIOCSKEYCODE),
#ifdef EVIOCSKEYCODE_V2
	IOCTL(EVIOCSKEYCODE_V2),
#endif
	IOCTL(EVIOCGNAME(0)),
	IOCTL(EVIOCGPHYS(0)),
	IOCTL(EVIOCGUNIQ(0)),
#ifdef EVIOCGPROP
	IOCTL(EVIOCGPROP(0)),
#endif
#ifdef EVIOCGMTSLOTS
	IOCTL(EVIOCGMTSLOTS(0)),
#endif
	IOCTL(EVIOCGKEY(0)),
	IOCTL(EVIOCGLED(0)),
	IOCTL(EVIOCGSND(0)),
	IOCTL(EVIOCGSW(0)),
	IOCTL(EVIOCGBIT(0,0)),
	IOCTL(EVIOCGABS(0)),
	IOCTL(EVIOCSABS(0)),
	IOCTL(EVIOCSFF),
	IOCTL(EVIOCRMFF),
	IOCTL(EVIOCGEFFECTS),
	IOCTL(EVIOCGRAB),
#ifdef EVIOCSCLOCKID
	IOCTL(EVIOCSCLOCKID),
#endif
};

static const char *const input_devs[] = {
コード例 #11
0
		/*
		 * It so happens that the pointer that gives us the trouble
		 * is the last field in the structure. Since we don't support
		 * custom waveforms in uinput anyway we can just copy the whole
		 * thing (to the compat size) and ignore the pointer.
		 */
		memcpy(&ff_up_compat.effect, &ff_up->effect,
			sizeof(struct ff_effect_compat));
		memcpy(&ff_up_compat.old, &ff_up->old,
			sizeof(struct ff_effect_compat));

		if (copy_to_user(buffer, &ff_up_compat,
				 sizeof(struct uinput_ff_upload_compat)))
			return -EFAULT;
	} else {
		if (copy_to_user(buffer, ff_up,
				 sizeof(struct uinput_ff_upload)))
			return -EFAULT;
	}

	return 0;
}

static int uinput_ff_upload_from_user(const char __user *buffer,
				      struct uinput_ff_upload *ff_up)
{
	if (INPUT_COMPAT_TEST) {
		struct uinput_ff_upload_compat ff_up_compat;

		if (copy_from_user(&ff_up_compat, buffer,
				   sizeof(struct uinput_ff_upload_compat)))
			return -EFAULT;

		ff_up->request_id = ff_up_compat.request_id;
		ff_up->retval = ff_up_compat.retval;
		memcpy(&ff_up->effect, &ff_up_compat.effect,
			sizeof(struct ff_effect_compat));
		memcpy(&ff_up->old, &ff_up_compat.old,
			sizeof(struct ff_effect_compat));

	} else {
		if (copy_from_user(ff_up, buffer,
				   sizeof(struct uinput_ff_upload)))
			return -EFAULT;
	}

	return 0;
}

#else

static int uinput_ff_upload_to_user(char __user *buffer,
				    const struct uinput_ff_upload *ff_up)
{
	if (copy_to_user(buffer, ff_up, sizeof(struct uinput_ff_upload)))
		return -EFAULT;

	return 0;
}

static int uinput_ff_upload_from_user(const char __user *buffer,
				      struct uinput_ff_upload *ff_up)
{
	if (copy_from_user(ff_up, buffer, sizeof(struct uinput_ff_upload)))
		return -EFAULT;

	return 0;
}

#endif

#define uinput_set_bit(_arg, _bit, _max)		\
({							\
	int __ret = 0;					\
	if (udev->state == UIST_CREATED)		\
		__ret =  -EINVAL;			\
	else if ((_arg) > (_max))			\
		__ret = -EINVAL;			\
	else set_bit((_arg), udev->dev->_bit);		\
	__ret;						\
})

#ifdef CONFIG_FEATURE_PANTECH_MDS_MTC //|| defined(FEATURE_PANTECH_STABILITY)
#ifdef CONFIG_COMPAT 
#define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
#define BITS_TO_LONGS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
#ifdef __BIG_ENDIAN
static int bits_to_user(unsigned long *bits, unsigned int maxbit,
       unsigned int maxlen, void __user *p, int compat)
{
   int len, i;
   if (compat) {
     len = BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t);
     if (len > maxlen)
       len = maxlen;
     for (i = 0; i < len / sizeof(compat_long_t); i++)
       if (copy_to_user((compat_long_t __user *) p + i,
            (compat_long_t *) bits +
             i + 1 - ((i % 2) << 1),
            sizeof(compat_long_t)))
         return -EFAULT;
   } else {
     len = BITS_TO_LONGS(maxbit) * sizeof(long);
     if (len > maxlen)
       len = maxlen;
     if (copy_to_user(p, bits, len))
       return -EFAULT;
   }
   return len;
}
#else
 static int bits_to_user(unsigned long *bits, unsigned int maxbit,
      unsigned int maxlen, void __user *p, int compat)
{
  int len = compat ?
      BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t) :
      BITS_TO_LONGS(maxbit) * sizeof(long);
  if (len > maxlen)
    len = maxlen;
  return copy_to_user(p, bits, len) ? -EFAULT : len;
}
#endif /* __BIG_ENDIAN */
#else
static int bits_to_user(unsigned long *bits, unsigned int maxbit,
      unsigned int maxlen, void __user *p, int compat)
{
  int len = BITS_TO_LONGS(maxbit) * sizeof(long);
  if (len > maxlen)
    len = maxlen;
  return copy_to_user(p, bits, len) ? -EFAULT : len;
}
#endif /* CONFIG_COMPAT */
static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
{
  int len;
  if (!str)
    return -ENOENT;
  len = strlen(str) + 1;
  if (len > maxlen)
    len = maxlen;
  return copy_to_user(p, str, len) ? -EFAULT : len;
}
#define OLD_KEY_MAX 0x1ff
static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user *p, int compat_mode) 
{
  unsigned long *bits;
  int len;
  switch (_IOC_NR(cmd) & EV_MAX) {
   case      0: bits = dev->evbit;  len = EV_MAX;  break;
   case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
   case EV_REL: bits = dev->relbit; len = REL_MAX; break;
   case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
   case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
   case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
   case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
   case EV_FF:  bits = dev->ffbit;  len = FF_MAX;  break;
   case EV_SW:  bits = dev->swbit;  len = SW_MAX;  break;
   default: return -EINVAL;
  }
  if ((_IOC_NR(cmd) & EV_MAX) == EV_KEY && _IOC_SIZE(cmd) == OLD_KEY_MAX) {
     len = OLD_KEY_MAX;
  }
   return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
}
#undef OLD_KEY_MAX
#endif/*CONFIG_FEATURE_PANTECH_MDS_MTC || FEATURE_PANTECH_STABILITY*/
static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
				 unsigned long arg, void __user *p)
{
	int			retval;
	struct uinput_device	*udev = file->private_data;
	struct uinput_ff_upload ff_up;
	struct uinput_ff_erase  ff_erase;
	struct uinput_request   *req;
	char			*phys;

	retval = mutex_lock_interruptible(&udev->mutex);
	if (retval)
		return retval;

	if (!udev->dev) {
		retval = uinput_allocate_device(udev);
		if (retval)
			goto out;
	}

	switch (cmd) {
		case UI_DEV_CREATE:
			retval = uinput_create_device(udev);
			break;

		case UI_DEV_DESTROY:
			uinput_destroy_device(udev);
			break;
#ifdef CONFIG_FEATURE_PANTECH_MDS_MTC //|| defined(FEATURE_PANTECH_STABILITY)
   case EVIOCGVERSION: 
		 if (udev->state != UIST_CREATED) 
			retval = -ENODEV;	
		 else put_user(EV_VERSION, (int __user *)p);
		  break;
	 case EVIOCGID:
		 if (udev->state != UIST_CREATED) 
			retval = -ENODEV;	
	   else if (copy_to_user(p, &udev->dev->id, sizeof(struct input_id)))
			retval = -EFAULT;
			break; 
#endif/*CONFIG_FEATURE_PANTECH_MDS_MTC || FEATURE_PANTECH_STABILITY*/	 

		case UI_SET_EVBIT:
			retval = uinput_set_bit(arg, evbit, EV_MAX);
			break;

		case UI_SET_KEYBIT:
			retval = uinput_set_bit(arg, keybit, KEY_MAX);
			break;

		case UI_SET_RELBIT:
			retval = uinput_set_bit(arg, relbit, REL_MAX);
			break;

		case UI_SET_ABSBIT:
			retval = uinput_set_bit(arg, absbit, ABS_MAX);
			break;

		case UI_SET_MSCBIT:
			retval = uinput_set_bit(arg, mscbit, MSC_MAX);
			break;

		case UI_SET_LEDBIT:
			retval = uinput_set_bit(arg, ledbit, LED_MAX);
			break;

		case UI_SET_SNDBIT:
			retval = uinput_set_bit(arg, sndbit, SND_MAX);
			break;

		case UI_SET_FFBIT:
			retval = uinput_set_bit(arg, ffbit, FF_MAX);
			break;

		case UI_SET_SWBIT:
			retval = uinput_set_bit(arg, swbit, SW_MAX);
			break;

		case UI_SET_PROPBIT:
			retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX);
			break;

		case UI_SET_PHYS:
			if (udev->state == UIST_CREATED) {
				retval = -EINVAL;
				goto out;
			}

			phys = strndup_user(p, 1024);
			if (IS_ERR(phys)) {
				retval = PTR_ERR(phys);
				goto out;
			}

			kfree(udev->dev->phys);
			udev->dev->phys = phys;
			break;

		case UI_BEGIN_FF_UPLOAD:
			retval = uinput_ff_upload_from_user(p, &ff_up);
			if (retval)
				break;

			req = uinput_request_find(udev, ff_up.request_id);
			if (!req || req->code != UI_FF_UPLOAD || !req->u.upload.effect) {
				retval = -EINVAL;
				break;
			}

			ff_up.retval = 0;
			ff_up.effect = *req->u.upload.effect;
			if (req->u.upload.old)
				ff_up.old = *req->u.upload.old;
			else
				memset(&ff_up.old, 0, sizeof(struct ff_effect));

			retval = uinput_ff_upload_to_user(p, &ff_up);
			break;

		case UI_BEGIN_FF_ERASE:
			if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
				retval = -EFAULT;
				break;
			}

			req = uinput_request_find(udev, ff_erase.request_id);
			if (!req || req->code != UI_FF_ERASE) {
				retval = -EINVAL;
				break;
			}

			ff_erase.retval = 0;
			ff_erase.effect_id = req->u.effect_id;
			if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) {
				retval = -EFAULT;
				break;
			}

			break;

		case UI_END_FF_UPLOAD:
			retval = uinput_ff_upload_from_user(p, &ff_up);
			if (retval)
				break;

			req = uinput_request_find(udev, ff_up.request_id);
			if (!req || req->code != UI_FF_UPLOAD ||
			    !req->u.upload.effect) {
				retval = -EINVAL;
				break;
			}

			req->retval = ff_up.retval;
			uinput_request_done(udev, req);
			break;

		case UI_END_FF_ERASE:
			if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
				retval = -EFAULT;
				break;
			}

			req = uinput_request_find(udev, ff_erase.request_id);
			if (!req || req->code != UI_FF_ERASE) {
				retval = -EINVAL;
				break;
			}

			req->retval = ff_erase.retval;
			uinput_request_done(udev, req);
			break;

		default:
#ifdef CONFIG_FEATURE_PANTECH_MDS_MTC // || defined(FEATURE_PANTECH_STABILITY)
		{
			 if (udev->state != UIST_CREATED){ 
				retval = -ENODEV;	
				break;
			 }
			 if (_IOC_DIR(cmd) == _IOC_READ) { 
				if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
				  handle_eviocgbit(udev->dev, cmd, p, 0);
				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
				  bits_to_user(udev->dev->key, KEY_MAX, _IOC_SIZE(cmd),
				              p, 0);
				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
				  bits_to_user(udev->dev->led, LED_MAX, _IOC_SIZE(cmd),
				              p, 0);
				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
				  bits_to_user(udev->dev->snd, SND_MAX, _IOC_SIZE(cmd),
				              p, 0);
				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
				  bits_to_user(udev->dev->sw, SW_MAX, _IOC_SIZE(cmd),
				              p, 0);
				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
				  str_to_user(udev->dev->name, _IOC_SIZE(cmd), p);
				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
				  str_to_user(udev->dev->phys, _IOC_SIZE(cmd), p);
				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
				  str_to_user(udev->dev->uniq, _IOC_SIZE(cmd), p);
				if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
			      int t;
			      struct input_absinfo abs;
			      t = _IOC_NR(cmd) & ABS_MAX;
						abs.value = input_abs_get_val(udev->dev,t);
						abs.minimum = input_abs_get_min(udev->dev,t);
				    abs.maximum = input_abs_get_max(udev->dev,t);
				    abs.fuzz = input_abs_get_fuzz(udev->dev,t);
				    abs.flat = input_abs_get_flat(udev->dev,t);
				/*
			      abs.value = udev->dev->abs[t];
				    abs.minimum = udev->dev->absmin[t];
				    abs.maximum = udev->dev->absmax[t];
				    abs.fuzz = udev->dev->absfuzz[t];
				    abs.flat = udev->dev->absflat[t];

				*/
						if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
						 retval= -EFAULT;
				  }
			}
		}
#else
			retval = -EINVAL;
#endif/*CONFIG_FEATURE_PANTECH_MDS_MTC || FEATURE_PANTECH_STABILITY*/
	}

 out:
	mutex_unlock(&udev->mutex);
	return retval;
}
コード例 #12
0
ファイル: ioctl_tree.c プロジェクト: APokorny/umockdev
    /* evdev */
    I_SIMPLE_STRUCT_IN(EVIOCGVERSION, 0, ioctl_insertion_parent_stateless),
    I_SIMPLE_STRUCT_IN(EVIOCGID, 0, ioctl_insertion_parent_stateless),
    I_SIMPLE_STRUCT_IN(EVIOCGREP, 0, ioctl_insertion_parent_stateless),
    I_SIMPLE_STRUCT_IN(EVIOCGKEYCODE, 0, ioctl_insertion_parent_stateless),
    I_SIMPLE_STRUCT_IN(EVIOCGKEYCODE_V2, 0, ioctl_insertion_parent_stateless),
    I_SIMPLE_STRUCT_IN(EVIOCGEFFECTS, 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGABS(0), "EVIOCGABS", ABS_MAX, ioctl_insertion_parent_stateless),
    /* we define these with len==32, but they apply to any len */
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGBIT(0, 32), "EVIOCGBIT", EV_MAX, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGNAME(32), "EVIOCGNAME", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGPHYS(32), "EVIOCGPHYS", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGUNIQ(32), "EVIOCGUNIQ", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGPROP(32), "EVIOCGPROP", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGKEY(32), "EVIOCGKEY", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGLED(32), "EVIOCGLED", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGSND(32), "EVIOCGSND", 0, ioctl_insertion_parent_stateless),
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGSW(32), "EVIOCGSW", 0, ioctl_insertion_parent_stateless),

    /* this was introduced not too long ago */
#ifdef EVIOCGMTSLOTS
    I_NAMED_SIMPLE_STRUCT_IN(EVIOCGMTSLOTS(32), "EVIOCGMTSLOTS", 0, ioctl_insertion_parent_stateless),
#endif

    /* terminator */
    {0, 0, 0, "", NULL, NULL, NULL, NULL, NULL}
};

const ioctl_type *
ioctl_type_get_by_id(unsigned long id)
{
コード例 #13
0
ファイル: getevent.c プロジェクト: mini-box/picosam9-tools
static int print_possible_events(int fd)
{
    uint8_t *bits = NULL;
    ssize_t bits_size = 0;
    const char* label;
    int i, j, k;
    int res, res2;
    
    printf("  events:\n");
    for(i = 0; i <= EV_MAX; i++) {
        int count = 0;
        while(1) {
            res = ioctl(fd, EVIOCGBIT(i, bits_size), bits);
            if(res < bits_size)
                break;
            bits_size = res + 16;
            bits = realloc(bits, bits_size * 2);
            if(bits == NULL) {
                fprintf(stderr, "failed to allocate buffer of size %d\n", bits_size);
                return 1;
            }
        }
        res2 = 0;
        switch(i) {
            case EV_SYN:
                label = "SYN";
                break;
            case EV_KEY:
                res2 = ioctl(fd, EVIOCGKEY(res), bits + bits_size);
                label = "KEY";
                break;
            case EV_REL:
                label = "REL";
                break;
            case EV_ABS:
                label = "ABS";
                break;
            case EV_MSC:
                label = "MSC";
                break;
            case EV_LED:
                res2 = ioctl(fd, EVIOCGLED(res), bits + bits_size);
                label = "LED";
                break;
            case EV_SND:
                res2 = ioctl(fd, EVIOCGSND(res), bits + bits_size);
                label = "SND";
                break;
            case EV_SW:
                res2 = ioctl(fd, EVIOCGSW(bits_size), bits + bits_size);
                label = "SW ";
                break;
            case EV_REP:
                label = "REP";
                break;
            case EV_FF:
                label = "FF ";
                break;
            case EV_PWR:
                label = "PWR";
                break;
            default:
                res2 = 0;
                label = "???";
        }
        for(j = 0; j < res; j++) {
            for(k = 0; k < 8; k++)
                if(bits[j] & 1 << k) {
                    char down;
                    if(j < res2 && (bits[j + bits_size] & 1 << k))
                        down = '*';
                    else
                        down = ' ';
                    if(count == 0)
                        printf("    %s (%04x):", label, i);
                    else if((count & 0x7) == 0 || i == EV_ABS)
                        printf("\n               ");
                    printf(" %04x%c", j * 8 + k, down);
                    if(i == EV_ABS) {
                        struct input_absinfo abs;
                        if(ioctl(fd, EVIOCGABS(j * 8 + k), &abs) == 0) {
                            printf(" value %d, min %d, max %d, fuzz %d flat %d", abs.value, abs.minimum, abs.maximum, abs.fuzz, abs.flat);
                        }
                    }
                    count++;
                }
        }
        if(count)
            printf("\n");
    }
    free(bits);
    return 0;
}
コード例 #14
0
static int
evdev_read_ioctl(struct tcb *const tcp, const unsigned int code,
		 const kernel_ulong_t arg)
{
	/* fixed-number fixed-length commands */
	switch (code) {
		case EVIOCGVERSION:
			tprints(", ");
			printnum_int(tcp, arg, "%#x");
			return 1;
		case EVIOCGEFFECTS:
			tprints(", ");
			printnum_int(tcp, arg, "%u");
			return 1;
		case EVIOCGID:
			return getid_ioctl(tcp, arg);
# ifdef EVIOCGREP
		case EVIOCGREP:
			return repeat_ioctl(tcp, arg);
# endif
		case EVIOCGKEYCODE:
			return keycode_ioctl(tcp, arg);
# ifdef EVIOCGKEYCODE_V2
		case EVIOCGKEYCODE_V2:
			return keycode_V2_ioctl(tcp, arg);
# endif
	}

	/* fixed-number variable-length commands */
	switch (_IOC_NR(code)) {
# ifdef EVIOCGMTSLOTS
		case _IOC_NR(EVIOCGMTSLOTS(0)):
			return mtslots_ioctl(tcp, code, arg);
# endif
		case _IOC_NR(EVIOCGNAME(0)):
		case _IOC_NR(EVIOCGPHYS(0)):
		case _IOC_NR(EVIOCGUNIQ(0)):
			tprints(", ");
			if (syserror(tcp))
				printaddr(arg);
			else
				printstrn(tcp, arg, tcp->u_rval);
			return 1;
# ifdef EVIOCGPROP
		case _IOC_NR(EVIOCGPROP(0)):
			return decode_bitset(tcp, arg, evdev_prop,
					     INPUT_PROP_MAX, "PROP_???");
# endif
		case _IOC_NR(EVIOCGSND(0)):
			return decode_bitset(tcp, arg, evdev_snd,
					     SND_MAX, "SND_???");
# ifdef EVIOCGSW
		case _IOC_NR(EVIOCGSW(0)):
			return decode_bitset(tcp, arg, evdev_switch,
					     SW_MAX, "SW_???");
# endif
		case _IOC_NR(EVIOCGKEY(0)):
			return decode_bitset(tcp, arg, evdev_keycode,
					     KEY_MAX, "KEY_???");
		case _IOC_NR(EVIOCGLED(0)):
			return decode_bitset(tcp, arg, evdev_leds,
					     LED_MAX, "LED_???");
	}

	/* multi-number fixed-length commands */
	if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
		return abs_ioctl(tcp, arg);

	/* multi-number variable-length commands */
	if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
		return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg);

	return 0;
}