1 /*
2 * Copyright (C) 2005-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 "LibInputPointer.h"
10
11 #include "AppInboundProtocol.h"
12 #include "ServiceBroker.h"
13 #include "input/mouse/MouseStat.h"
14 #include "utils/log.h"
15 #include "windowing/GraphicContext.h"
16
17 #include <algorithm>
18 #include <string.h>
19
20 #include <linux/input.h>
21
ProcessButton(libinput_event_pointer * e)22 void CLibInputPointer::ProcessButton(libinput_event_pointer *e)
23 {
24 const uint32_t b = libinput_event_pointer_get_button(e);
25 const bool pressed = libinput_event_pointer_get_button_state(e) == LIBINPUT_BUTTON_STATE_PRESSED;
26 unsigned char xbmc_button = 0;
27
28 switch (b)
29 {
30 case BTN_LEFT:
31 xbmc_button = XBMC_BUTTON_LEFT;
32 break;
33 case BTN_RIGHT:
34 xbmc_button = XBMC_BUTTON_RIGHT;
35 break;
36 case BTN_MIDDLE:
37 xbmc_button = XBMC_BUTTON_MIDDLE;
38 break;
39 case BTN_SIDE:
40 xbmc_button = XBMC_BUTTON_X1;
41 break;
42 case BTN_EXTRA:
43 xbmc_button = XBMC_BUTTON_X2;
44 break;
45 case BTN_FORWARD:
46 xbmc_button = XBMC_BUTTON_X3;
47 break;
48 case BTN_BACK:
49 xbmc_button = XBMC_BUTTON_X4;
50 break;
51 default:
52 break;
53 }
54
55 XBMC_Event event;
56 memset(&event, 0, sizeof(event));
57
58 event.type = pressed ? XBMC_MOUSEBUTTONDOWN : XBMC_MOUSEBUTTONUP;
59 event.button.button = xbmc_button;
60 event.button.x = static_cast<uint16_t>(m_pos.X);
61 event.button.y = static_cast<uint16_t>(m_pos.Y);
62
63 CLog::Log(LOGDEBUG, "CLibInputPointer::%s - event.type: %i, event.button.button: %i, event.button.x: %i, event.button.y: %i", __FUNCTION__, event.type, event.button.button, event.button.x, event.button.y);
64
65 std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
66 if (appPort)
67 appPort->OnEvent(event);
68 }
69
ProcessMotion(libinput_event_pointer * e)70 void CLibInputPointer::ProcessMotion(libinput_event_pointer *e)
71 {
72 const double dx = libinput_event_pointer_get_dx(e);
73 const double dy = libinput_event_pointer_get_dy(e);
74
75 m_pos.X += static_cast<int>(dx);
76 m_pos.Y += static_cast<int>(dy);
77
78 // limit the mouse to the screen width
79 m_pos.X = std::min(CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth(), m_pos.X);
80 m_pos.X = std::max(0, m_pos.X);
81
82 // limit the mouse to the screen height
83 m_pos.Y = std::min(CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight(), m_pos.Y);
84 m_pos.Y = std::max(0, m_pos.Y);
85
86 XBMC_Event event;
87 memset(&event, 0, sizeof(event));
88
89 event.type = XBMC_MOUSEMOTION;
90 event.motion.x = static_cast<uint16_t>(m_pos.X);
91 event.motion.y = static_cast<uint16_t>(m_pos.Y);
92
93 CLog::Log(LOGDEBUG, "CLibInputPointer::%s - event.type: %i, event.motion.x: %i, event.motion.y: %i", __FUNCTION__, event.type, event.motion.x, event.motion.y);
94
95 std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
96 if (appPort)
97 appPort->OnEvent(event);
98 }
99
ProcessMotionAbsolute(libinput_event_pointer * e)100 void CLibInputPointer::ProcessMotionAbsolute(libinput_event_pointer *e)
101 {
102 m_pos.X = static_cast<int>(libinput_event_pointer_get_absolute_x_transformed(e, CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth()));
103 m_pos.Y = static_cast<int>(libinput_event_pointer_get_absolute_y_transformed(e, CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight()));
104
105 XBMC_Event event;
106 event.type = XBMC_MOUSEMOTION;
107 event.motion.x = static_cast<uint16_t>(m_pos.X);
108 event.motion.y = static_cast<uint16_t>(m_pos.Y);
109
110 CLog::Log(LOGDEBUG, "CLibInputPointer::%s - event.type: %i, event.motion.x: %i, event.motion.y: %i", __FUNCTION__, event.type, event.motion.x, event.motion.y);
111
112 std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
113 if (appPort)
114 appPort->OnEvent(event);
115 }
116
ProcessAxis(libinput_event_pointer * e)117 void CLibInputPointer::ProcessAxis(libinput_event_pointer *e)
118 {
119 unsigned char scroll = 0;
120 if (!libinput_event_pointer_has_axis(e, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
121 return;
122
123 const double v = libinput_event_pointer_get_axis_value(e, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
124 if (v < 0)
125 scroll = XBMC_BUTTON_WHEELUP;
126 else
127 scroll = XBMC_BUTTON_WHEELDOWN;
128
129 XBMC_Event event;
130 memset(&event, 0, sizeof(event));
131
132 event.type = XBMC_MOUSEBUTTONDOWN;
133 event.button.button = scroll;
134 event.button.x = static_cast<uint16_t>(m_pos.X);
135 event.button.y = static_cast<uint16_t>(m_pos.Y);
136
137 CLog::Log(LOGDEBUG, "CLibInputPointer::%s - scroll: %s, event.button.x: %i, event.button.y: %i", __FUNCTION__, scroll == XBMC_BUTTON_WHEELUP ? "up" : "down", event.button.x, event.button.y);
138
139 std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
140 if (appPort)
141 appPort->OnEvent(event);
142
143 event.type = XBMC_MOUSEBUTTONUP;
144
145 if (appPort)
146 appPort->OnEvent(event);
147 }
148