[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / android / activity / AndroidKey.cpp
1 /*
2  *      Copyright (C) 2012-2013 Team XBMC
3  *      http://www.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 "XBMCApp.h"
23 #include "guilib/Key.h"
24 #include "windowing/WinEvents.h"
25
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 }
138 };
139
140 bool CAndroidKey::onKeyboardEvent(AInputEvent* event)
141 {
142   CXBMCApp::android_printf("%s", __PRETTY_FUNCTION__);
143   if (event == NULL)
144     return false;
145
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);
150
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++)
154   {
155     if (keycode == keyMap[index].nativeKey)
156     {
157       sym = keyMap[index].xbmcKey;
158       break;
159     }
160   }
161   
162   // check if this is a key we don't want to handle
163   if (sym == XBMCK_LAST)
164     return false;
165
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;
175   /* TODO:
176   if (state & AMETA_SYM_ON)
177     modifiers |= 0x000?;*/
178
179   switch (AKeyEvent_getAction(event))
180   {
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);
188       return true;
189
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);
197       return true;
198
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");
205       break;
206
207     default:
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");
213       break;
214   }
215
216   return false;
217 }
218
219 void CAndroidKey::XBMC_Key(uint8_t code, uint16_t key, uint16_t modifiers, bool up)
220 {
221   XBMC_Event newEvent;
222   memset(&newEvent, 0, sizeof(newEvent));
223
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;
231
232   CXBMCApp::android_printf("XBMC_Key(%u, %u, 0x%04X, %d)", code, key, modifiers, up);
233   CWinEvents::MessagePush(&newEvent);
234 }