diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2010-12-21 17:37:36 +0100 | 
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2010-12-21 17:50:18 +0100 | 
| commit | bab20f4538105d9b942858634ef8ce9e962996b7 (patch) | |
| tree | e46b6139a20308d93be4bcbc4ba3b56fa975f18d | |
| parent | 1bc6faa48907919376b14429f3b802d0d16fc00a (diff) | |
Support kernel device properties
In the upcoming 2.6.38 kernel, there is a new device property
bitfield, useful during device setup. This patch adds support
for it.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
| -rw-r--r-- | include/evemu.h | 3 | ||||
| -rw-r--r-- | src/evemu-impl.h | 3 | ||||
| -rw-r--r-- | src/evemu.c | 94 | 
3 files changed, 87 insertions, 13 deletions
| diff --git a/include/evemu.h b/include/evemu.h index 698a539..5bfcd3e 100644 --- a/include/evemu.h +++ b/include/evemu.h @@ -41,7 +41,8 @@ void evemu_delete(struct evemu_device *dev);  const char *evemu_get_name(const struct evemu_device *dev); -int evemu_has(const struct evemu_device *dev, int type, int code); +int evemu_has_prop(const struct evemu_device *dev, int code); +int evemu_has_event(const struct evemu_device *dev, int type, int code);  int evemu_extract(struct evemu_device *dev, int fd);  int evemu_write(const struct evemu_device *dev, FILE *fp); diff --git a/src/evemu-impl.h b/src/evemu-impl.h index 2346590..1112e92 100644 --- a/src/evemu-impl.h +++ b/src/evemu-impl.h @@ -11,8 +11,9 @@ struct evemu_device {  	int version_major, version_minor;  	char name[UINPUT_MAX_NAME_SIZE];  	struct input_id id; +	unsigned char prop[EVPLAY_NBYTES];  	unsigned char mask[EV_CNT][EVPLAY_NBYTES]; -	int bytes[EV_CNT]; +	int pbytes, mbytes[EV_CNT];  	struct input_absinfo abs[ABS_CNT];  }; diff --git a/src/evemu.c b/src/evemu.c index 53bda86..32f8f06 100644 --- a/src/evemu.c +++ b/src/evemu.c @@ -34,6 +34,17 @@  #include <errno.h>  #include <poll.h> +#ifndef UI_SET_PROPBIT +#define UI_SET_PROPBIT		_IOW(UINPUT_IOCTL_BASE, 110, int) +#define EVIOCGPROP(len)		_IOC(_IOC_READ, 'E', 0x09, len) +#define INPUT_PROP_POINTER		0x00 +#define INPUT_PROP_DIRECT		0x01 +#define INPUT_PROP_BUTTONPAD		0x02 +#define INPUT_PROP_SEMI_MT		0x03 +#define INPUT_PROP_MAX			0x1f +#define INPUT_PROP_CNT			(INPUT_PROP_MAX + 1) +#endif +  #define SYSCALL(call) while (((call) == -1) && (errno == EINTR))  static void copy_bits(unsigned char *mask, const unsigned long *bits, int bytes) @@ -68,7 +79,12 @@ const char *evemu_get_name(const struct evemu_device *dev)  	return dev->name;  } -int evemu_has(const struct evemu_device *dev, int type, int code) +int evemu_has_prop(const struct evemu_device *dev, int code) +{ +	return (dev->prop[code >> 3] >> (code & 7)) & 1; +} + +int evemu_has_event(const struct evemu_device *dev, int type, int code)  {  	return (dev->mask[type][code >> 3] >> (code & 7)) & 1;  } @@ -91,16 +107,22 @@ int evemu_extract(struct evemu_device *dev, int fd)  	if (rc < 0)  		return rc; +	SYSCALL(rc = ioctl(fd, EVIOCGPROP(sizeof(bits)), bits)); +	if (rc >= 0) { +		copy_bits(dev->prop, bits, rc); +		dev->pbytes = rc; +	} +  	for (i = 0; i < EV_CNT; i++) {  		SYSCALL(rc = ioctl(fd, EVIOCGBIT(i, sizeof(bits)), bits));  		if (rc < 0)  			continue;  		copy_bits(dev->mask[i], bits, rc); -		dev->bytes[i] = rc; +		dev->mbytes[i] = rc;  	}  	for (i = 0; i < ABS_CNT; i++) { -		if (!evemu_has(dev, EV_ABS, i)) +		if (!evemu_has_event(dev, EV_ABS, i))  			continue;  		SYSCALL(rc = ioctl(fd, EVIOCGABS(i), &dev->abs[i]));  		if (rc < 0) @@ -110,6 +132,15 @@ int evemu_extract(struct evemu_device *dev, int fd)  	return 0;  } +static void write_prop(FILE * fp, const unsigned char *mask, int bytes) +{ +	int i; +	for (i = 0; i < bytes; i += 8) +		fprintf(fp, "P: %02x %02x %02x %02x %02x %02x %02x %02x\n", +			mask[i], mask[i + 1], mask[i + 2], mask[i + 3], +			mask[i + 4], mask[i + 5], mask[i + 6], mask[i + 7]); +} +  static void write_mask(FILE * fp, int index,  		       const unsigned char *mask, int bytes)  { @@ -136,14 +167,28 @@ int evemu_write(const struct evemu_device *dev, FILE *fp)  		dev->id.bustype, dev->id.vendor,  		dev->id.product, dev->id.version); +	write_prop(fp, dev->prop, dev->pbytes); +  	for (i = 0; i < EV_CNT; i++) -		write_mask(fp, i, dev->mask[i], dev->bytes[i]); +		write_mask(fp, i, dev->mask[i], dev->mbytes[i]);  	for (i = 0; i < ABS_CNT; i++) -		if (evemu_has(dev, EV_ABS, i)) +		if (evemu_has_event(dev, EV_ABS, i))  			write_abs(fp, i, &dev->abs[i]);  } +static void read_prop(struct evemu_device *dev, FILE *fp) +{ +	unsigned int mask[8]; +	int i; +	while (fscanf(fp, "P: %02x %02x %02x %02x %02x %02x %02x %02x\n", +		      mask + 0, mask + 1, mask + 2, mask + 3, +		      mask + 4, mask + 5, mask + 6, mask + 7) > 0) { +		for (i = 0; i < 8; i++) +			dev->prop[dev->pbytes++] = mask[i]; +	} +} +  static void read_mask(struct evemu_device *dev, FILE *fp)  {  	unsigned int mask[8]; @@ -152,7 +197,7 @@ static void read_mask(struct evemu_device *dev, FILE *fp)  		      &index, mask + 0, mask + 1, mask + 2, mask + 3,  		      mask + 4, mask + 5, mask + 6, mask + 7) > 0) {  		for (i = 0; i < 8; i++) -			dev->mask[index][dev->bytes[index]++] = mask[i]; +			dev->mask[index][dev->mbytes[index]++] = mask[i];  	}  } @@ -186,6 +231,8 @@ int evemu_read(struct evemu_device *dev, FILE *fp)  	dev->id.product = product;  	dev->id.version = version; +	read_prop(dev, fp); +  	read_mask(dev, fp);  	read_abs(dev, fp); @@ -254,7 +301,14 @@ int evemu_play(FILE *fp, int fd)  	return 0;  } -static int set_bit(int fd, int type, int code) +static int set_prop_bit(int fd, int code) +{ +	int ret; +	SYSCALL(ret = ioctl(fd, UI_SET_PROPBIT, code)); +	return ret; +} + +static int set_event_bit(int fd, int type, int code)  {  	int ret = 0; @@ -291,14 +345,28 @@ static int set_bit(int fd, int type, int code)  	return ret;  } +static int set_prop(const struct evemu_device *dev, int fd) +{ +	int bits = 8 * dev->pbytes; +	int ret, i; +	for (i = 0; i < bits; i++) { +		if (!evemu_has_prop(dev, i)) +			continue; +		ret = set_prop_bit(fd, i); +		if (ret < 0) +			return ret; +	} +	return 0; +} +  static int set_mask(const struct evemu_device *dev, int type, int fd)  { -	int bits = 8 * dev->bytes[type]; +	int bits = 8 * dev->mbytes[type];  	int ret, i;  	for (i = 0; i < bits; i++) { -		if (!evemu_has(dev, type, i)) +		if (!evemu_has_event(dev, type, i))  			continue; -		ret = set_bit(fd, type, i); +		ret = set_event_bit(fd, type, i);  		if (ret < 0)  			return ret;  	} @@ -314,7 +382,7 @@ int evemu_create(const struct evemu_device *dev, int fd)  	memcpy(udev.name, dev->name, sizeof(udev.name));  	udev.id = dev->id;  	for (i = 0; i < ABS_CNT; i++) { -		if (!evemu_has(dev, EV_ABS, i)) +		if (!evemu_has_event(dev, EV_ABS, i))  			continue;  		udev.absmax[i] = dev->abs[i].maximum;  		udev.absmin[i] = dev->abs[i].minimum; @@ -322,6 +390,10 @@ int evemu_create(const struct evemu_device *dev, int fd)  		udev.absflat[i] = dev->abs[i].flat;  	} +	ret = set_prop(dev, fd); +	if (ret < 0) +		return ret; +  	for (i = 0; i < EV_CNT; i++) {  		ret = set_mask(dev, i, fd);  		if (ret < 0) | 
