/* * 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 "GUIDialogTeletext.h" #include "ServiceBroker.h" #include "application/ApplicationComponents.h" #include "application/ApplicationPlayer.h" #include "dialogs/GUIDialogKaiToast.h" #include "guilib/GUIMessage.h" #include "guilib/GUITexture.h" #include "guilib/LocalizeStrings.h" #include "guilib/Texture.h" #include "settings/Settings.h" #include "settings/SettingsComponent.h" #include "utils/ColorUtils.h" #include "utils/log.h" static int teletextFadeAmount = 0; CGUIDialogTeletext::CGUIDialogTeletext() : CGUIDialog(WINDOW_DIALOG_OSD_TELETEXT, ""), m_pTxtTexture(nullptr) { m_renderOrder = RENDER_ORDER_DIALOG_TELETEXT; } CGUIDialogTeletext::~CGUIDialogTeletext() = default; bool CGUIDialogTeletext::OnAction(const CAction& action) { if (m_TextDecoder.HandleAction(action)) { MarkDirtyRegion(); return true; } return CGUIDialog::OnAction(action); } bool CGUIDialogTeletext::OnBack(int actionID) { m_bClose = true; MarkDirtyRegion(); return true; } bool CGUIDialogTeletext::OnMessage(CGUIMessage& message) { if (message.GetMessage() == GUI_MSG_WINDOW_INIT) { /* Do not open if no teletext is available */ const auto& components = CServiceBroker::GetAppComponents(); const auto appPlayer = components.GetComponent(); if (!appPlayer->HasTeletextCache()) { Close(); CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(23049), "", 1500, false); return true; } } else if (message.GetMessage() == GUI_MSG_NOTIFY_ALL) { if (message.GetParam1() == GUI_MSG_WINDOW_RESIZE) { SetCoordinates(); } } return CGUIDialog::OnMessage(message); } void CGUIDialogTeletext::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) { CGUIDialog::Process(currentTime, dirtyregions); m_renderRegion = m_vertCoords; } void CGUIDialogTeletext::Render() { // Do not render if we have no texture if (!m_pTxtTexture) { CLog::Log(LOGERROR, "CGUITeletextBox::Render called without texture"); return; } m_TextDecoder.RenderPage(); if (!m_bClose) { if (teletextFadeAmount < 100) { teletextFadeAmount = std::min(100, teletextFadeAmount + 5); MarkDirtyRegion(); } } else { if (teletextFadeAmount > 0) { teletextFadeAmount = std::max(0, teletextFadeAmount - 10); MarkDirtyRegion(); } if (teletextFadeAmount == 0) Close(); } unsigned char* textureBuffer = (unsigned char*)m_TextDecoder.GetTextureBuffer(); if (!m_bClose && m_TextDecoder.NeedRendering() && textureBuffer) { m_pTxtTexture->Update(m_TextDecoder.GetWidth(), m_TextDecoder.GetHeight(), m_TextDecoder.GetWidth()*4, XB_FMT_A8R8G8B8, textureBuffer, false); m_TextDecoder.RenderingDone(); MarkDirtyRegion(); } UTILS::COLOR::Color color = (static_cast(teletextFadeAmount * 2.55f) & 0xff) << 24 | 0xFFFFFF; CGUITexture::DrawQuad(m_vertCoords, color, m_pTxtTexture.get()); CGUIDialog::Render(); } void CGUIDialogTeletext::OnInitWindow() { teletextFadeAmount = 0; m_bClose = false; m_windowLoaded = true; SetCoordinates(); if (!m_TextDecoder.InitDecoder()) { CLog::Log(LOGERROR, "{}: failed to init teletext decoder", __FUNCTION__); Close(); } m_pTxtTexture = CTexture::CreateTexture(m_TextDecoder.GetWidth(), m_TextDecoder.GetHeight(), XB_FMT_A8R8G8B8); if (!m_pTxtTexture) { CLog::Log(LOGERROR, "{}: failed to create texture", __FUNCTION__); Close(); } CGUIDialog::OnInitWindow(); } void CGUIDialogTeletext::OnDeinitWindow(int nextWindowID) { m_windowLoaded = false; m_TextDecoder.EndDecoder(); m_pTxtTexture.reset(); CGUIDialog::OnDeinitWindow(nextWindowID); } void CGUIDialogTeletext::SetCoordinates() { float left, right, top, bottom; CServiceBroker::GetWinSystem()->GetGfxContext().SetScalingResolution(m_coordsRes, m_needsScaling); left = CServiceBroker::GetWinSystem()->GetGfxContext().ScaleFinalXCoord(0, 0); right = CServiceBroker::GetWinSystem()->GetGfxContext().ScaleFinalXCoord((float)m_coordsRes.iWidth, 0); top = CServiceBroker::GetWinSystem()->GetGfxContext().ScaleFinalYCoord(0, 0); bottom = CServiceBroker::GetWinSystem()->GetGfxContext().ScaleFinalYCoord(0, (float)m_coordsRes.iHeight); if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_VIDEOPLAYER_TELETEXTSCALE)) { /* Fixed aspect ratio to 4:3 for teletext */ float width = right - left; float height = bottom - top; if (width / 4 > height / 3) { left = (width - height * 4 / 3) / 2; right = width - left; } else { top = (height - width * 3 / 4) / 2; bottom = height - top; } } m_vertCoords.SetRect(left, top, right, bottom); MarkDirtyRegion(); }