예제 #1
0
파일: descr.c 프로젝트: ele7enxxh/dtrace-pf
int
hid_get_report_id(int fd)
{
	report_desc_t rep;
	hid_data_t d;
	hid_item_t h;
	int kindset;
	int temp = -1;
	int ret;

	if ((rep = hid_get_report_desc(fd)) == NULL)
		goto use_ioctl;
	kindset = 1 << hid_input | 1 << hid_output | 1 << hid_feature;
	for (d = hid_start_parse(rep, kindset, -1); hid_get_item(d, &h); ) {
		/* Return the first report ID we met. */
		if (h.report_ID != 0) {
			temp = h.report_ID;
			break;
		}
	}
	hid_end_parse(d);
	hid_dispose_report_desc(rep);

	if (temp > 0)
		return (temp);

use_ioctl:
	ret = ioctl(fd, USB_GET_REPORT_ID, &temp);
#ifdef HID_COMPAT7
	if (ret < 0)
		ret = hid_get_report_id_compat7(fd);
	else
#endif
		ret = temp;

	return (ret);
}
예제 #2
0
int
SDL_SYS_JoystickOpen(SDL_Joystick *joy)
{
	char *path = joynames[joy->index];
	struct joystick_hwdata *hw;
	struct hid_item hitem;
	struct hid_data *hdata;
	struct report *rep;
	int fd;
	int i;

	fd = open(path, O_RDONLY);
	if (fd == -1) {
		SDL_SetError("%s: %s", path, strerror(errno));
		return (-1);
	}

	hw = (struct joystick_hwdata *)SDL_malloc(sizeof(struct joystick_hwdata));
	if (hw == NULL) {
		SDL_OutOfMemory();
		close(fd);
		return (-1);
	}
	joy->hwdata = hw;
	hw->fd = fd;
	hw->path = strdup(path);
	hw->x = 0;
	hw->y = 0;
	hw->xmin = 0xffff;
	hw->ymin = 0xffff;
	hw->xmax = 0;
	hw->ymax = 0;
	if (! SDL_strncmp(path, "/dev/joy", 8)) {
		hw->type = BSDJOY_JOY;
		joy->naxes = 2;
		joy->nbuttons = 2;
		joy->nhats = 0;
		joy->nballs = 0;
		joydevnames[joy->index] = strdup("Gameport joystick");
		goto usbend;
	} else {
		hw->type = BSDJOY_UHID;
	}

	{
	    int ax;
	    for (ax = 0; ax < JOYAXE_count; ax++)
		hw->axis_map[ax] = -1;
	}
	hw->repdesc = hid_get_report_desc(fd);
	if (hw->repdesc == NULL) {
		SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
		    strerror(errno));
		goto usberr;
	}
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)
       rep->rid = hid_get_report_id(fd);
       if (rep->rid < 0) {
#else
	rep = &hw->inreport;
	if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
#endif
		rep->rid = -1; /* XXX */
	}
	if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
		goto usberr;
	}
	if (rep->size <= 0) {
		SDL_SetError("%s: Input report descriptor has invalid length",
		    hw->path);
		goto usberr;
	}

#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111)
	hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
#else
	hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
#endif
	if (hdata == NULL) {
		SDL_SetError("%s: Cannot start HID parser", hw->path);
		goto usberr;
	}
	joy->naxes = 0;
	joy->nbuttons = 0;
	joy->nhats = 0;
	joy->nballs = 0;
	for (i=0; i<JOYAXE_count; i++)
		hw->axis_map[i] = -1;

	while (hid_get_item(hdata, &hitem) > 0) {
		char *sp;
		const char *s;

		switch (hitem.kind) {
		case hid_collection:
			switch (HID_PAGE(hitem.usage)) {
			case HUP_GENERIC_DESKTOP:
				switch (HID_USAGE(hitem.usage)) {
				case HUG_JOYSTICK:
				case HUG_GAME_PAD:
					s = hid_usage_in_page(hitem.usage);
					sp = SDL_malloc(SDL_strlen(s) + 5);
					SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)", s,
					    joy->index);
					joydevnames[joy->index] = sp;
				}
			}
			break;
		case hid_input:
			switch (HID_PAGE(hitem.usage)) {
			case HUP_GENERIC_DESKTOP: {
			    unsigned usage = HID_USAGE(hitem.usage);
			    int joyaxe = usage_to_joyaxe(usage);
			    if (joyaxe >= 0) {
				hw->axis_map[joyaxe] = 1;
			    } else if (usage == HUG_HAT_SWITCH) {
				joy->nhats++;
			    }
			    break;
			}
			case HUP_BUTTON:
				joy->nbuttons++;
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
	}
	hid_end_parse(hdata);
	for (i=0; i<JOYAXE_count; i++)
		if (hw->axis_map[i] > 0)
			hw->axis_map[i] = joy->naxes++;

