diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2005-12-09 11:43:09 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2005-12-09 11:43:09 +0000 | 
| commit | d7cde36719252eaab14fad2d2c094bb6e7003059 (patch) | |
| tree | 4af5f9442ed84990c339876c112382404b3860e4 | |
| parent | b039c1a971aa2f4d4ca29b8453fbb2a360b5dbf7 (diff) | |
Add support for the old RFCOMM based EPoX presenter
| -rw-r--r-- | hidd/Makefile.am | 4 | ||||
| -rw-r--r-- | hidd/fakehid.c | 296 | ||||
| -rw-r--r-- | hidd/sdp.c | 71 | ||||
| -rw-r--r-- | hidd/uinput.h | 516 | 
4 files changed, 871 insertions, 16 deletions
| diff --git a/hidd/Makefile.am b/hidd/Makefile.am index cc043457..ba01caeb 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -1,8 +1,8 @@  bin_PROGRAMS = hidd -hidd_SOURCES = main.c hidd.h sdp.c fakehid.c -hidd_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a +hidd_SOURCES = main.c hidd.h sdp.c uinput.h fakehid.c +hidd_LDADD = @BLUEZ_LIBS@ -lm $(top_builddir)/common/libtextfile.a  AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/hidd/fakehid.c b/hidd/fakehid.c index 1483f022..b9fbc200 100644 --- a/hidd/fakehid.c +++ b/hidd/fakehid.c @@ -27,6 +27,12 @@  #include <stdio.h>  #include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <signal.h> +#include <sys/poll.h> +#include <sys/ioctl.h>  #include <sys/socket.h>  #include <bluetooth/bluetooth.h> @@ -34,16 +40,300 @@  #include <bluetooth/hidp.h>  #include "hidd.h" - -#include <X11/Xlib.h> -#include <X11/extensions/XTest.h> +#include "uinput.h"  #include <math.h> +static void event(int fd, uint16_t type, uint16_t code, int32_t value) +{ +	struct uinput_event event; + +	if (fd <= fileno(stderr)) +		return; + +	memset(&event, 0, sizeof(event)); +	event.type = type; +	event.code = code; +	event.value = value; + +	write(fd, &event, sizeof(event)); +} + +static void func(int fd) +{ +} + +static void back(int fd) +{ +} + +static void next(int fd) +{ +} + +static void button(int fd, unsigned int button, int is_press) +{ +	switch (button) { +	case 1: +		event(fd, EV_KEY, BTN_LEFT, is_press); +		break; +	case 3: +		event(fd, EV_KEY, BTN_RIGHT, is_press); +		break; +	} + +	event(fd, EV_SYN, SYN_REPORT, 0); +} + +static void move(int fd, unsigned int direction) +{ +	double angle; +	int32_t x, y; + +	angle = (direction * 22.5) * 3.1415926 / 180; +	x = (int) (sin(angle) * 8); +	y = (int) (cos(angle) * -8); + +	event(fd, EV_REL, REL_X, x); +	event(fd, EV_REL, REL_Y, y); + +	event(fd, EV_SYN, SYN_REPORT, 0); +} + +static void epox_decode(int fd, unsigned char event) +{ +	switch (event) { +	case 48: +		func(fd); break; +	case 55: +		back(fd); break; +	case 56: +		next(fd); break; +	case 53: +		button(fd, 1, 1); break; +	case 121: +		button(fd, 1, 0); break; +	case 113: +		break; +	case 54: +		button(fd, 3, 1); break; +	case 120: +		button(fd, 3, 0); break; +	case 112: +		break; +	case 51: +		move(fd, 0); break; +	case 97: +		move(fd, 1); break; +	case 65: +		move(fd, 2); break; +	case 98: +		move(fd, 3); break; +	case 50: +		move(fd, 4); break; +	case 99: +		move(fd, 5); break; +	case 67: +		move(fd, 6); break; +	case 101: +		move(fd, 7); break; +	case 52: +		move(fd, 8); break; +	case 100: +		move(fd, 9); break; +	case 66: +		move(fd, 10); break; +	case 102: +		move(fd, 11); break; +	case 49: +		move(fd, 12); break; +	case 103: +		move(fd, 13); break; +	case 57: +		move(fd, 14); break; +	case 104: +		move(fd, 15); break; +	case 69: +		break; +	default: +		printf("Unknown event code %d\n", event); +		break; +	} +} + +static int uinput_create(int keyboard, int mouse) +{ +	struct uinput_dev dev; +	int fd, aux; + +	fd = open("/dev/uinput", O_RDWR); +	if (fd < 0) { +		fd = open("/dev/input/uinput", O_RDWR); +		if (fd < 0) { +			fd = open("/dev/misc/uinput", O_RDWR); +			if (fd < 0) { +				fprintf(stderr, "Can't open input device: %s (%d)", +							strerror(errno), errno); +				return -1; +			} +		} +	} + +	memset(&dev, 0, sizeof(dev)); +	strncpy(dev.name, "Bluetooth FakeHID", UINPUT_MAX_NAME_SIZE); +	dev.id.bustype = BUS_BLUETOOTH; +	dev.id.vendor = 0x0000; +	dev.id.product = 0x0000; +	dev.id.version = 0x0000; + +	if (write(fd, &dev, sizeof(dev)) < 0) { +		fprintf(stderr, "Can't write device information: %s (%d)", +							strerror(errno), errno); +		close(fd); +		return -1; +	} + +	if (mouse) { +		ioctl(fd, UI_SET_EVBIT, EV_REL); + +		for (aux = REL_X; aux <= REL_MISC; aux++) +			ioctl(fd, UI_SET_RELBIT, aux); +	} + +	if (keyboard) { +		ioctl(fd, UI_SET_EVBIT, EV_KEY); +		ioctl(fd, UI_SET_EVBIT, EV_LED); +		ioctl(fd, UI_SET_EVBIT, EV_REP); + +		for (aux = KEY_RESERVED; aux <= KEY_UNKNOWN; aux++) +			ioctl(fd, UI_SET_KEYBIT, aux); + +		//for (aux = LED_NUML; aux <= LED_MISC; aux++) +		//	ioctl(fd, UI_SET_LEDBIT, aux); +	} + +	if (mouse) { +		ioctl(fd, UI_SET_EVBIT, EV_KEY); + +		for (aux = BTN_LEFT; aux <= BTN_BACK; aux++) +			ioctl(fd, UI_SET_KEYBIT, aux); +	} + +	ioctl(fd, UI_DEV_CREATE); + +	return fd; +} + +static int rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) +{ +	struct sockaddr_rc addr; +	int sk; + +	sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); +	if (sk < 0) { +		fprintf(stderr, "Can't create socket: %s (%d)\n", +							strerror(errno), errno); +		return -1; +	} + +	memset(&addr, 0, sizeof(addr)); +	addr.rc_family = AF_BLUETOOTH; +	bacpy(&addr.rc_bdaddr, src); + +	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { +		fprintf(stderr, "Can't bind socket: %s (%d)\n", +							strerror(errno), errno); +		close(sk); +		return -1; +	} + +	memset(&addr, 0, sizeof(addr)); +	addr.rc_family = AF_BLUETOOTH; +	bacpy(&addr.rc_bdaddr, dst); +	addr.rc_channel = channel; + +	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { +		fprintf(stderr, "Can't connect: %s (%d)\n", +							strerror(errno), errno); +		close(sk); +		return -1; +	} + +	return sk; +} + +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ +} + +static void sig_term(int sig) +{ +	__io_canceled = 1; +} +  void epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)  { +	unsigned char buf[16]; +	struct sigaction sa; +	struct pollfd p; +	char addr[18]; +	int i, fd, sk, len; + +	sk = rfcomm_connect(src, dst, channel); +	if (sk < 0) +		return; + +	fd = uinput_create(1, 1); +	if (fd < 0) { +		close(sk); +		return; +	} + +	ba2str(dst, addr); + +	printf("Connected to %s on channel %d\n", addr, channel); +	printf("Press CTRL-C for hangup\n"); + +	memset(&sa, 0, sizeof(sa)); +	sa.sa_flags   = SA_NOCLDSTOP; +	sa.sa_handler = SIG_IGN; +	sigaction(SIGCHLD, &sa, NULL); +	sigaction(SIGPIPE, &sa, NULL); + +	sa.sa_handler = sig_term; +	sigaction(SIGTERM, &sa, NULL); +	sigaction(SIGINT,  &sa, NULL); + +	sa.sa_handler = sig_hup; +	sigaction(SIGHUP, &sa, NULL); + +	p.fd = sk; +	p.events = POLLIN | POLLERR | POLLHUP; + +	while (!__io_canceled) { +		p.revents = 0; +		if (poll(&p, 1, 100) < 1) +			continue; + +		len = read(sk, buf, sizeof(buf)); +		if (len < 0) +			break; + +		for (i = 0; i < len; i++) +			epox_decode(fd, buf[i]); +	} + +	printf("Disconnected\n"); + +	ioctl(fd, UI_DEV_DESTROY); + +	close(fd); +	close(sk);  }  void headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel)  { +	printf("Not implemented\n");  } @@ -175,19 +175,21 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co  	search = sdp_list_append(NULL, &svclass);  	attrid = sdp_list_append(NULL, &range); -	err = sdp_service_search_attr_req(s, search, SDP_ATTR_REQ_RANGE, attrid, &pnp_rsp); +	err = sdp_service_search_attr_req(s, search, +					SDP_ATTR_REQ_RANGE, attrid, &pnp_rsp); -	sdp_list_free(search, 0); -	sdp_list_free(attrid, 0); +	sdp_list_free(search, NULL); +	sdp_list_free(attrid, NULL);  	sdp_uuid16_create(&svclass, HID_SVCLASS_ID);  	search = sdp_list_append(NULL, &svclass);  	attrid = sdp_list_append(NULL, &range); -	err = sdp_service_search_attr_req(s, search, SDP_ATTR_REQ_RANGE, attrid, &hid_rsp); +	err = sdp_service_search_attr_req(s, search, +					SDP_ATTR_REQ_RANGE, attrid, &hid_rsp); -	sdp_list_free(search, 0); -	sdp_list_free(attrid, 0); +	sdp_list_free(search, NULL); +	sdp_list_free(attrid, NULL);  	memset(&addr, 0, sizeof(addr));  	addrlen = sizeof(addr); @@ -270,19 +272,66 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co  int get_alternate_device_info(const bdaddr_t *src, const bdaddr_t *dst, uint16_t *uuid, uint8_t *channel)  { +	uint16_t attr = SDP_ATTR_PROTO_DESC_LIST;  	sdp_session_t *s; +	sdp_list_t *search, *attrid, *rsp; +	uuid_t svclass; +	int err;  	s = sdp_connect(src, dst, SDP_RETRY_IF_BUSY | SDP_WAIT_ON_CLOSE);  	if (!s)  		return -1; +	sdp_uuid16_create(&svclass, HEADSET_SVCLASS_ID); +	search = sdp_list_append(NULL, &svclass); +	attrid = sdp_list_append(NULL, &attr); + +	err = sdp_service_search_attr_req(s, search, +					SDP_ATTR_REQ_INDIVIDUAL, attrid, &rsp); + +	sdp_list_free(search, NULL); +	sdp_list_free(attrid, NULL); + +	if (err <= 0) { +		sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID); +		search = sdp_list_append(NULL, &svclass); +		attrid = sdp_list_append(NULL, &attr); + +		err = sdp_service_search_attr_req(s, search, +					SDP_ATTR_REQ_INDIVIDUAL, attrid, &rsp); + +		sdp_list_free(search, NULL); +		sdp_list_free(attrid, NULL); + +		if (err < 0) { +			sdp_close(s); +			return err; +		} + +		if (uuid) +			*uuid = SERIAL_PORT_SVCLASS_ID; +	} else { +		if (uuid) +			*uuid = HEADSET_SVCLASS_ID; +	} +  	sdp_close(s); -	if (uuid) -		*uuid = 0x0000; +	for (; rsp; rsp = rsp->next) { +		sdp_record_t *rec = (sdp_record_t *) rsp->data; +		sdp_list_t *protos; + +		if (!sdp_get_access_protos(rec, &protos)) { +			uint8_t ch = sdp_get_proto_port(protos, RFCOMM_UUID); +			if (ch > 0) { +				if (channel) +					*channel = ch; +				return 0; +			} +		} -	if (channel) -		*channel = 0; +		sdp_record_free(rec); +	} -	return 0; +	return -EIO;  } diff --git a/hidd/uinput.h b/hidd/uinput.h new file mode 100644 index 00000000..3a4d6860 --- /dev/null +++ b/hidd/uinput.h @@ -0,0 +1,516 @@ +/* + * + *  BlueZ - Bluetooth protocol stack for Linux + * + *  Copyright (C) 2003-2005  Marcel Holtmann <marcel@holtmann.org> + * + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, write to the Free Software + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA + * + */ + +#ifndef __UINPUT_H +#define __UINPUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <sys/time.h> +#include <sys/ioctl.h> + +/* Events */ + +#define EV_SYN			0x00 +#define EV_KEY			0x01 +#define EV_REL			0x02 +#define EV_ABS			0x03 +#define EV_MSC			0x04 +#define EV_LED			0x11 +#define EV_SND			0x12 +#define EV_REP			0x14 +#define EV_FF			0x15 +#define EV_PWR			0x16 +#define EV_FF_STATUS		0x17 +#define EV_MAX			0x1f + +/* Synchronization events */ + +#define SYN_REPORT		0 +#define SYN_CONFIG		1 + +/* Keys and buttons */ + +#define KEY_RESERVED		0 +#define KEY_ESC			1 +#define KEY_1			2 +#define KEY_2			3 +#define KEY_3			4 +#define KEY_4			5 +#define KEY_5			6 +#define KEY_6			7 +#define KEY_7			8 +#define KEY_8			9 +#define KEY_9			10 +#define KEY_0			11 +#define KEY_MINUS		12 +#define KEY_EQUAL		13 +#define KEY_BACKSPACE		14 +#define KEY_TAB			15 +#define KEY_Q			16 +#define KEY_W			17 +#define KEY_E			18 +#define KEY_R			19 +#define KEY_T			20 +#define KEY_Y			21 +#define KEY_U			22 +#define KEY_I			23 +#define KEY_O			24 +#define KEY_P			25 +#define KEY_LEFTBRACE		26 +#define KEY_RIGHTBRACE		27 +#define KEY_ENTER		28 +#define KEY_LEFTCTRL		29 +#define KEY_A			30 +#define KEY_S			31 +#define KEY_D			32 +#define KEY_F			33 +#define KEY_G			34 +#define KEY_H			35 +#define KEY_J			36 +#define KEY_K			37 +#define KEY_L			38 +#define KEY_SEMICOLON		39 +#define KEY_APOSTROPHE		40 +#define KEY_GRAVE		41 +#define KEY_LEFTSHIFT		42 +#define KEY_BACKSLASH		43 +#define KEY_Z			44 +#define KEY_X			45 +#define KEY_C			46 +#define KEY_V			47 +#define KEY_B			48 +#define KEY_N			49 +#define KEY_M			50 +#define KEY_COMMA		51 +#define KEY_DOT			52 +#define KEY_SLASH		53 +#define KEY_RIGHTSHIFT		54 +#define KEY_KPASTERISK		55 +#define KEY_LEFTALT		56 +#define KEY_SPACE		57 +#define KEY_CAPSLOCK		58 +#define KEY_F1			59 +#define KEY_F2			60 +#define KEY_F3			61 +#define KEY_F4			62 +#define KEY_F5			63 +#define KEY_F6			64 +#define KEY_F7			65 +#define KEY_F8			66 +#define KEY_F9			67 +#define KEY_F10			68 +#define KEY_NUMLOCK		69 +#define KEY_SCROLLLOCK		70 +#define KEY_KP7			71 +#define KEY_KP8			72 +#define KEY_KP9			73 +#define KEY_KPMINUS		74 +#define KEY_KP4			75 +#define KEY_KP5			76 +#define KEY_KP6			77 +#define KEY_KPPLUS		78 +#define KEY_KP1			79 +#define KEY_KP2			80 +#define KEY_KP3			81 +#define KEY_KP0			82 +#define KEY_KPDOT		83 +#define KEY_103RD		84 +#define KEY_F13			85 +#define KEY_102ND		86 +#define KEY_F11			87 +#define KEY_F12			88 +#define KEY_F14			89 +#define KEY_F15			90 +#define KEY_F16			91 +#define KEY_F17			92 +#define KEY_F18			93 +#define KEY_F19			94 +#define KEY_F20			95 +#define KEY_KPENTER		96 +#define KEY_RIGHTCTRL		97 +#define KEY_KPSLASH		98 +#define KEY_SYSRQ		99 +#define KEY_RIGHTALT		100 +#define KEY_LINEFEED		101 +#define KEY_HOME		102 +#define KEY_UP			103 +#define KEY_PAGEUP		104 +#define KEY_LEFT		105 +#define KEY_RIGHT		106 +#define KEY_END			107 +#define KEY_DOWN		108 +#define KEY_PAGEDOWN		109 +#define KEY_INSERT		110 +#define KEY_DELETE		111 +#define KEY_MACRO		112 +#define KEY_MUTE		113 +#define KEY_VOLUMEDOWN		114 +#define KEY_VOLUMEUP		115 +#define KEY_POWER		116 +#define KEY_KPEQUAL		117 +#define KEY_KPPLUSMINUS		118 +#define KEY_PAUSE		119 +#define KEY_F21			120 +#define KEY_F22			121 +#define KEY_F23			122 +#define KEY_F24			123 +#define KEY_KPCOMMA		124 +#define KEY_LEFTMETA		125 +#define KEY_RIGHTMETA		126 +#define KEY_COMPOSE		127 + +#define KEY_STOP		128 +#define KEY_AGAIN		129 +#define KEY_PROPS		130 +#define KEY_UNDO		131 +#define KEY_FRONT		132 +#define KEY_COPY		133 +#define KEY_OPEN		134 +#define KEY_PASTE		135 +#define KEY_FIND		136 +#define KEY_CUT			137 +#define KEY_HELP		138 +#define KEY_MENU		139 +#define KEY_CALC		140 +#define KEY_SETUP		141 +#define KEY_SLEEP		142 +#define KEY_WAKEUP		143 +#define KEY_FILE		144 +#define KEY_SENDFILE		145 +#define KEY_DELETEFILE		146 +#define KEY_XFER		147 +#define KEY_PROG1		148 +#define KEY_PROG2		149 +#define KEY_WWW			150 +#define KEY_MSDOS		151 +#define KEY_COFFEE		152 +#define KEY_DIRECTION		153 +#define KEY_CYCLEWINDOWS	154 +#define KEY_MAIL		155 +#define KEY_BOOKMARKS		156 +#define KEY_COMPUTER		157 +#define KEY_BACK		158 +#define KEY_FORWARD		159 +#define KEY_CLOSECD		160 +#define KEY_EJECTCD		161 +#define KEY_EJECTCLOSECD	162 +#define KEY_NEXTSONG		163 +#define KEY_PLAYPAUSE		164 +#define KEY_PREVIOUSSONG	165 +#define KEY_STOPCD		166 +#define KEY_RECORD		167 +#define KEY_REWIND		168 +#define KEY_PHONE		169 +#define KEY_ISO			170 +#define KEY_CONFIG		171 +#define KEY_HOMEPAGE		172 +#define KEY_REFRESH		173 +#define KEY_EXIT		174 +#define KEY_MOVE		175 +#define KEY_EDIT		176 +#define KEY_SCROLLUP		177 +#define KEY_SCROLLDOWN		178 +#define KEY_KPLEFTPAREN		179 +#define KEY_KPRIGHTPAREN	180 + +#define KEY_INTL1		181 +#define KEY_INTL2		182 +#define KEY_INTL3		183 +#define KEY_INTL4		184 +#define KEY_INTL5		185 +#define KEY_INTL6		186 +#define KEY_INTL7		187 +#define KEY_INTL8		188 +#define KEY_INTL9		189 +#define KEY_LANG1		190 +#define KEY_LANG2		191 +#define KEY_LANG3		192 +#define KEY_LANG4		193 +#define KEY_LANG5		194 +#define KEY_LANG6		195 +#define KEY_LANG7		196 +#define KEY_LANG8		197 +#define KEY_LANG9		198 + +#define KEY_PLAYCD		200 +#define KEY_PAUSECD		201 +#define KEY_PROG3		202 +#define KEY_PROG4		203 +#define KEY_SUSPEND		205 +#define KEY_CLOSE		206 + +#define KEY_UNKNOWN		220 + +#define KEY_BRIGHTNESSDOWN	224 +#define KEY_BRIGHTNESSUP	225 + +#define BTN_MISC		0x100 +#define BTN_0			0x100 +#define BTN_1			0x101 +#define BTN_2			0x102 +#define BTN_3			0x103 +#define BTN_4			0x104 +#define BTN_5			0x105 +#define BTN_6			0x106 +#define BTN_7			0x107 +#define BTN_8			0x108 +#define BTN_9			0x109 + +#define BTN_MOUSE		0x110 +#define BTN_LEFT		0x110 +#define BTN_RIGHT		0x111 +#define BTN_MIDDLE		0x112 +#define BTN_SIDE		0x113 +#define BTN_EXTRA		0x114 +#define BTN_FORWARD		0x115 +#define BTN_BACK		0x116 +#define BTN_TASK		0x117 + +#define BTN_JOYSTICK		0x120 +#define BTN_TRIGGER		0x120 +#define BTN_THUMB		0x121 +#define BTN_THUMB2		0x122 +#define BTN_TOP			0x123 +#define BTN_TOP2		0x124 +#define BTN_PINKIE		0x125 +#define BTN_BASE		0x126 +#define BTN_BASE2		0x127 +#define BTN_BASE3		0x128 +#define BTN_BASE4		0x129 +#define BTN_BASE5		0x12a +#define BTN_BASE6		0x12b +#define BTN_DEAD		0x12f + +#define BTN_GAMEPAD		0x130 +#define BTN_A			0x130 +#define BTN_B			0x131 +#define BTN_C			0x132 +#define BTN_X			0x133 +#define BTN_Y			0x134 +#define BTN_Z			0x135 +#define BTN_TL			0x136 +#define BTN_TR			0x137 +#define BTN_TL2			0x138 +#define BTN_TR2			0x139 +#define BTN_SELECT		0x13a +#define BTN_START		0x13b +#define BTN_MODE		0x13c +#define BTN_THUMBL		0x13d +#define BTN_THUMBR		0x13e + +#define BTN_DIGI		0x140 +#define BTN_TOOL_PEN		0x140 +#define BTN_TOOL_RUBBER		0x141 +#define BTN_TOOL_BRUSH		0x142 +#define BTN_TOOL_PENCIL		0x143 +#define BTN_TOOL_AIRBRUSH	0x144 +#define BTN_TOOL_FINGER		0x145 +#define BTN_TOOL_MOUSE		0x146 +#define BTN_TOOL_LENS		0x147 +#define BTN_TOUCH		0x14a +#define BTN_STYLUS		0x14b +#define BTN_STYLUS2		0x14c +#define BTN_TOOL_DOUBLETAP	0x14d +#define BTN_TOOL_TRIPLETAP	0x14e + +#define BTN_WHEEL		0x150 +#define BTN_GEAR_DOWN		0x150 +#define BTN_GEAR_UP		0x151 + +#define KEY_MAX			0x1ff + +/* Relative axes */ + +#define REL_X			0x00 +#define REL_Y			0x01 +#define REL_Z			0x02 +#define REL_RX			0x03 +#define REL_RY			0x04 +#define REL_RZ			0x05 +#define REL_HWHEEL		0x06 +#define REL_DIAL		0x07 +#define REL_WHEEL		0x08 +#define REL_MISC		0x09 +#define REL_MAX			0x0f + +/* Absolute axes */ + +#define ABS_X			0x00 +#define ABS_Y			0x01 +#define ABS_Z			0x02 +#define ABS_RX			0x03 +#define ABS_RY			0x04 +#define ABS_RZ			0x05 +#define ABS_THROTTLE		0x06 +#define ABS_RUDDER		0x07 +#define ABS_WHEEL		0x08 +#define ABS_GAS			0x09 +#define ABS_BRAKE		0x0a +#define ABS_HAT0X		0x10 +#define ABS_HAT0Y		0x11 +#define ABS_HAT1X		0x12 +#define ABS_HAT1Y		0x13 +#define ABS_HAT2X		0x14 +#define ABS_HAT2Y		0x15 +#define ABS_HAT3X		0x16 +#define ABS_HAT3Y		0x17 +#define ABS_PRESSURE		0x18 +#define ABS_DISTANCE		0x19 +#define ABS_TILT_X		0x1a +#define ABS_TILT_Y		0x1b +#define ABS_TOOL_WIDTH		0x1c +#define ABS_VOLUME		0x20 +#define ABS_MISC		0x28 +#define ABS_MAX			0x3f + +/* Switch events */ + +#define SW_0			0x00 +#define SW_1			0x01 +#define SW_2			0x02 +#define SW_3			0x03 +#define SW_4			0x04 +#define SW_5			0x05 +#define SW_6			0x06 +#define SW_7			0x07 +#define SW_MAX			0x0f + +/* Misc events */ + +#define MSC_SERIAL		0x00 +#define MSC_PULSELED		0x01 +#define MSC_GESTURE		0x02 +#define MSC_RAW			0x03 +#define MSC_SCAN		0x04 +#define MSC_MAX			0x07 + +/* LEDs */ + +#define LED_NUML		0x00 +#define LED_CAPSL		0x01 +#define LED_SCROLLL		0x02 +#define LED_COMPOSE		0x03 +#define LED_KANA		0x04 +#define LED_SLEEP		0x05 +#define LED_SUSPEND		0x06 +#define LED_MUTE		0x07 +#define LED_MISC		0x08 +#define LED_MAIL		0x09 +#define LED_CHARGING		0x0a +#define LED_MAX			0x0f + +/* Autorepeat values */ + +#define REP_DELAY		0x00 +#define REP_PERIOD		0x01 +#define REP_MAX			0x01 + +/* Sounds */ + +#define SND_CLICK		0x00 +#define SND_BELL		0x01 +#define SND_TONE		0x02 +#define SND_MAX			0x07 + +/* Identifiers */ + +#define ID_BUS			0 +#define ID_VENDOR		1 +#define ID_PRODUCT		2 +#define ID_VERSION		3 + +#define BUS_PCI			0x01 +#define BUS_ISAPNP		0x02 +#define BUS_USB			0x03 +#define BUS_HIL			0x04 +#define BUS_BLUETOOTH		0x05 + +#define BUS_ISA			0x10 +#define BUS_I8042		0x11 +#define BUS_XTKBD		0x12 +#define BUS_RS232		0x13 +#define BUS_GAMEPORT		0x14 +#define BUS_PARPORT		0x15 +#define BUS_AMIGA		0x16 +#define BUS_ADB			0x17 +#define BUS_I2C			0x18 +#define BUS_HOST		0x19 +#define BUS_GSC			0x1A + +/* User input interface */ + +#define UINPUT_IOCTL_BASE	'U' + +#define UI_DEV_CREATE		_IO(UINPUT_IOCTL_BASE, 1) +#define UI_DEV_DESTROY		_IO(UINPUT_IOCTL_BASE, 2) + +#define UI_SET_EVBIT		_IOW(UINPUT_IOCTL_BASE, 100, int) +#define UI_SET_KEYBIT		_IOW(UINPUT_IOCTL_BASE, 101, int) +#define UI_SET_RELBIT		_IOW(UINPUT_IOCTL_BASE, 102, int) +#define UI_SET_ABSBIT		_IOW(UINPUT_IOCTL_BASE, 103, int) +#define UI_SET_MSCBIT		_IOW(UINPUT_IOCTL_BASE, 104, int) +#define UI_SET_LEDBIT		_IOW(UINPUT_IOCTL_BASE, 105, int) +#define UI_SET_SNDBIT		_IOW(UINPUT_IOCTL_BASE, 106, int) +#define UI_SET_FFBIT		_IOW(UINPUT_IOCTL_BASE, 107, int) +#define UI_SET_PHYS		_IOW(UINPUT_IOCTL_BASE, 108, char*) +#define UI_SET_SWBIT		_IOW(UINPUT_IOCTL_BASE, 109, int) + +#ifndef NBITS +#define NBITS(x) ((((x) - 1) / (sizeof(long) * 8)) + 1) +#endif + +#define UINPUT_MAX_NAME_SIZE	80 + +struct uinput_id { +	uint16_t bustype; +	uint16_t vendor; +	uint16_t product; +	uint16_t version; +}; + +struct uinput_dev { +	char name[UINPUT_MAX_NAME_SIZE]; +	struct uinput_id id; +	int ff_effects_max; +	int absmax[ABS_MAX + 1]; +	int absmin[ABS_MAX + 1]; +	int absfuzz[ABS_MAX + 1]; +	int absflat[ABS_MAX + 1]; +}; + +struct uinput_event { +	struct timeval time; +	uint16_t type; +	uint16_t code; +	int32_t value; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __UINPUT_H */ | 
