4ed345d823298c3ec9b630188cba9b28cacae182
[vuplus_xbmc] / xbmc / android / activity / EventLoop.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 "EventLoop.h"
22 #include "XBMCApp.h"
23 #include "AndroidExtra.h"
24
25 CEventLoop::CEventLoop(android_app* application)
26   : m_enabled(false),
27     m_application(application),
28     m_activityHandler(NULL), m_inputHandler(NULL)
29 {
30   if (m_application == NULL)
31     return;
32
33   m_application->userData = this;
34   m_application->onAppCmd = activityCallback;
35   m_application->onInputEvent = inputCallback;
36 }
37
38 void CEventLoop::run(IActivityHandler &activityHandler, IInputHandler &inputHandler)
39 {
40   int ident;
41   int events;
42   struct android_poll_source* source;
43
44   m_activityHandler = &activityHandler;
45   m_inputHandler = &inputHandler;
46
47   CXBMCApp::android_printf("CEventLoop: starting event loop");
48   while (1)
49   {
50     // We will block forever waiting for events.
51     while ((ident = ALooper_pollAll(-1, NULL, &events, (void**)&source)) >= 0)
52     {
53       // Process this event.
54       if (source != NULL)
55         source->process(m_application, source);
56
57       // Check if we are exiting.
58       if (m_application->destroyRequested)
59       {
60         CXBMCApp::android_printf("CEventLoop: we are being destroyed");
61         return;
62       }
63     }
64   }
65 }
66
67 void CEventLoop::processActivity(int32_t command)
68 {
69   switch (command)
70   {
71     case APP_CMD_CONFIG_CHANGED:
72       m_activityHandler->onConfigurationChanged();
73       break;
74
75     case APP_CMD_INIT_WINDOW:
76       // The window is being shown, get it ready.
77       m_activityHandler->onCreateWindow(m_application->window);
78
79       // set the proper DPI value
80       m_inputHandler->setDPI(CXBMCApp::GetDPI());
81       break;
82
83     case APP_CMD_WINDOW_RESIZED:
84       // The window has been resized
85       m_activityHandler->onResizeWindow();
86       break;
87
88     case APP_CMD_TERM_WINDOW:
89       // The window is being hidden or closed, clean it up.
90       m_activityHandler->onDestroyWindow();
91       break;
92
93     case APP_CMD_GAINED_FOCUS:
94       m_activityHandler->onGainFocus();
95       break;
96
97     case APP_CMD_LOST_FOCUS:
98       m_activityHandler->onLostFocus();
99       break;
100
101     case APP_CMD_LOW_MEMORY:
102       m_activityHandler->onLowMemory();
103       break;
104
105     case APP_CMD_START:
106       m_activityHandler->onStart();
107       break;
108
109     case APP_CMD_RESUME:
110       m_activityHandler->onResume();
111       break;
112
113     case APP_CMD_SAVE_STATE:
114       // The system has asked us to save our current state. Do so.
115       m_activityHandler->onSaveState(&m_application->savedState, &m_application->savedStateSize);
116       break;
117
118     case APP_CMD_PAUSE:
119       m_activityHandler->onPause();
120       break;
121
122     case APP_CMD_STOP:
123       m_activityHandler->onStop();
124       break;
125
126     case APP_CMD_DESTROY:
127       m_activityHandler->onDestroy();
128       break;
129
130     default:
131       break;
132   }
133 }
134
135 int32_t CEventLoop::processInput(AInputEvent* event)
136 {
137   int32_t rtn    = 0;
138   int32_t type   = AInputEvent_getType(event);
139   int32_t source = AInputEvent_getSource(event);
140   int32_t repeat = AKeyEvent_getRepeatCount(event);
141   int32_t keycod = AKeyEvent_getKeyCode(event);
142
143   switch(type)
144   {
145     case AINPUT_EVENT_TYPE_KEY:
146       if (source & AINPUT_SOURCE_GAMEPAD || source & AINPUT_SOURCE_JOYSTICK)
147       {
148         if (m_inputHandler->onJoyStickKeyEvent(event))
149           return true;
150       }
151       if (source & AINPUT_SOURCE_CLASS_BUTTON)
152         rtn = m_inputHandler->onKeyboardEvent(event);
153       break;
154     case AINPUT_EVENT_TYPE_MOTION:
155       switch(source)
156       {
157         case AINPUT_SOURCE_TOUCHSCREEN:
158           rtn = m_inputHandler->onTouchEvent(event);
159           break;
160         case AINPUT_SOURCE_MOUSE:
161           rtn = m_inputHandler->onMouseEvent(event);
162           break;
163         case AINPUT_SOURCE_GAMEPAD:
164         case AINPUT_SOURCE_JOYSTICK:
165           rtn = m_inputHandler->onJoyStickMotionEvent(event);
166           break;
167       }
168       break;
169   }
170
171   return rtn;
172 }
173
174 void CEventLoop::activityCallback(android_app* application, int32_t command)
175 {
176   if (application == NULL || application->userData == NULL)
177     return;
178
179   CEventLoop& eventLoop = *((CEventLoop*)application->userData);
180   eventLoop.processActivity(command);
181 }
182
183 int32_t CEventLoop::inputCallback(android_app* application, AInputEvent* event)
184 {
185   if (application == NULL || application->userData == NULL || event == NULL)
186     return 0;
187
188   CEventLoop& eventLoop = *((CEventLoop*)application->userData);
189
190   return eventLoop.processInput(event);
191 }
192