2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "RemoteControlXbox.h"
11 #include "ServiceBroker.h"
12 #include "application/AppInboundProtocol.h"
13 #include "input/remote/IRRemote.h"
14 #include "settings/AdvancedSettings.h"
15 #include "settings/SettingsComponent.h"
16 #include "utils/log.h"
18 #define XBOX_REMOTE_DEVICE_ID L"GIP:0000F50000000001"
19 #define XBOX_REMOTE_DEVICE_NAME "Xbox One Game Controller"
23 using namespace Windows::Foundation
;
25 using namespace winrt::Windows::Media
;
26 using namespace winrt::Windows::System
;
27 using namespace winrt::Windows::UI::Core
;
29 CRemoteControlXbox::CRemoteControlXbox()
30 : m_bInitialized(false)
35 CRemoteControlXbox::~CRemoteControlXbox()
41 bool CRemoteControlXbox::IsRemoteDevice(const std::wstring
&deviceId
) const
43 return deviceId
.compare(XBOX_REMOTE_DEVICE_ID
) == 0;
46 void CRemoteControlXbox::Disconnect()
48 m_bInitialized
= false;
49 auto coreWindow
= CoreWindow::GetForCurrentThread();
50 if (!coreWindow
) // window is destroyed already
53 // unregister our key handler
54 coreWindow
.Dispatcher().AcceleratorKeyActivated(m_token
);
56 auto smtc
= SystemMediaTransportControls::GetForCurrentView();
59 smtc
.ButtonPressed(m_mediatoken
);
63 void CRemoteControlXbox::Initialize()
65 auto dispatcher
= CoreWindow::GetForCurrentThread().Dispatcher();
66 m_token
= dispatcher
.AcceleratorKeyActivated([this](const CoreDispatcher
& sender
, const AcceleratorKeyEventArgs
& args
)
68 if (IsRemoteDevice(args
.DeviceId().c_str()))
69 HandleAcceleratorKey(sender
, args
);
72 auto smtc
= SystemMediaTransportControls::GetForCurrentView();
75 m_mediatoken
= smtc
.ButtonPressed([this](auto&&, const SystemMediaTransportControlsButtonPressedEventArgs
& args
)
77 HandleMediaButton(args
);
81 m_bInitialized
= true;
84 void CRemoteControlXbox::HandleAcceleratorKey(const CoreDispatcher
& sender
, const AcceleratorKeyEventArgs
& args
)
86 auto button
= TranslateVirtualKey(args
.VirtualKey());
90 XBMC_Event newEvent
= {};
91 newEvent
.type
= XBMC_BUTTON
;
92 newEvent
.keybutton
.button
= button
;
93 newEvent
.keybutton
.holdtime
= 0;
95 std::shared_ptr
<CAppInboundProtocol
> appPort
= CServiceBroker::GetAppPort();
97 switch (args
.EventType())
99 case CoreAcceleratorKeyEventType::KeyDown
:
100 case CoreAcceleratorKeyEventType::SystemKeyDown
:
102 if (!args
.KeyStatus().WasKeyDown
) // first occurrence
104 m_firstClickTime
= std::chrono::steady_clock::now();
106 appPort
->OnEvent(newEvent
);
111 if (m_repeatCount
> CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_remoteDelay
)
113 auto now
= std::chrono::steady_clock::now();
115 std::chrono::duration_cast
<std::chrono::milliseconds
>(now
- m_firstClickTime
);
117 newEvent
.keybutton
.holdtime
= duration
.count();
119 appPort
->OnEvent(newEvent
);
124 case CoreAcceleratorKeyEventType::KeyUp
:
125 case CoreAcceleratorKeyEventType::SystemKeyUp
:
130 case CoreAcceleratorKeyEventType::Character
:
131 case CoreAcceleratorKeyEventType::SystemCharacter
:
132 case CoreAcceleratorKeyEventType::UnicodeCharacter
:
133 case CoreAcceleratorKeyEventType::DeadCharacter
:
134 case CoreAcceleratorKeyEventType::SystemDeadCharacter
:
141 void CRemoteControlXbox::HandleMediaButton(const SystemMediaTransportControlsButtonPressedEventArgs
& args
)
143 XBMC_Event newEvent
= {};
144 newEvent
.type
= XBMC_BUTTON
;
145 newEvent
.keybutton
.button
= TranslateMediaKey(args
.Button());
146 newEvent
.keybutton
.holdtime
= 0;
147 std::shared_ptr
<CAppInboundProtocol
> appPort
= CServiceBroker::GetAppPort();
149 appPort
->OnEvent(newEvent
);
152 int32_t CRemoteControlXbox::TranslateVirtualKey(VirtualKey vk
)
156 case VirtualKey::GamepadDPadLeft
:
157 return XINPUT_IR_REMOTE_LEFT
;
158 case VirtualKey::GamepadDPadUp
:
159 return XINPUT_IR_REMOTE_UP
;
160 case VirtualKey::GamepadDPadRight
:
161 return XINPUT_IR_REMOTE_RIGHT
;
162 case VirtualKey::GamepadDPadDown
:
163 return XINPUT_IR_REMOTE_DOWN
;
164 case VirtualKey::GamepadA
:
165 return XINPUT_IR_REMOTE_SELECT
;
166 case VirtualKey::GamepadB
:
167 return XINPUT_IR_REMOTE_BACK
;
168 case VirtualKey::GamepadX
:
169 return XINPUT_IR_REMOTE_CONTENTS_MENU
;
170 case VirtualKey::GamepadY
:
171 return XINPUT_IR_REMOTE_INFO
;
172 case VirtualKey::Clear
:
173 return XINPUT_IR_REMOTE_CLEAR
;
174 case VirtualKey::PageDown
:
175 return XINPUT_IR_REMOTE_CHANNEL_MINUS
;
176 case VirtualKey::PageUp
:
177 return XINPUT_IR_REMOTE_CHANNEL_PLUS
;
178 case VirtualKey::Number0
:
179 return XINPUT_IR_REMOTE_0
;
180 case VirtualKey::Number1
:
181 return XINPUT_IR_REMOTE_1
;
182 case VirtualKey::Number2
:
183 return XINPUT_IR_REMOTE_2
;
184 case VirtualKey::Number3
:
185 return XINPUT_IR_REMOTE_3
;
186 case VirtualKey::Number4
:
187 return XINPUT_IR_REMOTE_4
;
188 case VirtualKey::Number5
:
189 return XINPUT_IR_REMOTE_5
;
190 case VirtualKey::Number6
:
191 return XINPUT_IR_REMOTE_6
;
192 case VirtualKey::Number7
:
193 return XINPUT_IR_REMOTE_7
;
194 case VirtualKey::Number8
:
195 return XINPUT_IR_REMOTE_8
;
196 case VirtualKey::Number9
:
197 return XINPUT_IR_REMOTE_9
;
198 case VirtualKey::Decimal
:
199 return XINPUT_IR_REMOTE_STAR
;
200 case VirtualKey::GamepadView
:
201 return XINPUT_IR_REMOTE_DISPLAY
;
202 case VirtualKey::GamepadMenu
:
203 return XINPUT_IR_REMOTE_MENU
;
205 CLog::LogF(LOGDEBUG
, "unknown vrtual key {}", static_cast<int>(vk
));
210 int32_t CRemoteControlXbox::TranslateMediaKey(SystemMediaTransportControlsButton mk
)
214 case SystemMediaTransportControlsButton::ChannelDown
:
215 return XINPUT_IR_REMOTE_CHANNEL_MINUS
;
217 case SystemMediaTransportControlsButton::ChannelUp
:
218 return XINPUT_IR_REMOTE_CHANNEL_PLUS
;
219 case SystemMediaTransportControlsButton::FastForward
:
220 return XINPUT_IR_REMOTE_FORWARD
;
221 case SystemMediaTransportControlsButton::Rewind
:
222 return XINPUT_IR_REMOTE_REVERSE
;
223 case SystemMediaTransportControlsButton::Next
:
224 return XINPUT_IR_REMOTE_SKIP_PLUS
;
225 case SystemMediaTransportControlsButton::Previous
:
226 return XINPUT_IR_REMOTE_SKIP_MINUS
;
227 case SystemMediaTransportControlsButton::Pause
:
228 return XINPUT_IR_REMOTE_PAUSE
;
229 case SystemMediaTransportControlsButton::Play
:
230 return XINPUT_IR_REMOTE_PLAY
;
231 case SystemMediaTransportControlsButton::Stop
:
232 return XINPUT_IR_REMOTE_STOP
;
233 case SystemMediaTransportControlsButton::Record
:
234 return XINPUT_IR_REMOTE_RECORD
;