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 "GUIDialogTeletext.h"
10
11 #include "Application.h"
12 #include "ServiceBroker.h"
13 #include "dialogs/GUIDialogKaiToast.h"
14 #include "guilib/GUITexture.h"
15 #include "guilib/LocalizeStrings.h"
16 #include "guilib/Texture.h"
17 #include "settings/Settings.h"
18 #include "settings/SettingsComponent.h"
19 #include "utils/Color.h"
20 #include "utils/log.h"
21
22 static int teletextFadeAmount = 0;
23
CGUIDialogTeletext()24 CGUIDialogTeletext::CGUIDialogTeletext()
25 : CGUIDialog(WINDOW_DIALOG_OSD_TELETEXT, "")
26 {
27 m_pTxtTexture = NULL;
28 m_renderOrder = RENDER_ORDER_DIALOG_TELETEXT;
29 }
30
31 CGUIDialogTeletext::~CGUIDialogTeletext() = default;
32
OnAction(const CAction & action)33 bool CGUIDialogTeletext::OnAction(const CAction& action)
34 {
35 if (m_TextDecoder.HandleAction(action))
36 {
37 MarkDirtyRegion();
38 return true;
39 }
40
41 return CGUIDialog::OnAction(action);
42 }
43
OnBack(int actionID)44 bool CGUIDialogTeletext::OnBack(int actionID)
45 {
46 m_bClose = true;
47 MarkDirtyRegion();
48 return true;
49 }
50
OnMessage(CGUIMessage & message)51 bool CGUIDialogTeletext::OnMessage(CGUIMessage& message)
52 {
53 if (message.GetMessage() == GUI_MSG_WINDOW_INIT)
54 {
55 /* Do not open if no teletext is available */
56 if (!g_application.GetAppPlayer().GetTeletextCache())
57 {
58 Close();
59 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(23049), "", 1500, false);
60 return true;
61 }
62 }
63 else if (message.GetMessage() == GUI_MSG_NOTIFY_ALL)
64 {
65 if (message.GetParam1() == GUI_MSG_WINDOW_RESIZE)
66 {
67 SetCoordinates();
68 }
69 }
70 return CGUIDialog::OnMessage(message);
71 }
72
Process(unsigned int currentTime,CDirtyRegionList & dirtyregions)73 void CGUIDialogTeletext::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
74 {
75 CGUIDialog::Process(currentTime, dirtyregions);
76 m_renderRegion = m_vertCoords;
77 }
78
Render()79 void CGUIDialogTeletext::Render()
80 {
81 // Do not render if we have no texture
82 if (!m_pTxtTexture)
83 {
84 CLog::Log(LOGERROR, "CGUITeletextBox::Render called without texture");
85 return;
86 }
87
88 m_TextDecoder.RenderPage();
89
90 if (!m_bClose)
91 {
92 if (teletextFadeAmount < 100)
93 {
94 teletextFadeAmount = std::min(100, teletextFadeAmount + 5);
95 MarkDirtyRegion();
96 }
97 }
98 else
99 {
100 if (teletextFadeAmount > 0)
101 {
102 teletextFadeAmount = std::max(0, teletextFadeAmount - 10);
103 MarkDirtyRegion();
104 }
105
106 if (teletextFadeAmount == 0)
107 Close();
108 }
109
110 unsigned char* textureBuffer = (unsigned char*)m_TextDecoder.GetTextureBuffer();
111 if (!m_bClose && m_TextDecoder.NeedRendering() && textureBuffer)
112 {
113 m_pTxtTexture->Update(m_TextDecoder.GetWidth(), m_TextDecoder.GetHeight(), m_TextDecoder.GetWidth()*4, XB_FMT_A8R8G8B8, textureBuffer, false);
114 m_TextDecoder.RenderingDone();
115 MarkDirtyRegion();
116 }
117
118 UTILS::Color color = (static_cast<UTILS::Color>(teletextFadeAmount * 2.55f) & 0xff) << 24 | 0xFFFFFF;
119 CGUITexture::DrawQuad(m_vertCoords, color, m_pTxtTexture);
120
121 CGUIDialog::Render();
122 }
123
OnInitWindow()124 void CGUIDialogTeletext::OnInitWindow()
125 {
126 teletextFadeAmount = 0;
127 m_bClose = false;
128 m_windowLoaded = true;
129
130 SetCoordinates();
131
132 if (!m_TextDecoder.InitDecoder())
133 {
134 CLog::Log(LOGERROR, "%s: failed to init teletext decoder", __FUNCTION__);
135 Close();
136 }
137
138 m_pTxtTexture =
139 CTexture::CreateTexture(m_TextDecoder.GetWidth(), m_TextDecoder.GetHeight(), XB_FMT_A8R8G8B8);
140 if (!m_pTxtTexture)
141 {
142 CLog::Log(LOGERROR, "%s: failed to create texture", __FUNCTION__);
143 Close();
144 }
145
146 CGUIDialog::OnInitWindow();
147 }
148
OnDeinitWindow(int nextWindowID)149 void CGUIDialogTeletext::OnDeinitWindow(int nextWindowID)
150 {
151 m_windowLoaded = false;
152 m_TextDecoder.EndDecoder();
153
154 delete m_pTxtTexture;
155 m_pTxtTexture = NULL;
156
157 CGUIDialog::OnDeinitWindow(nextWindowID);
158 }
159
SetCoordinates()160 void CGUIDialogTeletext::SetCoordinates()
161 {
162 float left, right, top, bottom;
163
164 CServiceBroker::GetWinSystem()->GetGfxContext().SetScalingResolution(m_coordsRes, m_needsScaling);
165
166 left = CServiceBroker::GetWinSystem()->GetGfxContext().ScaleFinalXCoord(0, 0);
167 right = CServiceBroker::GetWinSystem()->GetGfxContext().ScaleFinalXCoord((float)m_coordsRes.iWidth, 0);
168 top = CServiceBroker::GetWinSystem()->GetGfxContext().ScaleFinalYCoord(0, 0);
169 bottom = CServiceBroker::GetWinSystem()->GetGfxContext().ScaleFinalYCoord(0, (float)m_coordsRes.iHeight);
170
171 if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_VIDEOPLAYER_TELETEXTSCALE))
172 {
173 /* Fixed aspect ratio to 4:3 for teletext */
174 float width = right - left;
175 float height = bottom - top;
176 if (width / 4 > height / 3)
177 {
178 left = (width - height * 4 / 3) / 2;
179 right = width - left;
180 }
181 else
182 {
183 top = (height - width * 3 / 4) / 2;
184 bottom = height - top;
185 }
186 }
187
188 m_vertCoords.SetRect(left,
189 top,
190 right,
191 bottom);
192
193 MarkDirtyRegion();
194 }
195