summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-12-09 11:43:09 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-12-09 11:43:09 +0000
commitd7cde36719252eaab14fad2d2c094bb6e7003059 (patch)
tree4af5f9442ed84990c339876c112382404b3860e4
parentb039c1a971aa2f4d4ca29b8453fbb2a360b5dbf7 (diff)
Add support for the old RFCOMM based EPoX presenter
-rw-r--r--hidd/Makefile.am4
-rw-r--r--hidd/fakehid.c296
-rw-r--r--hidd/sdp.c71
-rw-r--r--hidd/uinput.h516
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");
}
diff --git a/hidd/sdp.c b/hidd/sdp.c
index 285438e8..c86fb2ff 100644
--- a/hidd/sdp.c
+++ b/hidd/sdp.c
@@ -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 */