From: Jason Gerecke <killert...@gmail.com>

The button number to evdev code mapping is non-predictable on some tablets and
needs to be hardcoded in the device files.

Some heuristics is employed here so we don't have to add it to all files, only
the ones that fall out of the heuristics for a specific class.

The Huion 610 Pro currently has a list of assumed mappings to avoid having
warnings in every single client. This requires someone with that device to
fix it.

Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net>
---
 data/bamboo-0fg-s-p.tablet      |   1 +
 data/bamboo-16fg-m-pt.tablet    |   1 +
 data/bamboo-16fg-s-p.tablet     |   1 +
 data/bamboo-16fg-s-pt.tablet    |   1 +
 data/bamboo-16fg-s-t.tablet     |   1 +
 data/bamboo-2fg-fun-m-pt.tablet |   1 +
 data/bamboo-2fg-fun-s-pt.tablet |   1 +
 data/bamboo-2fg-s-pt.tablet     |   1 +
 data/bamboo-2fg-s-t.tablet      |   1 +
 data/bamboo-4fg-fun-m.tablet    |   1 +
 data/bamboo-4fg-fun-s.tablet    |   1 +
 data/bamboo-4fg-s-pt.tablet     |   1 +
 data/bamboo-4fg-s-t.tablet      |   1 +
 data/bamboo-4fg-se-m-pt.tablet  |   1 +
 data/bamboo-4fg-se-s-pt.tablet  |   1 +
 data/huion-h610-pro.tablet      |   2 +
 data/wacom.example              |   3 +
 libwacom/Makefile.am            |   1 +
 libwacom/input-event-codes.h    | 838 ++++++++++++++++++++++++++++++++++++++++
 libwacom/libwacom-database.c    |  96 +++++
 libwacom/libwacom.c             |  30 ++
 libwacom/libwacom.h             |   9 +
 libwacom/libwacomint.h          |   1 +
 test/load.c                     |  23 ++
 24 files changed, 1018 insertions(+)
 create mode 100644 libwacom/input-event-codes.h

diff --git a/data/bamboo-0fg-s-p.tablet b/data/bamboo-0fg-s-p.tablet
index 041fcff..58d3eae 100644
--- a/data/bamboo-0fg-s-p.tablet
+++ b/data/bamboo-0fg-s-p.tablet
@@ -57,3 +57,4 @@ Ring=true
 
 [Buttons]
 Top=A;B;C;D
+EvdevCodes=0x116;0x115;0x110;0x111
diff --git a/data/bamboo-16fg-m-pt.tablet b/data/bamboo-16fg-m-pt.tablet
index d377213..39bce84 100644
--- a/data/bamboo-16fg-m-pt.tablet
+++ b/data/bamboo-16fg-m-pt.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x110;0x115;0x116;0x111
diff --git a/data/bamboo-16fg-s-p.tablet b/data/bamboo-16fg-s-p.tablet
index 8d116db..9d1fe83 100644
--- a/data/bamboo-16fg-s-p.tablet
+++ b/data/bamboo-16fg-s-p.tablet
@@ -21,3 +21,4 @@ Stylus=true
 Reversible=true
 Touch=false
 Buttons=0
+EvdevCodes=0x110;0x115;0x116;0x111
diff --git a/data/bamboo-16fg-s-pt.tablet b/data/bamboo-16fg-s-pt.tablet
index 47f50e4..516a931 100644
--- a/data/bamboo-16fg-s-pt.tablet
+++ b/data/bamboo-16fg-s-pt.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x110;0x115;0x116;0x111
diff --git a/data/bamboo-16fg-s-t.tablet b/data/bamboo-16fg-s-t.tablet
index ca43691..82350d6 100644
--- a/data/bamboo-16fg-s-t.tablet
+++ b/data/bamboo-16fg-s-t.tablet
@@ -24,3 +24,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x110;0x115;0x116;0x111
diff --git a/data/bamboo-2fg-fun-m-pt.tablet b/data/bamboo-2fg-fun-m-pt.tablet
index fae4738..75d3f9f 100644
--- a/data/bamboo-2fg-fun-m-pt.tablet
+++ b/data/bamboo-2fg-fun-m-pt.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/bamboo-2fg-fun-s-pt.tablet b/data/bamboo-2fg-fun-s-pt.tablet
index 47aec96..706c68d 100644
--- a/data/bamboo-2fg-fun-s-pt.tablet
+++ b/data/bamboo-2fg-fun-s-pt.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/bamboo-2fg-s-pt.tablet b/data/bamboo-2fg-s-pt.tablet
index 1bd6a57..1aa6ddb 100644
--- a/data/bamboo-2fg-s-pt.tablet
+++ b/data/bamboo-2fg-s-pt.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/bamboo-2fg-s-t.tablet b/data/bamboo-2fg-s-t.tablet
index 8748ecb..16fd82a 100644
--- a/data/bamboo-2fg-s-t.tablet
+++ b/data/bamboo-2fg-s-t.tablet
@@ -24,3 +24,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/bamboo-4fg-fun-m.tablet b/data/bamboo-4fg-fun-m.tablet
index eee3e54..d791d7e 100644
--- a/data/bamboo-4fg-fun-m.tablet
+++ b/data/bamboo-4fg-fun-m.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/bamboo-4fg-fun-s.tablet b/data/bamboo-4fg-fun-s.tablet
index 7791805..3c976fa 100644
--- a/data/bamboo-4fg-fun-s.tablet
+++ b/data/bamboo-4fg-fun-s.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/bamboo-4fg-s-pt.tablet b/data/bamboo-4fg-s-pt.tablet
index 25d205f..8c4ee02 100644
--- a/data/bamboo-4fg-s-pt.tablet
+++ b/data/bamboo-4fg-s-pt.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/bamboo-4fg-s-t.tablet b/data/bamboo-4fg-s-t.tablet
index 39c9a20..747079c 100644
--- a/data/bamboo-4fg-s-t.tablet
+++ b/data/bamboo-4fg-s-t.tablet
@@ -24,3 +24,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/bamboo-4fg-se-m-pt.tablet b/data/bamboo-4fg-se-m-pt.tablet
index da41297..54943fb 100644
--- a/data/bamboo-4fg-se-m-pt.tablet
+++ b/data/bamboo-4fg-se-m-pt.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/bamboo-4fg-se-s-pt.tablet b/data/bamboo-4fg-se-s-pt.tablet
index c19db4e..689f481 100644
--- a/data/bamboo-4fg-se-s-pt.tablet
+++ b/data/bamboo-4fg-se-s-pt.tablet
@@ -25,3 +25,4 @@ Buttons=4
 
 [Buttons]
 Left=A;B;C;D
