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