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