/*
Neutrino-GUI - DBoxII-Project
Copyright (C) 2001 Steffen Hehn 'McClean'
Homepage: http://dbox.cyberphoria.org/
Copyright (C) 2012-2013 defans@bluepeercrew.us
License: GPL
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include // sort
#include
#include "audiomute.h"
#include "screensaver.h"
#include
#include
extern CInfoClock *InfoClock;
#include
extern cVideo * videoDecoder;
using namespace std;
CScreenSaver::CScreenSaver()
{
thrScreenSaver = 0;
m_frameBuffer = CFrameBuffer::getInstance();
m_viewer = new CPictureViewer();
index = 0;
status_mute = CAudioMute::getInstance()->getStatus();
scr_clock = NULL;
}
CScreenSaver::~CScreenSaver()
{
if(thrScreenSaver)
pthread_cancel(thrScreenSaver);
thrScreenSaver = 0;
delete m_viewer;
if (scr_clock)
delete scr_clock;
}
CScreenSaver* CScreenSaver::getInstance()
{
static CScreenSaver * screenSaver = NULL;
if (!screenSaver)
screenSaver = new CScreenSaver();
return screenSaver;
}
void CScreenSaver::Start()
{
OnBeforeStart();
status_mute = CAudioMute::getInstance()->getStatus();
CAudioMute::getInstance()->enableMuteIcon(false);
m_viewer->SetScaling((CPictureViewer::ScalingMode)g_settings.picviewer_scaling);
m_viewer->SetVisible(g_settings.screen_StartX, g_settings.screen_EndX, g_settings.screen_StartY, g_settings.screen_EndY);
if (g_settings.video_Format == 3)
m_viewer->SetAspectRatio(float(16.0/9));
else
m_viewer->SetAspectRatio(float(4.0/3));
m_viewer->Cleanup();
m_frameBuffer->stopFrame();
if(!thrScreenSaver)
{
//printf("[%s] %s: starting thread\n", __FILE__, __FUNCTION__);
pthread_create(&thrScreenSaver, NULL, ScreenSaverPrg, (void*) this);
pthread_detach(thrScreenSaver);
}
}
void CScreenSaver::Stop()
{
if(thrScreenSaver)
{
pthread_cancel(thrScreenSaver);
thrScreenSaver = 0;
}
if(thrScreenSaver)
pthread_cancel(thrScreenSaver);
thrScreenSaver = 0;
if (scr_clock){
scr_clock->Stop();
delete scr_clock;
scr_clock = NULL;
}
m_frameBuffer->paintBackground(); //clear entire screen
CAudioMute::getInstance()->enableMuteIcon(status_mute);
if (!OnAfterStop.empty())
OnAfterStop();
else
InfoClock->enableInfoClock();
}
void* CScreenSaver::ScreenSaverPrg(void* arg)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
CScreenSaver * PScreenSaver = static_cast(arg);
PScreenSaver->ReadDir(); //TODO kill Screensaver if false
PScreenSaver->m_frameBuffer->Clear();
if (g_settings.screensaver_timeout)
{
while(1)
{
PScreenSaver->paint();
sleep(g_settings.screensaver_timeout);
}
}
else
PScreenSaver->paint(); //just paint first found picture
return 0;
}
bool CScreenSaver::ReadDir()
{
string d = g_settings.screensaver_dir;
if (d.length() > 1)
{
//remove trailing slash
string::iterator it = d.end() - 1;
if (*it == '/')
d.erase(it);
}
char *dir_name = (char *) d.c_str();
struct dirent *dirpointer;
DIR *dir;
char curr_ext[5];
int curr_lenght;
bool ret = false;
v_bg_files.clear();
/* open dir */
if((dir=opendir(dir_name)) == NULL) {
fprintf(stderr,"[CScreenSaver] %s - %d : error open dir...\n", __func__, __LINE__);
return ret;
}
/* read complete dir */
while((dirpointer=readdir(dir)) != NULL)
{
curr_lenght = strlen((*dirpointer).d_name);
string str = dir_name;
//printf("%d\n",curr_lenght);
if(curr_lenght > 4)
{
strncpy(curr_ext,(*dirpointer).d_name+(curr_lenght-4),5);
//printf("%s\n",curr_ext);
if (strcasecmp(".jpg",curr_ext) && strcasecmp(".png",curr_ext))
continue;
str += "/";
str += (*dirpointer).d_name;
if ((string) dir_name == ICONSDIR)
{
/*
backward compatiblity:
just add the standard mp3-?.jpg pictures
to get the same behavior as usual
*/
if (str.find("/mp3-") == string::npos)
continue;
}
v_bg_files.push_back(str);
}
}
sort(v_bg_files.begin(), v_bg_files.end());
/* close pointer */
if(closedir(dir) == -1)
dprintf(DEBUG_NORMAL, "[CScreenSaver] %s - %d : Error no closed %s\n", __func__, __LINE__, dir_name);
if(!v_bg_files.empty())
ret = true;
else
dprintf(DEBUG_NORMAL, "[CScreenSaver] %s - %d : no picture found\n", __func__, __LINE__);
return ret;
}
void CScreenSaver::paint()
{
if (g_settings.screensaver_mode == SCR_MODE_IMAGE && !v_bg_files.empty()){
if( (index >= v_bg_files.size()) || (access(v_bg_files.at(index).c_str(), F_OK)) )
{
ReadDir();
index = 0;
return;
}
dprintf(DEBUG_INFO, "[CScreenSaver] %s - %d : %s\n", __func__, __LINE__, v_bg_files.at(index).c_str());
m_viewer->ShowImage(v_bg_files.at(index).c_str(), false /*unscaled*/);
if (!g_settings.screensaver_random)
index++;
else
index = rand() % v_bg_files.size();
if(index == v_bg_files.size())
index = 0;
}
else{
if (!scr_clock){
scr_clock = new CComponentsFrmClock(1, 1, NULL, "%H.%M:%S", "%H.%M %S", true);
scr_clock->setClockFont(g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_NUMBER]);
scr_clock->setTextColor(COL_DARK_GRAY);
scr_clock->enableSaveBg();
scr_clock->doPaintBg(false);
}
if (scr_clock->isPainted())
scr_clock->Stop();
scr_clock->kill();
scr_clock->setPosP(rand() % 80, rand() % 90);
scr_clock->Start();
}
}