1 /*
2  *  Copyright (C) 2017-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 "GameWindowFullScreen.h"
10 
11 #include "Application.h" //! @todo Remove me
12 #include "ApplicationPlayer.h" //! @todo Remove me
13 #include "GUIInfoManager.h" //! @todo Remove me
14 #include "GameWindowFullScreenText.h"
15 #include "ServiceBroker.h"
16 #include "cores/RetroPlayer/guibridge/GUIGameRenderManager.h"
17 #include "cores/RetroPlayer/guibridge/GUIRenderHandle.h"
18 #include "games/GameServices.h"
19 #include "games/GameSettings.h"
20 #include "guilib/GUIComponent.h"
21 #include "guilib/GUIControl.h"
22 #include "guilib/GUIDialog.h"
23 #include "guilib/GUIWindowManager.h" //! @todo Remove me
24 #include "guilib/WindowIDs.h"
25 #include "input/actions/Action.h"
26 #include "input/actions/ActionIDs.h"
27 #include "windowing/GraphicContext.h" //! @todo Remove me
28 
29 using namespace KODI;
30 using namespace KODI::GUILIB;
31 using namespace RETRO;
32 
CGameWindowFullScreen(void)33 CGameWindowFullScreen::CGameWindowFullScreen(void)
34   : CGUIWindow(WINDOW_FULLSCREEN_GAME, "VideoFullScreen.xml"),
35     m_fullscreenText(new CGameWindowFullScreenText(*this))
36 {
37   // initialize CGUIControl
38   m_controlStats = new GUICONTROLSTATS;
39 
40   // initialize CGUIWindow
41   m_loadType = KEEP_IN_MEMORY;
42 
43   RegisterWindow();
44 }
45 
~CGameWindowFullScreen()46 CGameWindowFullScreen::~CGameWindowFullScreen()
47 {
48   UnregisterWindow();
49 
50   delete m_controlStats;
51 }
52 
Process(unsigned int currentTime,CDirtyRegionList & dirtyregion)53 void CGameWindowFullScreen::Process(unsigned int currentTime, CDirtyRegionList& dirtyregion)
54 {
55   if (m_renderHandle->IsDirty())
56     MarkDirtyRegion();
57 
58   m_controlStats->Reset();
59 
60   CGUIWindow::Process(currentTime, dirtyregion);
61 
62   //! @todo This isn't quite optimal - ideally we'd only be dirtying up the actual video render rect
63   //!       which is probably the job of the renderer as it can more easily track resizing etc.
64   m_renderRegion.SetRect(
65       0, 0, static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth()),
66       static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight()));
67 }
68 
Render()69 void CGameWindowFullScreen::Render()
70 {
71   m_renderHandle->Render();
72 
73   CGUIWindow::Render();
74 }
75 
RenderEx()76 void CGameWindowFullScreen::RenderEx()
77 {
78   CGUIWindow::RenderEx();
79 
80   m_renderHandle->RenderEx();
81 }
82 
OnAction(const CAction & action)83 bool CGameWindowFullScreen::OnAction(const CAction& action)
84 {
85   switch (action.GetID())
86   {
87     case ACTION_SHOW_OSD:
88     case ACTION_TRIGGER_OSD:
89     {
90       TriggerOSD();
91       return true;
92     }
93     case ACTION_MOUSE_MOVE:
94     {
95       if (action.GetAmount(2) || action.GetAmount(3))
96       {
97         TriggerOSD();
98         return true;
99       }
100       break;
101     }
102     case ACTION_MOUSE_LEFT_CLICK:
103     {
104       TriggerOSD();
105       return true;
106     }
107     case ACTION_SHOW_GUI:
108     {
109       // Switch back to the menu
110       CServiceBroker::GetGUI()->GetWindowManager().PreviousWindow();
111       return true;
112     }
113     case ACTION_ASPECT_RATIO:
114     {
115       // Toggle the aspect ratio mode (only if the info is onscreen)
116       // g_application.GetAppPlayer().SetRenderViewMode(CViewModeSettings::GetNextQuickCycleViewMode(CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ViewMode));
117       return true;
118     }
119     default:
120       break;
121   }
122 
123   return CGUIWindow::OnAction(action);
124 }
125 
OnMessage(CGUIMessage & message)126 bool CGameWindowFullScreen::OnMessage(CGUIMessage& message)
127 {
128   switch (message.GetMessage())
129   {
130     case GUI_MSG_SETFOCUS:
131     case GUI_MSG_LOSTFOCUS:
132     {
133       if (message.GetSenderId() != WINDOW_FULLSCREEN_GAME)
134         return true;
135       break;
136     }
137     default:
138       break;
139   }
140 
141   return CGUIWindow::OnMessage(message);
142 }
143 
FrameMove()144 void CGameWindowFullScreen::FrameMove()
145 {
146   m_fullscreenText->FrameMove();
147 
148   CGUIWindow::FrameMove();
149 }
150 
ClearBackground()151 void CGameWindowFullScreen::ClearBackground()
152 {
153   m_renderHandle->ClearBackground();
154 
155   CGUIWindow::ClearBackground();
156 }
157 
HasVisibleControls()158 bool CGameWindowFullScreen::HasVisibleControls()
159 {
160   return m_controlStats->nCountVisible > 0;
161 }
162 
OnWindowLoaded()163 void CGameWindowFullScreen::OnWindowLoaded()
164 {
165   CGUIWindow::OnWindowLoaded();
166 
167   // Override the clear colour - we must never clear fullscreen
168   m_clearBackground = 0;
169 
170   m_fullscreenText->OnWindowLoaded();
171 }
172 
OnInitWindow()173 void CGameWindowFullScreen::OnInitWindow()
174 {
175   GUIINFO::CPlayerGUIInfo& guiInfo =
176       CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider();
177   guiInfo.SetShowInfo(false);
178   guiInfo.SetDisplayAfterSeek(0); // Make sure display after seek is off
179 
180   // Switch resolution
181   CServiceBroker::GetWinSystem()->GetGfxContext().SetFullScreenVideo(true); //! @todo
182 
183   CGUIWindow::OnInitWindow();
184 
185   // Show OSD help
186   GAME::CGameSettings& gameSettings = CServiceBroker::GetGameServices().GameSettings();
187   if (gameSettings.ShowOSDHelp())
188     TriggerOSD();
189   else
190   {
191     //! @todo We need to route this check through the GUI bridge. By adding the
192     //        dependency to the application player here, we are prevented from
193     //        having multiple players.
194     if (!g_application.GetAppPlayer().HasGameAgent())
195     {
196       gameSettings.SetShowOSDHelp(true);
197       TriggerOSD();
198     }
199   }
200 }
201 
OnDeinitWindow(int nextWindowID)202 void CGameWindowFullScreen::OnDeinitWindow(int nextWindowID)
203 {
204   // Close all active modal dialogs
205   CServiceBroker::GetGUI()->GetWindowManager().CloseInternalModalDialogs(true);
206 
207   CGUIWindow::OnDeinitWindow(nextWindowID);
208 
209   CServiceBroker::GetWinSystem()->GetGfxContext().SetFullScreenVideo(false); //! @todo
210 }
211 
TriggerOSD()212 void CGameWindowFullScreen::TriggerOSD()
213 {
214   CGUIDialog* pOSD = GetOSD();
215   if (pOSD != nullptr)
216   {
217     if (!pOSD->IsDialogRunning())
218       pOSD->Open();
219   }
220 }
221 
GetOSD()222 CGUIDialog* CGameWindowFullScreen::GetOSD()
223 {
224   return CServiceBroker::GetGUI()->GetWindowManager().GetDialog(WINDOW_DIALOG_GAME_OSD);
225 }
226 
RegisterWindow()227 void CGameWindowFullScreen::RegisterWindow()
228 {
229   m_renderHandle = CServiceBroker::GetGameRenderManager().RegisterWindow(*this);
230 }
231 
UnregisterWindow()232 void CGameWindowFullScreen::UnregisterWindow()
233 {
234   m_renderHandle.reset();
235 }
236