usbend:
	/* The poll blocks the event thread. */
	fcntl(fd, F_SETFL, O_NONBLOCK);

	return (0);
usberr:
	close(hw->fd);
	SDL_free(hw->path);
	SDL_free(hw);
	return (-1);
}

void
SDL_SYS_JoystickUpdate(SDL_Joystick *joy)
{
	struct hid_item hitem;
	struct hid_data *hdata;
	struct report *rep;
	int nbutton, naxe = -1;
	Sint32 v;

#if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
	struct joystick gameport;
 
	if (joy->hwdata->type == BSDJOY_JOY) {
		if (read(joy->hwdata->fd, &gameport, sizeof gameport) != sizeof gameport)
			return;
		if (abs(joy->hwdata->x - gameport.x) > 8) {
			joy->hwdata->x = gameport.x;
			if (joy->hwdata->x < joy->hwdata->xmin) {
				joy->hwdata->xmin = joy->hwdata->x;
			}
			if (joy->hwdata->x > joy->hwdata->xmax) {
				joy->hwdata->xmax = joy->hwdata->x;
			}
			if (joy->hwdata->xmin == joy->hwdata->xmax) {
				joy->hwdata->xmin--;
				joy->hwdata->xmax++;
			}
			v = (Sint32)joy->hwdata->x;
			v -= (joy->hwdata->xmax + joy->hwdata->xmin + 1)/2;
			v *= 32768/((joy->hwdata->xmax - joy->hwdata->xmin + 1)/2);
			SDL_PrivateJoystickAxis(joy, 0, v);
		}
		if (abs(joy->hwdata->y - gameport.y) > 8) {
			joy->hwdata->y = gameport.y;
			if (joy->hwdata->y < joy->hwdata->ymin) {
				joy->hwdata->ymin = joy->hwdata->y;
			}
			if (joy->hwdata->y > joy->hwdata->ymax) {
				joy->hwdata->ymax = joy->hwdata->y;
			}
			if (joy->hwdata->ymin == joy->hwdata->ymax) {
				joy->hwdata->ymin--;
				joy->hwdata->ymax++;
			}
			v = (Sint32)joy->hwdata->y;
			v -= (joy->hwdata->ymax + joy->hwdata->ymin + 1)/2;
			v *= 32768/((joy->hwdata->ymax - joy->hwdata->ymin + 1)/2);
			SDL_PrivateJoystickAxis(joy, 1, v);
		}
		if (gameport.b1 != joy->buttons[0]) {
			SDL_PrivateJoystickButton(joy, 0, gameport.b1);
		}
		if (gameport.b2 != joy->buttons[1]) {
			SDL_PrivateJoystickButton(joy, 1, gameport.b2);
		}
		return;
	}
#endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */
	
	rep = &joy->hwdata->inreport;

	if (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) != rep->size) {
		return;
	}
#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111)
	hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
#else
	hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
