From d7cde36719252eaab14fad2d2c094bb6e7003059 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Dec 2005 11:43:09 +0000 Subject: Add support for the old RFCOMM based EPoX presenter --- hidd/Makefile.am | 4 +- hidd/fakehid.c | 296 ++++++++++++++++++++++++++++++- hidd/sdp.c | 71 ++++++-- hidd/uinput.h | 516 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 871 insertions(+), 16 deletions(-) create mode 100644 hidd/uinput.h 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 #include +#include +#include +#include +#include +#include +#include #include #include @@ -34,16 +40,300 @@ #include #include "hidd.h" - -#include -#include +#include "uinput.h" #include +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 + * + * + * 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 +#include +#include + +/* 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 */ -- cgit