+EvdevCodes=0x111;0x116;0x115;0x110
diff --git a/data/huion-h610-pro.tablet b/data/huion-h610-pro.tablet
index 697f894..2cb625e 100644
--- a/data/huion-h610-pro.tablet
+++ b/data/huion-h610-pro.tablet
@@ -20,3 +20,5 @@ Buttons=8
 
 [Buttons]
 Left=A;B;C;D;E;F;G;H
+# FIXME: This needs to be verified by someone with an actual device
+EvdevCodes=0x100;0x101;0x102;0x103;0x104;0x105;0x106;0x107
diff --git a/data/wacom.example b/data/wacom.example
index 376a56d..3765371 100644
--- a/data/wacom.example
+++ b/data/wacom.example
@@ -123,6 +123,9 @@ Left=A;B
 Right=C;D
 Top=
 Bottom=
+# The evdev codes for the buttons in order A, B, C, ...
+# The code must be defined for all buttons or this line is ignored
+EvdevCodes=0x110;0x112;0x111;0x113
 
 #####################
 # ADVANCED FEATURES #
diff --git a/libwacom/Makefile.am b/libwacom/Makefile.am
index a990e67..7bdbd61 100644
--- a/libwacom/Makefile.am
+++ b/libwacom/Makefile.am
@@ -3,6 +3,7 @@ lib_LTLIBRARIES=libwacom.la
 AM_CPPFLAGS = $(GLIB_CFLAGS) -DDATADIR="\"$(datadir)/libwacom\"" 
-DG_LOG_DOMAIN="\"$(PACKAGE)\""
 
 libwacom_la_SOURCES = \
+                      input-event-codes.h \
                       libwacom.h \
                       libwacomint.h \
                       libwacom.c \