#endif
	if (hdata == NULL) {
		fprintf(stderr, "%s: Cannot start HID parser\n",
		    joy->hwdata->path);
		return;
	}

	for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
		switch (hitem.kind) {
		case hid_input:
			switch (HID_PAGE(hitem.usage)) {
			case HUP_GENERIC_DESKTOP: {
			    unsigned usage = HID_USAGE(hitem.usage);
			    int joyaxe = usage_to_joyaxe(usage);
			    if (joyaxe >= 0) {
				naxe = joy->hwdata->axis_map[joyaxe];
				/* scaleaxe */
				v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
							 &hitem);
				v -= (hitem.logical_maximum + hitem.logical_minimum + 1)/2;
				v *= 32768/((hitem.logical_maximum - hitem.logical_minimum + 1)/2);
				if (v != joy->axes[naxe]) {
				    SDL_PrivateJoystickAxis(joy, naxe, v);
				}
			    } else if (usage == HUG_HAT_SWITCH) {
				v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
							 &hitem);
				SDL_PrivateJoystickHat(joy, 0,
					hatval_to_sdl(v)-hitem.logical_minimum);
			    }
			    break;
			}
			case HUP_BUTTON:
				v = (Sint32)hid_get_data(REP_BUF_DATA(rep),
				    &hitem);
				if (joy->buttons[nbutton] != v) {
					SDL_PrivateJoystickButton(joy,
					    nbutton, v);
				}
				nbutton++;
				break;
			default:
				continue;
			}
			break;
		default:
			break;
		}
	}
	hid_end_parse(hdata);

	return;
}

/* Function to close a joystick after use */
void
SDL_SYS_JoystickClose(SDL_Joystick *joy)
{
	if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8))	{
		report_free(&joy->hwdata->inreport);
		hid_dispose_report_desc(joy->hwdata->repdesc);
	}
	close(joy->hwdata->fd);
	SDL_free(joy->hwdata->path);
	SDL_free(joy->hwdata);

	return;
}

void
SDL_SYS_JoystickQuit(void)
{
	int i;

	for (i = 0; i < MAX_JOYS; i++) {
		if (joynames[i] != NULL)
			SDL_free(joynames[i]);
		if (joydevnames[i] != NULL)
			SDL_free(joydevnames[i]);
	}

	return;
}
예제 #3
0
int
SDL_SYS_JoystickOpen(SDL_Joystick *joy)
{
	char *path = joynames[joy->index];
	struct joystick_hwdata *hw;
	struct hid_item hitem;
	struct hid_data *hdata;
	struct report *rep;
	int fd;
	int i;

	fd = open(path, O_RDONLY);
	if (fd == -1) {
		SDL_SetError("%s: %s", path, strerror(errno));
		return (-1);
	}

	hw = (struct joystick_hwdata *)SDL_malloc(sizeof(struct joystick_hwdata));
	if (hw == NULL) {
		SDL_OutOfMemory();
		close(fd);
		return (-1);
	}
	joy->hwdata = hw;
	hw->fd = fd;
	hw->path = strdup(path);
	hw->x = 0;
	hw->y = 0;
	hw->xmin = 0xffff;
	hw->ymin = 0xffff;
	hw->xmax = 0;
	hw->ymax = 0;
	if (! SDL_strncmp(path, "/dev/joy", 8)) {
		hw->type = BSDJOY_JOY;
		joy->naxes = 2;
		joy->nbuttons = 2;
		joy->nhats = 0;
		joy->nballs = 0;
		joydevnames[joy->index] = strdup("Gameport joystick");
		goto usbend;
	} else {
		hw->type = BSDJOY_UHID;
	}

	{
	    int ax;
	    for (ax = 0; ax < JOYAXE_count; ax++)
		hw->axis_map[ax] = -1;
	}
	hw->repdesc = hid_get_report_desc(fd);
	if (hw->repdesc == NULL) {
		SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
		    strerror(errno));
		goto usberr;
	}

	rep = &hw->inreport;
	if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
		rep->rid = -1; /* XXX */
	}
	if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
		goto usberr;
	}
	if (rep->size <= 0) {
		SDL_SetError("%s: Input report descriptor has invalid length",
		    hw->path);
		goto usberr;
	}

#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_version >= 500111)
	hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
#else
	hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
