diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/video/windows/GUIWindowFullScreen.cpp | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/video/windows/GUIWindowFullScreen.cpp')
-rw-r--r-- | xbmc/video/windows/GUIWindowFullScreen.cpp | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/xbmc/video/windows/GUIWindowFullScreen.cpp b/xbmc/video/windows/GUIWindowFullScreen.cpp new file mode 100644 index 0000000..7cebc5f --- /dev/null +++ b/xbmc/video/windows/GUIWindowFullScreen.cpp @@ -0,0 +1,437 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "GUIWindowFullScreen.h" + +#include "FileItem.h" +#include "GUIInfoManager.h" +#include "GUIWindowFullScreenDefines.h" +#include "ServiceBroker.h" +#include "application/Application.h" +#include "application/ApplicationComponents.h" +#include "application/ApplicationPlayer.h" +#include "cores/IPlayer.h" +#include "guilib/GUIComponent.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "input/Key.h" +#include "settings/DisplaySettings.h" +#include "settings/Settings.h" +#include "settings/SettingsComponent.h" +#include "utils/StringUtils.h" +#include "video/ViewModeSettings.h" +#include "video/dialogs/GUIDialogFullScreenInfo.h" +#include "video/dialogs/GUIDialogSubtitleSettings.h" +#include "windowing/WinSystem.h" + +#include <algorithm> +#include <stdio.h> +#if defined(TARGET_DARWIN) +#include "platform/posix/PosixResourceCounter.h" +#endif + +using namespace KODI::GUILIB; +using namespace KODI::MESSAGING; + +#if defined(TARGET_DARWIN) +static CPosixResourceCounter m_resourceCounter; +#endif + +CGUIWindowFullScreen::CGUIWindowFullScreen() + : CGUIWindow(WINDOW_FULLSCREEN_VIDEO, "VideoFullScreen.xml") +{ + m_viewModeChanged = true; + m_dwShowViewModeTimeout = {}; + m_bShowCurrentTime = false; + m_loadType = KEEP_IN_MEMORY; + // audio + // - language + // - volume + // - stream + + // video + // - Create Bookmark (294) + // - Cycle bookmarks (295) + // - Clear bookmarks (296) + // - jump to specific time + // - slider + // - av delay + + // subtitles + // - delay + // - language + + m_controlStats = new GUICONTROLSTATS; +} + +CGUIWindowFullScreen::~CGUIWindowFullScreen(void) +{ + delete m_controlStats; +} + +bool CGUIWindowFullScreen::OnAction(const CAction &action) +{ + auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + switch (action.GetID()) + { + case ACTION_SHOW_OSD: + ToggleOSD(); + return true; + + case ACTION_TRIGGER_OSD: + TriggerOSD(); + return true; + + case ACTION_MOUSE_MOVE: + if (action.GetAmount(2) || action.GetAmount(3)) + { + if (!appPlayer->IsInMenu()) + { + TriggerOSD(); + return true; + } + } + break; + + case ACTION_MOUSE_LEFT_CLICK: + if (!appPlayer->IsInMenu()) + { + TriggerOSD(); + return true; + } + break; + + case ACTION_SHOW_GUI: + { + // switch back to the menu + CServiceBroker::GetGUI()->GetWindowManager().PreviousWindow(); + return true; + } + break; + + case ACTION_SHOW_OSD_TIME: + m_bShowCurrentTime = !m_bShowCurrentTime; + CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider().SetShowTime(m_bShowCurrentTime); + return true; + break; + + case ACTION_SHOW_INFO: + { + CGUIDialogFullScreenInfo* pDialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogFullScreenInfo>(WINDOW_DIALOG_FULLSCREEN_INFO); + if (pDialog) + { + CFileItem item(g_application.CurrentFileItem()); + pDialog->Open(); + return true; + } + break; + } + + case ACTION_ASPECT_RATIO: + { // toggle the aspect ratio mode (only if the info is onscreen) + if (m_dwShowViewModeTimeout.time_since_epoch().count() != 0) + { + CVideoSettings vs = appPlayer->GetVideoSettings(); + vs.m_ViewMode = CViewModeSettings::GetNextQuickCycleViewMode(vs.m_ViewMode); + appPlayer->SetRenderViewMode(vs.m_ViewMode, vs.m_CustomZoomAmount, vs.m_CustomPixelRatio, + vs.m_CustomVerticalShift, vs.m_CustomNonLinStretch); + } + else + m_viewModeChanged = true; + m_dwShowViewModeTimeout = std::chrono::steady_clock::now(); + } + return true; + break; + case ACTION_SHOW_PLAYLIST: + { + CFileItem item(g_application.CurrentFileItem()); + if (item.HasPVRChannelInfoTag()) + CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_DIALOG_PVR_OSD_CHANNELS); + else if (item.HasVideoInfoTag()) + CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_VIDEO_PLAYLIST); + else if (item.HasMusicInfoTag()) + CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_MUSIC_PLAYLIST); + } + return true; + break; + case ACTION_BROWSE_SUBTITLE: + { + std::string path = CGUIDialogSubtitleSettings::BrowseForSubtitle(); + if (!path.empty()) + appPlayer->AddSubtitle(path); + return true; + } + default: + break; + } + + return CGUIWindow::OnAction(action); +} + +void CGUIWindowFullScreen::ClearBackground() +{ + const auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + if (appPlayer->IsRenderingVideoLayer()) + CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0); +} + +void CGUIWindowFullScreen::OnWindowLoaded() +{ + CGUIWindow::OnWindowLoaded(); + // override the clear colour - we must never clear fullscreen + m_clearBackground = 0; +} + +bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) +{ + switch (message.GetMessage()) + { + case GUI_MSG_WINDOW_INIT: + { + // check whether we've come back here from a window during which time we've actually + // stopped playing videos + const auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + if (message.GetParam1() == WINDOW_INVALID && !appPlayer->IsPlayingVideo()) + { // why are we here if nothing is playing??? + CServiceBroker::GetGUI()->GetWindowManager().PreviousWindow(); + return true; + } + + GUIINFO::CPlayerGUIInfo& guiInfo = CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPlayerInfoProvider(); + guiInfo.SetShowInfo(false); + m_bShowCurrentTime = false; + + // switch resolution + CServiceBroker::GetWinSystem()->GetGfxContext().SetFullScreenVideo(true); + + // now call the base class to load our windows + CGUIWindow::OnMessage(message); + + m_dwShowViewModeTimeout = {}; + m_viewModeChanged = true; + + + return true; + } + case GUI_MSG_WINDOW_DEINIT: + { + // close all active modal dialogs + CServiceBroker::GetGUI()->GetWindowManager().CloseInternalModalDialogs(true); + + CGUIWindow::OnMessage(message); + + CServiceBroker::GetSettingsComponent()->GetSettings()->Save(); + + CServiceBroker::GetWinSystem()->GetGfxContext().SetFullScreenVideo(false); + + return true; + } + case GUI_MSG_SETFOCUS: + case GUI_MSG_LOSTFOCUS: + if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true; + break; + } + + return CGUIWindow::OnMessage(message); +} + +EVENT_RESULT CGUIWindowFullScreen::OnMouseEvent(const CPoint &point, const CMouseEvent &event) +{ + if (event.m_id == ACTION_MOUSE_RIGHT_CLICK) + { // no control found to absorb this click - go back to GUI + OnAction(CAction(ACTION_SHOW_GUI)); + return EVENT_RESULT_HANDLED; + } + if (event.m_id == ACTION_MOUSE_WHEEL_UP) + { + return g_application.OnAction(CAction(ACTION_ANALOG_SEEK_FORWARD, 0.5f)) ? EVENT_RESULT_HANDLED : EVENT_RESULT_UNHANDLED; + } + if (event.m_id == ACTION_MOUSE_WHEEL_DOWN) + { + return g_application.OnAction(CAction(ACTION_ANALOG_SEEK_BACK, 0.5f)) ? EVENT_RESULT_HANDLED : EVENT_RESULT_UNHANDLED; + } + if (event.m_id >= ACTION_GESTURE_NOTIFY && event.m_id <= ACTION_GESTURE_END) // gestures + return EVENT_RESULT_UNHANDLED; + return EVENT_RESULT_UNHANDLED; +} + +void CGUIWindowFullScreen::FrameMove() +{ + const auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + if (!appPlayer->HasPlayer()) + return; + + //---------------------- + // ViewMode Information + //---------------------- + + auto now = std::chrono::steady_clock::now(); + auto duration = + std::chrono::duration_cast<std::chrono::milliseconds>(now - m_dwShowViewModeTimeout); + + if (m_dwShowViewModeTimeout.time_since_epoch().count() != 0 && duration.count() > 2500) + { + m_dwShowViewModeTimeout = {}; + m_viewModeChanged = true; + } + + if (m_dwShowViewModeTimeout.time_since_epoch().count() != 0) + { + RESOLUTION_INFO res = CServiceBroker::GetWinSystem()->GetGfxContext().GetResInfo(); + + { + // get the "View Mode" string + const std::string& strTitle = g_localizeStrings.Get(629); + const auto& vs = appPlayer->GetVideoSettings(); + int sId = CViewModeSettings::GetViewModeStringIndex(vs.m_ViewMode); + const std::string& strMode = g_localizeStrings.Get(sId); + std::string strInfo = StringUtils::Format("{} : {}", strTitle, strMode); + CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1); + msg.SetLabel(strInfo); + OnMessage(msg); + } + // show sizing information + VideoStreamInfo info; + appPlayer->GetVideoStreamInfo(CURRENT_STREAM, info); + { + // Splitres scaling factor + float xscale = (float)res.iScreenWidth / (float)res.iWidth; + float yscale = (float)res.iScreenHeight / (float)res.iHeight; + + std::string strSizing = StringUtils::Format( + g_localizeStrings.Get(245), (int)info.SrcRect.Width(), (int)info.SrcRect.Height(), + (int)(info.DestRect.Width() * xscale), (int)(info.DestRect.Height() * yscale), + CDisplaySettings::GetInstance().GetZoomAmount(), + info.videoAspectRatio * CDisplaySettings::GetInstance().GetPixelRatio(), + CDisplaySettings::GetInstance().GetPixelRatio(), + CDisplaySettings::GetInstance().GetVerticalShift()); + CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW2); + msg.SetLabel(strSizing); + OnMessage(msg); + } + // show resolution information + { + std::string strStatus; + if (CServiceBroker::GetWinSystem()->IsFullScreen()) + strStatus = StringUtils::Format("{} {}x{}@{:.2f}Hz - {}", g_localizeStrings.Get(13287), + res.iScreenWidth, res.iScreenHeight, res.fRefreshRate, + g_localizeStrings.Get(244)); + else + strStatus = + StringUtils::Format("{} {}x{} - {}", g_localizeStrings.Get(13287), res.iScreenWidth, + res.iScreenHeight, g_localizeStrings.Get(242)); + + CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW3); + msg.SetLabel(strStatus); + OnMessage(msg); + } + } + + if (m_viewModeChanged) + { + if (m_dwShowViewModeTimeout.time_since_epoch().count() != 0) + { + SET_CONTROL_VISIBLE(LABEL_ROW1); + SET_CONTROL_VISIBLE(LABEL_ROW2); + SET_CONTROL_VISIBLE(LABEL_ROW3); + SET_CONTROL_VISIBLE(BLUE_BAR); + } + else + { + SET_CONTROL_HIDDEN(LABEL_ROW1); + SET_CONTROL_HIDDEN(LABEL_ROW2); + SET_CONTROL_HIDDEN(LABEL_ROW3); + SET_CONTROL_HIDDEN(BLUE_BAR); + } + m_viewModeChanged = false; + } +} + +void CGUIWindowFullScreen::Process(unsigned int currentTime, CDirtyRegionList &dirtyregion) +{ + const auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + if (appPlayer->IsRenderingGuiLayer()) + MarkDirtyRegion(); + + m_controlStats->Reset(); + + CGUIWindow::Process(currentTime, dirtyregion); + + //! @todo This isn't quite optimal - ideally we'd only be dirtying up the actual video render rect + //! which is probably the job of the renderer as it can more easily track resizing etc. + m_renderRegion.SetRect(0, 0, (float)CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth(), (float)CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight()); +} + +void CGUIWindowFullScreen::Render() +{ + CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(CServiceBroker::GetWinSystem()->GetGfxContext().GetVideoResolution(), false); + auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + appPlayer->Render(true, 255); + CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(m_coordsRes, m_needsScaling); + CGUIWindow::Render(); +} + +void CGUIWindowFullScreen::RenderEx() +{ + CGUIWindow::RenderEx(); + CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(CServiceBroker::GetWinSystem()->GetGfxContext().GetVideoResolution(), false); + auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + appPlayer->Render(false, 255, false); + CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(m_coordsRes, m_needsScaling); +} + +void CGUIWindowFullScreen::SeekChapter(int iChapter) +{ + auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + appPlayer->SeekChapter(iChapter); +} + +void CGUIWindowFullScreen::ToggleOSD() +{ + CGUIDialog *pOSD = GetOSD(); + if (pOSD) + { + if (pOSD->IsDialogRunning()) + pOSD->Close(); + else + pOSD->Open(); + } + + MarkDirtyRegion(); +} + +void CGUIWindowFullScreen::TriggerOSD() +{ + CGUIDialog *pOSD = GetOSD(); + if (pOSD && !pOSD->IsDialogRunning()) + { + const auto& components = CServiceBroker::GetAppComponents(); + const auto appPlayer = components.GetComponent<CApplicationPlayer>(); + if (!appPlayer->IsPlayingGame()) + pOSD->SetAutoClose(3000); + pOSD->Open(); + } +} + +bool CGUIWindowFullScreen::HasVisibleControls() +{ + return m_controlStats->nCountVisible > 0; +} + +CGUIDialog* CGUIWindowFullScreen::GetOSD() +{ + return CServiceBroker::GetGUI()->GetWindowManager().GetDialog(WINDOW_DIALOG_VIDEO_OSD); +} |