diff --git a/libwacom/input-event-codes.h b/libwacom/input-event-codes.h
new file mode 100644
index 0000000..f5a8d96
--- /dev/null
+++ b/libwacom/input-event-codes.h
@@ -0,0 +1,838 @@
+/*
+ * Input event codes
+ *
+ *    *** IMPORTANT ***
+ * This file is not only included from C-code but also from devicetree source
+ * files. As such this file MUST only contain comments and defines.
+ *
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2015 Hans de Goede <hdego...@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#ifndef _UAPI_INPUT_EVENT_CODES_H
+#define _UAPI_INPUT_EVENT_CODES_H
+
+/*
+ * Device properties and quirks
+ */
+
+#define INPUT_PROP_POINTER             0x00    /* needs a pointer */
+#define INPUT_PROP_DIRECT              0x01    /* direct input devices */
+#define INPUT_PROP_BUTTONPAD           0x02    /* has button(s) under pad */
+#define INPUT_PROP_SEMI_MT             0x03    /* touch rectangle only */
+#define INPUT_PROP_TOPBUTTONPAD                0x04    /* softbuttons at top 
of pad */
+#define INPUT_PROP_POINTING_STICK      0x05    /* is a pointing stick */
+#define INPUT_PROP_ACCELEROMETER       0x06    /* has accelerometer */
+
+#define INPUT_PROP_MAX                 0x1f
+#define INPUT_PROP_CNT                 (INPUT_PROP_MAX + 1)
+
+/*
+ * Event types
+ */
+
+#define EV_SYN                 0x00
+#define EV_KEY                 0x01
+#define EV_REL                 0x02
+#define EV_ABS                 0x03
+#define EV_MSC                 0x04
+#define EV_SW                  0x05
+#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
+#define EV_CNT                 (EV_MAX+1)
+
+/*
+ * Synchronization events.
+ */
+
+#define SYN_REPORT             0
+#define SYN_CONFIG             1
+#define SYN_MT_REPORT          2
+#define SYN_DROPPED            3
+#define SYN_MAX                        0xf
+#define SYN_CNT                        (SYN_MAX+1)
+
+/*
+ * Keys and buttons
+ *
+ * Most of the keys/buttons are modeled after USB HUT 1.12
+ * (see http://www.usb.org/developers/hidpage).
+ * Abbreviations in the comments:
+ * AC - Application Control
+ * AL - Application Launch Button
+ * SC - System Control
+ */
+
+#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_ZENKAKUHANKAKU     85
+#define KEY_102ND              86
+#define KEY_F11                        87
+#define KEY_F12                        88
+#define KEY_RO                 89
+#define KEY_KATAKANA           90
+#define KEY_HIRAGANA           91
+#define KEY_HENKAN             92
+#define KEY_KATAKANAHIRAGANA   93
+#define KEY_MUHENKAN           94
+#define KEY_KPJPCOMMA          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     /* SC System Power Down */
+#define KEY_KPEQUAL            117
+#define KEY_KPPLUSMINUS                118
+#define KEY_PAUSE              119
+#define KEY_SCALE              120     /* AL Compiz Scale (Expose) */
+
+#define KEY_KPCOMMA            121
+#define KEY_HANGEUL            122
+#define KEY_HANGUEL            KEY_HANGEUL
+#define KEY_HANJA              123
+#define KEY_YEN                        124
+#define KEY_LEFTMETA           125
+#define KEY_RIGHTMETA          126
+#define KEY_COMPOSE            127
+
+#define KEY_STOP               128     /* AC Stop */
+#define KEY_AGAIN              129
+#define KEY_PROPS              130     /* AC Properties */
+#define KEY_UNDO               131     /* AC Undo */
+#define KEY_FRONT              132
+#define KEY_COPY               133     /* AC Copy */
+#define KEY_OPEN               134     /* AC Open */
+#define KEY_PASTE              135     /* AC Paste */
+#define KEY_FIND               136     /* AC Search */
+#define KEY_CUT                        137     /* AC Cut */
+#define KEY_HELP               138     /* AL Integrated Help Center */
+#define KEY_MENU               139     /* Menu (show menu) */
+#define KEY_CALC               140     /* AL Calculator */
+#define KEY_SETUP              141
+#define KEY_SLEEP              142     /* SC System Sleep */
+#define KEY_WAKEUP             143     /* System Wake Up */
+#define KEY_FILE               144     /* AL Local Machine Browser */
+#define KEY_SENDFILE           145
+#define KEY_DELETEFILE         146
+#define KEY_XFER               147
+#define KEY_PROG1              148
+#define KEY_PROG2              149
+#define KEY_WWW                        150     /* AL Internet Browser */
+#define KEY_MSDOS              151
+#define KEY_COFFEE             152     /* AL Terminal Lock/Screensaver */
+#define KEY_SCREENLOCK         KEY_COFFEE
+#define KEY_ROTATE_DISPLAY     153     /* Display orientation for e.g. tablets 
*/
+#define KEY_DIRECTION          KEY_ROTATE_DISPLAY
+#define KEY_CYCLEWINDOWS       154
+#define KEY_MAIL               155
+#define KEY_BOOKMARKS          156     /* AC Bookmarks */
+#define KEY_COMPUTER           157
+#define KEY_BACK               158     /* AC Back */
+#define KEY_FORWARD            159     /* AC Forward */
+#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     /* Media Select Telephone */
+#define KEY_ISO                        170
+#define KEY_CONFIG             171     /* AL Consumer Control Configuration */
+#define KEY_HOMEPAGE           172     /* AC Home */
+#define KEY_REFRESH            173     /* AC Refresh */
+#define KEY_EXIT               174     /* AC Exit */
+#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_NEW                        181     /* AC New */
+#define KEY_REDO               182     /* AC Redo/Repeat */
+
+#define KEY_F13                        183
+#define KEY_F14                        184
+#define KEY_F15                        185
+#define KEY_F16                        186
+#define KEY_F17                        187
+#define KEY_F18                        188
+#define KEY_F19                        189
+#define KEY_F20                        190
+#define KEY_F21                        191
+#define KEY_F22                        192
+#define KEY_F23                        193
+#define KEY_F24                        194
+
+#define KEY_PLAYCD             200
+#define KEY_PAUSECD            201
+#define KEY_PROG3              202
+#define KEY_PROG4              203
+#define KEY_DASHBOARD          204     /* AL Dashboard */
+#define KEY_SUSPEND            205
+#define KEY_CLOSE              206     /* AC Close */
+#define KEY_PLAY               207
+#define KEY_FASTFORWARD                208
+#define KEY_BASSBOOST          209
+#define KEY_PRINT              210     /* AC Print */
+#define KEY_HP                 211
+#define KEY_CAMERA             212
+#define KEY_SOUND              213
+#define KEY_QUESTION           214
+#define KEY_EMAIL              215
+#define KEY_CHAT               216
+#define KEY_SEARCH             217
+#define KEY_CONNECT            218
+#define KEY_FINANCE            219     /* AL Checkbook/Finance */
+#define KEY_SPORT              220
+#define KEY_SHOP               221
+#define KEY_ALTERASE           222
+#define KEY_CANCEL             223     /* AC Cancel */
+#define KEY_BRIGHTNESSDOWN     224
+#define KEY_BRIGHTNESSUP       225
+#define KEY_MEDIA              226
+
+#define KEY_SWITCHVIDEOMODE    227     /* Cycle between available video
+                                          outputs (Monitor/LCD/TV-out/etc) */
+#define KEY_KBDILLUMTOGGLE     228
+#define KEY_KBDILLUMDOWN       229
+#define KEY_KBDILLUMUP         230
+
+#define KEY_SEND               231     /* AC Send */
+#define KEY_REPLY              232     /* AC Reply */
+#define KEY_FORWARDMAIL                233     /* AC Forward Msg */
+#define KEY_SAVE               234     /* AC Save */
+#define KEY_DOCUMENTS          235
+
+#define KEY_BATTERY            236
+
+#define KEY_BLUETOOTH          237
+#define KEY_WLAN               238
+#define KEY_UWB                        239
+
+#define KEY_UNKNOWN            240
+
+#define KEY_VIDEO_NEXT         241     /* drive next video source */
+#define KEY_VIDEO_PREV         242     /* drive previous video source */
+#define KEY_BRIGHTNESS_CYCLE   243     /* brightness up, after max is min */
+#define KEY_BRIGHTNESS_AUTO    244     /* Set Auto Brightness: manual
+                                         brightness control is off,
+                                         rely on ambient */
+#define KEY_BRIGHTNESS_ZERO    KEY_BRIGHTNESS_AUTO
+#define KEY_DISPLAY_OFF                245     /* display device to off state 
*/
+
+#define KEY_WWAN               246     /* Wireless WAN (LTE, UMTS, GSM, etc.) 
*/
+#define KEY_WIMAX              KEY_WWAN
+#define KEY_RFKILL             247     /* Key that controls all radios */
+
+#define KEY_MICMUTE            248     /* Mute / unmute the microphone */
+
+/* Code 255 is reserved for special needs of AT keyboard driver */
+
+#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_SOUTH              0x130
+#define BTN_A                  BTN_SOUTH
+#define BTN_EAST               0x131
+#define BTN_B                  BTN_EAST
+#define BTN_C                  0x132
+#define BTN_NORTH              0x133
+#define BTN_X                  BTN_NORTH
+#define BTN_WEST               0x134
+#define BTN_Y                  BTN_WEST
+#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_TOOL_QUINTTAP      0x148   /* Five fingers on trackpad */
+#define BTN_TOUCH              0x14a
+#define BTN_STYLUS             0x14b
+#define BTN_STYLUS2            0x14c
+#define BTN_TOOL_DOUBLETAP     0x14d
+#define BTN_TOOL_TRIPLETAP     0x14e
+#define BTN_TOOL_QUADTAP       0x14f   /* Four fingers on trackpad */
+
+#define BTN_WHEEL              0x150
+#define BTN_GEAR_DOWN          0x150
+#define BTN_GEAR_UP            0x151
+
+#define KEY_OK                 0x160
+#define KEY_SELECT             0x161
+#define KEY_GOTO               0x162
+#define KEY_CLEAR              0x163
+#define KEY_POWER2             0x164
+#define KEY_OPTION             0x165
+#define KEY_INFO               0x166   /* AL OEM Features/Tips/Tutorial */
+#define KEY_TIME               0x167
+#define KEY_VENDOR             0x168
+#define KEY_ARCHIVE            0x169
+#define KEY_PROGRAM            0x16a   /* Media Select Program Guide */
+#define KEY_CHANNEL            0x16b
+#define KEY_FAVORITES          0x16c
+#define KEY_EPG                        0x16d
+#define KEY_PVR                        0x16e   /* Media Select Home */
+#define KEY_MHP                        0x16f
+#define KEY_LANGUAGE           0x170
+#define KEY_TITLE              0x171
+#define KEY_SUBTITLE           0x172
+#define KEY_ANGLE              0x173
+#define KEY_ZOOM               0x174
+#define KEY_MODE               0x175
+#define KEY_KEYBOARD           0x176
+#define KEY_SCREEN             0x177
+#define KEY_PC                 0x178   /* Media Select Computer */
+#define KEY_TV                 0x179   /* Media Select TV */
+#define KEY_TV2                        0x17a   /* Media Select Cable */
+#define KEY_VCR                        0x17b   /* Media Select VCR */
+#define KEY_VCR2               0x17c   /* VCR Plus */
+#define KEY_SAT                        0x17d   /* Media Select Satellite */
+#define KEY_SAT2               0x17e
+#define KEY_CD                 0x17f   /* Media Select CD */
+#define KEY_TAPE               0x180   /* Media Select Tape */
+#define KEY_RADIO              0x181
+#define KEY_TUNER              0x182   /* Media Select Tuner */
+#define KEY_PLAYER             0x183
+#define KEY_TEXT               0x184
+#define KEY_DVD                        0x185   /* Media Select DVD */
+#define KEY_AUX                        0x186
+#define KEY_MP3                        0x187
+#define KEY_AUDIO              0x188   /* AL Audio Browser */
+#define KEY_VIDEO              0x189   /* AL Movie Browser */
+#define KEY_DIRECTORY          0x18a
+#define KEY_LIST               0x18b
+#define KEY_MEMO               0x18c   /* Media Select Messages */
+#define KEY_CALENDAR           0x18d
+#define KEY_RED                        0x18e
+#define KEY_GREEN              0x18f
+#define KEY_YELLOW             0x190
+#define KEY_BLUE               0x191
+#define KEY_CHANNELUP          0x192   /* Channel Increment */
+#define KEY_CHANNELDOWN                0x193   /* Channel Decrement */
+#define KEY_FIRST              0x194
+#define KEY_LAST               0x195   /* Recall Last */
+#define KEY_AB                 0x196
+#define KEY_NEXT               0x197
+#define KEY_RESTART            0x198
+#define KEY_SLOW               0x199
+#define KEY_SHUFFLE            0x19a
+#define KEY_BREAK              0x19b
+#define KEY_PREVIOUS           0x19c
+#define KEY_DIGITS             0x19d
+#define KEY_TEEN               0x19e
+#define KEY_TWEN               0x19f
+#define KEY_VIDEOPHONE         0x1a0   /* Media Select Video Phone */
+#define KEY_GAMES              0x1a1   /* Media Select Games */
+#define KEY_ZOOMIN             0x1a2   /* AC Zoom In */
+#define KEY_ZOOMOUT            0x1a3   /* AC Zoom Out */
+#define KEY_ZOOMRESET          0x1a4   /* AC Zoom */
+#define KEY_WORDPROCESSOR      0x1a5   /* AL Word Processor */
+#define KEY_EDITOR             0x1a6   /* AL Text Editor */
+#define KEY_SPREADSHEET                0x1a7   /* AL Spreadsheet */
+#define KEY_GRAPHICSEDITOR     0x1a8   /* AL Graphics Editor */
+#define KEY_PRESENTATION       0x1a9   /* AL Presentation App */
+#define KEY_DATABASE           0x1aa   /* AL Database App */
+#define KEY_NEWS               0x1ab   /* AL Newsreader */
+#define KEY_VOICEMAIL          0x1ac   /* AL Voicemail */
+#define KEY_ADDRESSBOOK                0x1ad   /* AL Contacts/Address Book */
+#define KEY_MESSENGER          0x1ae   /* AL Instant Messaging */
+#define KEY_DISPLAYTOGGLE      0x1af   /* Turn display (LCD) on and off */
+#define KEY_BRIGHTNESS_TOGGLE  KEY_DISPLAYTOGGLE
+#define KEY_SPELLCHECK         0x1b0   /* AL Spell Check */
+#define KEY_LOGOFF             0x1b1   /* AL Logoff */
+
+#define KEY_DOLLAR             0x1b2
+#define KEY_EURO               0x1b3
+
+#define KEY_FRAMEBACK          0x1b4   /* Consumer - transport controls */
+#define KEY_FRAMEFORWARD       0x1b5
+#define KEY_CONTEXT_MENU       0x1b6   /* GenDesc - system context menu */
+#define KEY_MEDIA_REPEAT       0x1b7   /* Consumer - transport control */
+#define KEY_10CHANNELSUP       0x1b8   /* 10 channels up (10+) */
+#define KEY_10CHANNELSDOWN     0x1b9   /* 10 channels down (10-) */
+#define KEY_IMAGES             0x1ba   /* AL Image Browser */
+
+#define KEY_DEL_EOL            0x1c0
+#define KEY_DEL_EOS            0x1c1
+#define KEY_INS_LINE           0x1c2
+#define KEY_DEL_LINE           0x1c3
+
+#define KEY_FN                 0x1d0
+#define KEY_FN_ESC             0x1d1
+#define KEY_FN_F1              0x1d2
+#define KEY_FN_F2              0x1d3
+#define KEY_FN_F3              0x1d4
+#define KEY_FN_F4              0x1d5
+#define KEY_FN_F5              0x1d6
+#define KEY_FN_F6              0x1d7
+#define KEY_FN_F7              0x1d8
+#define KEY_FN_F8              0x1d9
+#define KEY_FN_F9              0x1da
+#define KEY_FN_F10             0x1db
+#define KEY_FN_F11             0x1dc
+#define KEY_FN_F12             0x1dd
+#define KEY_FN_1               0x1de
+#define KEY_FN_2               0x1df
+#define KEY_FN_D               0x1e0
+#define KEY_FN_E               0x1e1
+#define KEY_FN_F               0x1e2
+#define KEY_FN_S               0x1e3
+#define KEY_FN_B               0x1e4
+
+#define KEY_BRL_DOT1           0x1f1
+#define KEY_BRL_DOT2           0x1f2
+#define KEY_BRL_DOT3           0x1f3
+#define KEY_BRL_DOT4           0x1f4
+#define KEY_BRL_DOT5           0x1f5
+#define KEY_BRL_DOT6           0x1f6
+#define KEY_BRL_DOT7           0x1f7
+#define KEY_BRL_DOT8           0x1f8
+#define KEY_BRL_DOT9           0x1f9
+#define KEY_BRL_DOT10          0x1fa
+
+#define KEY_NUMERIC_0          0x200   /* used by phones, remote controls, */
+#define KEY_NUMERIC_1          0x201   /* and other keypads */
+#define KEY_NUMERIC_2          0x202
+#define KEY_NUMERIC_3          0x203
+#define KEY_NUMERIC_4          0x204
+#define KEY_NUMERIC_5          0x205
+#define KEY_NUMERIC_6          0x206
+#define KEY_NUMERIC_7          0x207
+#define KEY_NUMERIC_8          0x208
+#define KEY_NUMERIC_9          0x209
+#define KEY_NUMERIC_STAR       0x20a
+#define KEY_NUMERIC_POUND      0x20b
+#define KEY_NUMERIC_A          0x20c   /* Phone key A - HUT Telephony 0xb9 */
+#define KEY_NUMERIC_B          0x20d
+#define KEY_NUMERIC_C          0x20e
+#define KEY_NUMERIC_D          0x20f
+
+#define KEY_CAMERA_FOCUS       0x210
+#define KEY_WPS_BUTTON         0x211   /* WiFi Protected Setup key */
+
+#define KEY_TOUCHPAD_TOGGLE    0x212   /* Request switch touchpad on or off */
+#define KEY_TOUCHPAD_ON                0x213
+#define KEY_TOUCHPAD_OFF       0x214
+
+#define KEY_CAMERA_ZOOMIN      0x215
+#define KEY_CAMERA_ZOOMOUT     0x216
+#define KEY_CAMERA_UP          0x217
+#define KEY_CAMERA_DOWN                0x218
+#define KEY_CAMERA_LEFT                0x219
+#define KEY_CAMERA_RIGHT       0x21a
+
+#define KEY_ATTENDANT_ON       0x21b
+#define KEY_ATTENDANT_OFF      0x21c
+#define KEY_ATTENDANT_TOGGLE   0x21d   /* Attendant call on or off */
+#define KEY_LIGHTS_TOGGLE      0x21e   /* Reading light on or off */
+
+#define BTN_DPAD_UP            0x220
+#define BTN_DPAD_DOWN          0x221
+#define BTN_DPAD_LEFT          0x222
+#define BTN_DPAD_RIGHT         0x223
+
+#define KEY_ALS_TOGGLE         0x230   /* Ambient light sensor */
+
+#define KEY_BUTTONCONFIG               0x240   /* AL Button Configuration */
+#define KEY_TASKMANAGER                0x241   /* AL Task/Project Manager */
+#define KEY_JOURNAL            0x242   /* AL Log/Journal/Timecard */
+#define KEY_CONTROLPANEL               0x243   /* AL Control Panel */
+#define KEY_APPSELECT          0x244   /* AL Select Task/Application */
+#define KEY_SCREENSAVER                0x245   /* AL Screen Saver */
+#define KEY_VOICECOMMAND               0x246   /* Listening Voice Command */
+
+#define KEY_BRIGHTNESS_MIN             0x250   /* Set Brightness to Minimum */
+#define KEY_BRIGHTNESS_MAX             0x251   /* Set Brightness to Maximum */
+
+#define KEY_KBDINPUTASSIST_PREV                0x260
+#define KEY_KBDINPUTASSIST_NEXT                0x261
+#define KEY_KBDINPUTASSIST_PREVGROUP           0x262
+#define KEY_KBDINPUTASSIST_NEXTGROUP           0x263
+#define KEY_KBDINPUTASSIST_ACCEPT              0x264
+#define KEY_KBDINPUTASSIST_CANCEL              0x265
+
+/* Diagonal movement keys */
+#define KEY_RIGHT_UP                   0x266
+#define KEY_RIGHT_DOWN                 0x267
+#define KEY_LEFT_UP                    0x268
+#define KEY_LEFT_DOWN                  0x269
+
+#define KEY_ROOT_MENU                  0x26a /* Show Device's Root Menu */
+/* Show Top Menu of the Media (e.g. DVD) */
+#define KEY_MEDIA_TOP_MENU             0x26b
+#define KEY_NUMERIC_11                 0x26c
+#define KEY_NUMERIC_12                 0x26d
+/*
+ * Toggle Audio Description: refers to an audio service that helps blind and
+ * visually impaired consumers understand the action in a program. Note: in
+ * some countries this is referred to as "Video Description".
+ */
+#define KEY_AUDIO_DESC                 0x26e
+#define KEY_3D_MODE                    0x26f
+#define KEY_NEXT_FAVORITE              0x270
+#define KEY_STOP_RECORD                        0x271
+#define KEY_PAUSE_RECORD               0x272
+#define KEY_VOD                                0x273 /* Video on Demand */
+#define KEY_UNMUTE                     0x274
+#define KEY_FASTREVERSE                        0x275
+#define KEY_SLOWREVERSE                        0x276
+/*
+ * Control a data application associated with the currently viewed channel,
+ * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
+ */
+#define KEY_DATA                       0x277
+#define KEY_ONSCREEN_KEYBOARD          0x278
+
+#define BTN_TRIGGER_HAPPY              0x2c0
+#define BTN_TRIGGER_HAPPY1             0x2c0
+#define BTN_TRIGGER_HAPPY2             0x2c1
+#define BTN_TRIGGER_HAPPY3             0x2c2
+#define BTN_TRIGGER_HAPPY4             0x2c3
+#define BTN_TRIGGER_HAPPY5             0x2c4
+#define BTN_TRIGGER_HAPPY6             0x2c5
+#define BTN_TRIGGER_HAPPY7             0x2c6
+#define BTN_TRIGGER_HAPPY8             0x2c7
+#define BTN_TRIGGER_HAPPY9             0x2c8
+#define BTN_TRIGGER_HAPPY10            0x2c9
+#define BTN_TRIGGER_HAPPY11            0x2ca
+#define BTN_TRIGGER_HAPPY12            0x2cb
+#define BTN_TRIGGER_HAPPY13            0x2cc
+#define BTN_TRIGGER_HAPPY14            0x2cd
+#define BTN_TRIGGER_HAPPY15            0x2ce
+#define BTN_TRIGGER_HAPPY16            0x2cf
+#define BTN_TRIGGER_HAPPY17            0x2d0
+#define BTN_TRIGGER_HAPPY18            0x2d1
+#define BTN_TRIGGER_HAPPY19            0x2d2
+#define BTN_TRIGGER_HAPPY20            0x2d3
+#define BTN_TRIGGER_HAPPY21            0x2d4
+#define BTN_TRIGGER_HAPPY22            0x2d5
+#define BTN_TRIGGER_HAPPY23            0x2d6
+#define BTN_TRIGGER_HAPPY24            0x2d7
+#define BTN_TRIGGER_HAPPY25            0x2d8
+#define BTN_TRIGGER_HAPPY26            0x2d9
+#define BTN_TRIGGER_HAPPY27            0x2da
+#define BTN_TRIGGER_HAPPY28            0x2db
+#define BTN_TRIGGER_HAPPY29            0x2dc
+#define BTN_TRIGGER_HAPPY30            0x2dd
+#define BTN_TRIGGER_HAPPY31            0x2de
+#define BTN_TRIGGER_HAPPY32            0x2df
+#define BTN_TRIGGER_HAPPY33            0x2e0
+#define BTN_TRIGGER_HAPPY34            0x2e1
+#define BTN_TRIGGER_HAPPY35            0x2e2
+#define BTN_TRIGGER_HAPPY36            0x2e3
+#define BTN_TRIGGER_HAPPY37            0x2e4
+#define BTN_TRIGGER_HAPPY38            0x2e5
+#define BTN_TRIGGER_HAPPY39            0x2e6
+#define BTN_TRIGGER_HAPPY40            0x2e7
+
+/* We avoid low common keys in module aliases so they don't get huge. */
+#define KEY_MIN_INTERESTING    KEY_MUTE
+#define KEY_MAX                        0x2ff
+#define KEY_CNT                        (KEY_MAX+1)
+
+/*
+ * 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
+#define REL_CNT                        (REL_MAX+1)
+
+/*
+ * 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_MT_SLOT            0x2f    /* MT slot being modified */
+#define ABS_MT_TOUCH_MAJOR     0x30    /* Major axis of touching ellipse */
+#define ABS_MT_TOUCH_MINOR     0x31    /* Minor axis (omit if circular) */
+#define ABS_MT_WIDTH_MAJOR     0x32    /* Major axis of approaching ellipse */
+#define ABS_MT_WIDTH_MINOR     0x33    /* Minor axis (omit if circular) */
+#define ABS_MT_ORIENTATION     0x34    /* Ellipse orientation */
+#define ABS_MT_POSITION_X      0x35    /* Center X touch position */
+#define ABS_MT_POSITION_Y      0x36    /* Center Y touch position */
+#define ABS_MT_TOOL_TYPE       0x37    /* Type of touching device */
+#define ABS_MT_BLOB_ID         0x38    /* Group a set of packets as a blob */
+#define ABS_MT_TRACKING_ID     0x39    /* Unique ID of initiated contact */
+#define ABS_MT_PRESSURE                0x3a    /* Pressure on contact area */
+#define ABS_MT_DISTANCE                0x3b    /* Contact hover distance */
+#define ABS_MT_TOOL_X          0x3c    /* Center X tool position */
+#define ABS_MT_TOOL_Y          0x3d    /* Center Y tool position */
+
+
+#define ABS_MAX                        0x3f
+#define ABS_CNT                        (ABS_MAX+1)
+
+/*
+ * Switch events
+ */
+
+#define SW_LID                 0x00  /* set = lid shut */
+#define SW_TABLET_MODE         0x01  /* set = tablet mode */
+#define SW_HEADPHONE_INSERT    0x02  /* set = inserted */
+#define SW_RFKILL_ALL          0x03  /* rfkill master switch, type "any"
+                                        set = radio enabled */
+#define SW_RADIO               SW_RFKILL_ALL   /* deprecated */
+#define SW_MICROPHONE_INSERT   0x04  /* set = inserted */
+#define SW_DOCK                        0x05  /* set = plugged into dock */
+#define SW_LINEOUT_INSERT      0x06  /* set = inserted */
+#define SW_JACK_PHYSICAL_INSERT 0x07  /* set = mechanical switch set */
+#define SW_VIDEOOUT_INSERT     0x08  /* set = inserted */
+#define SW_CAMERA_LENS_COVER   0x09  /* set = lens covered */
+#define SW_KEYPAD_SLIDE                0x0a  /* set = keypad slide out */
+#define SW_FRONT_PROXIMITY     0x0b  /* set = front proximity sensor active */
+#define SW_ROTATE_LOCK         0x0c  /* set = rotate locked/disabled */
+#define SW_LINEIN_INSERT       0x0d  /* set = inserted */
+#define SW_MUTE_DEVICE         0x0e  /* set = device disabled */
+#define SW_PEN_INSERTED                0x0f  /* set = pen inserted */
+#define SW_MAX                 0x0f
+#define SW_CNT                 (SW_MAX+1)
+
+/*
+ * Misc events
+ */
+
+#define MSC_SERIAL             0x00
+#define MSC_PULSELED           0x01
+#define MSC_GESTURE            0x02
+#define MSC_RAW                        0x03
+#define MSC_SCAN               0x04
+#define MSC_TIMESTAMP          0x05
+#define MSC_MAX                        0x07
+#define MSC_CNT                        (MSC_MAX+1)
+
+/*
+ * 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
+#define LED_CNT                        (LED_MAX+1)
+
+/*
+ * Autorepeat values
+ */
+
+#define REP_DELAY              0x00
+#define REP_PERIOD             0x01
+#define REP_MAX                        0x01
+#define REP_CNT                        (REP_MAX+1)
+
+/*
+ * Sounds
+ */
+
+#define SND_CLICK              0x00
+#define SND_BELL               0x01
+#define SND_TONE               0x02
+#define SND_MAX                        0x07
+#define SND_CNT                        (SND_MAX+1)
+
+#endif
diff --git a/libwacom/libwacom-database.c b/libwacom/libwacom-database.c
index 1241e99..e98b3a8 100644
--- a/libwacom/libwacom-database.c
+++ b/libwacom/libwacom-database.c
@@ -29,10 +29,13 @@
 #endif
 
 #include "libwacomint.h"