#endif
	if (hdata == NULL) {
		SDL_SetError("%s: Cannot start HID parser", hw->path);
		goto usberr;
	}
	joy->naxes = 0;
	joy->nbuttons = 0;
	joy->nhats = 0;
	joy->nballs = 0;
	for (i=0; i<JOYAXE_count; i++)
		hw->axis_map[i] = -1;

	while (hid_get_item(hdata, &hitem) > 0) {
		char *sp;
		const char *s;

		switch (hitem.kind) {
		case hid_collection:
			switch (HID_PAGE(hitem.usage)) {
			case HUP_GENERIC_DESKTOP:
				switch (HID_USAGE(hitem.usage)) {
				case HUG_JOYSTICK:
				case HUG_GAME_PAD:
					s = hid_usage_in_page(hitem.usage);
					sp = SDL_malloc(SDL_strlen(s) + 5);
					SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)", s,
					    joy->index);
					joydevnames[joy->index] = sp;
				}
			}
			break;
		case hid_input:
			switch (HID_PAGE(hitem.usage)) {
			case HUP_GENERIC_DESKTOP: {
			    unsigned usage = HID_USAGE(hitem.usage);
			    int joyaxe = usage_to_joyaxe(usage);
			    if (joyaxe >= 0) {
				hw->axis_map[joyaxe] = 1;
			    } else if (usage == HUG_HAT_SWITCH) {
				joy->nhats++;
			    }
			    break;
			}
			case HUP_BUTTON:
				joy->nbuttons++;
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
	}
	hid_end_parse(hdata);
	for (i=0; i<JOYAXE_count; i++)
		if (hw->axis_map[i] > 0)
			hw->axis_map[i] = joy->naxes++;

usbend:
	/* The poll blocks the event thread. */
	fcntl(fd, F_SETFL, O_NONBLOCK);

	return (0);
