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 "InputOperations.h"
10 
11 #include "Application.h"
12 #include "guilib/GUIAudioManager.h"
13 #include "guilib/GUIKeyboardFactory.h"
14 #include "guilib/GUIWindow.h"
15 #include "guilib/GUIWindowManager.h"
16 #include "input/ButtonTranslator.h"
17 #include "input/Key.h"
18 #include "input/actions/ActionTranslator.h"
19 #include "messaging/ApplicationMessenger.h"
20 #include "utils/Variant.h"
21 
22 using namespace JSONRPC;
23 using namespace KODI::MESSAGING;
24 
25 //! @todo the breakage of the screensaver should be refactored
26 //! to one central super duper place for getting rid of
27 //! 1 million dupes
handleScreenSaver()28 bool CInputOperations::handleScreenSaver()
29 {
30   g_application.ResetScreenSaver();
31   if (g_application.WakeUpScreenSaverAndDPMS())
32     return true;
33 
34   return false;
35 }
36 
SendAction(int actionID,bool wakeScreensaver,bool waitResult)37 JSONRPC_STATUS CInputOperations::SendAction(int actionID, bool wakeScreensaver /* = true */, bool waitResult /* = false */)
38 {
39   if(!wakeScreensaver || !handleScreenSaver())
40   {
41     g_application.ResetSystemIdleTimer();
42     CGUIComponent* gui = CServiceBroker::GetGUI();
43     if (gui)
44       gui->GetAudioManager().PlayActionSound(actionID);
45 
46     if (waitResult)
47       CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(actionID)));
48     else
49       CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(actionID)));
50   }
51   return ACK;
52 }
53 
activateWindow(int windowID)54 JSONRPC_STATUS CInputOperations::activateWindow(int windowID)
55 {
56   if(!handleScreenSaver())
57     CApplicationMessenger::GetInstance().SendMsg(TMSG_GUI_ACTIVATE_WINDOW, windowID, 0);
58 
59   return ACK;
60 }
61 
SendText(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)62 JSONRPC_STATUS CInputOperations::SendText(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
63 {
64   if (CGUIKeyboardFactory::SendTextToActiveKeyboard(parameterObject["text"].asString(), parameterObject["done"].asBoolean()))
65     return ACK;
66 
67   CGUIWindow *window = CServiceBroker::GetGUI()->GetWindowManager().GetWindow(CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindowOrDialog());
68   if (!window)
69     return ACK;
70 
71   CGUIMessage msg(GUI_MSG_SET_TEXT, 0, window->GetFocusedControlID());
72   msg.SetLabel(parameterObject["text"].asString());
73   msg.SetParam1(parameterObject["done"].asBoolean() ? 1 : 0);
74   CApplicationMessenger::GetInstance().SendGUIMessage(msg, window->GetID());
75 
76   return ACK;
77 }
78 
ExecuteAction(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)79 JSONRPC_STATUS CInputOperations::ExecuteAction(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
80 {
81   unsigned int action;
82   if (!CActionTranslator::TranslateString(parameterObject["action"].asString(), action))
83     return InvalidParams;
84 
85   return SendAction(action);
86 }
87 
ButtonEvent(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)88 JSONRPC_STATUS CInputOperations::ButtonEvent(const std::string& method,
89                                              ITransportLayer* transport,
90                                              IClient* client,
91                                              const CVariant& parameterObject,
92                                              CVariant& result)
93 {
94   std::string button = parameterObject["button"].asString();
95   std::string keymap = parameterObject["keymap"].asString();
96   int holdtime = static_cast<int>(parameterObject["holdtime"].asInteger());
97   if (holdtime < 0)
98   {
99     return InvalidParams;
100   }
101 
102   uint32_t keycode = CButtonTranslator::TranslateString(keymap, button);
103   if (keycode == 0)
104   {
105     return InvalidParams;
106   }
107 
108   XBMC_Event* newEvent = new XBMC_Event;
109   newEvent->type = XBMC_BUTTON;
110   newEvent->keybutton.button = keycode;
111   newEvent->keybutton.holdtime = holdtime;
112 
113   CApplicationMessenger::GetInstance().PostMsg(TMSG_EVENT, -1, -1, static_cast<void*>(newEvent));
114 
115   return ACK;
116 }
117 
Left(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)118 JSONRPC_STATUS CInputOperations::Left(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
119 {
120   return SendAction(ACTION_MOVE_LEFT);
121 }
122 
Right(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)123 JSONRPC_STATUS CInputOperations::Right(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
124 {
125   return SendAction(ACTION_MOVE_RIGHT);
126 }
127 
Down(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)128 JSONRPC_STATUS CInputOperations::Down(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
129 {
130   return SendAction(ACTION_MOVE_DOWN);
131 }
132 
Up(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)133 JSONRPC_STATUS CInputOperations::Up(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
134 {
135   return SendAction(ACTION_MOVE_UP);
136 }
137 
Select(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)138 JSONRPC_STATUS CInputOperations::Select(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
139 {
140   return SendAction(ACTION_SELECT_ITEM);
141 }
142 
Back(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)143 JSONRPC_STATUS CInputOperations::Back(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
144 {
145   return SendAction(ACTION_NAV_BACK);
146 }
147 
ContextMenu(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)148 JSONRPC_STATUS CInputOperations::ContextMenu(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
149 {
150   return SendAction(ACTION_CONTEXT_MENU);
151 }
152 
Info(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)153 JSONRPC_STATUS CInputOperations::Info(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
154 {
155   return SendAction(ACTION_SHOW_INFO);
156 }
157 
Home(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)158 JSONRPC_STATUS CInputOperations::Home(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
159 {
160   return activateWindow(WINDOW_HOME);
161 }
162 
ShowCodec(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)163 JSONRPC_STATUS CInputOperations::ShowCodec(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
164 {
165   return MethodNotFound;
166 }
167 
ShowOSD(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)168 JSONRPC_STATUS CInputOperations::ShowOSD(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
169 {
170   return SendAction(ACTION_SHOW_OSD);
171 }
172 
ShowPlayerProcessInfo(const std::string & method,ITransportLayer * transport,IClient * client,const CVariant & parameterObject,CVariant & result)173 JSONRPC_STATUS CInputOperations::ShowPlayerProcessInfo(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
174 {
175   return SendAction(ACTION_PLAYER_PROCESS_INFO);
176 }
177