+#include "input-event-codes.h"
 
+#include <assert.h>
 #include <glib.h>
 #include <dirent.h>
 #include <string.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 
@@ -377,6 +380,96 @@ libwacom_parse_buttons_key(WacomDevice      *device,
        g_strfreev (vals);
 }
 
+static inline bool
+set_button_codes_from_string(WacomDevice *device, char **strvals)
+{
+       gint i;
+
+       assert(strvals);
+
+       for (i = 0; i < device->num_buttons; i++) {
+               glong val;
+
+               if (!strvals[i]) {
+                       g_error ("%s: Missing EvdevCode for button %d, ignoring 
all codes\n",
+                                device->name, i);
+                       return false;
+               }
+
+               val = strtol (strvals[i], NULL, 0);
+               if (val < BTN_MISC || val >= BTN_DIGI) {
+                       g_warning ("%s: Invalid EvdevCode %ld for button %d, 
ignoring all codes\n",
+                                  device->name, val, i);
+                       return false;
+               }
+               device->button_codes[i] = (int)val;
+       }
+
+       return true;
+}
+
+static inline void
+set_button_codes_from_heuristics(WacomDevice *device)
+{
+       gint i;
+       for (i = 0; i < device->num_buttons; i++) {
+               if (device->cls == WCLASS_BAMBOO ||
+                   device->cls == WCLASS_GRAPHIRE) {
+                       switch (i) {
+                       case 0:
+                               device->button_codes[i] = BTN_LEFT;
+                               break;
+                       case 1:
+                               device->button_codes[i] = BTN_RIGHT;
+                               break;
+                       case 2:
+                               device->button_codes[i] = BTN_FORWARD;
+                               break;
+                       case 3:
+                               device->button_codes[i] = BTN_BACK;
+                               break;
+                       default:
+                               device->button_codes[i] = 0;
+                               break;
+                       }
+               } else {
+                       /* Assume traditional ExpressKey ordering */
+                       switch (i) {
+                       case 0 ... 9:
+                               device->button_codes[i] = BTN_0 + i;
+                               break;
+                       case 10 ... 15:
+                               device->button_codes[i] = BTN_A + (i-10);
+                               break;
+                       case 16:
+                       case 17:
+                               device->button_codes[i] = BTN_BASE + (i-16);
+                               break;
+                       default:
+                               device->button_codes[i] = 0;
+                               break;
+                       }
+               }
+
+               if (device->button_codes[i] == 0)
+                       g_warning ("Unable to determine evdev code for button 
%d (%s)", i, device->name);
+       }
+}
+
+static void
+libwacom_parse_button_codes(WacomDevice *device,
+                           GKeyFile    *keyfile)
+{
+       char **vals;
+
+       vals = g_key_file_get_string_list(keyfile, BUTTONS_GROUP, "EvdevCodes", 
NULL, NULL);
+       if (!vals ||
+           !set_button_codes_from_string(device, vals))
+               set_button_codes_from_heuristics(device);
+
+       g_strfreev (vals);
+}
+
 static int
 libwacom_parse_num_modes (WacomDevice      *device,
                          GKeyFile         *keyfile,
@@ -405,6 +498,8 @@ libwacom_parse_buttons(WacomDevice *device,
        for (i = 0; i < G_N_ELEMENTS (options); i++)
                libwacom_parse_buttons_key(device, keyfile, options[i].key, 
options[i].flag);
 
+       libwacom_parse_button_codes(device, keyfile);
+
        device->ring_num_modes = libwacom_parse_num_modes(device, keyfile, 
"RingNumModes", WACOM_BUTTON_RING_MODESWITCH);
        device->ring2_num_modes = libwacom_parse_num_modes(device, keyfile, 
"Ring2NumModes", WACOM_BUTTON_RING2_MODESWITCH);
        device->strips_num_modes = libwacom_parse_num_modes(device, keyfile, 
"StripsNumModes", WACOM_BUTTON_TOUCHSTRIP_MODESWITCH);
@@ -570,6 +665,7 @@ libwacom_parse_tablet_keyfile(const char *datadir, const 
char *filename)
        }
        if (device->num_buttons > 0) {
                device->buttons = g_new0 (WacomButtonFlags, 
device->num_buttons);
+               device->button_codes = g_new0 (gint, device->num_buttons);
                libwacom_parse_buttons(device, keyfile);
        }
 
diff --git a/libwacom/libwacom.c b/libwacom/libwacom.c
index 5ab0ab5..197e860 100644
--- a/libwacom/libwacom.c
+++ b/libwacom/libwacom.c
@@ -349,6 +349,7 @@ libwacom_copy(const WacomDevice *device)
        d->status_leds = g_memdup (device->status_leds, sizeof(WacomStatusLEDs) 
* device->num_leds);
        d->num_buttons = device->num_buttons;
        d->buttons = g_memdup (device->buttons, sizeof(WacomButtonFlags) * 
device->num_buttons);
+       d->button_codes = g_memdup (device->button_codes, sizeof(int) * 
device->num_buttons);
        return d;
 }
 
@@ -456,6 +457,9 @@ libwacom_compare(const WacomDevice *a, const WacomDevice 
*b, WacomCompareFlags f
        if (memcmp(a->buttons, b->buttons, sizeof(WacomButtonFlags) * 
a->num_buttons) != 0)
                return 1;
 
+       if (memcmp(a->button_codes, b->button_codes, sizeof(int) * 
a->num_buttons) != 0)
+               return 1;
+
        if ((flags & WCOMPARE_MATCHES) && compare_matches(a, b) != 0)
                return 1;
        else if (strcmp(a->matches[a->match]->match, 
b->matches[b->match]->match) != 0)
@@ -661,6 +665,16 @@ static void print_button_flag_if(int fd, const WacomDevice 
*device, const char *
        dprintf(fd, "\n");
 }
 
+static void print_button_evdev_codes(int fd, const WacomDevice *device)
+{
+       int nbuttons = libwacom_get_num_buttons(device);
+       char b;
+       dprintf(fd, "EvdevCodes=");
+       for (b = 'A'; b < 'A' + nbuttons; b++)
+               dprintf(fd, "0x%x;", libwacom_get_button_evdev_code(device, b));
+       dprintf(fd, "\n");
+}
+
 static void print_buttons_for_device (int fd, const WacomDevice *device)
 {
        int nbuttons = libwacom_get_num_buttons(device);
@@ -679,6 +693,7 @@ static void print_buttons_for_device (int fd, const 
WacomDevice *device)
        print_button_flag_if(fd, device, "OLEDs", WACOM_BUTTON_OLED);
        print_button_flag_if(fd, device, "Ring", WACOM_BUTTON_RING_MODESWITCH);
        print_button_flag_if(fd, device, "Ring2", 
WACOM_BUTTON_RING2_MODESWITCH);
+       print_button_evdev_codes(fd, device);
        dprintf(fd, "RingNumModes=%d\n", libwacom_get_ring_num_modes(device));
        dprintf(fd, "Ring2NumModes=%d\n", libwacom_get_ring2_num_modes(device));
        dprintf(fd, "StripsNumModes=%d\n", 
libwacom_get_strips_num_modes(device));
@@ -811,6 +826,7 @@ libwacom_destroy(WacomDevice *device)
        g_free (device->supported_styli);
        g_free (device->status_leds);
        g_free (device->buttons);
+       g_free (device->button_codes);
        g_free (device);
 }
 
@@ -1053,6 +1069,20 @@ libwacom_get_button_flag(const WacomDevice *device, char 
button)
        return device->buttons[index];
 }
 
+int
+libwacom_get_button_evdev_code(const WacomDevice *device, char button)
+{
+       int index;
+
+       g_return_val_if_fail (device->num_buttons > 0, 0);
+       g_return_val_if_fail (button >= 'A', 0);
+       g_return_val_if_fail (button < 'A' + device->num_buttons, 0);
+
+       index = button - 'A';
+
+       return device->button_codes[index];
+}
+
 const WacomStylus *libwacom_stylus_get_for_id (const WacomDeviceDatabase *db, 
int id)
 {
        return g_hash_table_lookup (db->stylus_ht, GINT_TO_POINTER(id));
diff --git a/libwacom/libwacom.h b/libwacom/libwacom.h
index d4c94ef..3bac686 100644
--- a/libwacom/libwacom.h
+++ b/libwacom/libwacom.h
@@ -550,6 +550,15 @@ WacomButtonFlags libwacom_get_button_flag(const 
WacomDevice *device,
                                          char               button);
 
 /**
+ * @param device The tablet to query
+ * @param button The ID of the button to check for, between 'A' and 'Z'
+ * @return The evdev event code sent when the button is pressed or 0 if
+ * unknown.
+ */
+int libwacom_get_button_evdev_code(const WacomDevice *device,
+                                  char               button);
+
+/**
  * Get the WacomStylus for the given tool ID.
  *
  * @param db A Tablet and Stylus database.
diff --git a/libwacom/libwacomint.h b/libwacom/libwacomint.h
index e887d11..3cf3ace 100644
--- a/libwacom/libwacomint.h
+++ b/libwacom/libwacomint.h
@@ -88,6 +88,7 @@ struct _WacomDevice {
 
        int num_buttons;
        WacomButtonFlags *buttons;
+       int *button_codes;
 
        int num_leds;
        WacomStatusLEDs *status_leds;
diff --git a/test/load.c b/test/load.c
index 583cd06..7d4b907 100644
--- a/test/load.c
+++ b/test/load.c
@@ -28,6 +28,8 @@
 #include "config.h"
 #endif
 
+#include "input-event-codes.h"
+
 #include <stdio.h>
 #include <string.h>
 #include "libwacom.h"
@@ -140,6 +142,27 @@ int main(int argc, char **argv)
        assert(libwacom_match_get_product_id(match) == 0xf6);
        assert(libwacom_match_get_bustype(match) == WBUSTYPE_USB);
 
+       device = libwacom_new_from_name(db, "Wacom Cintiq 13HD", NULL);
+       assert(device);
+       assert(libwacom_get_button_evdev_code(device, 'A') == BTN_0);
+       assert(libwacom_get_button_evdev_code(device, 'B') == BTN_1);
+       assert(libwacom_get_button_evdev_code(device, 'C') == BTN_2);
+       assert(libwacom_get_button_evdev_code(device, 'D') == BTN_3);
+       assert(libwacom_get_button_evdev_code(device, 'E') == BTN_4);
+       assert(libwacom_get_button_evdev_code(device, 'F') == BTN_5);
+       assert(libwacom_get_button_evdev_code(device, 'G') == BTN_6);
+       assert(libwacom_get_button_evdev_code(device, 'H') == BTN_7);
+       assert(libwacom_get_button_evdev_code(device, 'I') == BTN_8);
+       libwacom_destroy(device);
+
+       device = libwacom_new_from_name(db, "Wacom Bamboo Pen", NULL);
+       assert(device);
+       assert(libwacom_get_button_evdev_code(device, 'A') == BTN_BACK);
+       assert(libwacom_get_button_evdev_code(device, 'B') == BTN_FORWARD);
+       assert(libwacom_get_button_evdev_code(device, 'C') == BTN_LEFT);
+       assert(libwacom_get_button_evdev_code(device, 'D') == BTN_RIGHT);
+       libwacom_destroy(device);
+
        libwacom_database_destroy (db);
        return 0;
 }
-- 
2.13.6


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to