2 * Copyright (C) 2012-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/>.
21 #include "AndroidKey.h"
23 #include "guilib/Key.h"
24 #include "windowing/WinEvents.h"
26 static KeyMap keyMap[] = {
27 { AKEYCODE_UNKNOWN , XBMCK_LAST },
28 { AKEYCODE_SOFT_LEFT , XBMCK_LEFT },
29 { AKEYCODE_SOFT_RIGHT , XBMCK_RIGHT },
30 { AKEYCODE_HOME , XBMCK_HOME },
31 { AKEYCODE_BACK , XBMCK_BACKSPACE },
32 { AKEYCODE_CALL , XBMCK_LAST },
33 { AKEYCODE_ENDCALL , XBMCK_LAST },
34 { AKEYCODE_0 , XBMCK_0 },
35 { AKEYCODE_1 , XBMCK_1 },
36 { AKEYCODE_2 , XBMCK_2 },
37 { AKEYCODE_3 , XBMCK_3 },
38 { AKEYCODE_4 , XBMCK_4 },
39 { AKEYCODE_5 , XBMCK_5 },
40 { AKEYCODE_6 , XBMCK_6 },
41 { AKEYCODE_7 , XBMCK_7 },
42 { AKEYCODE_8 , XBMCK_8 },
43 { AKEYCODE_9 , XBMCK_9 },
44 { AKEYCODE_STAR , XBMCK_ASTERISK },
45 { AKEYCODE_POUND , XBMCK_HASH },
46 { AKEYCODE_DPAD_UP , XBMCK_UP },
47 { AKEYCODE_DPAD_DOWN , XBMCK_DOWN },
48 { AKEYCODE_DPAD_LEFT , XBMCK_LEFT },
49 { AKEYCODE_DPAD_RIGHT , XBMCK_RIGHT },
50 { AKEYCODE_DPAD_CENTER , XBMCK_RETURN },
51 { AKEYCODE_VOLUME_UP , XBMCK_PLUS },
52 { AKEYCODE_VOLUME_DOWN , XBMCK_MINUS },
53 { AKEYCODE_POWER , XBMCK_POWER },
54 { AKEYCODE_CAMERA , XBMCK_LAST },
55 { AKEYCODE_CLEAR , XBMCK_LAST },
56 { AKEYCODE_A , XBMCK_a },
57 { AKEYCODE_B , XBMCK_b },
58 { AKEYCODE_C , XBMCK_c },
59 { AKEYCODE_D , XBMCK_d },
60 { AKEYCODE_E , XBMCK_e },
61 { AKEYCODE_F , XBMCK_f },
62 { AKEYCODE_G , XBMCK_g },
63 { AKEYCODE_H , XBMCK_h },
64 { AKEYCODE_I , XBMCK_i },
65 { AKEYCODE_J , XBMCK_j },
66 { AKEYCODE_K , XBMCK_k },
67 { AKEYCODE_L , XBMCK_l },
68 { AKEYCODE_M , XBMCK_m },
69 { AKEYCODE_N , XBMCK_n },
70 { AKEYCODE_O , XBMCK_o },
71 { AKEYCODE_P , XBMCK_p },
72 { AKEYCODE_Q , XBMCK_q },
73 { AKEYCODE_R , XBMCK_r },
74 { AKEYCODE_S , XBMCK_s },
75 { AKEYCODE_T , XBMCK_t },
76 { AKEYCODE_U , XBMCK_u },
77 { AKEYCODE_V , XBMCK_v },
78 { AKEYCODE_W , XBMCK_w },
79 { AKEYCODE_X , XBMCK_x },
80 { AKEYCODE_Y , XBMCK_y },
81 { AKEYCODE_Z , XBMCK_z },
82 { AKEYCODE_COMMA , XBMCK_COMMA },
83 { AKEYCODE_PERIOD , XBMCK_PERIOD },
84 { AKEYCODE_ALT_LEFT , XBMCK_LEFT },
85 { AKEYCODE_ALT_RIGHT , XBMCK_RIGHT },
86 { AKEYCODE_SHIFT_LEFT , XBMCK_LEFT },
87 { AKEYCODE_SHIFT_RIGHT , XBMCK_RIGHT },
88 { AKEYCODE_TAB , XBMCK_TAB },
89 { AKEYCODE_SPACE , XBMCK_SPACE },
90 { AKEYCODE_SYM , XBMCK_LAST },
91 { AKEYCODE_EXPLORER , XBMCK_LAST },
92 { AKEYCODE_ENVELOPE , XBMCK_LAST },
93 { AKEYCODE_ENTER , XBMCK_RETURN },
94 { AKEYCODE_DEL , XBMCK_DELETE },
95 { AKEYCODE_GRAVE , XBMCK_BACKQUOTE },
96 { AKEYCODE_MINUS , XBMCK_MINUS },
97 { AKEYCODE_EQUALS , XBMCK_EQUALS },
98 { AKEYCODE_LEFT_BRACKET , XBMCK_LEFTBRACKET },
99 { AKEYCODE_RIGHT_BRACKET , XBMCK_RIGHTBRACKET },
100 { AKEYCODE_BACKSLASH , XBMCK_BACKSLASH },
101 { AKEYCODE_SEMICOLON , XBMCK_SEMICOLON },
102 { AKEYCODE_APOSTROPHE , XBMCK_QUOTE },
103 { AKEYCODE_SLASH , XBMCK_SLASH },
104 { AKEYCODE_AT , XBMCK_AT },
105 { AKEYCODE_NUM , XBMCK_NUMLOCK },
106 { AKEYCODE_HEADSETHOOK , XBMCK_LAST },
107 { AKEYCODE_FOCUS , XBMCK_LAST }, // *Camera* focus
108 { AKEYCODE_PLUS , XBMCK_PLUS },
109 { AKEYCODE_MENU , XBMCK_MENU },
110 { AKEYCODE_NOTIFICATION , XBMCK_LAST },
111 { AKEYCODE_SEARCH , XBMCK_LAST },
112 { AKEYCODE_MEDIA_PLAY_PAUSE, XBMCK_MEDIA_PLAY_PAUSE },
113 { AKEYCODE_MEDIA_STOP , XBMCK_MEDIA_STOP },
114 { AKEYCODE_MEDIA_NEXT , XBMCK_MEDIA_NEXT_TRACK },
115 { AKEYCODE_MEDIA_PREVIOUS , XBMCK_MEDIA_PREV_TRACK },
116 { AKEYCODE_MEDIA_REWIND , XBMCK_REWIND },
117 { AKEYCODE_MEDIA_FAST_FORWARD , XBMCK_FASTFORWARD },
118 { AKEYCODE_MUTE , XBMCK_VOLUME_MUTE },
119 { AKEYCODE_PAGE_UP , XBMCK_PAGEUP },
120 { AKEYCODE_PAGE_DOWN , XBMCK_PAGEDOWN },
121 { AKEYCODE_PICTSYMBOLS , XBMCK_LAST },
122 { AKEYCODE_SWITCH_CHARSET , XBMCK_LAST },
123 { AKEYCODE_BUTTON_A , XBMCK_LAST },
124 { AKEYCODE_BUTTON_B , XBMCK_LAST },
125 { AKEYCODE_BUTTON_C , XBMCK_LAST },
126 { AKEYCODE_BUTTON_X , XBMCK_LAST },
127 { AKEYCODE_BUTTON_Y , XBMCK_LAST },
128 { AKEYCODE_BUTTON_Z , XBMCK_LAST },
129 { AKEYCODE_BUTTON_L1 , XBMCK_LAST },
130 { AKEYCODE_BUTTON_R1 , XBMCK_LAST },
131 { AKEYCODE_BUTTON_L2 , XBMCK_LAST },
132 { AKEYCODE_BUTTON_R2 , XBMCK_LAST },
133 { AKEYCODE_BUTTON_THUMBL , XBMCK_LAST },
134 { AKEYCODE_BUTTON_THUMBR , XBMCK_LAST },
135 { AKEYCODE_BUTTON_START , XBMCK_LAST },
136 { AKEYCODE_BUTTON_SELECT , XBMCK_LAST },
137 { AKEYCODE_BUTTON_MODE , XBMCK_LAST }
140 bool CAndroidKey::onKeyboardEvent(AInputEvent* event)
142 CXBMCApp::android_printf("%s", __PRETTY_FUNCTION__);
146 int32_t keycode = AKeyEvent_getKeyCode(event);
147 int32_t flags = AKeyEvent_getFlags(event);
148 int32_t state = AKeyEvent_getMetaState(event);
149 int32_t repeatCount = AKeyEvent_getRepeatCount(event);
151 // Check if we got some special key
152 uint16_t sym = XBMCK_UNKNOWN;
153 for (unsigned int index = 0; index < sizeof(keyMap) / sizeof(KeyMap); index++)
155 if (keycode == keyMap[index].nativeKey)
157 sym = keyMap[index].xbmcKey;
162 // check if this is a key we don't want to handle
163 if (sym == XBMCK_LAST)
166 uint16_t modifiers = 0;
167 if (state & AMETA_ALT_LEFT_ON)
168 modifiers |= XBMCKMOD_LALT;
169 if (state & AMETA_ALT_RIGHT_ON)
170 modifiers |= XBMCKMOD_RALT;
171 if (state & AMETA_SHIFT_LEFT_ON)
172 modifiers |= XBMCKMOD_LSHIFT;
173 if (state & AMETA_SHIFT_RIGHT_ON)
174 modifiers |= XBMCKMOD_RSHIFT;
176 if (state & AMETA_SYM_ON)
177 modifiers |= 0x000?;*/
179 switch (AKeyEvent_getAction(event))
181 case AKEY_EVENT_ACTION_DOWN:
182 CXBMCApp::android_printf("CXBMCApp: key down (code: %d; repeat: %d; flags: 0x%0X; alt: %s; shift: %s; sym: %s)",
183 keycode, repeatCount, flags,
184 (state & AMETA_ALT_ON) ? "yes" : "no",
185 (state & AMETA_SHIFT_ON) ? "yes" : "no",
186 (state & AMETA_SYM_ON) ? "yes" : "no");
187 XBMC_Key((uint8_t)keycode, sym, modifiers, false);
190 case AKEY_EVENT_ACTION_UP:
191 CXBMCApp::android_printf("CXBMCApp: key up (code: %d; repeat: %d; flags: 0x%0X; alt: %s; shift: %s; sym: %s)",
192 keycode, repeatCount, flags,
193 (state & AMETA_ALT_ON) ? "yes" : "no",
194 (state & AMETA_SHIFT_ON) ? "yes" : "no",
195 (state & AMETA_SYM_ON) ? "yes" : "no");
196 XBMC_Key((uint8_t)keycode, sym, modifiers, true);
199 case AKEY_EVENT_ACTION_MULTIPLE:
200 CXBMCApp::android_printf("CXBMCApp: key multiple (code: %d; repeat: %d; flags: 0x%0X; alt: %s; shift: %s; sym: %s)",
201 keycode, repeatCount, flags,
202 (state & AMETA_ALT_ON) ? "yes" : "no",
203 (state & AMETA_SHIFT_ON) ? "yes" : "no",
204 (state & AMETA_SYM_ON) ? "yes" : "no");
208 CXBMCApp::android_printf("CXBMCApp: unknown key (code: %d; repeat: %d; flags: 0x%0X; alt: %s; shift: %s; sym: %s)",
209 keycode, repeatCount, flags,
210 (state & AMETA_ALT_ON) ? "yes" : "no",
211 (state & AMETA_SHIFT_ON) ? "yes" : "no",
212 (state & AMETA_SYM_ON) ? "yes" : "no");
219 void CAndroidKey::XBMC_Key(uint8_t code, uint16_t key, uint16_t modifiers, bool up)
222 memset(&newEvent, 0, sizeof(newEvent));
224 unsigned char type = up ? XBMC_KEYUP : XBMC_KEYDOWN;
225 newEvent.type = type;
226 newEvent.key.type = type;
227 newEvent.key.keysym.scancode = code;
228 newEvent.key.keysym.sym = (XBMCKey)key;
229 newEvent.key.keysym.unicode = key;
230 newEvent.key.keysym.mod = (XBMCMod)modifiers;
232 CXBMCApp::android_printf("XBMC_Key(%u, %u, 0x%04X, %d)", code, key, modifiers, up);
233 CWinEvents::MessagePush(&newEvent);