2 * Copyright (C) 2005-2008 Team XBMC
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)
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.
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
22 #include "threads/SystemClock.h"
24 #include "GUIWindowFullScreen.h"
25 #include "Application.h"
27 #ifdef HAS_VIDEO_PLAYBACK
28 #include "cores/VideoRenderers/RenderManager.h"
30 #include "GUIInfoManager.h"
31 #include "guilib/GUIProgressControl.h"
32 #include "guilib/GUIAudioManager.h"
33 #include "guilib/GUILabelControl.h"
34 #include "video/dialogs/GUIDialogVideoOSD.h"
35 #include "guilib/GUIFontManager.h"
36 #include "guilib/GUITextLayout.h"
37 #include "guilib/GUIWindowManager.h"
38 #include "video/dialogs/GUIDialogFullScreenInfo.h"
39 #include "video/dialogs/GUIDialogAudioSubtitleSettings.h"
40 #include "dialogs/GUIDialogNumeric.h"
41 #include "dialogs/GUIDialogKaiToast.h"
42 #include "guilib/GUISliderControl.h"
43 #include "settings/Settings.h"
45 #include "video/VideoReferenceClock.h"
46 #include "settings/AdvancedSettings.h"
47 #include "utils/CPUInfo.h"
48 #include "settings/GUISettings.h"
49 #include "guilib/LocalizeStrings.h"
50 #include "threads/SingleLock.h"
51 #include "utils/log.h"
52 #include "utils/TimeUtils.h"
53 #include "XBDateTime.h"
54 #include "input/ButtonTranslator.h"
55 #include "windowing/WindowingFactory.h"
59 #if defined(TARGET_DARWIN)
60 #include "linux/LinuxResourceCounter.h"
68 #define BTN_OSD_VIDEO 13
69 #define BTN_OSD_AUDIO 14
70 #define BTN_OSD_SUBTITLE 15
72 #define MENU_ACTION_AVDELAY 1
73 #define MENU_ACTION_SEEK 2
74 #define MENU_ACTION_SUBTITLEDELAY 3
75 #define MENU_ACTION_SUBTITLEONOFF 4
76 #define MENU_ACTION_SUBTITLELANGUAGE 5
77 #define MENU_ACTION_INTERLEAVED 6
78 #define MENU_ACTION_FRAMERATECONVERSIONS 7
79 #define MENU_ACTION_AUDIO_STREAM 8
81 #define MENU_ACTION_NEW_BOOKMARK 9
82 #define MENU_ACTION_NEXT_BOOKMARK 10
83 #define MENU_ACTION_CLEAR_BOOKMARK 11
85 #define MENU_ACTION_NOCACHE 12
100 //Displays current position, visible after seek or when forced
101 //Alt, use conditional visibility Player.DisplayAfterSeek
102 #define LABEL_CURRENT_TIME 22
104 //Displays when video is rebuffering
105 //Alt, use conditional visibility Player.IsCaching
106 #define LABEL_BUFFERING 24
108 //Progressbar used for buffering status and after seeking
109 #define CONTROL_PROGRESS 23
111 #if defined(TARGET_DARWIN)
112 static CLinuxResourceCounter m_resourceCounter;
115 static color_t color[8] = { 0xFFFFFF00, 0xFFFFFFFF, 0xFF0099FF, 0xFF00FF00, 0xFFCCFF00, 0xFF00FFFF, 0xFFE5E5E5, 0xFFC0C0C0 };
117 CGUIWindowFullScreen::CGUIWindowFullScreen(void)
118 : CGUIWindow(WINDOW_FULLSCREEN_VIDEO, "VideoFullScreen.xml")
120 m_timeCodeStamp[0] = 0;
121 m_timeCodePosition = 0;
122 m_timeCodeShow = false;
123 m_timeCodeTimeout = 0;
124 m_bShowViewModeInfo = false;
125 m_dwShowViewModeTimeout = 0;
126 m_bShowCurrentTime = false;
135 // - Create Bookmark (294)
136 // - Cycle bookmarks (295)
137 // - Clear bookmarks (296)
138 // - jump to specific time
148 CGUIWindowFullScreen::~CGUIWindowFullScreen(void)
151 void CGUIWindowFullScreen::AllocResources(bool forceLoad)
153 CGUIWindow::AllocResources(forceLoad);
154 DynamicResourceAlloc(false);
157 void CGUIWindowFullScreen::FreeResources(bool forceUnload)
160 DynamicResourceAlloc(true);
161 CGUIWindow::FreeResources(forceUnload);
164 bool CGUIWindowFullScreen::OnAction(const CAction &action)
166 if (g_application.m_pPlayer != NULL && g_application.m_pPlayer->OnAction(action))
169 if (m_timeCodePosition > 0 && action.GetButtonCode())
170 { // check whether we have a mapping in our virtual videotimeseek "window" and have a select action
171 CKey key(action.GetButtonCode());
172 CAction timeSeek = CButtonTranslator::GetInstance().GetAction(WINDOW_VIDEO_TIME_SEEK, key, false);
173 if (timeSeek.GetID() == ACTION_SELECT_ITEM)
175 SeekToTimeCodeStamp(SEEK_ABSOLUTE);
180 const unsigned int MsgTime = 300;
181 const unsigned int DisplTime = 2000;
183 switch (action.GetID())
185 case ACTION_SHOW_OSD:
189 case ACTION_SHOW_GUI:
191 // switch back to the menu
192 OutputDebugString("Switching to GUI\n");
193 g_windowManager.PreviousWindow();
194 OutputDebugString("Now in GUI\n");
199 case ACTION_PLAYER_PLAY:
201 if (m_timeCodePosition > 0)
203 SeekToTimeCodeStamp(SEEK_ABSOLUTE);
208 case ACTION_STEP_BACK:
209 if (m_timeCodePosition > 0)
210 SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_BACKWARD);
212 g_application.m_pPlayer->Seek(false, false);
216 case ACTION_STEP_FORWARD:
217 if (m_timeCodePosition > 0)
218 SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_FORWARD);
220 g_application.m_pPlayer->Seek(true, false);
224 case ACTION_BIG_STEP_BACK:
225 if (m_timeCodePosition > 0)
226 SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_BACKWARD);
228 g_application.m_pPlayer->Seek(false, true);
232 case ACTION_BIG_STEP_FORWARD:
233 if (m_timeCodePosition > 0)
234 SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_FORWARD);
236 g_application.m_pPlayer->Seek(true, true);
240 case ACTION_NEXT_SCENE:
241 if (g_application.m_pPlayer->SeekScene(true))
242 g_infoManager.SetDisplayAfterSeek();
246 case ACTION_PREV_SCENE:
247 if (g_application.m_pPlayer->SeekScene(false))
248 g_infoManager.SetDisplayAfterSeek();
252 case ACTION_SHOW_OSD_TIME:
253 m_bShowCurrentTime = !m_bShowCurrentTime;
254 if(!m_bShowCurrentTime)
255 g_infoManager.SetDisplayAfterSeek(0); //Force display off
256 g_infoManager.SetShowTime(m_bShowCurrentTime);
260 case ACTION_SHOW_SUBTITLES:
262 if (g_application.m_pPlayer->GetSubtitleCount() == 0)
265 g_settings.m_currentVideoSettings.m_SubtitleOn = !g_settings.m_currentVideoSettings.m_SubtitleOn;
266 g_application.m_pPlayer->SetSubtitleVisible(g_settings.m_currentVideoSettings.m_SubtitleOn);
267 CStdString sub, lang;
268 if (g_settings.m_currentVideoSettings.m_SubtitleOn)
270 g_application.m_pPlayer->GetSubtitleName(g_application.m_pPlayer->GetSubtitle(),sub);
271 g_application.m_pPlayer->GetSubtitleLanguage(g_application.m_pPlayer->GetSubtitle(),lang);
273 sub.Format("%s [%s]", sub.c_str(), lang.c_str());
276 sub = g_localizeStrings.Get(1223);
277 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info,
278 g_localizeStrings.Get(287), sub, DisplTime, false, MsgTime);
283 case ACTION_SHOW_INFO:
285 CGUIDialogFullScreenInfo* pDialog = (CGUIDialogFullScreenInfo*)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO);
294 case ACTION_NEXT_SUBTITLE:
296 if (g_application.m_pPlayer->GetSubtitleCount() == 0)
299 if(g_settings.m_currentVideoSettings.m_SubtitleStream < 0)
300 g_settings.m_currentVideoSettings.m_SubtitleStream = g_application.m_pPlayer->GetSubtitle();
302 if (g_settings.m_currentVideoSettings.m_SubtitleOn)
304 g_settings.m_currentVideoSettings.m_SubtitleStream++;
305 if (g_settings.m_currentVideoSettings.m_SubtitleStream >= g_application.m_pPlayer->GetSubtitleCount())
307 g_settings.m_currentVideoSettings.m_SubtitleStream = 0;
308 g_settings.m_currentVideoSettings.m_SubtitleOn = false;
309 g_application.m_pPlayer->SetSubtitleVisible(false);
311 g_application.m_pPlayer->SetSubtitle(g_settings.m_currentVideoSettings.m_SubtitleStream);
315 g_settings.m_currentVideoSettings.m_SubtitleOn = true;
316 g_application.m_pPlayer->SetSubtitleVisible(true);
319 CStdString sub, lang;
320 if (g_settings.m_currentVideoSettings.m_SubtitleOn)
322 g_application.m_pPlayer->GetSubtitleName(g_settings.m_currentVideoSettings.m_SubtitleStream,sub);
323 g_application.m_pPlayer->GetSubtitleLanguage(g_settings.m_currentVideoSettings.m_SubtitleStream,lang);
325 sub.Format("%s [%s]", sub.c_str(), lang.c_str());
328 sub = g_localizeStrings.Get(1223);
329 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(287), sub, DisplTime, false, MsgTime);
334 case ACTION_SUBTITLE_DELAY_MIN:
335 g_settings.m_currentVideoSettings.m_SubtitleDelay -= 0.1f;
336 if (g_settings.m_currentVideoSettings.m_SubtitleDelay < -g_advancedSettings.m_videoSubsDelayRange)
337 g_settings.m_currentVideoSettings.m_SubtitleDelay = -g_advancedSettings.m_videoSubsDelayRange;
338 if (g_application.m_pPlayer)
339 g_application.m_pPlayer->SetSubTitleDelay(g_settings.m_currentVideoSettings.m_SubtitleDelay);
341 ShowSlider(action.GetID(), 22006, g_settings.m_currentVideoSettings.m_SubtitleDelay,
342 -g_advancedSettings.m_videoSubsDelayRange, 0.1f,
343 g_advancedSettings.m_videoSubsDelayRange);
346 case ACTION_SUBTITLE_DELAY_PLUS:
347 g_settings.m_currentVideoSettings.m_SubtitleDelay += 0.1f;
348 if (g_settings.m_currentVideoSettings.m_SubtitleDelay > g_advancedSettings.m_videoSubsDelayRange)
349 g_settings.m_currentVideoSettings.m_SubtitleDelay = g_advancedSettings.m_videoSubsDelayRange;
350 if (g_application.m_pPlayer)
351 g_application.m_pPlayer->SetSubTitleDelay(g_settings.m_currentVideoSettings.m_SubtitleDelay);
353 ShowSlider(action.GetID(), 22006, g_settings.m_currentVideoSettings.m_SubtitleDelay,
354 -g_advancedSettings.m_videoSubsDelayRange, 0.1f,
355 g_advancedSettings.m_videoSubsDelayRange);
358 case ACTION_SUBTITLE_DELAY:
359 ShowSlider(action.GetID(), 22006, g_settings.m_currentVideoSettings.m_SubtitleDelay,
360 -g_advancedSettings.m_videoSubsDelayRange, 0.1f,
361 g_advancedSettings.m_videoSubsDelayRange, true);
364 case ACTION_AUDIO_DELAY:
365 ShowSlider(action.GetID(), 297, g_settings.m_currentVideoSettings.m_AudioDelay,
366 -g_advancedSettings.m_videoAudioDelayRange, 0.025f,
367 g_advancedSettings.m_videoAudioDelayRange, true);
370 case ACTION_AUDIO_DELAY_MIN:
371 g_settings.m_currentVideoSettings.m_AudioDelay -= 0.025f;
372 if (g_settings.m_currentVideoSettings.m_AudioDelay < -g_advancedSettings.m_videoAudioDelayRange)
373 g_settings.m_currentVideoSettings.m_AudioDelay = -g_advancedSettings.m_videoAudioDelayRange;
374 if (g_application.m_pPlayer)
375 g_application.m_pPlayer->SetAVDelay(g_settings.m_currentVideoSettings.m_AudioDelay);
377 ShowSlider(action.GetID(), 297, g_settings.m_currentVideoSettings.m_AudioDelay,
378 -g_advancedSettings.m_videoAudioDelayRange, 0.025f,
379 g_advancedSettings.m_videoAudioDelayRange);
382 case ACTION_AUDIO_DELAY_PLUS:
383 g_settings.m_currentVideoSettings.m_AudioDelay += 0.025f;
384 if (g_settings.m_currentVideoSettings.m_AudioDelay > g_advancedSettings.m_videoAudioDelayRange)
385 g_settings.m_currentVideoSettings.m_AudioDelay = g_advancedSettings.m_videoAudioDelayRange;
386 if (g_application.m_pPlayer)
387 g_application.m_pPlayer->SetAVDelay(g_settings.m_currentVideoSettings.m_AudioDelay);
389 ShowSlider(action.GetID(), 297, g_settings.m_currentVideoSettings.m_AudioDelay,
390 -g_advancedSettings.m_videoAudioDelayRange, 0.025f,
391 g_advancedSettings.m_videoAudioDelayRange);
394 case ACTION_AUDIO_NEXT_LANGUAGE:
396 if (g_application.m_pPlayer->GetAudioStreamCount() == 1)
399 if(g_settings.m_currentVideoSettings.m_AudioStream < 0)
400 g_settings.m_currentVideoSettings.m_AudioStream = g_application.m_pPlayer->GetAudioStream();
402 g_settings.m_currentVideoSettings.m_AudioStream++;
403 if (g_settings.m_currentVideoSettings.m_AudioStream >= g_application.m_pPlayer->GetAudioStreamCount())
404 g_settings.m_currentVideoSettings.m_AudioStream = 0;
405 g_application.m_pPlayer->SetAudioStream(g_settings.m_currentVideoSettings.m_AudioStream); // Set the audio stream to the one selected
407 g_application.m_pPlayer->GetAudioStreamName(g_settings.m_currentVideoSettings.m_AudioStream,aud);
408 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(460), aud, DisplTime, false, MsgTime);
423 if (g_application.CurrentFileItem().IsLiveTV())
427 CStdString strChannel;
428 strChannel.Format("%i", action.GetID() - REMOTE_0);
429 if (CGUIDialogNumeric::ShowAndGetNumber(strChannel, g_localizeStrings.Get(19000)))
430 channelNr = atoi(strChannel.c_str());
433 OnAction(CAction(ACTION_CHANNEL_SWITCH, (float)channelNr));
437 ChangetheTimeCode(action.GetID());
443 case ACTION_ASPECT_RATIO:
444 { // toggle the aspect ratio mode (only if the info is onscreen)
445 if (m_bShowViewModeInfo)
447 #ifdef HAS_VIDEO_PLAYBACK
448 g_renderManager.SetViewMode(++g_settings.m_currentVideoSettings.m_ViewMode);
451 m_bShowViewModeInfo = true;
452 m_dwShowViewModeTimeout = XbmcThreads::SystemClockMillis();
456 case ACTION_SMALL_STEP_BACK:
457 if (m_timeCodePosition > 0)
458 SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_BACKWARD);
461 int orgpos = (int)g_application.GetTime();
462 int jumpsize = g_advancedSettings.m_videoSmallStepBackSeconds; // secs
463 int setpos = (orgpos > jumpsize) ? orgpos - jumpsize : 0;
464 g_application.SeekTime((double)setpos);
470 g_settings.m_currentVideoSettings.m_CustomZoomAmount += 0.01f;
471 if (g_settings.m_currentVideoSettings.m_CustomZoomAmount > 2.f)
472 g_settings.m_currentVideoSettings.m_CustomZoomAmount = 2.f;
473 g_settings.m_currentVideoSettings.m_ViewMode = VIEW_MODE_CUSTOM;
474 g_renderManager.SetViewMode(VIEW_MODE_CUSTOM);
475 ShowSlider(action.GetID(), 216, g_settings.m_currentVideoSettings.m_CustomZoomAmount, 0.5f, 0.1f, 2.0f);
479 case ACTION_ZOOM_OUT:
481 g_settings.m_currentVideoSettings.m_CustomZoomAmount -= 0.01f;
482 if (g_settings.m_currentVideoSettings.m_CustomZoomAmount < 0.5f)
483 g_settings.m_currentVideoSettings.m_CustomZoomAmount = 0.5f;
484 g_settings.m_currentVideoSettings.m_ViewMode = VIEW_MODE_CUSTOM;
485 g_renderManager.SetViewMode(VIEW_MODE_CUSTOM);
486 ShowSlider(action.GetID(), 216, g_settings.m_currentVideoSettings.m_CustomZoomAmount, 0.5f, 0.1f, 2.0f);
490 case ACTION_INCREASE_PAR:
492 g_settings.m_currentVideoSettings.m_CustomPixelRatio += 0.01f;
493 if (g_settings.m_currentVideoSettings.m_CustomPixelRatio > 2.f)
494 g_settings.m_currentVideoSettings.m_CustomZoomAmount = 2.f;
495 g_settings.m_currentVideoSettings.m_ViewMode = VIEW_MODE_CUSTOM;
496 g_renderManager.SetViewMode(VIEW_MODE_CUSTOM);
497 ShowSlider(action.GetID(), 217, g_settings.m_currentVideoSettings.m_CustomPixelRatio, 0.5f, 0.1f, 2.0f);
501 case ACTION_DECREASE_PAR:
503 g_settings.m_currentVideoSettings.m_CustomPixelRatio -= 0.01f;
504 if (g_settings.m_currentVideoSettings.m_CustomZoomAmount < 0.5f)
505 g_settings.m_currentVideoSettings.m_CustomPixelRatio = 0.5f;
506 g_settings.m_currentVideoSettings.m_ViewMode = VIEW_MODE_CUSTOM;
507 g_renderManager.SetViewMode(VIEW_MODE_CUSTOM);
508 ShowSlider(action.GetID(), 217, g_settings.m_currentVideoSettings.m_CustomPixelRatio, 0.5f, 0.1f, 2.0f);
512 case ACTION_VSHIFT_UP:
514 g_settings.m_currentVideoSettings.m_CustomVerticalShift -= 0.01f;
515 if (g_settings.m_currentVideoSettings.m_CustomVerticalShift < -2.0f)
516 g_settings.m_currentVideoSettings.m_CustomVerticalShift = -2.0f;
517 g_settings.m_currentVideoSettings.m_ViewMode = VIEW_MODE_CUSTOM;
518 g_renderManager.SetViewMode(VIEW_MODE_CUSTOM);
519 ShowSlider(action.GetID(), 225, g_settings.m_currentVideoSettings.m_CustomVerticalShift, -2.0f, 0.1f, 2.0f);
523 case ACTION_VSHIFT_DOWN:
525 g_settings.m_currentVideoSettings.m_CustomVerticalShift += 0.01f;
526 if (g_settings.m_currentVideoSettings.m_CustomVerticalShift > 2.0f)
527 g_settings.m_currentVideoSettings.m_CustomVerticalShift = 2.0f;
528 g_settings.m_currentVideoSettings.m_ViewMode = VIEW_MODE_CUSTOM;
529 g_renderManager.SetViewMode(VIEW_MODE_CUSTOM);
530 ShowSlider(action.GetID(), 225, g_settings.m_currentVideoSettings.m_CustomVerticalShift, -2.0f, 0.1f, 2.0f);
534 case ACTION_SUBTITLE_VSHIFT_UP:
536 RESOLUTION_INFO& res_info = g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()];
537 int subalign = g_guiSettings.GetInt("subtitles.align");
538 if ((subalign == SUBTITLE_ALIGN_BOTTOM_OUTSIDE) || (subalign == SUBTITLE_ALIGN_TOP_INSIDE))
540 res_info.iSubtitles ++;
541 if (res_info.iSubtitles >= res_info.iHeight)
542 res_info.iSubtitles = res_info.iHeight - 1;
544 ShowSlider(action.GetID(), 274, (float) res_info.iHeight - res_info.iSubtitles, 0.0f, 1.0f, (float) res_info.iHeight);
548 res_info.iSubtitles --;
549 if (res_info.iSubtitles < 0)
550 res_info.iSubtitles = 0;
552 if (subalign == SUBTITLE_ALIGN_MANUAL)
553 ShowSlider(action.GetID(), 274, (float) res_info.iSubtitles, 0.0f, 1.0f, (float) res_info.iHeight);
555 ShowSlider(action.GetID(), 274, (float) res_info.iSubtitles - res_info.iHeight, (float) -res_info.iHeight, -1.0f, 0.0f);
560 case ACTION_SUBTITLE_VSHIFT_DOWN:
562 RESOLUTION_INFO& res_info = g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()];
563 int subalign = g_guiSettings.GetInt("subtitles.align");
564 if ((subalign == SUBTITLE_ALIGN_BOTTOM_OUTSIDE) || (subalign == SUBTITLE_ALIGN_TOP_INSIDE))
566 res_info.iSubtitles--;
567 if (res_info.iSubtitles < 0)
568 res_info.iSubtitles = 0;
570 ShowSlider(action.GetID(), 274, (float) res_info.iHeight - res_info.iSubtitles, 0.0f, 1.0f, (float) res_info.iHeight);
574 res_info.iSubtitles++;
575 if (res_info.iSubtitles >= res_info.iHeight)
576 res_info.iSubtitles = res_info.iHeight - 1;
578 if (subalign == SUBTITLE_ALIGN_MANUAL)
579 ShowSlider(action.GetID(), 274, (float) res_info.iSubtitles, 0.0f, 1.0f, (float) res_info.iHeight);
581 ShowSlider(action.GetID(), 274, (float) res_info.iSubtitles - res_info.iHeight, (float) -res_info.iHeight, -1.0f, 0.0f);
586 case ACTION_SUBTITLE_ALIGN:
588 RESOLUTION_INFO& res_info = g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()];
589 int subalign = g_guiSettings.GetInt("subtitles.align");
592 if (subalign > SUBTITLE_ALIGN_TOP_OUTSIDE)
593 subalign = SUBTITLE_ALIGN_MANUAL;
595 res_info.iSubtitles = res_info.iHeight - 1;
597 g_guiSettings.SetInt("subtitles.align", subalign);
598 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info,
599 g_localizeStrings.Get(21460),
600 g_localizeStrings.Get(21461 + subalign),
601 TOAST_DISPLAY_TIME, false);
605 case ACTION_VOLAMP_UP:
606 case ACTION_VOLAMP_DOWN:
608 float sliderMax = VOLUME_DRC_MAXIMUM / 100.0f;
609 float sliderMin = VOLUME_DRC_MINIMUM / 100.0f;
611 if (action.GetID() == ACTION_VOLAMP_UP)
612 g_settings.m_currentVideoSettings.m_VolumeAmplification += 1.0f;
614 g_settings.m_currentVideoSettings.m_VolumeAmplification -= 1.0f;
616 g_settings.m_currentVideoSettings.m_VolumeAmplification =
617 std::max(std::min(g_settings.m_currentVideoSettings.m_VolumeAmplification, sliderMax), sliderMin);
619 if (g_application.m_pPlayer)
620 g_application.m_pPlayer->SetDynamicRangeCompression((long)(g_settings.m_currentVideoSettings.m_VolumeAmplification * 100));
622 ShowSlider(action.GetID(), 660, g_settings.m_currentVideoSettings.m_VolumeAmplification, sliderMin, 1.0f, sliderMax);
629 return CGUIWindow::OnAction(action);
632 void CGUIWindowFullScreen::OnWindowLoaded()
634 CGUIWindow::OnWindowLoaded();
635 // override the clear colour - we must never clear fullscreen
636 m_clearBackground = 0;
638 CGUIProgressControl* pProgress = (CGUIProgressControl*)GetControl(CONTROL_PROGRESS);
641 if( pProgress->GetInfo() == 0 || pProgress->GetVisibleCondition() == 0)
643 pProgress->SetInfo(PLAYER_PROGRESS);
644 pProgress->SetVisibleCondition("player.displayafterseek");
645 pProgress->SetVisible(true);
649 CGUILabelControl* pLabel = (CGUILabelControl*)GetControl(LABEL_BUFFERING);
650 if(pLabel && pLabel->GetVisibleCondition() == 0)
652 pLabel->SetVisibleCondition("player.caching");
653 pLabel->SetVisible(true);
656 pLabel = (CGUILabelControl*)GetControl(LABEL_CURRENT_TIME);
657 if(pLabel && pLabel->GetVisibleCondition() == 0)
659 pLabel->SetVisibleCondition("player.displayafterseek");
660 pLabel->SetVisible(true);
661 pLabel->SetLabel("$INFO(VIDEOPLAYER.TIME) / $INFO(VIDEOPLAYER.DURATION)");
663 m_showCodec.Parse("player.showcodec", GetID());
666 bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message)
668 switch (message.GetMessage())
670 case GUI_MSG_WINDOW_INIT:
672 // check whether we've come back here from a window during which time we've actually
673 // stopped playing videos
674 if (message.GetParam1() == WINDOW_INVALID && !g_application.IsPlayingVideo())
675 { // why are we here if nothing is playing???
676 g_windowManager.PreviousWindow();
679 g_infoManager.SetShowInfo(false);
680 g_infoManager.SetShowCodec(false);
681 m_bShowCurrentTime = false;
682 g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off.
685 g_graphicsContext.SetFullScreenVideo(true);
687 #ifdef HAS_VIDEO_PLAYBACK
688 // make sure renderer is uptospeed
689 g_renderManager.Update(false);
691 // now call the base class to load our windows
692 CGUIWindow::OnMessage(message);
694 m_bShowViewModeInfo = false;
696 if (CUtil::IsUsingTTFSubtitles())
698 CSingleLock lock (m_fontLock);
700 CStdString fontPath = "special://xbmc/media/Fonts/";
701 fontPath += g_guiSettings.GetString("subtitles.font");
703 // We scale based on PAL4x3 - this at least ensures all sizing is constant across resolutions.
704 RESOLUTION_INFO pal(720, 576, 0);
705 CGUIFont *subFont = g_fontManager.LoadTTF("__subtitle__", fontPath, color[g_guiSettings.GetInt("subtitles.color")], 0, g_guiSettings.GetInt("subtitles.height"), g_guiSettings.GetInt("subtitles.style"), false, 1.0f, 1.0f, &pal, true);
706 CGUIFont *borderFont = g_fontManager.LoadTTF("__subtitleborder__", fontPath, 0xFF000000, 0, g_guiSettings.GetInt("subtitles.height"), g_guiSettings.GetInt("subtitles.style"), true, 1.0f, 1.0f, &pal, true);
707 if (!subFont || !borderFont)
708 CLog::Log(LOGERROR, "CGUIWindowFullScreen::OnMessage(WINDOW_INIT) - Unable to load subtitle font");
710 m_subsLayout = new CGUITextLayout(subFont, true, 0, borderFont);
717 case GUI_MSG_WINDOW_DEINIT:
719 CGUIWindow::OnMessage(message);
721 CGUIDialog *pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_OSD_TELETEXT);
722 if (pDialog) pDialog->Close(true);
723 CGUIDialogSlider *slider = (CGUIDialogSlider *)g_windowManager.GetWindow(WINDOW_DIALOG_SLIDER);
724 if (slider) slider->Close(true);
725 pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD);
726 if (pDialog) pDialog->Close(true);
727 pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO);
728 if (pDialog) pDialog->Close(true);
732 CSingleLock lock (g_graphicsContext);
733 g_graphicsContext.SetFullScreenVideo(false);
736 #ifdef HAS_VIDEO_PLAYBACK
737 // make sure renderer is uptospeed
738 g_renderManager.Update(false);
741 CSingleLock lockFont(m_fontLock);
744 g_fontManager.Unload("__subtitle__");
745 g_fontManager.Unload("__subtitleborder__");
752 case GUI_MSG_SETFOCUS:
753 case GUI_MSG_LOSTFOCUS:
754 if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true;
758 return CGUIWindow::OnMessage(message);
761 EVENT_RESULT CGUIWindowFullScreen::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
763 if (event.m_id == ACTION_MOUSE_RIGHT_CLICK)
764 { // no control found to absorb this click - go back to GUI
765 OnAction(CAction(ACTION_SHOW_GUI));
766 return EVENT_RESULT_HANDLED;
768 if (event.m_id == ACTION_MOUSE_WHEEL_UP)
770 return g_application.OnAction(CAction(ACTION_ANALOG_SEEK_FORWARD, 0.5f)) ? EVENT_RESULT_HANDLED : EVENT_RESULT_UNHANDLED;
772 if (event.m_id == ACTION_MOUSE_WHEEL_DOWN)
774 return g_application.OnAction(CAction(ACTION_ANALOG_SEEK_BACK, 0.5f)) ? EVENT_RESULT_HANDLED : EVENT_RESULT_UNHANDLED;
776 if (event.m_id != ACTION_MOUSE_MOVE || event.m_offsetX || event.m_offsetY)
777 { // some other mouse action has occurred - bring up the OSD
778 // if it is not already running
779 CGUIDialogVideoOSD *pOSD = (CGUIDialogVideoOSD *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD);
780 if (pOSD && !pOSD->IsDialogRunning())
782 pOSD->SetAutoClose(3000);
785 return EVENT_RESULT_HANDLED;
787 return EVENT_RESULT_UNHANDLED;
790 void CGUIWindowFullScreen::FrameMove()
792 if (g_application.GetPlaySpeed() != 1)
793 g_infoManager.SetDisplayAfterSeek();
794 if (m_bShowCurrentTime)
795 g_infoManager.SetDisplayAfterSeek();
797 if (!g_application.m_pPlayer) return;
799 if( g_application.m_pPlayer->IsCaching() )
801 g_infoManager.SetDisplayAfterSeek(0); //Make sure these stuff aren't visible now
804 //------------------------
805 m_showCodec.Update();
808 // show audio codec info
809 CStdString strAudio, strVideo, strGeneral;
810 g_application.m_pPlayer->GetAudioInfo(strAudio);
812 CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1);
813 msg.SetLabel(strAudio);
816 // show video codec info
817 g_application.m_pPlayer->GetVideoInfo(strVideo);
819 CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW2);
820 msg.SetLabel(strVideo);
824 g_application.m_pPlayer->GetGeneralInfo(strGeneral);
826 CStdString strGeneralFPS;
827 #if defined(TARGET_DARWIN)
828 // We show CPU usage for the entire process, as it's arguably more useful.
829 double dCPU = m_resourceCounter.GetCPUUsage();
831 strCores.Format("cpu:%.0f%%", dCPU);
833 CStdString strCores = g_cpuInfo.GetCoresUsageString();
840 if (g_VideoReferenceClock.GetClockInfo(missedvblanks, clockspeed, refreshrate))
841 strClock.Format("S( refresh:%i missed:%i speed:%+.3f%% %s )"
845 , g_renderManager.GetVSyncState().c_str());
847 strGeneralFPS.Format("%s\nW( fps:%02.2f %s ) %s"
849 , g_infoManager.GetFPS()
850 , strCores.c_str(), strClock.c_str() );
852 CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW3);
853 msg.SetLabel(strGeneralFPS);
857 //----------------------
858 // ViewMode Information
859 //----------------------
860 if (m_bShowViewModeInfo && XbmcThreads::SystemClockMillis() - m_dwShowViewModeTimeout > 2500)
862 m_bShowViewModeInfo = false;
864 if (m_bShowViewModeInfo)
867 // get the "View Mode" string
868 CStdString strTitle = g_localizeStrings.Get(629);
869 CStdString strMode = g_localizeStrings.Get(630 + g_settings.m_currentVideoSettings.m_ViewMode);
871 strInfo.Format("%s : %s", strTitle.c_str(), strMode.c_str());
872 CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1);
873 msg.SetLabel(strInfo);
876 // show sizing information
877 CRect SrcRect, DestRect;
879 g_application.m_pPlayer->GetVideoRect(SrcRect, DestRect);
880 g_application.m_pPlayer->GetVideoAspectRatio(fAR);
882 CStdString strSizing;
883 strSizing.Format(g_localizeStrings.Get(245),
884 (int)SrcRect.Width(), (int)SrcRect.Height(),
885 (int)DestRect.Width(), (int)DestRect.Height(),
886 g_settings.m_fZoomAmount, fAR*g_settings.m_fPixelRatio,
887 g_settings.m_fPixelRatio, g_settings.m_fVerticalShift);
888 CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW2);
889 msg.SetLabel(strSizing);
892 // show resolution information
893 int iResolution = g_graphicsContext.GetVideoResolution();
895 CStdString strStatus;
896 if (g_Windowing.IsFullScreen())
897 strStatus.Format("%s %ix%i@%.2fHz - %s",
898 g_localizeStrings.Get(13287), g_settings.m_ResInfo[iResolution].iWidth,
899 g_settings.m_ResInfo[iResolution].iHeight, g_settings.m_ResInfo[iResolution].fRefreshRate,
900 g_localizeStrings.Get(244));
902 strStatus.Format("%s %ix%i - %s",
903 g_localizeStrings.Get(13287), g_settings.m_ResInfo[iResolution].iWidth,
904 g_settings.m_ResInfo[iResolution].iHeight, g_localizeStrings.Get(242));
906 CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW3);
907 msg.SetLabel(strStatus);
912 if (m_timeCodeShow && m_timeCodePosition != 0)
914 if ( (XbmcThreads::SystemClockMillis() - m_timeCodeTimeout) >= 2500)
916 m_timeCodeShow = false;
917 m_timeCodePosition = 0;
919 CStdString strDispTime = "00:00:00";
921 CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1);
923 for (int pos = 7, i = m_timeCodePosition; pos >= 0 && i > 0; pos--)
925 if (strDispTime[pos] != ':')
928 strDispTime[pos] = (char)m_timeCodeStamp[i] + '0';
932 strDispTime += "/" + g_infoManager.GetDuration(TIME_FORMAT_HH_MM_SS) + " [" + g_infoManager.GetCurrentPlayTime(TIME_FORMAT_HH_MM_SS) + "]"; // duration [ time ]
933 msg.SetLabel(strDispTime);
937 if (m_showCodec || m_bShowViewModeInfo)
939 SET_CONTROL_VISIBLE(LABEL_ROW1);
940 SET_CONTROL_VISIBLE(LABEL_ROW2);
941 SET_CONTROL_VISIBLE(LABEL_ROW3);
942 SET_CONTROL_VISIBLE(BLUE_BAR);
944 else if (m_timeCodeShow)
946 SET_CONTROL_VISIBLE(LABEL_ROW1);
947 SET_CONTROL_HIDDEN(LABEL_ROW2);
948 SET_CONTROL_HIDDEN(LABEL_ROW3);
949 SET_CONTROL_VISIBLE(BLUE_BAR);
953 SET_CONTROL_HIDDEN(LABEL_ROW1);
954 SET_CONTROL_HIDDEN(LABEL_ROW2);
955 SET_CONTROL_HIDDEN(LABEL_ROW3);
956 SET_CONTROL_HIDDEN(BLUE_BAR);
960 void CGUIWindowFullScreen::Process(unsigned int currentTime, CDirtyRegionList &dirtyregion)
962 // TODO: This isn't quite optimal - ideally we'd only be dirtying up the actual video render rect
963 // which is probably the job of the renderer as it can more easily track resizing etc.
965 CGUIWindow::Process(currentTime, dirtyregion);
966 m_renderRegion.SetRect(0, 0, (float)g_graphicsContext.GetWidth(), (float)g_graphicsContext.GetHeight());
969 void CGUIWindowFullScreen::Render()
971 if (g_application.m_pPlayer)
972 RenderTTFSubtitles();
973 CGUIWindow::Render();
976 void CGUIWindowFullScreen::RenderTTFSubtitles()
978 if ((g_application.GetCurrentPlayer() == EPC_MPLAYER ||
979 #if defined(HAS_AMLPLAYER)
980 g_application.GetCurrentPlayer() == EPC_AMLPLAYER ||
982 g_application.GetCurrentPlayer() == EPC_DVDPLAYER) &&
983 CUtil::IsUsingTTFSubtitles() && (g_application.m_pPlayer->GetSubtitleVisible()))
985 CSingleLock lock (m_fontLock);
990 CStdString subtitleText = "How now brown cow";
991 if (g_application.m_pPlayer->GetCurrentSubtitle(subtitleText))
993 // Remove HTML-like tags from the subtitles until
994 subtitleText.Replace("\\r", "");
995 subtitleText.Replace("\r", "");
996 subtitleText.Replace("\\n", "[CR]");
997 subtitleText.Replace("\n", "[CR]");
998 subtitleText.Replace("<br>", "[CR]");
999 subtitleText.Replace("\\N", "[CR]");
1000 subtitleText.Replace("<i>", "[I]");
1001 subtitleText.Replace("</i>", "[/I]");
1002 subtitleText.Replace("<b>", "[B]");
1003 subtitleText.Replace("</b>", "[/B]");
1004 subtitleText.Replace("<u>", "");
1005 subtitleText.Replace("<p>", "");
1006 subtitleText.Replace("<P>", "");
1007 subtitleText.Replace(" ", "");
1008 subtitleText.Replace("</u>", "");
1009 subtitleText.Replace("</i", "[/I]"); // handle tags which aren't closed properly (happens).
1010 subtitleText.Replace("</b", "[/B]");
1011 subtitleText.Replace("</u", "");
1013 RESOLUTION res = g_graphicsContext.GetVideoResolution();
1014 g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetResInfo(), false);
1016 float maxWidth = (float) g_settings.m_ResInfo[res].Overscan.right - g_settings.m_ResInfo[res].Overscan.left;
1017 m_subsLayout->Update(subtitleText, maxWidth * 0.9f, false, true); // true to force LTR reading order (most Hebrew subs are this format)
1019 int subalign = g_guiSettings.GetInt("subtitles.align");
1020 float textWidth, textHeight;
1021 m_subsLayout->GetTextExtent(textWidth, textHeight);
1022 float x = maxWidth * 0.5f + g_settings.m_ResInfo[res].Overscan.left;
1023 float y = (float) g_settings.m_ResInfo[res].iSubtitles;
1025 if (subalign == SUBTITLE_ALIGN_MANUAL)
1026 y = (float) g_settings.m_ResInfo[res].iSubtitles - textHeight;
1029 CRect SrcRect, DestRect;
1030 g_application.m_pPlayer->GetVideoRect(SrcRect, DestRect);
1032 if ((subalign == SUBTITLE_ALIGN_TOP_INSIDE) || (subalign == SUBTITLE_ALIGN_TOP_OUTSIDE))
1037 // use the manual distance to the screenbottom as an offset to the automatic location
1038 if ((subalign == SUBTITLE_ALIGN_BOTTOM_INSIDE) || (subalign == SUBTITLE_ALIGN_TOP_OUTSIDE))
1039 y -= textHeight + g_graphicsContext.GetHeight() - g_settings.m_ResInfo[res].iSubtitles;
1041 y += g_graphicsContext.GetHeight() - g_settings.m_ResInfo[res].iSubtitles;
1043 y = std::max(y, (float) g_settings.m_ResInfo[res].Overscan.top);
1044 y = std::min(y, g_settings.m_ResInfo[res].Overscan.bottom - textHeight);
1047 m_subsLayout->RenderOutline(x, y, 0, 0xFF000000, XBFONT_CENTER_X, maxWidth);
1049 // reset rendering resolution
1050 g_graphicsContext.SetRenderingResolution(m_coordsRes, m_needsScaling);
1055 void CGUIWindowFullScreen::ChangetheTimeCode(int remote)
1057 if (remote >= REMOTE_0 && remote <= REMOTE_9)
1059 m_timeCodeShow = true;
1060 m_timeCodeTimeout = XbmcThreads::SystemClockMillis();
1062 if (m_timeCodePosition < 6)
1063 m_timeCodeStamp[m_timeCodePosition++] = remote - REMOTE_0;
1067 for (int i = 0; i < 5; i++)
1068 m_timeCodeStamp[i] = m_timeCodeStamp[i+1];
1069 m_timeCodeStamp[5] = remote - REMOTE_0;
1074 void CGUIWindowFullScreen::SeekToTimeCodeStamp(SEEK_TYPE type, SEEK_DIRECTION direction)
1076 double total = GetTimeCodeStamp();
1077 if (type == SEEK_RELATIVE)
1078 total = g_application.GetTime() + (((direction == SEEK_FORWARD) ? 1 : -1) * total);
1080 if (total < g_application.GetTotalTime())
1081 g_application.SeekTime(total);
1083 m_timeCodePosition = 0;
1084 m_timeCodeShow = false;
1087 double CGUIWindowFullScreen::GetTimeCodeStamp()
1089 // Convert the timestamp into an integer
1091 for (int i = 0; i < m_timeCodePosition; i++)
1092 tot = tot * 10 + m_timeCodeStamp[i];
1094 // Interpret result as HHMMSS
1095 int s = tot % 100; tot /= 100;
1096 int m = tot % 100; tot /= 100;
1098 return h * 3600 + m * 60 + s;
1101 void CGUIWindowFullScreen::SeekChapter(int iChapter)
1103 g_application.m_pPlayer->SeekChapter(iChapter);
1105 // Make sure gui items are visible.
1106 g_infoManager.SetDisplayAfterSeek();
1109 void CGUIWindowFullScreen::ShowSlider(int action, int label, float value, float min, float delta, float max, bool modal)
1111 m_sliderAction = action;
1113 CGUIDialogSlider::ShowAndGetInput(g_localizeStrings.Get(label), value, min, delta, max, this);
1115 CGUIDialogSlider::Display(label, value, min, delta, max, this);
1118 void CGUIWindowFullScreen::OnSliderChange(void *data, CGUISliderControl *slider)
1123 if (m_sliderAction == ACTION_ZOOM_OUT || m_sliderAction == ACTION_ZOOM_IN ||
1124 m_sliderAction == ACTION_INCREASE_PAR || m_sliderAction == ACTION_DECREASE_PAR ||
1125 m_sliderAction == ACTION_VSHIFT_UP || m_sliderAction == ACTION_VSHIFT_DOWN ||
1126 m_sliderAction == ACTION_SUBTITLE_VSHIFT_UP || m_sliderAction == ACTION_SUBTITLE_VSHIFT_DOWN)
1128 CStdString strValue;
1129 strValue.Format("%1.2f",slider->GetFloatValue());
1130 slider->SetTextValue(strValue);
1132 else if (m_sliderAction == ACTION_VOLAMP_UP || m_sliderAction == ACTION_VOLAMP_DOWN)
1133 slider->SetTextValue(CGUIDialogAudioSubtitleSettings::FormatDecibel(slider->GetFloatValue(), 1.0f));
1135 slider->SetTextValue(CGUIDialogAudioSubtitleSettings::FormatDelay(slider->GetFloatValue(), 0.025f));
1137 if (g_application.m_pPlayer)
1139 if (m_sliderAction == ACTION_AUDIO_DELAY)
1141 g_settings.m_currentVideoSettings.m_AudioDelay = slider->GetFloatValue();
1142 g_application.m_pPlayer->SetAVDelay(g_settings.m_currentVideoSettings.m_AudioDelay);
1144 else if (m_sliderAction == ACTION_SUBTITLE_DELAY)
1146 g_settings.m_currentVideoSettings.m_SubtitleDelay = slider->GetFloatValue();
1147 g_application.m_pPlayer->SetSubTitleDelay(g_settings.m_currentVideoSettings.m_SubtitleDelay);
1152 void CGUIWindowFullScreen::ToggleOSD()
1154 CGUIDialogVideoOSD *pOSD = (CGUIDialogVideoOSD *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD);
1157 if (pOSD->IsDialogRunning())