usberr:
	close(hw->fd);
	SDL_free(hw->path);
	SDL_free(hw);
	return (-1);
}
예제 #4
0
int
main(int argc, char **argv)
{
	const char *conf = NULL;
	const char *dev = NULL;
	const char *table = NULL;
	int fd, fp, ch, n, val, i;
	size_t sz, sz1;
	int demon, ignore, dieearly;
	report_desc_t repd;
	char buf[100];
	char devnamebuf[PATH_MAX];
	struct command *cmd;
	int reportid = -1;

	demon = 1;
	ignore = 0;
	dieearly = 0;
	while ((ch = getopt(argc, argv, "c:def:ip:r:t:v")) != -1) {
		switch(ch) {
		case 'c':
			conf = optarg;
			break;
		case 'd':
			demon ^= 1;
			break;
		case 'e':
			dieearly = 1;
			break;
		case 'i':
			ignore++;
			break;
		case 'f':
			dev = optarg;
			break;
		case 'p':
			pidfile = optarg;
			break;
		case 'r':
			reportid = atoi(optarg);
			break;
		case 't':
			table = optarg;
			break;
		case 'v':
			demon = 0;
			verbose++;
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (conf == NULL || dev == NULL)
		usage();

	hid_init(table);

	if (dev[0] != '/') {
		snprintf(devnamebuf, sizeof(devnamebuf), "/dev/%s%s",
			 isdigit(dev[0]) ? "uhid" : "", dev);
		dev = devnamebuf;
	}

	fd = open(dev, O_RDWR);
	if (fd < 0)
		err(1, "%s", dev);
	repd = hid_get_report_desc(fd);
	if (repd == NULL)
		err(1, "hid_get_report_desc() failed");

	commands = parse_conf(conf, repd, reportid, ignore);

	sz = (size_t)hid_report_size(repd, hid_input, -1);

	if (verbose)
		printf("report size %zu\n", sz);
	if (sz > sizeof buf)
		errx(1, "report too large");

	(void)signal(SIGHUP, sighup);

	if (demon) {
		fp = open(pidfile, O_WRONLY|O_CREAT, S_IRUSR|S_IRGRP|S_IROTH);
		if (fp < 0)
			err(1, "%s", pidfile);
		if (daemon(0, 0) < 0)
			err(1, "daemon()");
		snprintf(buf, sizeof(buf), "%ld\n", (long)getpid());
		sz1 = strlen(buf);
		if (write(fp, buf, sz1) < 0)
			err(1, "%s", pidfile);
		close(fp);
		isdemon = 1;
	}

	for(;;) {
		n = read(fd, buf, sz);
		if (verbose > 2) {
			printf("read %d bytes:", n);
			for (i = 0; i < n; i++)
				printf(" %02x", buf[i]);
			printf("\n");
		}
		if (n < 0) {
			if (verbose)
				err(1, "read");
			else
				exit(1);
		}
#if 0
		if (n != sz) {
			err(2, "read size");
		}
#endif
		for (cmd = commands; cmd; cmd = cmd->next) {
			if (cmd->item.report_ID != 0 &&
			    buf[0] != cmd->item.report_ID)
				continue;
			if (cmd->item.flags & HIO_VARIABLE)
				val = hid_get_data(buf, &cmd->item);
			else {
				uint32_t pos = cmd->item.pos;
				for (i = 0; i < cmd->item.report_count; i++) {
					val = hid_get_data(buf, &cmd->item);
					if (val == cmd->value)
						break;
					cmd->item.pos += cmd->item.report_size;
				}
				cmd->item.pos = pos;
				val = (i < cmd->item.report_count) ?
				    cmd->value : -1;
			}
			if (cmd->value != val && cmd->anyvalue == 0)
				goto next;
			if ((cmd->debounce == 0) ||
			    ((cmd->debounce == 1) && ((cmd->lastseen == -1) ||
					       (cmd->lastseen != val)))) {
				docmd(cmd, val, dev, argc, argv);
				goto next;
			}
			if ((cmd->debounce > 1) &&
			    ((cmd->lastused == -1) ||
			     (abs(cmd->lastused - val) >= cmd->debounce))) {
				docmd(cmd, val, dev, argc, argv);
				cmd->lastused = val;
				goto next;
			}
next:
			cmd->lastseen = val;
		}

		if (dieearly)
			exit(0);

		if (reparse) {
			struct command *cmds =
			    parse_conf(conf, repd, reportid, ignore);
			if (cmds) {
				freecommands(commands);
				commands = cmds;
			}
			reparse = 0;
		}
	}

	exit(0);
}
예제 #5
0
int
main(int argc, char **argv)
{
	report_desc_t r;
	char *table = NULL;
	char devnam[100], *dev = NULL;
	int f;
	int all = 0;
	int ch;
	int repdump = 0;
	int loop = 0;

	while ((ch = getopt(argc, argv, "af:lnrt:vwxz")) != -1) {
		switch(ch) {
		case 'a':
			all++;
			break;
		case 'f':
			dev = optarg;
			break;
		case 'l':
			loop ^= 1;
			break;
		case 'n':
			noname++;
			break;
		case 'r':
			repdump++;
			break;
		case 't':
			table = optarg;
			break;
		case 'v':
			verbose++;
			break;
		case 'w':
			wflag = 1;
			break;
		case 'x':
			hexdump = 1;
			break;
		case 'z':
			zflag = 1;
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (dev == NULL)
		usage();

	if (argc == 0 && !all && !repdump)
		usage();

	if (dev[0] != '/') {
		if (isdigit(dev[0]))
			snprintf(devnam, sizeof(devnam), "/dev/uhid%s", dev);
		else
			snprintf(devnam, sizeof(devnam), "/dev/%s", dev);
		dev = devnam;
	}

	hid_init(table);

	f = open(dev, O_RDWR);
	if (f < 0)
		err(1, "%s", dev);

	r = hid_get_report_desc(f);
	if (r == 0)
		errx(1, "USB_GET_REPORT_DESC");

	if (repdump) {
		printf("Report descriptor:\n");
		dumpitems(r);
	}
	if (argc != 0 || all) {
		parceargs(r, all, argc, argv);
		if (wflag)
			writedata(f, r);
		else
			dumpdata(f, r, loop);
	}

	hid_dispose_report_desc(r);
	exit(0);
}
int
jstkOpenDevice_bsd(JoystickDevPtr joystick, Bool probe)
{
    int cur_axis;
    int is_joystick, report_id = 0;
    int got_something;
    struct hid_data *d;
    struct hid_item h;
    report_desc_t rd;
    struct jstk_bsd_hid_data *bsddata;

    if (joystick->fd == -1) {
        if ((joystick->fd = open(joystick->device, O_RDWR | O_NDELAY, 0)) < 0) {
            xf86Msg(X_ERROR, "Cannot open joystick '%s' (%s)\n",
                    joystick->device, strerror(errno));
            return -1;
        }
    }

    if ((rd = hid_get_report_desc(joystick->fd)) == 0) {
        xf86Msg(X_ERROR, "Joystick: hid_get_report_desc failed: %s\n",
                strerror(errno));
        jstkCloseDevice_bsd(joystick);
        return -1;
    }

    if (ioctl(joystick->fd, USB_GET_REPORT_ID, &report_id) < 0) {
        xf86Msg(X_ERROR, "Joystick: ioctl USB_GET_REPORT_ID failed: %s\n",
                strerror(errno));
        jstkCloseDevice_bsd(joystick);
        return -1;
    }

    bsddata = (struct jstk_bsd_hid_data*)
              malloc(sizeof(struct jstk_bsd_hid_data));
    joystick->devicedata = (void*) bsddata;

    bsddata->dlen = hid_report_size(rd, hid_input, report_id);

    if ((bsddata->data_buf = malloc(bsddata->dlen)) == NULL) {
        fprintf(stderr, "error: couldn't malloc %d bytes\n", bsddata->dlen);
        hid_dispose_report_desc(rd);
        jstkCloseDevice_bsd(joystick);
        return -1;
    }

    is_joystick = 0;
    got_something = 0;
    cur_axis = 0;
    bsddata->hats = 0;
    joystick->num_axes = 0;
    joystick->num_buttons = 0;

    for (d = hid_start_parse(rd, 1 << hid_input, report_id);
         hid_get_item(d, &h); )
    {
        int usage, page;

        page = HID_PAGE(h.usage);
        usage = HID_USAGE(h.usage);

        is_joystick = is_joystick ||
                      (h.kind == hid_collection &&
                       page == HUP_GENERIC_DESKTOP &&
                       (usage == HUG_JOYSTICK || usage == HUG_GAME_PAD));

        if (h.kind != hid_input)
            continue;

        if (!is_joystick)
            continue;

        if (page == HUP_GENERIC_DESKTOP) {
            if (usage == HUG_HAT_SWITCH) {
                if ((bsddata->hats < MAXAXES) && (joystick->num_axes <= MAXAXES-2)) {
                    got_something = 1;
                    memcpy(&bsddata->hat_item[bsddata->hats], &h, sizeof(h));
                    bsddata->hats++;
                    joystick->num_axes += 2;
                }
            } else {
                if (joystick->num_axes < MAXAXES) {
                    got_something = 1;
                    memcpy(&bsddata->axis_item[cur_axis], &h, sizeof(h));
                    cur_axis++;
                    joystick->num_axes++;
                }
            }
        } else if (page == HUP_BUTTON) {
            if (joystick->num_buttons < MAXBUTTONS) {
                got_something = 1;
                memcpy(&bsddata->button_item[joystick->num_buttons], &h, sizeof(h));
                joystick->num_buttons++;
            }
	}
    }
    hid_end_parse(d);

    if (!got_something) {
        free(bsddata->data_buf);
        xf86Msg(X_ERROR, "Joystick: Didn't find any usable axes.\n");
        jstkCloseDevice_bsd(joystick);
        return -1;
    }

    bsddata->hotdata = 0;
    if (probe == TRUE) {
        xf86Msg(X_INFO, "Joystick: %d buttons, %d axes\n", 
                joystick->num_buttons, joystick->num_axes);
    }

    joystick->open_proc = jstkOpenDevice_bsd;
    joystick->read_proc = jstkReadData_bsd;
    joystick->close_proc = jstkCloseDevice_bsd;

    return joystick->fd;
}
예제 #7
0
void USBJoystick::initJoystick(const char *name)
{
  report_desc_t rd;
  hid_data *d;
  hid_item h;
  int report_id;

  status = false;
  hids = NULL;
  num_axis = 0;

  if ((fd = open(name, O_RDONLY | O_NONBLOCK)) < 0)
    return;

  if ((rd = hid_get_report_desc(fd)) == 0) {
    close(fd);
    return;
  }

  data_buf_size = hid_report_size(rd, hid_input, &report_id);
  if ((data_buf = (char *)malloc(data_buf_size)) == NULL) {
    hid_dispose_report_desc(rd);
  }
  data_buf_offset = (report_id != 0);

  int is_joystick = 0;
  int interesting_hid = FALSE;
  for (d = hid_start_parse(rd, 1 << hid_input); hid_get_item(d, &h); ) {
    int page = HID_PAGE(h.usage);
    int usage = HID_USAGE(h.usage);
    is_joystick = is_joystick ||
      (h.kind == hid_collection && page == HUP_GENERIC_DESKTOP &&
      (usage == HUG_JOYSTICK || usage == HUG_GAME_PAD));

    if (h.kind != hid_input)
      continue;

    if (!is_joystick)
      continue;

    interesting_hid = TRUE;
    if (page == HUP_GENERIC_DESKTOP) {
      int which_axis;
      switch (usage) {
	case HUG_X:
	case HUG_RX: which_axis = 0; break;
	case HUG_Y:
	case HUG_RY: which_axis = 1; break;
	case HUG_Z:
	case HUG_RZ: which_axis = 2; break;
	default: interesting_hid = FALSE;
      }
      if (interesting_hid) {
	axis_const[which_axis] = 1000 + (2000 * h.logical_maximum) / 
	  (h.logical_minimum - h.logical_maximum);
	axis_scale[which_axis] = (2000 * 10000) / 
	  (h.logical_maximum - h.logical_minimum);
	axis[which_axis] = (h.logical_minimum + h.logical_maximum) / 2;
	if (num_axis < (which_axis + 1))
	  num_axis = which_axis + 1;
      }
    }
    if (interesting_hid) {
      struct hid_item *newhid = new struct hid_item;
      if (newhid == NULL) {
	close(fd);
	return;
      }
      *newhid = h;
      newhid->next = hids;
      hids = newhid;
    }
  }
  hid_end_parse(d);

  status = true;
}
예제 #8
0
int
main(int argc, char **argv)
{
	const char *conf = NULL;
	const char *dev = NULL;
	int fd, ch, sz, n, val, i;
	int demon, ignore;
	report_desc_t repd;
	char buf[100];
	char devnamebuf[PATH_MAX];
	struct command *cmd;
	int reportid;

	demon = 1;
	ignore = 0;
	while ((ch = getopt(argc, argv, "c:df:iv")) != -1) {
		switch(ch) {
		case 'c':
			conf = optarg;
			break;
		case 'd':
			demon ^= 1;
			break;
		case 'i':
			ignore++;
			break;
		case 'f':
			dev = optarg;
			break;
		case 'v':
			demon = 0;
			verbose++;
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (conf == NULL || dev == NULL)
		usage();

	if (hid_start(NULL) == -1)
		errx(1, "hid_init");

	if (dev[0] != '/') {
		snprintf(devnamebuf, sizeof(devnamebuf), "/dev/%s%s",
		    isdigit((unsigned char)dev[0]) ? "uhid" : "", dev);
		dev = devnamebuf;
	}

	if (demon && conf[0] != '/')
		errx(1, "config file must have an absolute path, %s", conf);

	fd = open(dev, O_RDWR | O_CLOEXEC);
	if (fd < 0)
		err(1, "%s", dev);

	if (ioctl(fd, USB_GET_REPORT_ID, &reportid) < 0)
		reportid = -1;
	repd = hid_get_report_desc(fd);
	if (repd == NULL)
		err(1, "hid_get_report_desc() failed");

	commands = parse_conf(conf, repd, reportid, ignore);

	sz = hid_report_size(repd, hid_input, reportid);

	if (verbose)
		printf("report size %d\n", sz);
	if (sz > sizeof buf)
		errx(1, "report too large");

	(void)signal(SIGHUP, sighup);

	/* we do not care about the children, so ignore them */
	(void)signal(SIGCHLD, SIG_IGN);

	if (demon) {
		if (daemon(0, 0) < 0)
			err(1, "daemon()");
		isdemon = 1;
	}

	for(;;) {
		n = read(fd, buf, sz);
		if (verbose > 2) {
			printf("read %d bytes:", n);
			for (i = 0; i < n; i++)
				printf(" %02x", buf[i]);
			printf("\n");
		}
		if (n < 0) {
			if (verbose)
				err(1, "read");
			else
				exit(1);
		}
		if (n != sz) {
			err(2, "read size");
		}
		for (cmd = commands; cmd; cmd = cmd->next) {
			val = hid_get_data(buf, &cmd->item);
			if (cmd->value == val || cmd->anyvalue)
				docmd(cmd, val, dev, argc, argv);
		}
		if (reparse) {
			struct command *cmds =
			    parse_conf(conf, repd, reportid, ignore);
			if (cmds) {
				freecommands(commands);
				commands = cmds;
			}
			reparse = 0;
		}
	}

	exit(0);
}
예제 #9
0
int
main (int argc, char **argv)
{
    char *device_file;
    int fd = -1;
    int report_id;
    report_desc_t report_desc;
    struct hid_data *data;
    hid_item_t item;
    boolean is_keyboard = FALSE;
    boolean is_keypad = FALSE;
    boolean is_mouse = FALSE;
    boolean is_joystick = FALSE;

    if (! hfp_init(argc, argv))
        goto end;

    device_file = getenv("HAL_PROP_HIDDEV_DEVICE");
    if (! device_file)
        goto end;

    fd = open(device_file, O_RDONLY);
    if (fd < 0)
        goto end;

    /* give a meaningful process title for ps(1) */
    setproctitle("%s", device_file);

#ifdef HAVE_LIBUSB20
    report_id = hid_get_report_id(fd);
    if (report_id == -1)
#else
    if (ioctl(fd, USB_GET_REPORT_ID, &report_id) < 0)
#endif
        goto end;

    hid_init(NULL);

    report_desc = hid_get_report_desc(fd);
    if (! report_desc)
        goto end;

    for (data = hid_start_parse(report_desc, ~0, report_id); hid_get_item(data, &item);)
        if (item.kind == hid_collection)
        {
            if (item.collection == HID_COLLECTION_APPLICATION)
            {
                const char *page;
                char *full_page;
                int i;

                page = hid_usage_page(HID_PAGE(item.usage));

                full_page = hfp_strdup_printf("%s Page", page);
                for (i = 0; full_page[i] != 0; i++)
                    if (full_page[i] == '_')
                        full_page[i] = ' ';

                libhal_device_property_strlist_append(hfp_ctx, hfp_udi, "hiddev.application_pages", full_page, &hfp_error);
                hfp_free(full_page);
            }

            switch (item.usage)
            {
            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE):
                is_mouse = TRUE;
                break;

            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_JOYSTICK):
            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_GAME_PAD):
                is_joystick = TRUE;
                break;

            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD):
                is_keyboard = TRUE;
                break;

            case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYPAD):
                is_keypad = TRUE;
                break;
            }
        }
    hid_end_parse(data);

    hid_dispose_report_desc(report_desc);

    if (is_keyboard || is_mouse || is_joystick || is_keypad)
    {
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input", &hfp_error);
        libhal_device_set_property_string(hfp_ctx, hfp_udi, "info.category", "input", &hfp_error);
        libhal_device_set_property_string(hfp_ctx, hfp_udi, "input.device", device_file, &hfp_error);
    }
    if (is_keyboard)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keyboard", &hfp_error);
    if (is_keypad)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keypad", &hfp_error);
    if (is_keyboard || is_keypad)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.keys", &hfp_error);
    if (is_mouse)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.mouse", &hfp_error);
    if (is_joystick)
        libhal_device_add_capability(hfp_ctx, hfp_udi, "input.joystick", &hfp_error);

end:
    return 0;
}