2 * Copyright (C) 2007-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
22 #include "utils/StdString.h"
23 #include "utils/StringUtils.h"
24 #include "input/XBMC_keysym.h"
25 #include "input/XBMC_vkeys.h"
26 #include "input/XBMC_keytable.h"
28 // The array of XBMCKEYTABLEs used in XBMC.
29 // scancode, sym, unicode, ascii, vkey, keyname
30 static const XBMCKEYTABLE XBMCKeyTable
[] =
31 { { XBMCK_BACKSPACE
, 0, 0, XBMCVK_BACK
, "backspace" }
32 , { XBMCK_TAB
, 0, 0, XBMCVK_TAB
, "tab" }
33 , { XBMCK_RETURN
, 0, 0, XBMCVK_RETURN
, "return" }
34 , { XBMCK_ESCAPE
, 0, 0, XBMCVK_ESCAPE
, "escape" }
35 , { 0, 0, 0, XBMCVK_ESCAPE
, "esc" } // Allowed abbreviation for "escape"
37 // Number keys on the main keyboard
38 , { XBMCK_0
, '0', '0', XBMCVK_0
, "zero" }
39 , { XBMCK_1
, '1', '1', XBMCVK_1
, "one" }
40 , { XBMCK_2
, '2', '2', XBMCVK_2
, "two" }
41 , { XBMCK_3
, '3', '3', XBMCVK_3
, "three" }
42 , { XBMCK_4
, '4', '4', XBMCVK_4
, "four" }
43 , { XBMCK_5
, '5', '5', XBMCVK_5
, "five" }
44 , { XBMCK_6
, '6', '6', XBMCVK_6
, "six" }
45 , { XBMCK_7
, '7', '7', XBMCVK_7
, "seven" }
46 , { XBMCK_8
, '8', '8', XBMCVK_8
, "eight" }
47 , { XBMCK_9
, '9', '9', XBMCVK_9
, "nine" }
49 // A to Z - note that upper case A-Z don't have a matching name or
50 // vkey. Only the lower case a-z are used in key mappings.
51 , { XBMCK_a
, 'A', 'A', XBMCVK_A
, NULL
}
52 , { XBMCK_b
, 'B', 'B', XBMCVK_B
, NULL
}
53 , { XBMCK_c
, 'C', 'C', XBMCVK_C
, NULL
}
54 , { XBMCK_d
, 'D', 'D', XBMCVK_D
, NULL
}
55 , { XBMCK_e
, 'E', 'E', XBMCVK_E
, NULL
}
56 , { XBMCK_f
, 'F', 'F', XBMCVK_F
, NULL
}
57 , { XBMCK_g
, 'G', 'G', XBMCVK_G
, NULL
}
58 , { XBMCK_h
, 'H', 'H', XBMCVK_H
, NULL
}
59 , { XBMCK_i
, 'I', 'I', XBMCVK_I
, NULL
}
60 , { XBMCK_j
, 'J', 'J', XBMCVK_J
, NULL
}
61 , { XBMCK_k
, 'K', 'K', XBMCVK_K
, NULL
}
62 , { XBMCK_l
, 'L', 'L', XBMCVK_L
, NULL
}
63 , { XBMCK_m
, 'M', 'M', XBMCVK_M
, NULL
}
64 , { XBMCK_n
, 'N', 'N', XBMCVK_N
, NULL
}
65 , { XBMCK_o
, 'O', 'O', XBMCVK_O
, NULL
}
66 , { XBMCK_p
, 'P', 'P', XBMCVK_P
, NULL
}
67 , { XBMCK_q
, 'Q', 'Q', XBMCVK_Q
, NULL
}
68 , { XBMCK_r
, 'R', 'R', XBMCVK_R
, NULL
}
69 , { XBMCK_s
, 'S', 'S', XBMCVK_S
, NULL
}
70 , { XBMCK_t
, 'T', 'T', XBMCVK_T
, NULL
}
71 , { XBMCK_u
, 'U', 'U', XBMCVK_U
, NULL
}
72 , { XBMCK_v
, 'V', 'V', XBMCVK_V
, NULL
}
73 , { XBMCK_w
, 'W', 'W', XBMCVK_W
, NULL
}
74 , { XBMCK_x
, 'X', 'X', XBMCVK_X
, NULL
}
75 , { XBMCK_y
, 'Y', 'Y', XBMCVK_Y
, NULL
}
76 , { XBMCK_z
, 'Z', 'Z', XBMCVK_Z
, NULL
}
78 , { XBMCK_a
, 'a', 'a', XBMCVK_A
, "a" }
79 , { XBMCK_b
, 'b', 'b', XBMCVK_B
, "b" }
80 , { XBMCK_c
, 'c', 'c', XBMCVK_C
, "c" }
81 , { XBMCK_d
, 'd', 'd', XBMCVK_D
, "d" }
82 , { XBMCK_e
, 'e', 'e', XBMCVK_E
, "e" }
83 , { XBMCK_f
, 'f', 'f', XBMCVK_F
, "f" }
84 , { XBMCK_g
, 'g', 'g', XBMCVK_G
, "g" }
85 , { XBMCK_h
, 'h', 'h', XBMCVK_H
, "h" }
86 , { XBMCK_i
, 'i', 'i', XBMCVK_I
, "i" }
87 , { XBMCK_j
, 'j', 'j', XBMCVK_J
, "j" }
88 , { XBMCK_k
, 'k', 'k', XBMCVK_K
, "k" }
89 , { XBMCK_l
, 'l', 'l', XBMCVK_L
, "l" }
90 , { XBMCK_m
, 'm', 'm', XBMCVK_M
, "m" }
91 , { XBMCK_n
, 'n', 'n', XBMCVK_N
, "n" }
92 , { XBMCK_o
, 'o', 'o', XBMCVK_O
, "o" }
93 , { XBMCK_p
, 'p', 'p', XBMCVK_P
, "p" }
94 , { XBMCK_q
, 'q', 'q', XBMCVK_Q
, "q" }
95 , { XBMCK_r
, 'r', 'r', XBMCVK_R
, "r" }
96 , { XBMCK_s
, 's', 's', XBMCVK_S
, "s" }
97 , { XBMCK_t
, 't', 't', XBMCVK_T
, "t" }
98 , { XBMCK_u
, 'u', 'u', XBMCVK_U
, "u" }
99 , { XBMCK_v
, 'v', 'v', XBMCVK_V
, "v" }
100 , { XBMCK_w
, 'w', 'w', XBMCVK_W
, "w" }
101 , { XBMCK_x
, 'x', 'x', XBMCVK_X
, "x" }
102 , { XBMCK_y
, 'y', 'y', XBMCVK_Y
, "y" }
103 , { XBMCK_z
, 'z', 'z', XBMCVK_Z
, "z" }
105 // Misc printing characters
106 , { XBMCK_SPACE
, ' ', ' ', XBMCVK_SPACE
, "space" }
107 , { XBMCK_EXCLAIM
, '!', '!', XBMCVK_EXCLAIM
, "exclaim" }
108 , { XBMCK_QUOTEDBL
, '"', '"', XBMCVK_QUOTEDBL
, "doublequote" }
109 , { XBMCK_HASH
, '#', '#', XBMCVK_HASH
, "hash" }
110 , { XBMCK_DOLLAR
, '$', '$', XBMCVK_DOLLAR
, "dollar" }
111 , { XBMCK_PERCENT
, '%', '%', XBMCVK_PERCENT
, "percent" }
112 , { XBMCK_AMPERSAND
, '&', '&', XBMCVK_AMPERSAND
, "ampersand" }
113 , { XBMCK_QUOTE
, '\'', '\'', XBMCVK_QUOTE
, "quote" }
114 , { XBMCK_LEFTPAREN
, '(', '(', XBMCVK_LEFTPAREN
, "leftbracket" }
115 , { XBMCK_RIGHTPAREN
, ')', ')', XBMCVK_RIGHTPAREN
, "rightbracket" }
116 , { XBMCK_ASTERISK
, '*', '*', XBMCVK_ASTERISK
, "asterisk" }
117 , { XBMCK_PLUS
, '+', '+', XBMCVK_PLUS
, "plus" }
118 , { XBMCK_COMMA
, ',', ',', XBMCVK_COMMA
, "comma" }
119 , { XBMCK_MINUS
, '-', '-', XBMCVK_MINUS
, "minus" }
120 , { XBMCK_PERIOD
, '.', '.', XBMCVK_PERIOD
, "period" }
121 , { XBMCK_SLASH
, '/', '/', XBMCVK_SLASH
, "forwardslash" }
123 , { XBMCK_COLON
, ':', ':', XBMCVK_COLON
, "colon" }
124 , { XBMCK_SEMICOLON
, ';', ';', XBMCVK_SEMICOLON
, "semicolon" }
125 , { XBMCK_LESS
, '<', '<', XBMCVK_LESS
, "lessthan" }
126 , { XBMCK_EQUALS
, '=', '=', XBMCVK_EQUALS
, "equals" }
127 , { XBMCK_GREATER
, '>', '>', XBMCVK_GREATER
, "greaterthan" }
128 , { XBMCK_QUESTION
, '?', '?', XBMCVK_QUESTION
, "questionmark" }
129 , { XBMCK_AT
, '@', '@', XBMCVK_AT
, "at" }
131 , { XBMCK_LEFTBRACKET
, '[', '[', XBMCVK_LEFTBRACKET
, "opensquarebracket" }
132 , { XBMCK_BACKSLASH
, '\\', '\\', XBMCVK_BACKSLASH
, "backslash" }
133 , { XBMCK_RIGHTBRACKET
, ']', ']', XBMCVK_RIGHTBRACKET
, "closesquarebracket" }
134 , { XBMCK_CARET
, '^', '^', XBMCVK_CARET
, "caret" }
135 , { XBMCK_UNDERSCORE
, '_', '_', XBMCVK_UNDERSCORE
, "underline" }
136 , { XBMCK_BACKQUOTE
, '`', '`', XBMCVK_BACKQUOTE
, "leftquote" }
138 , { XBMCK_LEFTBRACE
, '{', '{', XBMCVK_LEFTBRACE
, "openbrace" }
139 , { XBMCK_PIPE
, '|', '|', XBMCVK_PIPE
, "pipe" }
140 , { XBMCK_RIGHTBRACE
, '}', '}', XBMCVK_RIGHTBRACE
, "closebrace" }
141 , { XBMCK_TILDE
, '~', '~', XBMCVK_TILDE
, "tilde" }
144 , { XBMCK_KP0
, '0', '0', XBMCVK_NUMPAD0
, "numpadzero"}
145 , { XBMCK_KP1
, '1', '1', XBMCVK_NUMPAD1
, "numpadone"}
146 , { XBMCK_KP2
, '2', '2', XBMCVK_NUMPAD2
, "numpadtwo"}
147 , { XBMCK_KP3
, '3', '3', XBMCVK_NUMPAD3
, "numpadthree"}
148 , { XBMCK_KP4
, '4', '4', XBMCVK_NUMPAD4
, "numpadfour"}
149 , { XBMCK_KP5
, '5', '5', XBMCVK_NUMPAD5
, "numpadfive"}
150 , { XBMCK_KP6
, '6', '6', XBMCVK_NUMPAD6
, "numpadsix"}
151 , { XBMCK_KP7
, '7', '7', XBMCVK_NUMPAD7
, "numpadseven"}
152 , { XBMCK_KP8
, '8', '8', XBMCVK_NUMPAD8
, "numpadeight"}
153 , { XBMCK_KP9
, '9', '9', XBMCVK_NUMPAD9
, "numpadnine"}
155 , { XBMCK_KP_DIVIDE
, '/', '/', XBMCVK_NUMPADDIVIDE
, "numpaddivide"}
156 , { XBMCK_KP_MULTIPLY
, '*', '*', XBMCVK_NUMPADTIMES
, "numpadtimes"}
157 , { XBMCK_KP_MINUS
, '-', '-', XBMCVK_NUMPADMINUS
, "numpadminus"}
158 , { XBMCK_KP_PLUS
, '+', '+', XBMCVK_NUMPADPLUS
, "numpadplus"}
159 , { XBMCK_KP_ENTER
, 0, 0, XBMCVK_NUMPADENTER
, "enter"}
160 , { XBMCK_KP_PERIOD
, '.', '.', XBMCVK_NUMPADPERIOD
, "numpadperiod"}
163 , { XBMCK_BROWSER_BACK
, 0, 0, XBMCVK_BROWSER_BACK
, "browser_back" }
164 , { XBMCK_BROWSER_FORWARD
, 0, 0, XBMCVK_BROWSER_FORWARD
, "browser_forward" }
165 , { XBMCK_BROWSER_REFRESH
, 0, 0, XBMCVK_BROWSER_REFRESH
, "browser_refresh" }
166 , { XBMCK_BROWSER_STOP
, 0, 0, XBMCVK_BROWSER_STOP
, "browser_stop" }
167 , { XBMCK_BROWSER_SEARCH
, 0, 0, XBMCVK_BROWSER_SEARCH
, "browser_search" }
168 , { XBMCK_BROWSER_FAVORITES
, 0, 0, XBMCVK_BROWSER_FAVORITES
, "browser_favorites" }
169 , { XBMCK_BROWSER_HOME
, 0, 0, XBMCVK_BROWSER_HOME
, "browser_home" }
170 , { XBMCK_VOLUME_MUTE
, 0, 0, XBMCVK_VOLUME_MUTE
, "volume_mute" }
171 , { XBMCK_VOLUME_DOWN
, 0, 0, XBMCVK_VOLUME_DOWN
, "volume_down" }
172 , { XBMCK_VOLUME_UP
, 0, 0, XBMCVK_VOLUME_UP
, "volume_up" }
173 , { XBMCK_MEDIA_NEXT_TRACK
, 0, 0, XBMCVK_MEDIA_NEXT_TRACK
, "next_track" }
174 , { XBMCK_MEDIA_PREV_TRACK
, 0, 0, XBMCVK_MEDIA_PREV_TRACK
, "prev_track" }
175 , { XBMCK_MEDIA_STOP
, 0, 0, XBMCVK_MEDIA_STOP
, "stop" }
176 , { XBMCK_MEDIA_PLAY_PAUSE
, 0, 0, XBMCVK_MEDIA_PLAY_PAUSE
, "play_pause" }
177 , { XBMCK_MEDIA_REWIND
, 0, 0, XBMCVK_MEDIA_REWIND
, "rewind" }
178 , { XBMCK_MEDIA_FASTFORWARD
, 0, 0, XBMCVK_MEDIA_FASTFORWARD
, "fastforward" }
179 , { XBMCK_LAUNCH_MAIL
, 0, 0, XBMCVK_LAUNCH_MAIL
, "launch_mail" }
180 , { XBMCK_LAUNCH_MEDIA_SELECT
, 0, 0, XBMCVK_LAUNCH_MEDIA_SELECT
, "launch_media_select" }
181 , { XBMCK_LAUNCH_APP1
, 0, 0, XBMCVK_LAUNCH_APP1
, "launch_app1_pc_icon" }
182 , { XBMCK_LAUNCH_APP2
, 0, 0, XBMCVK_LAUNCH_APP2
, "launch_app2_pc_icon" }
183 , { XBMCK_LAUNCH_FILE_BROWSER
, 0, 0, XBMCVK_LAUNCH_FILE_BROWSER
, "launch_file_browser" }
184 , { XBMCK_LAUNCH_MEDIA_CENTER
, 0, 0, XBMCVK_LAUNCH_MEDIA_CENTER
, "launch_media_center" }
187 , { XBMCK_F1
, 0, 0, XBMCVK_F1
, "f1"}
188 , { XBMCK_F2
, 0, 0, XBMCVK_F2
, "f2"}
189 , { XBMCK_F3
, 0, 0, XBMCVK_F3
, "f3"}
190 , { XBMCK_F4
, 0, 0, XBMCVK_F4
, "f4"}
191 , { XBMCK_F5
, 0, 0, XBMCVK_F5
, "f5"}
192 , { XBMCK_F6
, 0, 0, XBMCVK_F6
, "f6"}
193 , { XBMCK_F7
, 0, 0, XBMCVK_F7
, "f7"}
194 , { XBMCK_F8
, 0, 0, XBMCVK_F8
, "f8"}
195 , { XBMCK_F9
, 0, 0, XBMCVK_F9
, "f9"}
196 , { XBMCK_F10
, 0, 0, XBMCVK_F10
, "f10"}
197 , { XBMCK_F11
, 0, 0, XBMCVK_F11
, "f11"}
198 , { XBMCK_F12
, 0, 0, XBMCVK_F12
, "f12"}
199 , { XBMCK_F13
, 0, 0, XBMCVK_F13
, "f13"}
200 , { XBMCK_F14
, 0, 0, XBMCVK_F14
, "f14"}
201 , { XBMCK_F15
, 0, 0, XBMCVK_F15
, "f15"}
203 // Misc non-printing keys
204 , { XBMCK_UP
, 0, 0, XBMCVK_UP
, "up" }
205 , { XBMCK_DOWN
, 0, 0, XBMCVK_DOWN
, "down" }
206 , { XBMCK_RIGHT
, 0, 0, XBMCVK_RIGHT
, "right" }
207 , { XBMCK_LEFT
, 0, 0, XBMCVK_LEFT
, "left" }
208 , { XBMCK_INSERT
, 0, 0, XBMCVK_INSERT
, "insert" }
209 , { XBMCK_DELETE
, 0, 0, XBMCVK_DELETE
, "delete" }
210 , { XBMCK_HOME
, 0, 0, XBMCVK_HOME
, "home" }
211 , { XBMCK_END
, 0, 0, XBMCVK_END
, "end" }
212 , { XBMCK_PAGEUP
, 0, 0, XBMCVK_PAGEUP
, "pageup" }
213 , { XBMCK_PAGEDOWN
, 0, 0, XBMCVK_PAGEDOWN
, "pagedown" }
214 , { XBMCK_NUMLOCK
, 0, 0, XBMCVK_NUMLOCK
, "numlock" }
215 , { XBMCK_CAPSLOCK
, 0, 0, XBMCVK_CAPSLOCK
, "capslock" }
216 , { XBMCK_RSHIFT
, 0, 0, XBMCVK_RSHIFT
, "rightshift" }
217 , { XBMCK_LSHIFT
, 0, 0, XBMCVK_LSHIFT
, "leftshift" }
218 , { XBMCK_RCTRL
, 0, 0, XBMCVK_RCONTROL
, "rightctrl" }
219 , { XBMCK_LCTRL
, 0, 0, XBMCVK_LCONTROL
, "leftctrl" }
220 , { XBMCK_LALT
, 0, 0, XBMCVK_LMENU
, "leftalt" }
221 , { XBMCK_LSUPER
, 0, 0, XBMCVK_LWIN
, "leftwindows" }
222 , { XBMCK_RSUPER
, 0, 0, XBMCVK_RWIN
, "rightwindows" }
223 , { XBMCK_MENU
, 0, 0, XBMCVK_MENU
, "menu" }
224 , { XBMCK_PAUSE
, 0, 0, XBMCVK_PAUSE
, "pause" }
225 , { XBMCK_SCROLLOCK
, 0, 0, XBMCVK_SCROLLLOCK
, "scrolllock" }
226 , { XBMCK_PRINT
, 0, 0, XBMCVK_PRINTSCREEN
, "printscreen" }
227 , { XBMCK_POWER
, 0, 0, XBMCVK_POWER
, "power" }
228 , { XBMCK_SLEEP
, 0, 0, XBMCVK_SLEEP
, "sleep" }
231 static int XBMCKeyTableSize
= sizeof(XBMCKeyTable
)/sizeof(XBMCKEYTABLE
);
233 bool KeyTableLookupName(const char* keyname
, XBMCKEYTABLE
* keytable
)
235 // If the name being searched for is null or "" there will be no match
238 if (keyname
[0] == '\0')
241 // We need the button name to be in lowercase
242 CStdString lkeyname
= keyname
;
243 StringUtils::ToLower(lkeyname
);
245 // Look up the key name in XBMCKeyTable
246 for (int i
= 0; i
< XBMCKeyTableSize
; i
++)
247 { if (XBMCKeyTable
[i
].keyname
)
248 { if (strcmp(lkeyname
.c_str(), XBMCKeyTable
[i
].keyname
) == 0)
249 { *keytable
= XBMCKeyTable
[i
];
255 // The name wasn't found
259 bool KeyTableLookupSym(uint16_t sym
, XBMCKEYTABLE
* keytable
)
261 // If the sym being searched for is zero there will be no match
265 // Look up the sym in XBMCKeyTable
266 for (int i
= 0; i
< XBMCKeyTableSize
; i
++)
267 { if (sym
== XBMCKeyTable
[i
].sym
)
268 { *keytable
= XBMCKeyTable
[i
];
273 // The name wasn't found
277 bool KeyTableLookupUnicode(uint16_t unicode
, XBMCKEYTABLE
* keytable
)
279 // If the unicode being searched for is zero there will be no match
283 // Look up the unicode in XBMCKeyTable
284 for (int i
= 0; i
< XBMCKeyTableSize
; i
++)
285 { if (unicode
== XBMCKeyTable
[i
].unicode
)
286 { *keytable
= XBMCKeyTable
[i
];
291 // The name wasn't found
295 bool KeyTableLookupSymAndUnicode(uint16_t sym
, uint16_t unicode
, XBMCKEYTABLE
* keytable
)
297 // If the sym being searched for is zero there will be no match (the
298 // unicode can be zero if the sym is non-zero)
302 // Look up the sym and unicode in XBMCKeyTable
303 for (int i
= 0; i
< XBMCKeyTableSize
; i
++)
304 { if (sym
== XBMCKeyTable
[i
].sym
&& unicode
== XBMCKeyTable
[i
].unicode
)
305 { *keytable
= XBMCKeyTable
[i
];
310 // The sym and unicode weren't found
314 bool KeyTableLookupVKeyName(uint32_t vkey
, XBMCKEYTABLE
* keytable
)
316 // If the vkey being searched for is zero there will be no match
320 // Look up the vkey in XBMCKeyTable
321 for (int i
= 0; i
< XBMCKeyTableSize
; i
++)
322 { if (vkey
== XBMCKeyTable
[i
].vkey
&& XBMCKeyTable
[i
].keyname
)
323 { *keytable
= XBMCKeyTable
[i
];
328 // The name wasn't found