Merge pull request #4875 from koying/fixdroidremotekeyboard
[vuplus_xbmc] / xbmc / video / windows / GUIWindowFullScreen.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://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, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "threads/SystemClock.h"
22 #include "system.h"
23 #include "GUIWindowFullScreen.h"
24 #include "Application.h"
25 #include "ApplicationMessenger.h"
26 #include "Util.h"
27 #ifdef HAS_VIDEO_PLAYBACK
28 #include "cores/VideoRenderers/RenderManager.h"
29 #endif
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 "guilib/Key.h"
39 #include "video/dialogs/GUIDialogFullScreenInfo.h"
40 #include "dialogs/GUIDialogNumeric.h"
41 #include "settings/DisplaySettings.h"
42 #include "settings/MediaSettings.h"
43 #include "settings/Settings.h"
44 #include "guilib/GUISelectButtonControl.h"
45 #include "FileItem.h"
46 #include "video/VideoReferenceClock.h"
47 #include "settings/AdvancedSettings.h"
48 #include "utils/CPUInfo.h"
49 #include "guilib/LocalizeStrings.h"
50 #include "threads/SingleLock.h"
51 #include "utils/log.h"
52 #include "utils/TimeUtils.h"
53 #include "utils/URIUtils.h"
54 #include "utils/StringUtils.h"
55 #include "XBDateTime.h"
56 #include "input/ButtonTranslator.h"
57 #include "pvr/PVRManager.h"
58 #include "pvr/channels/PVRChannelGroupsContainer.h"
59 #include "windowing/WindowingFactory.h"
60 #include "cores/IPlayer.h"
61 #include "filesystem/File.h"
62
63 #include <stdio.h>
64 #include <algorithm>
65 #if defined(TARGET_DARWIN)
66 #include "linux/LinuxResourceCounter.h"
67 #endif
68
69 using namespace PVR;
70
71 #define BLUE_BAR                          0
72 #define LABEL_ROW1                       10
73 #define LABEL_ROW2                       11
74 #define LABEL_ROW3                       12
75 #define CONTROL_GROUP_CHOOSER            503
76
77 //Displays current position, visible after seek or when forced
78 //Alt, use conditional visibility Player.DisplayAfterSeek
79 #define LABEL_CURRENT_TIME               22
80
81 //Displays when video is rebuffering
82 //Alt, use conditional visibility Player.IsCaching
83 #define LABEL_BUFFERING                  24
84
85 //Progressbar used for buffering status and after seeking
86 #define CONTROL_PROGRESS                 23
87
88 #if defined(TARGET_DARWIN)
89 static CLinuxResourceCounter m_resourceCounter;
90 #endif
91
92 CGUIWindowFullScreen::CGUIWindowFullScreen(void)
93     : CGUIWindow(WINDOW_FULLSCREEN_VIDEO, "VideoFullScreen.xml")
94 {
95   m_timeCodeStamp[0] = 0;
96   m_timeCodePosition = 0;
97   m_timeCodeShow = false;
98   m_timeCodeTimeout = 0;
99   m_bShowViewModeInfo = false;
100   m_dwShowViewModeTimeout = 0;
101   m_bShowCurrentTime = false;
102   m_bGroupSelectShow = false;
103   m_loadType = KEEP_IN_MEMORY;
104   // audio
105   //  - language
106   //  - volume
107   //  - stream
108
109   // video
110   //  - Create Bookmark (294)
111   //  - Cycle bookmarks (295)
112   //  - Clear bookmarks (296)
113   //  - jump to specific time
114   //  - slider
115   //  - av delay
116
117   // subtitles
118   //  - delay
119   //  - language
120
121 }
122
123 CGUIWindowFullScreen::~CGUIWindowFullScreen(void)
124 {}
125
126 bool CGUIWindowFullScreen::OnAction(const CAction &action)
127 {
128   if (m_timeCodePosition > 0 && action.GetButtonCode())
129   { // check whether we have a mapping in our virtual videotimeseek "window" and have a select action
130     CKey key(action.GetButtonCode());
131     CAction timeSeek = CButtonTranslator::GetInstance().GetAction(WINDOW_VIDEO_TIME_SEEK, key, false);
132     if (timeSeek.GetID() == ACTION_SELECT_ITEM)
133     {
134       SeekToTimeCodeStamp(SEEK_ABSOLUTE);
135       return true;
136     }
137   }
138
139   switch (action.GetID())
140   {
141   case ACTION_SHOW_OSD:
142     ToggleOSD();
143     return true;
144
145   case ACTION_TRIGGER_OSD:
146     TriggerOSD();
147     return true;
148
149   case ACTION_SHOW_GUI:
150     {
151       // switch back to the menu
152       OutputDebugString("Switching to GUI\n");
153       g_windowManager.PreviousWindow();
154       OutputDebugString("Now in GUI\n");
155       return true;
156     }
157     break;
158
159   case ACTION_PLAYER_PLAY:
160   case ACTION_PAUSE:
161     if (m_timeCodePosition > 0)
162     {
163       SeekToTimeCodeStamp(SEEK_ABSOLUTE);
164       return true;
165     }
166     break;
167
168   case ACTION_STEP_BACK:
169     if (m_timeCodePosition > 0)
170       SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_BACKWARD);
171     else
172       g_application.m_pPlayer->Seek(false, false);
173     return true;
174
175   case ACTION_STEP_FORWARD:
176     if (m_timeCodePosition > 0)
177       SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_FORWARD);
178     else
179       g_application.m_pPlayer->Seek(true, false);
180     return true;
181
182   case ACTION_BIG_STEP_BACK:
183   case ACTION_CHAPTER_OR_BIG_STEP_BACK:
184     if (m_timeCodePosition > 0)
185       SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_BACKWARD);
186     else
187       g_application.m_pPlayer->Seek(false, true, action.GetID() == ACTION_CHAPTER_OR_BIG_STEP_BACK);
188     return true;
189
190   case ACTION_BIG_STEP_FORWARD:
191   case ACTION_CHAPTER_OR_BIG_STEP_FORWARD:
192     if (m_timeCodePosition > 0)
193       SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_FORWARD);
194     else
195       g_application.m_pPlayer->Seek(true, true, action.GetID() == ACTION_CHAPTER_OR_BIG_STEP_FORWARD);
196     return true;
197
198   case ACTION_NEXT_SCENE:
199     if (g_application.m_pPlayer->SeekScene(true))
200       g_infoManager.SetDisplayAfterSeek();
201     return true;
202     break;
203
204   case ACTION_PREV_SCENE:
205     if (g_application.m_pPlayer->SeekScene(false))
206       g_infoManager.SetDisplayAfterSeek();
207     return true;
208     break;
209
210   case ACTION_SHOW_OSD_TIME:
211     m_bShowCurrentTime = !m_bShowCurrentTime;
212     if(!m_bShowCurrentTime)
213       g_infoManager.SetDisplayAfterSeek(0); //Force display off
214     g_infoManager.SetShowTime(m_bShowCurrentTime);
215     return true;
216     break;
217
218   case ACTION_SHOW_INFO:
219     {
220       CGUIDialogFullScreenInfo* pDialog = (CGUIDialogFullScreenInfo*)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO);
221       if (pDialog)
222       {
223         CFileItem item(g_application.CurrentFileItem());
224         pDialog->DoModal();
225         return true;
226       }
227       break;
228     }
229
230   case REMOTE_0:
231   case REMOTE_1:
232   case REMOTE_2:
233   case REMOTE_3:
234   case REMOTE_4:
235   case REMOTE_5:
236   case REMOTE_6:
237   case REMOTE_7:
238   case REMOTE_8:
239   case REMOTE_9:
240     {
241       if (g_application.CurrentFileItem().IsLiveTV())
242       {
243         if(CPVRManager::Get().IsPlaying())
244         {
245           // pvr client addon
246           CPVRChannelPtr playingChannel;
247           if(!g_PVRManager.GetCurrentChannel(playingChannel))
248             return false;
249
250           if (action.GetID() == REMOTE_0)
251           {
252             CPVRChannelGroupPtr group = g_PVRChannelGroups->GetPreviousPlayedGroup();
253             if (group)
254             {
255               g_PVRManager.SetPlayingGroup(group);
256               CFileItemPtr fileItem = group->GetLastPlayedChannel(playingChannel->ChannelID());
257               if (fileItem && fileItem->HasPVRChannelInfoTag())
258               {
259                 CLog::Log(LOGDEBUG, "%s - switch to channel number %d", __FUNCTION__, fileItem->GetPVRChannelInfoTag()->ChannelNumber());
260                 g_application.OnAction(CAction(ACTION_CHANNEL_SWITCH, (float) fileItem->GetPVRChannelInfoTag()->ChannelNumber()));
261               }
262             }
263           }
264           else
265           {
266             int autoCloseTime = CSettings::Get().GetBool("pvrplayback.confirmchannelswitch") ? 0 : g_advancedSettings.m_iPVRNumericChannelSwitchTimeout;
267             CStdString strChannel = StringUtils::Format("%i", action.GetID() - REMOTE_0);
268             if (CGUIDialogNumeric::ShowAndGetNumber(strChannel, g_localizeStrings.Get(19000), autoCloseTime) || autoCloseTime)
269             {
270               int iChannelNumber = atoi(strChannel.c_str());
271               if (iChannelNumber > 0 && iChannelNumber != playingChannel->ChannelNumber())
272               {
273                 CPVRChannelGroupPtr selectedGroup = g_PVRManager.GetPlayingGroup(playingChannel->IsRadio());
274                 CFileItemPtr channel = selectedGroup->GetByChannelNumber(iChannelNumber);
275                 if (!channel || !channel->HasPVRChannelInfoTag())
276                   return false;
277
278                 g_application.OnAction(CAction(ACTION_CHANNEL_SWITCH, (float)iChannelNumber));
279               }
280             }
281           }
282         }
283         else
284         {
285           // filesystem provider like slingbox, cmyth, etc
286           int iChannelNumber = -1;
287           CStdString strChannel = StringUtils::Format("%i", action.GetID() - REMOTE_0);
288           if (CGUIDialogNumeric::ShowAndGetNumber(strChannel, g_localizeStrings.Get(19000)))
289             iChannelNumber = atoi(strChannel.c_str());
290             
291           if (iChannelNumber > 0)
292             g_application.OnAction(CAction(ACTION_CHANNEL_SWITCH, (float)iChannelNumber));
293         }
294       }
295       else
296       {
297         ChangetheTimeCode(action.GetID());
298       }
299       return true;
300     }
301     break;
302
303   case ACTION_ASPECT_RATIO:
304     { // toggle the aspect ratio mode (only if the info is onscreen)
305       if (m_bShowViewModeInfo)
306       {
307 #ifdef HAS_VIDEO_PLAYBACK
308         g_renderManager.SetViewMode(++CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode);
309 #endif
310       }
311       m_bShowViewModeInfo = true;
312       m_dwShowViewModeTimeout = XbmcThreads::SystemClockMillis();
313     }
314     return true;
315     break;
316   case ACTION_SMALL_STEP_BACK:
317     if (m_timeCodePosition > 0)
318       SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_BACKWARD);
319     else
320     {
321       int orgpos = (int)g_application.GetTime();
322       int jumpsize = g_advancedSettings.m_videoSmallStepBackSeconds; // secs
323       int setpos = (orgpos > jumpsize) ? orgpos - jumpsize : 0;
324       g_application.SeekTime((double)setpos);
325     }
326     return true;
327     break;
328   case ACTION_SHOW_PLAYLIST:
329     {
330       CFileItem item(g_application.CurrentFileItem());
331       if (item.HasPVRChannelInfoTag())
332         g_windowManager.ActivateWindow(WINDOW_DIALOG_PVR_OSD_CHANNELS);
333       else if (item.HasVideoInfoTag())
334         g_windowManager.ActivateWindow(WINDOW_VIDEO_PLAYLIST);
335       else if (item.HasMusicInfoTag())
336         g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST);
337     }
338     return true;
339     break;
340   case ACTION_PREVIOUS_CHANNELGROUP:
341     {
342       if (g_application.CurrentFileItem().HasPVRChannelInfoTag())
343         ChangetheTVGroup(false);
344       return true;
345     }
346   case ACTION_NEXT_CHANNELGROUP:
347     {
348       if (g_application.CurrentFileItem().HasPVRChannelInfoTag())
349         ChangetheTVGroup(true);
350       return true;
351     }
352   default:
353       break;
354   }
355
356   return CGUIWindow::OnAction(action);
357 }
358
359 void CGUIWindowFullScreen::OnWindowLoaded()
360 {
361   CGUIWindow::OnWindowLoaded();
362   // override the clear colour - we must never clear fullscreen
363   m_clearBackground = 0;
364
365   CGUIProgressControl* pProgress = (CGUIProgressControl*)GetControl(CONTROL_PROGRESS);
366   if(pProgress)
367   {
368     if( pProgress->GetInfo() == 0 || !pProgress->HasVisibleCondition())
369     {
370       pProgress->SetInfo(PLAYER_PROGRESS);
371       pProgress->SetVisibleCondition("player.displayafterseek");
372       pProgress->SetVisible(true);
373     }
374   }
375
376   CGUILabelControl* pLabel = (CGUILabelControl*)GetControl(LABEL_BUFFERING);
377   if(pLabel && !pLabel->HasVisibleCondition())
378   {
379     pLabel->SetVisibleCondition("player.caching");
380     pLabel->SetVisible(true);
381   }
382
383   pLabel = (CGUILabelControl*)GetControl(LABEL_CURRENT_TIME);
384   if(pLabel && !pLabel->HasVisibleCondition())
385   {
386     pLabel->SetVisibleCondition("player.displayafterseek");
387     pLabel->SetVisible(true);
388     pLabel->SetLabel("$INFO(VIDEOPLAYER.TIME) / $INFO(VIDEOPLAYER.DURATION)");
389   }
390
391   m_showCodec.Parse("player.showcodec", GetID());
392
393   FillInTVGroups();
394 }
395
396 bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message)
397 {
398   switch (message.GetMessage())
399   {
400   case GUI_MSG_WINDOW_INIT:
401     {
402       // check whether we've come back here from a window during which time we've actually
403       // stopped playing videos
404       if (message.GetParam1() == WINDOW_INVALID && !g_application.m_pPlayer->IsPlayingVideo())
405       { // why are we here if nothing is playing???
406         g_windowManager.PreviousWindow();
407         return true;
408       }
409       g_infoManager.SetShowInfo(false);
410       g_infoManager.SetShowCodec(false);
411       m_bShowCurrentTime = false;
412       m_bGroupSelectShow = false;
413       g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off.
414
415       // switch resolution
416       g_graphicsContext.SetFullScreenVideo(true);
417
418 #ifdef HAS_VIDEO_PLAYBACK
419       // make sure renderer is uptospeed
420       g_renderManager.Update();
421 #endif
422       // now call the base class to load our windows
423       CGUIWindow::OnMessage(message);
424
425       m_bShowViewModeInfo = false;
426
427       return true;
428     }
429   case GUI_MSG_WINDOW_DEINIT:
430     {
431       CGUIDialog *pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_OSD_TELETEXT);
432       if (pDialog) pDialog->Close(true);
433       pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_SLIDER);
434       if (pDialog) pDialog->Close(true);
435       pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD);
436       if (pDialog) pDialog->Close(true);
437       pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO);
438       if (pDialog) pDialog->Close(true);
439       pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_CHANNELS);
440       if (pDialog) pDialog->Close(true);
441       pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_GUIDE);
442       if (pDialog) pDialog->Close(true);
443       pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_DIRECTOR);
444       if (pDialog) pDialog->Close(true);
445       pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_CUTTER);
446       if (pDialog) pDialog->Close(true);
447       pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_SUBTITLES);
448       if (pDialog) pDialog->Close(true);
449
450       CGUIWindow::OnMessage(message);
451
452       CSettings::Get().Save();
453
454       CSingleLock lock (g_graphicsContext);
455       g_graphicsContext.SetFullScreenVideo(false);
456       lock.Leave();
457
458 #ifdef HAS_VIDEO_PLAYBACK
459       // make sure renderer is uptospeed
460       g_renderManager.Update();
461 #endif
462       return true;
463     }
464   case GUI_MSG_CLICKED:
465     {
466       unsigned int iControl = message.GetSenderId();
467       if (iControl == CONTROL_GROUP_CHOOSER && g_PVRManager.IsStarted())
468       {
469         // Get the currently selected label of the Select button
470         CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl);
471         OnMessage(msg);
472         CStdString strLabel = msg.GetLabel();
473
474         CPVRChannelPtr playingChannel;
475         if (g_PVRManager.GetCurrentChannel(playingChannel))
476         {
477           CPVRChannelGroupPtr selectedGroup = g_PVRChannelGroups->Get(playingChannel->IsRadio())->GetByName(strLabel);
478           if (selectedGroup)
479           {
480             g_PVRManager.SetPlayingGroup(selectedGroup);
481             CLog::Log(LOGDEBUG, "%s - switched to group '%s'", __FUNCTION__, selectedGroup->GroupName().c_str());
482
483             if (!selectedGroup->IsGroupMember(*playingChannel))
484             {
485               CLog::Log(LOGDEBUG, "%s - channel '%s' is not a member of '%s', switching to channel 1 of the new group",
486                   __FUNCTION__, playingChannel->ChannelName().c_str(), selectedGroup->GroupName().c_str());
487               CFileItemPtr switchChannel = selectedGroup->GetByChannelNumber(1);
488
489               if (switchChannel && switchChannel->HasPVRChannelInfoTag())
490                 g_application.OnAction(CAction(ACTION_CHANNEL_SWITCH, (float) switchChannel->GetPVRChannelInfoTag()->ChannelNumber()));
491               else
492               {
493                 CLog::Log(LOGERROR, "%s - cannot find channel '1' in group %s", __FUNCTION__, selectedGroup->GroupName().c_str());
494                 CApplicationMessenger::Get().MediaStop(false);
495               }
496             }
497           }
498           else
499           {
500             CLog::Log(LOGERROR, "%s - could not switch to group '%s'", __FUNCTION__, selectedGroup->GroupName().c_str());
501             CApplicationMessenger::Get().MediaStop(false);
502           }
503         }
504         else
505         {
506           CLog::Log(LOGERROR, "%s - cannot find the current channel", __FUNCTION__);
507           CApplicationMessenger::Get().MediaStop(false);
508         }
509
510         // hide the control and reset focus
511         m_bGroupSelectShow = false;
512         SET_CONTROL_HIDDEN(CONTROL_GROUP_CHOOSER);
513 //      SET_CONTROL_FOCUS(0, 0);
514
515         return true;
516       }
517       break;
518     }
519   case GUI_MSG_SETFOCUS:
520   case GUI_MSG_LOSTFOCUS:
521     if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true;
522     break;
523   }
524
525   return CGUIWindow::OnMessage(message);
526 }
527
528 EVENT_RESULT CGUIWindowFullScreen::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
529 {
530   if (event.m_id == ACTION_MOUSE_RIGHT_CLICK)
531   { // no control found to absorb this click - go back to GUI
532     OnAction(CAction(ACTION_SHOW_GUI));
533     return EVENT_RESULT_HANDLED;
534   }
535   if (event.m_id == ACTION_MOUSE_WHEEL_UP)
536   {
537     return g_application.OnAction(CAction(ACTION_ANALOG_SEEK_FORWARD, 0.5f)) ? EVENT_RESULT_HANDLED : EVENT_RESULT_UNHANDLED;
538   }
539   if (event.m_id == ACTION_MOUSE_WHEEL_DOWN)
540   {
541     return g_application.OnAction(CAction(ACTION_ANALOG_SEEK_BACK, 0.5f)) ? EVENT_RESULT_HANDLED : EVENT_RESULT_UNHANDLED;
542   }
543   if (event.m_id >= ACTION_GESTURE_NOTIFY && event.m_id <= ACTION_GESTURE_END) // gestures
544     return EVENT_RESULT_UNHANDLED;
545   return EVENT_RESULT_UNHANDLED;
546 }
547
548 void CGUIWindowFullScreen::FrameMove()
549 {
550   if (g_application.m_pPlayer->GetPlaySpeed() != 1)
551     g_infoManager.SetDisplayAfterSeek();
552   if (m_bShowCurrentTime)
553     g_infoManager.SetDisplayAfterSeek();
554
555   if (!g_application.m_pPlayer->HasPlayer()) return;
556
557   if( g_application.m_pPlayer->IsCaching() )
558   {
559     g_infoManager.SetDisplayAfterSeek(0); //Make sure these stuff aren't visible now
560   }
561
562   //------------------------
563   m_showCodec.Update();
564   if (m_showCodec)
565   {
566     // show audio codec info
567     CStdString strAudio, strVideo, strGeneral;
568     g_application.m_pPlayer->GetAudioInfo(strAudio);
569     {
570       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1);
571       msg.SetLabel(strAudio);
572       OnMessage(msg);
573     }
574     // show video codec info
575     g_application.m_pPlayer->GetVideoInfo(strVideo);
576     {
577       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW2);
578       msg.SetLabel(strVideo);
579       OnMessage(msg);
580     }
581     // show general info
582     g_application.m_pPlayer->GetGeneralInfo(strGeneral);
583     {
584       CStdString strGeneralFPS;
585 #if defined(TARGET_DARWIN)
586       // We show CPU usage for the entire process, as it's arguably more useful.
587       double dCPU = m_resourceCounter.GetCPUUsage();
588       CStdString strCores;
589       strCores = StringUtils::Format("cpu:%.0f%%", dCPU);
590 #else
591       CStdString strCores = g_cpuInfo.GetCoresUsageString();
592 #endif
593       int    missedvblanks;
594       int    refreshrate;
595       double clockspeed;
596       CStdString strClock;
597
598       if (g_VideoReferenceClock.GetClockInfo(missedvblanks, clockspeed, refreshrate))
599         strClock = StringUtils::Format("S( refresh:%i missed:%i speed:%+.3f%% %s )"
600                                        , refreshrate
601                                        , missedvblanks
602                                        , clockspeed - 100.0
603                                        , g_renderManager.GetVSyncState().c_str());
604
605       strGeneralFPS = StringUtils::Format("%s\nW( fps:%02.2f %s ) %s"
606                                           , strGeneral.c_str()
607                                           , g_infoManager.GetFPS()
608                                           , strCores.c_str(), strClock.c_str() );
609
610       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW3);
611       msg.SetLabel(strGeneralFPS);
612       OnMessage(msg);
613     }
614   }
615   //----------------------
616   // ViewMode Information
617   //----------------------
618   if (m_bShowViewModeInfo && XbmcThreads::SystemClockMillis() - m_dwShowViewModeTimeout > 2500)
619   {
620     m_bShowViewModeInfo = false;
621   }
622   if (m_bShowViewModeInfo)
623   {
624     RESOLUTION_INFO res = g_graphicsContext.GetResInfo();
625
626     {
627       // get the "View Mode" string
628       CStdString strTitle = g_localizeStrings.Get(629);
629       CStdString strMode = g_localizeStrings.Get(630 + CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode);
630       CStdString strInfo = StringUtils::Format("%s : %s", strTitle.c_str(), strMode.c_str());
631       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1);
632       msg.SetLabel(strInfo);
633       OnMessage(msg);
634     }
635     // show sizing information
636     SPlayerVideoStreamInfo info;
637     g_application.m_pPlayer->GetVideoStreamInfo(info);
638     {
639       // Splitres scaling factor
640       float xscale = (float)res.iScreenWidth  / (float)res.iWidth;
641       float yscale = (float)res.iScreenHeight / (float)res.iHeight;
642
643       CStdString strSizing = StringUtils::Format(g_localizeStrings.Get(245),
644                                                  (int)info.SrcRect.Width(),
645                                                  (int)info.SrcRect.Height(),
646                                                  (int)(info.DestRect.Width() * xscale),
647                                                  (int)(info.DestRect.Height() * yscale),
648                                                  CDisplaySettings::Get().GetZoomAmount(),
649                                                  info.videoAspectRatio*CDisplaySettings::Get().GetPixelRatio(),
650                                                  CDisplaySettings::Get().GetPixelRatio(),
651                                                  CDisplaySettings::Get().GetVerticalShift());
652       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW2);
653       msg.SetLabel(strSizing);
654       OnMessage(msg);
655     }
656     // show resolution information
657     {
658       CStdString strStatus;
659       if (g_Windowing.IsFullScreen())
660         strStatus = StringUtils::Format("%s %ix%i@%.2fHz - %s",
661                                         g_localizeStrings.Get(13287).c_str(),
662                                         res.iScreenWidth,
663                                         res.iScreenHeight,
664                                         res.fRefreshRate,
665                                         g_localizeStrings.Get(244).c_str());
666       else
667         strStatus = StringUtils::Format("%s %ix%i - %s",
668                                         g_localizeStrings.Get(13287).c_str(),
669                                         res.iScreenWidth,
670                                         res.iScreenHeight,
671                                         g_localizeStrings.Get(242).c_str());
672
673       CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW3);
674       msg.SetLabel(strStatus);
675       OnMessage(msg);
676     }
677   }
678
679   if (m_timeCodeShow && m_timeCodePosition != 0)
680   {
681     if ( (XbmcThreads::SystemClockMillis() - m_timeCodeTimeout) >= 2500)
682     {
683       m_timeCodeShow = false;
684       m_timeCodePosition = 0;
685     }
686     CStdString strDispTime = "00:00:00";
687
688     CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), LABEL_ROW1);
689
690     for (int pos = 7, i = m_timeCodePosition; pos >= 0 && i > 0; pos--)
691     {
692       if (strDispTime[pos] != ':')
693       {
694         i -= 1;
695         strDispTime[pos] = (char)m_timeCodeStamp[i] + '0';
696       }
697     }
698
699     strDispTime += "/" + g_infoManager.GetDuration(TIME_FORMAT_HH_MM_SS) + " [" + g_infoManager.GetCurrentPlayTime(TIME_FORMAT_HH_MM_SS) + "]"; // duration [ time ]
700     msg.SetLabel(strDispTime);
701     OnMessage(msg);
702   }
703
704   if (m_showCodec || m_bShowViewModeInfo)
705   {
706     SET_CONTROL_VISIBLE(LABEL_ROW1);
707     SET_CONTROL_VISIBLE(LABEL_ROW2);
708     SET_CONTROL_VISIBLE(LABEL_ROW3);
709     SET_CONTROL_VISIBLE(BLUE_BAR);
710     SET_CONTROL_HIDDEN(CONTROL_GROUP_CHOOSER);
711   }
712   else if (m_timeCodeShow)
713   {
714     SET_CONTROL_VISIBLE(LABEL_ROW1);
715     SET_CONTROL_HIDDEN(LABEL_ROW2);
716     SET_CONTROL_HIDDEN(LABEL_ROW3);
717     SET_CONTROL_VISIBLE(BLUE_BAR);
718     SET_CONTROL_HIDDEN(CONTROL_GROUP_CHOOSER);
719   }
720   else if (m_bGroupSelectShow)
721   {
722     SET_CONTROL_HIDDEN(LABEL_ROW1);
723     SET_CONTROL_HIDDEN(LABEL_ROW2);
724     SET_CONTROL_HIDDEN(LABEL_ROW3);
725     SET_CONTROL_HIDDEN(BLUE_BAR);
726     SET_CONTROL_VISIBLE(CONTROL_GROUP_CHOOSER);
727   }
728   else
729   {
730     SET_CONTROL_HIDDEN(LABEL_ROW1);
731     SET_CONTROL_HIDDEN(LABEL_ROW2);
732     SET_CONTROL_HIDDEN(LABEL_ROW3);
733     SET_CONTROL_HIDDEN(BLUE_BAR);
734     SET_CONTROL_HIDDEN(CONTROL_GROUP_CHOOSER);
735   }
736 }
737
738 void CGUIWindowFullScreen::Process(unsigned int currentTime, CDirtyRegionList &dirtyregion)
739 {
740   // TODO: This isn't quite optimal - ideally we'd only be dirtying up the actual video render rect
741   //       which is probably the job of the renderer as it can more easily track resizing etc.
742   MarkDirtyRegion();
743   CGUIWindow::Process(currentTime, dirtyregion);
744   m_renderRegion.SetRect(0, 0, (float)g_graphicsContext.GetWidth(), (float)g_graphicsContext.GetHeight());
745 }
746
747 void CGUIWindowFullScreen::Render()
748 {
749   CGUIWindow::Render();
750 }
751
752 void CGUIWindowFullScreen::ChangetheTimeCode(int remote)
753 {
754   if (remote >= REMOTE_0 && remote <= REMOTE_9)
755   {
756     m_timeCodeShow = true;
757     m_timeCodeTimeout = XbmcThreads::SystemClockMillis();
758
759     if (m_timeCodePosition < 6)
760       m_timeCodeStamp[m_timeCodePosition++] = remote - REMOTE_0;
761     else
762     {
763       // rotate around
764       for (int i = 0; i < 5; i++)
765         m_timeCodeStamp[i] = m_timeCodeStamp[i+1];
766       m_timeCodeStamp[5] = remote - REMOTE_0;
767     }
768   }
769 }
770
771 void CGUIWindowFullScreen::SeekToTimeCodeStamp(SEEK_TYPE type, SEEK_DIRECTION direction)
772 {
773   double total = GetTimeCodeStamp();
774   if (type == SEEK_RELATIVE)
775     total = g_application.GetTime() + (((direction == SEEK_FORWARD) ? 1 : -1) * total);
776
777   if (total < g_application.GetTotalTime())
778     g_application.SeekTime(total);
779
780   m_timeCodePosition = 0;
781   m_timeCodeShow = false;
782 }
783
784 double CGUIWindowFullScreen::GetTimeCodeStamp()
785 {
786   // Convert the timestamp into an integer
787   int tot = 0;
788   for (int i = 0; i < m_timeCodePosition; i++)
789     tot = tot * 10 + m_timeCodeStamp[i];
790
791   // Interpret result as HHMMSS
792   int s = tot % 100; tot /= 100;
793   int m = tot % 100; tot /= 100;
794   int h = tot % 100;
795   return h * 3600 + m * 60 + s;
796 }
797
798 void CGUIWindowFullScreen::SeekChapter(int iChapter)
799 {
800   g_application.m_pPlayer->SeekChapter(iChapter);
801
802   // Make sure gui items are visible.
803   g_infoManager.SetDisplayAfterSeek();
804 }
805
806 void CGUIWindowFullScreen::FillInTVGroups()
807 {
808   if (!g_PVRManager.IsStarted())
809     return;
810
811   CGUIMessage msgReset(GUI_MSG_LABEL_RESET, GetID(), CONTROL_GROUP_CHOOSER);
812   g_windowManager.SendMessage(msgReset);
813
814   const CPVRChannelGroups *groups = g_PVRChannelGroups->Get(g_PVRManager.IsPlayingRadio());
815   if (groups)
816     groups->FillGroupsGUI(GetID(), CONTROL_GROUP_CHOOSER);
817 }
818
819 void CGUIWindowFullScreen::ChangetheTVGroup(bool next)
820 {
821   if (!g_PVRManager.IsStarted())
822     return;
823
824   CGUISelectButtonControl* pButton = (CGUISelectButtonControl*)GetControl(CONTROL_GROUP_CHOOSER);
825   if (!pButton)
826     return;
827
828   if (!m_bGroupSelectShow)
829   {
830     SET_CONTROL_VISIBLE(CONTROL_GROUP_CHOOSER);
831     SET_CONTROL_FOCUS(CONTROL_GROUP_CHOOSER, 0);
832
833     // fire off an event that we've pressed this button...
834     OnAction(CAction(ACTION_SELECT_ITEM));
835
836     m_bGroupSelectShow = true;
837   }
838   else
839   {
840     if (next)
841       pButton->OnRight();
842     else
843       pButton->OnLeft();
844   }
845 }
846
847 void CGUIWindowFullScreen::ToggleOSD()
848 {
849   CGUIDialogVideoOSD *pOSD = (CGUIDialogVideoOSD *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD);
850   if (pOSD)
851   {
852     if (pOSD->IsDialogRunning())
853       pOSD->Close();
854     else
855       pOSD->DoModal();
856   }
857 }
858
859 void CGUIWindowFullScreen::TriggerOSD()
860 {
861   CGUIDialogVideoOSD *pOSD = (CGUIDialogVideoOSD *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD);
862   if (pOSD && !pOSD->IsDialogRunning())
863   {
864     pOSD->SetAutoClose(3000);
865     pOSD->DoModal();
866   }
867 }