Merged from linuxport rev21200:21590. Updated.
[xbmc:xbmc-antiquated.git] / XBMC / xbmc / GUIWindowFullScreen.cpp
1 /*
2  *      Copyright (C) 2005-2008 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include "stdafx.h"
23 #include "GUIWindowFullScreen.h"
24 #include "Application.h"
25 #include "Util.h"
26 #ifdef HAS_VIDEO_PLAYBACK
27 #include "cores/VideoRenderers/RenderManager.h"
28 #endif
29 #include "utils/GUIInfoManager.h"
30 #include "GUIProgressControl.h"
31 #include "GUIAudioManager.h"
32 #include "GUILabelControl.h"
33 #include "GUIWindowOSD.h"
34 #include "GUIFontManager.h"
35 #include "GUITextLayout.h"
36 #include "GUIWindowManager.h"
37 #include "GUIDialogFullScreenInfo.h"
38 #include "GUIDialogAudioSubtitleSettings.h"
39 #include "GUISliderControl.h"
40 #include "Settings.h"
41 #include "FileItem.h"
42 #include "VideoReferenceClock.h"
43
44 #include <stdio.h>
45
46
47 #define BLUE_BAR                          0
48 #define LABEL_ROW1                       10
49 #define LABEL_ROW2                       11
50 #define LABEL_ROW3                       12
51
52 #define BTN_OSD_VIDEO                    13
53 #define BTN_OSD_AUDIO                    14
54 #define BTN_OSD_SUBTITLE                 15
55
56 #define MENU_ACTION_AVDELAY               1
57 #define MENU_ACTION_SEEK                  2
58 #define MENU_ACTION_SUBTITLEDELAY         3
59 #define MENU_ACTION_SUBTITLEONOFF         4
60 #define MENU_ACTION_SUBTITLELANGUAGE      5
61 #define MENU_ACTION_INTERLEAVED           6
62 #define MENU_ACTION_FRAMERATECONVERSIONS  7
63 #define MENU_ACTION_AUDIO_STREAM          8
64
65 #define MENU_ACTION_NEW_BOOKMARK          9
66 #define MENU_ACTION_NEXT_BOOKMARK        10
67 #define MENU_ACTION_CLEAR_BOOKMARK       11
68
69 #define MENU_ACTION_NOCACHE              12
70
71 #define IMG_PAUSE                        16
72 #define IMG_2X                           17
73 #define IMG_4X                           18
74 #define IMG_8X                           19
75 #define IMG_16X                          20
76 #define IMG_32X                          21
77
78 #define IMG_2Xr                         117
79 #define IMG_4Xr                         118
80 #define IMG_8Xr                         119
81 #define IMG_16Xr                        120
82 #define IMG_32Xr                        121
83
84 //Displays current position, visible after seek or when forced
85 //Alt, use conditional visibility Player.DisplayAfterSeek
86 #define LABEL_CURRENT_TIME               22
87
88 //Displays when video is rebuffering
89 //Alt, use conditional visibility Player.IsCaching
90 #define LABEL_BUFFERING                  24
91
92 //Progressbar used for buffering status and after seeking
93 #define CONTROL_PROGRESS                 23
94
95 #ifdef __APPLE__
96 static CLinuxResourceCounter m_resourceCounter;
97 #endif
98
99 static DWORD color[6] = { 0xFFFFFF00, 0xFFFFFFFF, 0xFF0099FF, 0xFF00FF00, 0xFFCCFF00, 0xFF00FFFF };
100
101 CGUIWindowFullScreen::CGUIWindowFullScreen(void)
102     : CGUIWindow(WINDOW_FULLSCREEN_VIDEO, "VideoFullScreen.xml")
103 {
104   m_timeCodeStamp[0] = 0;
105   m_timeCodePosition = 0;
106   m_timeCodeShow = false;
107   m_timeCodeTimeout = 0;
108   m_bShowViewModeInfo = false;
109   m_dwShowViewModeTimeout = 0;
110   m_bShowCurrentTime = false;
111   m_subsLayout = NULL;
112   // audio
113   //  - language
114   //  - volume
115   //  - stream
116
117   // video
118   //  - Create Bookmark (294)
119   //  - Cycle bookmarks (295)
120   //  - Clear bookmarks (296)
121   //  - jump to specific time
122   //  - slider
123   //  - av delay
124
125   // subtitles
126   //  - delay
127   //  - language
128
129 }
130
131 CGUIWindowFullScreen::~CGUIWindowFullScreen(void)
132 {}
133
134 void CGUIWindowFullScreen::PreloadDialog(unsigned int windowID)
135 {
136   CGUIWindow *pWindow = m_gWindowManager.GetWindow(windowID);
137   if (pWindow)
138   {
139     pWindow->Initialize();
140     pWindow->DynamicResourceAlloc(false);
141     pWindow->AllocResources(false);
142   }
143 }
144
145 void CGUIWindowFullScreen::UnloadDialog(unsigned int windowID)
146 {
147   CGUIWindow *pWindow = m_gWindowManager.GetWindow(windowID);
148   if (pWindow) {
149     pWindow->FreeResources(pWindow->GetLoadOnDemand());
150   }
151 }
152
153 void CGUIWindowFullScreen::AllocResources(bool forceLoad)
154 {
155   CGUIWindow::AllocResources(forceLoad);
156   DynamicResourceAlloc(false);
157   PreloadDialog(WINDOW_OSD);
158   PreloadDialog(WINDOW_DIALOG_VIDEO_OSD_SETTINGS);
159   PreloadDialog(WINDOW_DIALOG_AUDIO_OSD_SETTINGS);
160   // No need to preload these here, as they're preloaded by our app
161 //  PreloadDialog(WINDOW_DIALOG_SEEK_BAR);
162 //  PreloadDialog(WINDOW_DIALOG_VOLUME_BAR);
163 //  PreloadDialog(WINDOW_DIALOG_MUTE_BUG);
164 }
165
166 void CGUIWindowFullScreen::FreeResources(bool forceUnload)
167 {
168   g_settings.Save();
169   DynamicResourceAlloc(true);
170   UnloadDialog(WINDOW_OSD);
171   UnloadDialog(WINDOW_DIALOG_VIDEO_OSD_SETTINGS);
172   UnloadDialog(WINDOW_DIALOG_AUDIO_OSD_SETTINGS);
173   // No need to unload these here, as they're preloaded by our app
174 //  UnloadDialog(WINDOW_DIALOG_SEEK_BAR);
175 //  UnloadDialog(WINDOW_DIALOG_VOLUME_BAR);
176 //  UnloadDialog(WINDOW_DIALOG_MUTE_BUG);
177   CGUIWindow::FreeResources(forceUnload);
178 }
179
180 bool CGUIWindowFullScreen::OnAction(const CAction &action)
181 {
182   if (g_application.m_pPlayer != NULL && g_application.m_pPlayer->OnAction(action))
183     return true;
184
185   switch (action.wID)
186   {
187
188   case ACTION_SHOW_GUI:
189     {
190       // switch back to the menu
191       OutputDebugString("Switching to GUI\n");
192       m_gWindowManager.PreviousWindow();
193       OutputDebugString("Now in GUI\n");
194       return true;
195     }
196     break;
197
198   case ACTION_STEP_BACK:
199     Seek(false, false);
200     return true;
201     break;
202
203   case ACTION_STEP_FORWARD:
204     Seek(true, false);
205     return true;
206     break;
207
208   case ACTION_BIG_STEP_BACK:
209     Seek(false, true);
210     return true;
211     break;
212
213   case ACTION_BIG_STEP_FORWARD:
214     Seek(true, true);
215     return true;
216     break;
217
218   case ACTION_NEXT_SCENE:
219     if (g_application.m_pPlayer->SeekScene(true))
220       g_infoManager.SetDisplayAfterSeek();
221     return true;
222     break;
223
224   case ACTION_PREV_SCENE:
225     if (g_application.m_pPlayer->SeekScene(false))
226       g_infoManager.SetDisplayAfterSeek();
227     return true;
228     break;
229
230   case ACTION_SHOW_OSD_TIME:
231     m_bShowCurrentTime = !m_bShowCurrentTime;
232     if(!m_bShowCurrentTime)
233       g_infoManager.SetDisplayAfterSeek(0); //Force display off
234     g_infoManager.SetShowTime(m_bShowCurrentTime);
235     return true;
236     break;
237
238   case ACTION_SHOW_SUBTITLES:
239     {
240       g_application.m_pPlayer->SetSubtitleVisible(!g_application.m_pPlayer->GetSubtitleVisible());
241     }
242     return true;
243     break;
244
245   case ACTION_SHOW_INFO:
246     {
247       CGUIDialogFullScreenInfo* pDialog = (CGUIDialogFullScreenInfo*)m_gWindowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO);
248       if (pDialog)
249       {
250         pDialog->DoModal();
251         return true;
252       }
253       break;
254     }
255
256   case ACTION_NEXT_SUBTITLE:
257     {
258       if (g_application.m_pPlayer->GetSubtitleCount() == 1)
259         return true;
260
261       g_stSettings.m_currentVideoSettings.m_SubtitleStream++;
262       if (g_stSettings.m_currentVideoSettings.m_SubtitleStream >= g_application.m_pPlayer->GetSubtitleCount())
263         g_stSettings.m_currentVideoSettings.m_SubtitleStream = 0;
264       g_application.m_pPlayer->SetSubtitle(g_stSettings.m_currentVideoSettings.m_SubtitleStream);
265       return true;
266     }
267     return true;
268     break;
269
270   case ACTION_SUBTITLE_DELAY_MIN:
271     g_stSettings.m_currentVideoSettings.m_SubtitleDelay -= 0.1f;
272     if (g_stSettings.m_currentVideoSettings.m_SubtitleDelay < -g_advancedSettings.m_videoSubsDelayRange)
273       g_stSettings.m_currentVideoSettings.m_SubtitleDelay = -g_advancedSettings.m_videoSubsDelayRange;
274     if (g_application.m_pPlayer)
275       g_application.m_pPlayer->SetSubTitleDelay(g_stSettings.m_currentVideoSettings.m_SubtitleDelay);
276
277     CGUIDialogSlider::Display(22006, g_stSettings.m_currentVideoSettings.m_SubtitleDelay,
278                                     -g_advancedSettings.m_videoSubsDelayRange, 0.1f,
279                                      g_advancedSettings.m_videoSubsDelayRange, this);
280
281     return true;
282     break;
283   case ACTION_SUBTITLE_DELAY_PLUS:
284     g_stSettings.m_currentVideoSettings.m_SubtitleDelay += 0.1f;
285     if (g_stSettings.m_currentVideoSettings.m_SubtitleDelay > g_advancedSettings.m_videoSubsDelayRange)
286       g_stSettings.m_currentVideoSettings.m_SubtitleDelay = g_advancedSettings.m_videoSubsDelayRange;
287     if (g_application.m_pPlayer)
288       g_application.m_pPlayer->SetSubTitleDelay(g_stSettings.m_currentVideoSettings.m_SubtitleDelay);
289
290     CGUIDialogSlider::Display(22006, g_stSettings.m_currentVideoSettings.m_SubtitleDelay,
291                                     -g_advancedSettings.m_videoSubsDelayRange, 0.1f,
292                                      g_advancedSettings.m_videoSubsDelayRange, this);
293     return true;
294     break;
295   case ACTION_SUBTITLE_DELAY:
296     CGUIDialogSlider::ShowAndGetInput(g_localizeStrings.Get(22006), g_stSettings.m_currentVideoSettings.m_SubtitleDelay,
297                                                                    -g_advancedSettings.m_videoSubsDelayRange, 0.1f,
298                                                                     g_advancedSettings.m_videoSubsDelayRange, this, (void *)&action.wID);
299     return true;
300     break;
301   case ACTION_AUDIO_DELAY:
302     CGUIDialogSlider::ShowAndGetInput(g_localizeStrings.Get(297), g_stSettings.m_currentVideoSettings.m_AudioDelay,
303                                                                  -g_advancedSettings.m_videoAudioDelayRange, 0.025f,
304                                                                   g_advancedSettings.m_videoAudioDelayRange, this, (void *)&action.wID);
305     return true;
306     break;
307   case ACTION_AUDIO_DELAY_MIN:
308     g_stSettings.m_currentVideoSettings.m_AudioDelay -= 0.025f;
309     if (g_stSettings.m_currentVideoSettings.m_AudioDelay < -g_advancedSettings.m_videoAudioDelayRange)
310       g_stSettings.m_currentVideoSettings.m_AudioDelay = -g_advancedSettings.m_videoAudioDelayRange;
311     if (g_application.m_pPlayer)
312       g_application.m_pPlayer->SetAVDelay(g_stSettings.m_currentVideoSettings.m_AudioDelay);
313
314     CGUIDialogSlider::Display(297, g_stSettings.m_currentVideoSettings.m_AudioDelay,
315                                   -g_advancedSettings.m_videoAudioDelayRange, 0.025f,
316                                    g_advancedSettings.m_videoAudioDelayRange, this);
317     return true;
318     break;
319   case ACTION_AUDIO_DELAY_PLUS:
320     g_stSettings.m_currentVideoSettings.m_AudioDelay += 0.025f;
321     if (g_stSettings.m_currentVideoSettings.m_AudioDelay > g_advancedSettings.m_videoAudioDelayRange)
322       g_stSettings.m_currentVideoSettings.m_AudioDelay = g_advancedSettings.m_videoAudioDelayRange;
323     if (g_application.m_pPlayer)
324       g_application.m_pPlayer->SetAVDelay(g_stSettings.m_currentVideoSettings.m_AudioDelay);
325
326     CGUIDialogSlider::Display(297, g_stSettings.m_currentVideoSettings.m_AudioDelay,
327                                   -g_advancedSettings.m_videoAudioDelayRange, 0.025f,
328                                    g_advancedSettings.m_videoAudioDelayRange, this);
329     return true;
330     break;
331   case ACTION_AUDIO_NEXT_LANGUAGE:
332       if (g_application.m_pPlayer->GetAudioStreamCount() == 1)
333         return true;
334
335       g_stSettings.m_currentVideoSettings.m_AudioStream++;
336       if (g_stSettings.m_currentVideoSettings.m_AudioStream >= g_application.m_pPlayer->GetAudioStreamCount())
337         g_stSettings.m_currentVideoSettings.m_AudioStream = 0;
338       g_application.m_pPlayer->SetAudioStream(g_stSettings.m_currentVideoSettings.m_AudioStream);    // Set the audio stream to the one selected
339     return true;
340     break;
341   case REMOTE_0:
342   case REMOTE_1:
343   case REMOTE_2:
344   case REMOTE_3:
345   case REMOTE_4:
346   case REMOTE_5:
347   case REMOTE_6:
348   case REMOTE_7:
349   case REMOTE_8:
350   case REMOTE_9:
351     ChangetheTimeCode(action.wID);
352     return true;
353     break;
354
355   case ACTION_ASPECT_RATIO:
356     { // toggle the aspect ratio mode (only if the info is onscreen)
357       if (m_bShowViewModeInfo)
358       {
359 #ifdef HAS_VIDEO_PLAYBACK
360         g_renderManager.SetViewMode(++g_stSettings.m_currentVideoSettings.m_ViewMode);
361 #endif
362       }
363       m_bShowViewModeInfo = true;
364       m_dwShowViewModeTimeout = timeGetTime();
365     }
366     return true;
367     break;
368   case ACTION_SMALL_STEP_BACK:
369     {
370       int orgpos = (int)g_application.GetTime();
371       int jumpsize = g_advancedSettings.m_videoSmallStepBackSeconds; // secs
372       int setpos = (orgpos > jumpsize) ? orgpos - jumpsize : 0;
373       g_application.SeekTime((double)setpos);
374
375       //Make sure gui items are visible
376       g_infoManager.SetDisplayAfterSeek();
377     }
378     return true;
379     break;
380   }
381   return CGUIWindow::OnAction(action);
382 }
383
384 void CGUIWindowFullScreen::OnWindowLoaded()
385 {
386   CGUIWindow::OnWindowLoaded();
387
388   CGUIProgressControl* pProgress = (CGUIProgressControl*)GetControl(CONTROL_PROGRESS);
389   if(pProgress)
390   {
391     if( pProgress->GetInfo() == 0 || pProgress->GetVisibleCondition() == 0)
392     {
393       pProgress->SetInfo(PLAYER_PROGRESS);
394       pProgress->SetVisibleCondition(PLAYER_DISPLAY_AFTER_SEEK, false);
395       pProgress->SetVisible(true);
396     }
397   }
398
399   CGUILabelControl* pLabel = (CGUILabelControl*)GetControl(LABEL_BUFFERING);
400   if(pLabel && pLabel->GetVisibleCondition() == 0)
401   {
402     pLabel->SetVisibleCondition(PLAYER_CACHING, false);
403     pLabel->SetVisible(true);
404   }
405
406   pLabel = (CGUILabelControl*)GetControl(LABEL_CURRENT_TIME);
407   if(pLabel && pLabel->GetVisibleCondition() == 0)
408   {
409     pLabel->SetVisibleCondition(PLAYER_DISPLAY_AFTER_SEEK, false);
410     pLabel->SetVisible(true);
411     pLabel->SetLabel("$INFO(VIDEOPLAYER.TIME) / $INFO(VIDEOPLAYER.DURATION)");
412   }
413 }
414
415 bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message)
416 {
417   switch (message.GetMessage())
418   {
419   case GUI_MSG_WINDOW_INIT:
420     {
421       // check whether we've come back here from a window during which time we've actually
422       // stopped playing videos
423       if (message.GetParam1() == WINDOW_INVALID && !g_application.IsPlayingVideo())
424       { // why are we here if nothing is playing???
425         m_gWindowManager.PreviousWindow();
426         return true;
427       }
428       m_bLastRender = false;
429       g_infoManager.SetShowInfo(false);
430       g_infoManager.SetShowCodec(false);
431       m_bShowCurrentTime = false;
432       g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off.
433
434       // setup the brightness, contrast and resolution
435       CUtil::SetBrightnessContrastGammaPercent(g_stSettings.m_currentVideoSettings.m_Brightness, g_stSettings.m_currentVideoSettings.m_Contrast, g_stSettings.m_currentVideoSettings.m_Gamma, false);
436
437       // switch resolution
438       CSingleLock lock (g_graphicsContext);
439       g_graphicsContext.SetFullScreenVideo(true);
440 #if defined(HAS_VIDEO_PLAYBACK) && !defined(__APPLE)
441           if (g_guiSettings.GetBool("videoplayer.adjustrefreshrate"))
442       {
443         RESOLUTION res = g_renderManager.GetResolution();
444         g_graphicsContext.SetVideoResolution(res, false, false);
445       }
446 #endif
447       lock.Leave();
448
449 #ifdef HAS_VIDEO_PLAYBACK
450       // make sure renderer is uptospeed
451       g_renderManager.Update(false);
452 #endif
453       // now call the base class to load our windows
454       CGUIWindow::OnMessage(message);
455
456       m_bShowViewModeInfo = false;
457
458       if (CUtil::IsUsingTTFSubtitles())
459       {
460         CSingleLock lock (m_fontLock);
461
462         CStdString fontPath = "special://xbmc/media/Fonts/";
463         fontPath += g_guiSettings.GetString("subtitles.font");
464
465         // We scale based on PAL4x3 - this at least ensures all sizing is constant across resolutions.
466         // it doesn't preserve aspect, however, so make sure we choose aspect as 1/scalingpixelratio
467         g_graphicsContext.SetScalingResolution(PAL_4x3, 0, 0, true);
468         float aspect = 1.0f / g_graphicsContext.GetScalingPixelRatio();
469         CGUIFont *subFont = g_fontManager.LoadTTF("__subtitle__", fontPath, color[g_guiSettings.GetInt("subtitles.color")], 0, g_guiSettings.GetInt("subtitles.height"), g_guiSettings.GetInt("subtitles.style"), 1.0f, aspect, PAL_4x3);
470         if (!subFont)
471           CLog::Log(LOGERROR, "CGUIWindowFullScreen::OnMessage(WINDOW_INIT) - Unable to load subtitle font");
472         else
473           m_subsLayout = new CGUITextLayout(subFont, true);
474       }
475       else
476         m_subsLayout = NULL;
477
478       return true;
479     }
480   case GUI_MSG_WINDOW_DEINIT:
481     {
482       CGUIWindow::OnMessage(message);
483
484       CGUIDialogSlider *slider = (CGUIDialogSlider *)m_gWindowManager.GetWindow(WINDOW_DIALOG_SLIDER);
485       if (slider) slider->Close(true);
486       CGUIDialog *pDialog = (CGUIDialog *)m_gWindowManager.GetWindow(WINDOW_OSD);
487       if (pDialog) pDialog->Close(true);
488       pDialog = (CGUIDialog *)m_gWindowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO);
489       if (pDialog) pDialog->Close(true);
490
491       FreeResources(true);
492
493       CSingleLock lock (g_graphicsContext);
494       CUtil::RestoreBrightnessContrastGamma();
495       g_graphicsContext.SetFullScreenVideo(false);
496 #if defined(HAS_VIDEO_PLAYBACK) && !defined(__APPLE)
497           if (g_guiSettings.GetBool("videoplayer.adjustrefreshrate"))
498           {
499         g_graphicsContext.SetVideoResolution(g_guiSettings.m_LookAndFeelResolution, TRUE);
500       }
501 #endif
502       lock.Leave();
503
504 #ifdef HAS_VIDEO_PLAYBACK
505       // make sure renderer is uptospeed
506       g_renderManager.Update(false);
507 #endif
508
509       CSingleLock lockFont(m_fontLock);
510       if (m_subsLayout)
511       {
512         g_fontManager.Unload("__subtitle__");
513         delete m_subsLayout;
514         m_subsLayout = NULL;
515       }
516
517       if (g_guiSettings.GetBool("lookandfeel.soundsduringplayback"))
518         g_audioManager.Enable(true);
519       return true;
520     }
521   case GUI_MSG_SETFOCUS:
522   case GUI_MSG_LOSTFOCUS:
523     if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true;
524     break;
525   }
526
527   return CGUIWindow::OnMessage(message);
528 }
529
530 bool CGUIWindowFullScreen::OnMouse(const CPoint &point)
531 {
532   if (g_Mouse.bClick[MOUSE_RIGHT_BUTTON])
533   { // no control found to absorb this click - go back to GUI
534     CAction action;
535     action.wID = ACTION_SHOW_GUI;
536     OnAction(action);
537     return true;
538   }
539   if (g_Mouse.bClick[MOUSE_LEFT_BUTTON])
540   { // no control found to absorb this click - pause video
541     CAction action;
542     action.wID = ACTION_PAUSE;
543     return g_application.OnAction(action);
544   }
545   if (g_Mouse.HasMoved())
546   { // movement - toggle the OSD
547     CGUIWindowOSD *pOSD = (CGUIWindowOSD *)m_gWindowManager.GetWindow(WINDOW_OSD);
548     if (pOSD)
549     {
550       pOSD->SetAutoClose(3000);
551       pOSD->DoModal();
552     }
553   }
554   return true;
555 }
556
557 // Override of Render() - RenderFullScreen() is where the action takes place
558 // this is called from the rendermanager, normally we won't come this way
559 // as player thread will handle rendering, and call this itself.
560 void CGUIWindowFullScreen::Render()
561 {
562 #ifdef HAS_VIDEO_PLAYBACK
563   g_renderManager.RenderUpdate(true);
564 #endif
565   // win32 video rendering uses this path all the time (it doesn't render from the player directly)
566   // so at this point we should renderfullscreen info as well.
567   if (NeedRenderFullScreen())
568     RenderFullScreen();
569 }
570
571 bool CGUIWindowFullScreen::NeedRenderFullScreen()
572 {
573   CSingleLock lock (g_graphicsContext);
574   if (g_application.m_pPlayer)
575   {
576     if (g_application.m_pPlayer->IsPaused() ) return true;
577     if (g_application.m_pPlayer->IsCaching() ) return true;
578     if (!g_application.m_pPlayer->IsPlaying() ) return true;
579   }
580   if (g_application.GetPlaySpeed() != 1) return true;
581   if (m_timeCodeShow) return true;
582   if (g_infoManager.GetBool(PLAYER_SHOWCODEC)) return true;
583   if (g_infoManager.GetBool(PLAYER_SHOWINFO)) return true;
584   if (IsAnimating(ANIM_TYPE_HIDDEN)) return true; // for the above info conditions
585   if (m_bShowViewModeInfo) return true;
586   if (m_bShowCurrentTime) return true;
587   if (g_infoManager.GetDisplayAfterSeek()) return true;
588   if (g_infoManager.GetBool(PLAYER_SEEKBAR, GetID())) return true;
589   if (CUtil::IsUsingTTFSubtitles() && g_application.m_pPlayer && g_application.m_pPlayer->GetSubtitleVisible() && m_subsLayout)
590     return true;
591   if (m_bLastRender)
592   {
593     m_bLastRender = false;
594   }
595
596   return false;
597 }
598
599 void CGUIWindowFullScreen::RenderFullScreen()
600 {
601   if (g_application.GetPlaySpeed() != 1)
602     g_infoManager.SetDisplayAfterSeek();
603   if (m_bShowCurrentTime)
604     g_infoManager.SetDisplayAfterSeek();
605
606   m_bLastRender = true;
607   if (!g_application.m_pPlayer) return ;
608
609   if( g_application.m_pPlayer->IsCaching() )
610   {
611     g_infoManager.SetDisplayAfterSeek(0); //Make sure these stuff aren't visible now
612   }
613
614   //------------------------
615   if (g_infoManager.GetBool(PLAYER_SHOWCODEC))
616   {
617     // show audio codec info
618     CStdString strAudio, strVideo, strGeneral;
619     g_application.m_pPlayer->GetAudioInfo(strAudio);
620     {
621       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1);
622       msg.SetLabel(strAudio);
623       OnMessage(msg);
624     }
625     // show video codec info
626     g_application.m_pPlayer->GetVideoInfo(strVideo);
627     {
628       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW2);
629       msg.SetLabel(strVideo);
630       OnMessage(msg);
631     }
632     // show general info
633     g_application.m_pPlayer->GetGeneralInfo(strGeneral);
634     {
635       CStdString strGeneralFPS;
636 #ifdef __APPLE__
637       // We show CPU usage for the entire process, as it's arguably more useful.
638       double dCPU = m_resourceCounter.GetCPUUsage();
639       CStdString strCores;
640       strCores.Format("cpu:%.0f%%", dCPU);
641 #else
642       CStdString strCores = g_cpuInfo.GetCoresUsageString();
643 #endif
644       int missedvblanks;
645       double clockspeed;
646       CStdString strClock;
647       
648       if (g_VideoReferenceClock.GetClockInfo(missedvblanks, clockspeed))
649         strClock.Format("S( missed:%i speed:%+.3f%% %s )"
650                        , missedvblanks
651                        , clockspeed - 100.0
652                        , g_renderManager.GetVSyncState().c_str());
653
654       strGeneralFPS.Format("%s\nW( fps:%02.2f %s ) %s"
655                          , strGeneral.c_str()
656                          , g_infoManager.GetFPS()
657                          , strCores.c_str(), strClock.c_str() );
658
659       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW3);
660       msg.SetLabel(strGeneralFPS);
661       OnMessage(msg);
662     }
663   }
664   //----------------------
665   // ViewMode Information
666   //----------------------
667   if (m_bShowViewModeInfo && timeGetTime() - m_dwShowViewModeTimeout > 2500)
668   {
669     m_bShowViewModeInfo = false;
670   }
671   if (m_bShowViewModeInfo)
672   {
673     {
674       // get the "View Mode" string
675       CStdString strTitle = g_localizeStrings.Get(629);
676       CStdString strMode = g_localizeStrings.Get(630 + g_stSettings.m_currentVideoSettings.m_ViewMode);
677       CStdString strInfo;
678       strInfo.Format("%s : %s", strTitle.c_str(), strMode.c_str());
679       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1);
680       msg.SetLabel(strInfo);
681       OnMessage(msg);
682     }
683     // show sizing information
684     RECT SrcRect, DestRect;
685     float fAR;
686     g_application.m_pPlayer->GetVideoRect(SrcRect, DestRect);
687     g_application.m_pPlayer->GetVideoAspectRatio(fAR);
688     {
689       CStdString strSizing;
690       strSizing.Format("Sizing: (%i,%i)->(%i,%i) (Zoom x%2.2f) AR:%2.2f:1 (Pixels: %2.2f:1)",
691                        SrcRect.right - SrcRect.left, SrcRect.bottom - SrcRect.top,
692                        DestRect.right - DestRect.left, DestRect.bottom - DestRect.top, g_stSettings.m_fZoomAmount, fAR*g_stSettings.m_fPixelRatio, g_stSettings.m_fPixelRatio);
693       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW2);
694       msg.SetLabel(strSizing);
695       OnMessage(msg);
696     }
697     // show resolution information
698     int iResolution = g_graphicsContext.GetVideoResolution();
699     {
700       CStdString strStatus;
701       strStatus.Format("%s %ix%i@%.2fHz %s",
702         g_localizeStrings.Get(13287), g_settings.m_ResInfo[iResolution].iWidth,
703         g_settings.m_ResInfo[iResolution].iHeight, g_settings.m_ResInfo[iResolution].fRefreshRate,
704         g_settings.m_ResInfo[iResolution].strMode);
705       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW3);
706       msg.SetLabel(strStatus);
707       OnMessage(msg);
708     }
709   }
710
711   RenderTTFSubtitles();
712
713   if (m_timeCodeShow && m_timeCodePosition != 0)
714   {
715     if ( (timeGetTime() - m_timeCodeTimeout) >= 2500)
716     {
717       m_timeCodeShow = false;
718       m_timeCodePosition = 0;
719     }
720     CStdString strDispTime = "??:??";
721
722     CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1);
723     for (int count = 0; count < m_timeCodePosition; count++)
724     {
725       if (m_timeCodeStamp[count] == -1)
726         strDispTime[count] = ':';
727       else
728         strDispTime[count] = (char)m_timeCodeStamp[count] + 48;
729     }
730     strDispTime += "/" + g_infoManager.GetVideoLabel(257) + " [" + g_infoManager.GetVideoLabel(254) + "]"; // duration [ time ]
731     msg.SetLabel(strDispTime);
732     OnMessage(msg);
733   }
734
735   if (g_infoManager.GetBool(PLAYER_SHOWCODEC) || m_bShowViewModeInfo)
736   {
737     SET_CONTROL_VISIBLE(LABEL_ROW1);
738     SET_CONTROL_VISIBLE(LABEL_ROW2);
739     SET_CONTROL_VISIBLE(LABEL_ROW3);
740     SET_CONTROL_VISIBLE(BLUE_BAR);
741   }
742   else if (m_timeCodeShow)
743   {
744     SET_CONTROL_VISIBLE(LABEL_ROW1);
745     SET_CONTROL_HIDDEN(LABEL_ROW2);
746     SET_CONTROL_HIDDEN(LABEL_ROW3);
747     SET_CONTROL_VISIBLE(BLUE_BAR);
748   }
749   else
750   {
751     SET_CONTROL_HIDDEN(LABEL_ROW1);
752     SET_CONTROL_HIDDEN(LABEL_ROW2);
753     SET_CONTROL_HIDDEN(LABEL_ROW3);
754     SET_CONTROL_HIDDEN(BLUE_BAR);
755   }
756   CGUIWindow::Render();
757 }
758
759 void CGUIWindowFullScreen::RenderTTFSubtitles()
760 {
761   //if ( g_application.GetCurrentPlayer() == EPC_MPLAYER && CUtil::IsUsingTTFSubtitles() && g_application.m_pPlayer->GetSubtitleVisible() && m_subsLayout)
762   if ((g_application.GetCurrentPlayer() == EPC_MPLAYER || g_application.GetCurrentPlayer() == EPC_DVDPLAYER) &&
763       CUtil::IsUsingTTFSubtitles() && g_application.m_pPlayer->GetSubtitleVisible())
764   {
765     CSingleLock lock (m_fontLock);
766
767     if(!m_subsLayout)
768       return;
769
770     CStdString subtitleText;
771     if (g_application.m_pPlayer->GetCurrentSubtitle(subtitleText))
772     {
773       // Remove HTML-like tags from the subtitles until
774       subtitleText.Replace("\\r", "");
775       subtitleText.Replace("\r", "");
776       subtitleText.Replace("\\n", "[CR]");
777       subtitleText.Replace("\n", "[CR]");
778       subtitleText.Replace("<br>", "[CR]");
779       subtitleText.Replace("\\N", "[CR]");
780       subtitleText.Replace("<i>", "[I]");
781       subtitleText.Replace("</i>", "[/I]");
782       subtitleText.Replace("<b>", "[B]");
783       subtitleText.Replace("</b>", "[/B]");
784       subtitleText.Replace("<u>", "");
785       subtitleText.Replace("<p>", "");
786       subtitleText.Replace("<P>", "");
787       subtitleText.Replace("&nbsp;", "");
788       subtitleText.Replace("</u>", "");
789       subtitleText.Replace("</i", "[/I]"); // handle tags which aren't closed properly (happens).
790       subtitleText.Replace("</b", "[/B]");
791       subtitleText.Replace("</u", "");
792
793       RESOLUTION res = g_graphicsContext.GetVideoResolution();
794       g_graphicsContext.SetRenderingResolution(res, 0, 0, false);
795
796       float maxWidth = (float) g_settings.m_ResInfo[res].Overscan.right - g_settings.m_ResInfo[res].Overscan.left;
797       m_subsLayout->Update(subtitleText, maxWidth * 0.9f, true); // true to force LTR reading order (most Hebrew subs are this format)
798
799       float textWidth, textHeight;
800       m_subsLayout->GetTextExtent(textWidth, textHeight);
801       float x = maxWidth * 0.5f + g_settings.m_ResInfo[res].Overscan.left;
802       float y = g_settings.m_ResInfo[res].iSubtitles - textHeight;
803
804       m_subsLayout->RenderOutline(x, y, 0, 0xFF000000, 3, XBFONT_CENTER_X, maxWidth);
805     }
806   }
807 }
808
809 void CGUIWindowFullScreen::ChangetheTimeCode(DWORD remote)
810 {
811   if (remote >= 58 && remote <= 67) //Make sure it's only for the remote
812   {
813     m_timeCodeShow = true;
814     m_timeCodeTimeout = timeGetTime();
815     int itime = remote - 58;
816     if (m_timeCodePosition <= 4 && m_timeCodePosition != 2)
817     {
818       m_timeCodeStamp[m_timeCodePosition++] = itime;
819       if (m_timeCodePosition == 2)
820         m_timeCodeStamp[m_timeCodePosition++] = -1;
821     }
822     if (m_timeCodePosition > 4)
823     {
824       long itotal, ih, im, is = 0;
825       ih = (m_timeCodeStamp[0] - 0) * 10;
826       ih += (m_timeCodeStamp[1] - 0);
827       im = (m_timeCodeStamp[3] - 0) * 10;
828       im += (m_timeCodeStamp[4] - 0);
829       im *= 60;
830       ih *= 3600;
831       itotal = ih + im + is;
832
833       if (itotal < g_application.GetTotalTime())
834         g_application.SeekTime((double)itotal);
835
836       m_timeCodePosition = 0;
837       m_timeCodeShow = false;
838     }
839   }
840 }
841
842 void CGUIWindowFullScreen::Seek(bool bPlus, bool bLargeStep)
843 {
844   g_application.m_pPlayer->Seek(bPlus, bLargeStep);
845
846   // Make sure gui items are visible.
847   g_infoManager.SetDisplayAfterSeek();
848 }
849
850 void CGUIWindowFullScreen::SeekChapter(int iChapter)
851 {
852   g_application.m_pPlayer->SeekChapter(iChapter);
853
854   // Make sure gui items are visible.
855   g_infoManager.SetDisplayAfterSeek();
856 }
857
858 void CGUIWindowFullScreen::OnSliderChange(void *data, CGUISliderControl *slider)
859 {
860   if (!slider)
861     return;
862
863   slider->SetTextValue(CGUIDialogAudioSubtitleSettings::FormatDelay(slider->GetFloatValue(), 0.025f));
864   if (data && g_application.m_pPlayer)
865   {
866     if (*(DWORD *)data == ACTION_AUDIO_DELAY)
867     {
868       g_stSettings.m_currentVideoSettings.m_AudioDelay = slider->GetFloatValue();
869       g_application.m_pPlayer->SetAVDelay(g_stSettings.m_currentVideoSettings.m_AudioDelay);
870     }
871     else if (*(DWORD *)data == ACTION_SUBTITLE_DELAY)
872     {
873       g_stSettings.m_currentVideoSettings.m_SubtitleDelay = slider->GetFloatValue();
874       g_application.m_pPlayer->SetSubTitleDelay(g_stSettings.m_currentVideoSettings.m_SubtitleDelay);
875     }
876   }
877 }