1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "AndroidMouse.h"
10
11 #include "AndroidExtra.h"
12 #include "AppInboundProtocol.h"
13 #include "ServiceBroker.h"
14 #include "XBMCApp.h"
15 #include "guilib/GUIWindowManager.h"
16 #include "input/mouse/MouseStat.h"
17 #include "windowing/android/WinSystemAndroid.h"
18
19 //#define DEBUG_VERBOSE
20
onMouseEvent(AInputEvent * event)21 bool CAndroidMouse::onMouseEvent(AInputEvent* event)
22 {
23 if (event == NULL)
24 return false;
25
26 int32_t eventAction = AMotionEvent_getAction(event);
27 int8_t mouseAction = eventAction & AMOTION_EVENT_ACTION_MASK;
28 size_t mousePointerIdx = eventAction >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
29
30 #ifdef DEBUG_VERBOSE
31 int32_t mousePointerId = AMotionEvent_getPointerId(event, mousePointerIdx);
32 CXBMCApp::android_printf("%s idx:%i, id:%i", __PRETTY_FUNCTION__, mousePointerIdx, mousePointerId);
33 #endif
34 float x = AMotionEvent_getX(event, mousePointerIdx);
35 float y = AMotionEvent_getY(event, mousePointerIdx);
36
37 switch (mouseAction)
38 {
39 case AMOTION_EVENT_ACTION_UP:
40 case AMOTION_EVENT_ACTION_DOWN:
41 MouseButton(x,y,mouseAction,AMotionEvent_getButtonState(event));
42 return true;
43 case AMOTION_EVENT_ACTION_SCROLL:
44 MouseWheel(x, y, AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_VSCROLL, mousePointerIdx));
45 return true;
46 default:
47 MouseMove(x,y);
48 return true;
49 }
50 return false;
51 }
52
MouseMove(float x,float y)53 void CAndroidMouse::MouseMove(float x, float y)
54 {
55 #ifdef DEBUG_VERBOSE
56 CXBMCApp::android_printf("%s: x:%f, y:%f", __PRETTY_FUNCTION__, x, y);
57 #endif
58 XBMC_Event newEvent;
59
60 memset(&newEvent, 0, sizeof(newEvent));
61
62 newEvent.type = XBMC_MOUSEMOTION;
63 newEvent.motion.x = x;
64 newEvent.motion.y = y;
65 std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
66 if (appPort)
67 appPort->OnEvent(newEvent);
68 }
69
MouseButton(float x,float y,int32_t action,int32_t buttons)70 void CAndroidMouse::MouseButton(float x, float y, int32_t action, int32_t buttons)
71 {
72 #ifdef DEBUG_VERBOSE
73 CXBMCApp::android_printf("%s: x:%f, y:%f, action:%i, buttons:%i", __PRETTY_FUNCTION__, x, y, action, buttons);
74 #endif
75 XBMC_Event newEvent;
76
77 memset(&newEvent, 0, sizeof(newEvent));
78
79 int32_t checkButtons = buttons;
80 if (action == AMOTION_EVENT_ACTION_UP)
81 checkButtons = m_lastButtonState;
82
83 newEvent.type = (action == AMOTION_EVENT_ACTION_DOWN) ? XBMC_MOUSEBUTTONDOWN : XBMC_MOUSEBUTTONUP;
84 newEvent.button.x = x;
85 newEvent.button.y = y;
86 if (checkButtons & AMOTION_EVENT_BUTTON_PRIMARY)
87 newEvent.button.button = XBMC_BUTTON_LEFT;
88 else if (checkButtons & AMOTION_EVENT_BUTTON_SECONDARY)
89 newEvent.button.button = XBMC_BUTTON_RIGHT;
90 else if (checkButtons & AMOTION_EVENT_BUTTON_TERTIARY)
91 newEvent.button.button = XBMC_BUTTON_MIDDLE;
92
93 std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
94 if (appPort)
95 appPort->OnEvent(newEvent);
96
97 m_lastButtonState = buttons;
98 }
99
MouseWheel(float x,float y,float value)100 void CAndroidMouse::MouseWheel(float x, float y, float value)
101 {
102 #ifdef DEBUG_VERBOSE
103 CXBMCApp::android_printf("%s: val:%f", __PRETTY_FUNCTION__, value);
104 #endif
105 XBMC_Event newEvent;
106
107 memset(&newEvent, 0, sizeof(newEvent));
108
109 if (value > 0.0f)
110 {
111 newEvent.type = XBMC_MOUSEBUTTONDOWN;
112 newEvent.button.button = XBMC_BUTTON_WHEELUP;
113 }
114 else if (value < 0.0f)
115 {
116 newEvent.type = XBMC_MOUSEBUTTONDOWN;
117 newEvent.button.button = XBMC_BUTTON_WHEELDOWN;
118 }
119 else
120 return;
121
122 newEvent.button.x = x;
123 newEvent.button.y = y;
124
125 std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
126 if (appPort)
127 appPort->OnEvent(newEvent);
128
129 newEvent.type = XBMC_MOUSEBUTTONUP;
130
131 dynamic_cast<CWinSystemAndroid*>(CServiceBroker::GetWinSystem())->MessagePush(&newEvent);
132 }
133