mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-27 15:32:52 +02:00
Should fix possible compiler warnings with -Waddress-of-packed-member.
Comes with newer compilers e.g gcc 9.x
Origin commit data
------------------
Branch: ni/coolstream
Commit: af2f80a9e9
Author: Thilo Graf <dbt@novatux.de>
Date: 2020-01-23 (Thu, 23 Jan 2020)
------------------
This commit was generated by Migit
1207 lines
29 KiB
C++
1207 lines
29 KiB
C++
/*
|
|
lcd4l
|
|
|
|
Copyright (C) 2012 'defans'
|
|
Homepage: http://www.bluepeercrew.us/
|
|
|
|
Copyright (C) 2012-2018 'vanhofen'
|
|
Homepage: http://www.neutrino-images.de/
|
|
|
|
Copyright (C) 2016-2019 'TangoCash'
|
|
|
|
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, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <pthread.h>
|
|
#include <sstream>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <iomanip>
|
|
|
|
#include <global.h>
|
|
#include <neutrino.h>
|
|
|
|
#include <timerdclient/timerdclient.h>
|
|
#include <system/helpers.h>
|
|
|
|
#include <driver/record.h>
|
|
#include <driver/audioplay.h>
|
|
#include <driver/radiotext.h>
|
|
#include <zapit/capmt.h>
|
|
#include <zapit/zapit.h>
|
|
#include <gui/movieplayer.h>
|
|
#include <gui/pictureviewer.h>
|
|
#include <eitd/sectionsd.h>
|
|
#include <hardware/video.h>
|
|
#include <gui/weather.h>
|
|
|
|
#include "lcd4l.h"
|
|
|
|
extern CRemoteControl *g_RemoteControl;
|
|
extern cVideo *videoDecoder;
|
|
extern CPictureViewer *g_PicViewer;
|
|
|
|
#define LCD_DATADIR "/tmp/lcd/"
|
|
|
|
#define LCD_ICONSDIR "/share/lcd/icons/"
|
|
#define ICONSEXT ".png"
|
|
|
|
#define LOGO_DUMMY LCD_ICONSDIR "blank.png"
|
|
|
|
#define BRIGHTNESS LCD_DATADIR "brightness"
|
|
#define BRIGHTNESS_STANDBY LCD_DATADIR "brightness_standby"
|
|
#define RESOLUTION LCD_DATADIR "resolution"
|
|
#define ASPECTRATIO LCD_DATADIR "aspectratio"
|
|
#define VIDEOTEXT LCD_DATADIR "videotext"
|
|
#define RADIOTEXT LCD_DATADIR "radiotext"
|
|
#define DOLBYDIGITAL LCD_DATADIR "dolbydigital"
|
|
#define TUNER LCD_DATADIR "tuner"
|
|
#define VOLUME LCD_DATADIR "volume"
|
|
#define MODE_REC LCD_DATADIR "mode_rec"
|
|
#define MODE_TSHIFT LCD_DATADIR "mode_tshift"
|
|
#define MODE_TIMER LCD_DATADIR "mode_timer"
|
|
#define MODE_ECM LCD_DATADIR "mode_ecm"
|
|
#define MODE_CAM LCD_DATADIR "mode_cam"
|
|
|
|
#define SERVICE LCD_DATADIR "service"
|
|
#define CHANNELNR LCD_DATADIR "channelnr"
|
|
#define LOGO LCD_DATADIR "logo"
|
|
#define MODE_LOGO LCD_DATADIR "mode_logo"
|
|
#define LAYOUT LCD_DATADIR "layout"
|
|
|
|
#define EVENT LCD_DATADIR "event"
|
|
#define INFO1 LCD_DATADIR "info1"
|
|
#define INFO2 LCD_DATADIR "info2"
|
|
#define PROGRESS LCD_DATADIR "progress"
|
|
#define DURATION LCD_DATADIR "duration"
|
|
#define START LCD_DATADIR "start"
|
|
#define END LCD_DATADIR "end"
|
|
|
|
#define FONT LCD_DATADIR "font"
|
|
#define FGCOLOR LCD_DATADIR "fgcolor"
|
|
#define BGCOLOR LCD_DATADIR "bgcolor"
|
|
|
|
#define FCOLOR1 LCD_DATADIR "fcolor1"
|
|
#define FCOLOR2 LCD_DATADIR "fcolor2"
|
|
#define PBCOLOR LCD_DATADIR "pbcolor"
|
|
|
|
#define WEATHER_CITY LCD_DATADIR "weather_city"
|
|
#define WEATHER_TIMESTAMP LCD_DATADIR "weather_timestamp"
|
|
#define WEATHER_TEMP LCD_DATADIR "weather_temp"
|
|
#define WEATHER_WIND LCD_DATADIR "weather_wind"
|
|
#define WEATHER_ICON LCD_DATADIR "weather_icon"
|
|
|
|
#define FLAG_LCD4LINUX "/tmp/.lcd4linux"
|
|
#define PIDFILE "/var/run/lcd4linux.pid"
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
CLCD4l::CLCD4l()
|
|
{
|
|
thrLCD4l = 0;
|
|
}
|
|
|
|
CLCD4l::~CLCD4l()
|
|
{
|
|
if (thrLCD4l)
|
|
pthread_cancel(thrLCD4l);
|
|
thrLCD4l = 0;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
void CLCD4l::InitLCD4l()
|
|
{
|
|
if (thrLCD4l)
|
|
{
|
|
printf("[CLCD4l] %s: initializing\n", __FUNCTION__);
|
|
Init();
|
|
}
|
|
}
|
|
|
|
void CLCD4l::StartLCD4l()
|
|
{
|
|
if (!thrLCD4l)
|
|
{
|
|
printf("[CLCD4l] %s: starting thread\n", __FUNCTION__);
|
|
pthread_create(&thrLCD4l, NULL, LCD4lProc, (void*) this);
|
|
pthread_detach(thrLCD4l);
|
|
}
|
|
}
|
|
|
|
void CLCD4l::StopLCD4l()
|
|
{
|
|
if (thrLCD4l)
|
|
{
|
|
printf("[CLCD4l] %s: stopping thread\n", __FUNCTION__);
|
|
pthread_cancel(thrLCD4l);
|
|
thrLCD4l = 0;
|
|
}
|
|
}
|
|
|
|
void CLCD4l::SwitchLCD4l()
|
|
{
|
|
if (thrLCD4l)
|
|
StopLCD4l();
|
|
else
|
|
StartLCD4l();
|
|
}
|
|
|
|
int CLCD4l::CreateFile(const char *file, std::string content, bool convert)
|
|
{
|
|
// returns 0 = ok; 1 = can't create file; -1 = thread not found
|
|
|
|
int ret = 0;
|
|
|
|
if (thrLCD4l)
|
|
{
|
|
if (WriteFile(file, content, convert) == false)
|
|
ret = 1;
|
|
}
|
|
else
|
|
ret = -1;
|
|
|
|
return ret;
|
|
}
|
|
|
|
int CLCD4l::RemoveFile(const char *file)
|
|
{
|
|
// returns 0 = ok; 1 = can't remove file;
|
|
|
|
int ret = 0;
|
|
|
|
if (access(file, F_OK) == 0)
|
|
{
|
|
if (unlink(file) != 0)
|
|
ret = 1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int CLCD4l::GetMaxBrightness()
|
|
{
|
|
int max_brightness;
|
|
|
|
switch (g_settings.lcd4l_display_type)
|
|
{
|
|
case SAMSUNG800x480:
|
|
case SAMSUNG800x600:
|
|
case SAMSUNG1024x600:
|
|
max_brightness = 10;
|
|
break;
|
|
case PEARL320x240:
|
|
default:
|
|
max_brightness = 7;
|
|
break;
|
|
}
|
|
|
|
return max_brightness;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
void CLCD4l::Init()
|
|
{
|
|
m_ParseID = 0;
|
|
|
|
m_Brightness = -1;
|
|
m_Brightness_standby = -1;
|
|
m_Resolution = "n/a";
|
|
m_AspectRatio = "n/a";
|
|
m_Videotext = -1;
|
|
m_Radiotext = -1;
|
|
m_DolbyDigital = "n/a";
|
|
m_Tuner = -1;
|
|
m_Volume = -1;
|
|
m_ModeRec = -1;
|
|
m_ModeTshift = -1;
|
|
m_ModeTimer = -1;
|
|
m_ModeEcm = -1;
|
|
m_ModeCamPresent= false;
|
|
m_ModeCam = -1;
|
|
|
|
m_Service = "n/a";
|
|
m_ChannelNr = -1;
|
|
m_Logo = "n/a";
|
|
m_ModeLogo = -1;
|
|
|
|
m_Layout = "n/a";
|
|
|
|
m_Event = "n/a";
|
|
m_Info1 = "n/a";
|
|
m_Info2 = "n/a";
|
|
m_Progress = -1;
|
|
for (int i = 0; i < (int)sizeof(m_Duration); i++)
|
|
m_Duration[i] = ' ';
|
|
m_Start = "00:00";
|
|
m_End = "00:00";
|
|
|
|
m_wcity = "";
|
|
m_wtimestamp = "";
|
|
m_wtemp = "";
|
|
m_wwind = "";
|
|
m_wicon = "";
|
|
|
|
if (!access(LCD_DATADIR, F_OK) == 0)
|
|
mkdir(LCD_DATADIR, 0755);
|
|
|
|
wait4daemon = true;
|
|
}
|
|
|
|
void* CLCD4l::LCD4lProc(void* arg)
|
|
{
|
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
|
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
|
|
|
CLCD4l *PLCD4l = static_cast<CLCD4l*>(arg);
|
|
|
|
PLCD4l->Init();
|
|
|
|
sleep(5); //please wait !
|
|
|
|
static bool FirstRun = true;
|
|
uint64_t p_ParseID = 0;
|
|
bool NewParseID = false;
|
|
|
|
//printf("[CLCD4l] %s: starting loop\n", __FUNCTION__);
|
|
while(1)
|
|
{
|
|
if ( (!access(PIDFILE, F_OK) == 0) && (!FirstRun) )
|
|
{
|
|
if (g_settings.lcd4l_support == 1) // automatic
|
|
{
|
|
if (PLCD4l->GetWaitStatus())
|
|
{
|
|
//printf("[CLCD4l] %s: waiting for lcd4linux\n", __FUNCTION__);
|
|
sleep(10);
|
|
continue;
|
|
}
|
|
else
|
|
PLCD4l->SetWaitStatus(true);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
usleep(5 * 100 * 1000); // 0.5 sec
|
|
NewParseID = PLCD4l->CompareParseID(p_ParseID);
|
|
if (NewParseID || p_ParseID == NeutrinoModes::mode_audio)
|
|
break;
|
|
}
|
|
|
|
//printf("[CLCD4l] %s: m_ParseID: %llx (NewParseID: %d)\n", __FUNCTION__, p_ParseID, NewParseID ? 1 : 0);
|
|
PLCD4l->ParseInfo(p_ParseID, NewParseID, FirstRun);
|
|
|
|
if (FirstRun)
|
|
{
|
|
PLCD4l->WriteFile(FLAG_LCD4LINUX);
|
|
FirstRun = false;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void CLCD4l::ParseInfo(uint64_t parseID, bool newID, bool firstRun)
|
|
{
|
|
SNeutrinoTheme &t = g_settings.theme;
|
|
|
|
std::string font = g_settings.font_file;
|
|
|
|
if (m_font.compare(font))
|
|
{
|
|
WriteFile(FONT, font);
|
|
m_font = font;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
std::string fgcolor = hexStr(t.infobar_Text_red)
|
|
+ hexStr(t.infobar_Text_green)
|
|
+ hexStr(t.infobar_Text_blue)
|
|
+ hexStrA2A(t.infobar_Text_alpha);
|
|
|
|
if (m_fgcolor.compare(fgcolor))
|
|
{
|
|
WriteFile(FGCOLOR, fgcolor);
|
|
m_fgcolor = fgcolor;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
std::string bgcolor = hexStr(t.infobar_red)
|
|
+ hexStr(t.infobar_green)
|
|
+ hexStr(t.infobar_blue)
|
|
+ hexStrA2A(t.infobar_alpha);
|
|
|
|
if (m_bgcolor.compare(bgcolor))
|
|
{
|
|
WriteFile(BGCOLOR, bgcolor);
|
|
m_bgcolor = bgcolor;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
std::string fcolor1 = hexStr(t.infobar_Text_red)
|
|
+ hexStr(t.infobar_Text_green)
|
|
+ hexStr(t.infobar_Text_blue)
|
|
+ hexStr(t.infobar_Text_alpha);
|
|
|
|
if (m_fcolor1.compare(fcolor1))
|
|
{
|
|
WriteFile(FCOLOR1, fcolor1);
|
|
m_fcolor1 = fcolor1;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
std::string fcolor2 = hexStr(t.colored_events_red)
|
|
+ hexStr(t.colored_events_green)
|
|
+ hexStr(t.colored_events_blue)
|
|
+ hexStr(t.colored_events_alpha);
|
|
|
|
if (!t.colored_events_infobar)
|
|
fcolor2 = fcolor1;
|
|
|
|
if (m_fcolor2.compare(fcolor2))
|
|
{
|
|
WriteFile(FCOLOR2, fcolor2);
|
|
m_fcolor2 = fcolor2;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
std::string pbcolor = hexStr(t.menu_Content_Selected_red)
|
|
+ hexStr(t.menu_Content_Selected_green)
|
|
+ hexStr(t.menu_Content_Selected_blue)
|
|
+ hexStrA2A(t.menu_Content_Selected_alpha);
|
|
|
|
if (m_pbcolor.compare(pbcolor))
|
|
{
|
|
WriteFile(PBCOLOR, pbcolor);
|
|
m_pbcolor = pbcolor;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
int Brightness = g_settings.lcd4l_brightness;
|
|
if (m_Brightness != Brightness)
|
|
{
|
|
WriteFile(BRIGHTNESS, to_string(Brightness));
|
|
m_Brightness = Brightness;
|
|
}
|
|
|
|
int Brightness_standby = g_settings.lcd4l_brightness_standby;
|
|
if (m_Brightness_standby != Brightness_standby)
|
|
{
|
|
WriteFile(BRIGHTNESS_STANDBY, to_string(Brightness_standby));
|
|
m_Brightness_standby = Brightness_standby;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
int x_res, y_res, framerate;
|
|
videoDecoder->getPictureInfo(x_res, y_res, framerate);
|
|
|
|
if (y_res == 1088)
|
|
y_res = 1080;
|
|
|
|
std::string Resolution = to_string(x_res) + "x" + to_string(y_res);
|
|
//Resolution += "\n" + to_string(framerate); //TODO
|
|
|
|
if (m_Resolution.compare(Resolution))
|
|
{
|
|
WriteFile(RESOLUTION, Resolution);
|
|
m_Resolution = Resolution;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
std::string AspectRatio;
|
|
switch (videoDecoder->getAspectRatio())
|
|
{
|
|
case 0:
|
|
AspectRatio = "n/a";
|
|
break;
|
|
case 1:
|
|
AspectRatio = "4:3";
|
|
break;
|
|
case 2:
|
|
AspectRatio = "14:9";
|
|
break;
|
|
case 3:
|
|
AspectRatio = "16:9";
|
|
break;
|
|
case 4:
|
|
AspectRatio = "20:9";
|
|
break;
|
|
default:
|
|
AspectRatio = "n/k";
|
|
break;
|
|
}
|
|
|
|
if (m_AspectRatio.compare(AspectRatio))
|
|
{
|
|
WriteFile(ASPECTRATIO, AspectRatio);
|
|
m_AspectRatio = AspectRatio;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
int Videotext = g_RemoteControl->current_PIDs.PIDs.vtxtpid;
|
|
|
|
if (m_Videotext != Videotext)
|
|
{
|
|
WriteFile(VIDEOTEXT, Videotext ? "yes" : "no");
|
|
m_Videotext = Videotext;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
int Radiotext = 0;
|
|
if (m_Mode == NeutrinoModes::mode_radio && g_settings.radiotext_enable && g_Radiotext)
|
|
Radiotext = g_Radiotext->haveRadiotext();
|
|
|
|
if (m_Radiotext != Radiotext)
|
|
{
|
|
WriteFile(RADIOTEXT, Radiotext ? "yes" : "no");
|
|
m_Radiotext = Radiotext;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
std::string DolbyDigital;
|
|
if ((g_RemoteControl->current_PIDs.PIDs.selected_apid < g_RemoteControl->current_PIDs.APIDs.size()) &&
|
|
(g_RemoteControl->current_PIDs.APIDs[g_RemoteControl->current_PIDs.PIDs.selected_apid].is_ac3))
|
|
DolbyDigital = "yes";
|
|
else
|
|
DolbyDigital = g_RemoteControl->has_ac3 ? "available" : "no";
|
|
|
|
if (m_DolbyDigital.compare(DolbyDigital))
|
|
{
|
|
WriteFile(DOLBYDIGITAL, DolbyDigital);
|
|
m_DolbyDigital = DolbyDigital;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
int Tuner = 1 + CFEManager::getInstance()->getLiveFE()->getNumber();
|
|
|
|
if (m_Tuner != Tuner)
|
|
{
|
|
WriteFile(TUNER, to_string(Tuner));
|
|
m_Tuner = Tuner;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
int Volume = g_settings.current_volume;
|
|
|
|
if (m_Volume != Volume)
|
|
{
|
|
WriteFile(VOLUME, to_string(Volume));
|
|
m_Volume = Volume;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
int ModeRec = 0;
|
|
int ModeTshift = 0;
|
|
|
|
int RecordMode = CRecordManager::getInstance()->GetRecordMode();
|
|
switch (RecordMode)
|
|
{
|
|
case CRecordManager::RECMODE_REC_TSHIFT:
|
|
ModeRec = 1;
|
|
ModeTshift = 1;
|
|
break;
|
|
case CRecordManager::RECMODE_REC:
|
|
ModeRec = 1;
|
|
break;
|
|
case CRecordManager::RECMODE_TSHIFT:
|
|
ModeTshift = 1;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (m_ModeRec != ModeRec)
|
|
{
|
|
WriteFile(MODE_REC, ModeRec ? "on" : "off");
|
|
m_ModeRec = ModeRec;
|
|
}
|
|
|
|
if (m_ModeTshift != ModeTshift)
|
|
{
|
|
WriteFile(MODE_TSHIFT, ModeTshift ? "on" : "off");
|
|
m_ModeTshift = ModeTshift;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
int ModeTimer = 0;
|
|
|
|
CTimerd::TimerList timerList;
|
|
CTimerdClient TimerdClient;
|
|
|
|
timerList.clear();
|
|
TimerdClient.getTimerList(timerList);
|
|
|
|
CTimerd::TimerList::iterator timer = timerList.begin();
|
|
|
|
for (; timer != timerList.end(); timer++)
|
|
{
|
|
if (timer->alarmTime > time(NULL) && (timer->eventType == CTimerd::TIMER_ZAPTO || timer->eventType == CTimerd::TIMER_RECORD))
|
|
{
|
|
// Nur "true", wenn irgendein timer in der zukunft liegt
|
|
// und dieser vom typ TIMER_ZAPTO oder TIMER_RECORD ist
|
|
ModeTimer = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (m_ModeTimer != ModeTimer)
|
|
{
|
|
WriteFile(MODE_TIMER, ModeTimer ? "on" : "off");
|
|
m_ModeTimer = ModeTimer;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
int ModeEcm = 0;
|
|
|
|
if (access("/tmp/ecm.info", F_OK) == 0)
|
|
{
|
|
struct stat buf;
|
|
stat("/tmp/ecm.info", &buf);
|
|
if (buf.st_size > 0)
|
|
ModeEcm = 1;
|
|
}
|
|
|
|
if (m_ModeEcm != ModeEcm)
|
|
{
|
|
WriteFile(MODE_ECM, ModeEcm ? "on" : "off");
|
|
m_ModeEcm = ModeEcm;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
if (firstRun) //FIXME; what if module is added/removed while lcd4l is running?
|
|
{
|
|
for (unsigned int i = 0; i < cCA::GetInstance()->GetNumberCISlots(); i++)
|
|
m_ModeCamPresent |= cCA::GetInstance()->ModulePresent(CA_SLOT_TYPE_CI, i);
|
|
}
|
|
|
|
int ModeCam = (m_ModeCamPresent && CCamManager::getInstance()->getUseCI());
|
|
|
|
if (m_ModeCam != ModeCam)
|
|
{
|
|
WriteFile(MODE_CAM, ModeCam ? "on" : "off");
|
|
m_ModeCam = ModeCam;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
if (newID || parseID == NeutrinoModes::mode_audio || parseID == NeutrinoModes::mode_ts)
|
|
{
|
|
std::string Service = "";
|
|
int ChannelNr = 0;
|
|
std::string Logo = LOGO_DUMMY;
|
|
int dummy;
|
|
int ModeLogo = 0;
|
|
|
|
int ModeStandby = 0;
|
|
|
|
if (m_ModeChannel)
|
|
{
|
|
if (m_ModeChannel > 1)
|
|
Service = g_RemoteControl->subChannels[g_RemoteControl->selected_subchannel].subservice_name;
|
|
else
|
|
Service = g_RemoteControl->getCurrentChannelName();
|
|
|
|
g_PicViewer->GetLogoName(parseID, Service, Logo, &dummy, &dummy, true, true);
|
|
|
|
ChannelNr = CNeutrinoApp::getInstance()->channelList->getActiveChannelNumber();
|
|
}
|
|
else if (parseID == NeutrinoModes::mode_audio)
|
|
{
|
|
const CAudioMetaData meta = CAudioPlayer::getInstance()->getMetaData();
|
|
if ( (!meta.sc_station.empty()) && (CAudioPlayer::getInstance()->getState() != CBaseDec::STOP))
|
|
Service = meta.sc_station;
|
|
else
|
|
{
|
|
Service = g_Locale->getText(LOCALE_AUDIOPLAYER_NAME);
|
|
|
|
switch (CAudioPlayer::getInstance()->getState())
|
|
{
|
|
case CBaseDec::REV:
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_REW ICONSEXT;
|
|
break;
|
|
case CBaseDec::FF:
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_FF ICONSEXT;
|
|
break;
|
|
case CBaseDec::PAUSE:
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_PAUSE ICONSEXT;
|
|
break;
|
|
case CBaseDec::PLAY:
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_PLAY ICONSEXT;
|
|
break;
|
|
default:
|
|
;
|
|
}
|
|
}
|
|
}
|
|
else if (parseID == NeutrinoModes::mode_pic)
|
|
{
|
|
Service = g_Locale->getText(LOCALE_PICTUREVIEWER_HEAD);
|
|
}
|
|
else if (parseID == NeutrinoModes::mode_ts)
|
|
{
|
|
if (ModeTshift)
|
|
Service = g_Locale->getText(LOCALE_RECORDINGMENU_TIMESHIFT);
|
|
else if (CMoviePlayerGui::getInstance().p_movie_info)
|
|
{
|
|
if (!CMoviePlayerGui::getInstance().p_movie_info->channelName.empty())
|
|
Service = CMoviePlayerGui::getInstance().p_movie_info->channelName;
|
|
}
|
|
|
|
if (Service.empty())
|
|
Service = g_Locale->getText(LOCALE_MOVIEPLAYER_HEAD);
|
|
|
|
switch (CMoviePlayerGui::getInstance().getState())
|
|
{
|
|
case 6: /* rewind */
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_REW ICONSEXT;
|
|
break;
|
|
case 5: /* fast forward */
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_FF ICONSEXT;
|
|
break;
|
|
case 4: /* pause */
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_PAUSE ICONSEXT;
|
|
break;
|
|
case 3: /* play */
|
|
if (ModeTshift && CMoviePlayerGui::getInstance().p_movie_info) /* show channel-logo */
|
|
{
|
|
if (!g_PicViewer->GetLogoName(CMoviePlayerGui::getInstance().p_movie_info->channelId,
|
|
CMoviePlayerGui::getInstance().p_movie_info->channelName,
|
|
Logo, &dummy, &dummy, true, true))
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_PLAY ICONSEXT;
|
|
}
|
|
else /* show play-icon */
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_PLAY ICONSEXT;
|
|
break;
|
|
default: /* show movieplayer-icon */
|
|
Logo = ICONSDIR "/" NEUTRINO_ICON_MOVIEPLAYER ICONSEXT;
|
|
}
|
|
}
|
|
else if (parseID == NeutrinoModes::mode_upnp)
|
|
{
|
|
Service = g_Locale->getText(LOCALE_UPNPBROWSER_HEAD);
|
|
}
|
|
else if (parseID == NeutrinoModes::mode_standby)
|
|
{
|
|
Service = "STANDBY";
|
|
ModeStandby = 1;
|
|
}
|
|
|
|
/* --- */
|
|
|
|
if (m_Service.compare(Service))
|
|
{
|
|
WriteFile(SERVICE, Service, true);
|
|
m_Service = Service;
|
|
}
|
|
|
|
if (m_ChannelNr != ChannelNr)
|
|
{
|
|
WriteFile(CHANNELNR, to_string(ChannelNr));
|
|
m_ChannelNr = ChannelNr;
|
|
}
|
|
|
|
if (m_Logo.compare(Logo))
|
|
{
|
|
WriteFile(LOGO, Logo);
|
|
m_Logo = Logo;
|
|
}
|
|
|
|
if (Logo != LOGO_DUMMY)
|
|
ModeLogo = 1;
|
|
|
|
if (m_ModeLogo != ModeLogo)
|
|
{
|
|
WriteFile(MODE_LOGO, to_string(ModeLogo));
|
|
m_ModeLogo = ModeLogo;
|
|
}
|
|
|
|
/* --- */
|
|
|
|
std::string DisplayType;
|
|
|
|
switch (g_settings.lcd4l_display_type)
|
|
{
|
|
case SAMSUNG800x480:
|
|
DisplayType = "Samsung800x480_";
|
|
break;
|
|
case SAMSUNG800x600:
|
|
DisplayType = "Samsung800x600_";
|
|
break;
|
|
case SAMSUNG1024x600:
|
|
DisplayType = "Samsung1024x600_";
|
|
break;
|
|
case PEARL320x240:
|
|
default:
|
|
DisplayType = "Pearl_";
|
|
break;
|
|
}
|
|
|
|
std::string Layout;
|
|
|
|
if (ModeStandby)
|
|
{
|
|
Layout = DisplayType + "standby";
|
|
}
|
|
else if ((g_settings.lcd4l_skin_radio) && (m_Mode == NeutrinoModes::mode_radio || m_Mode == NeutrinoModes::mode_webradio))
|
|
{
|
|
Layout = DisplayType + "radio";
|
|
}
|
|
else
|
|
{
|
|
switch (g_settings.lcd4l_skin)
|
|
{
|
|
case 100:
|
|
Layout = DisplayType + "user";
|
|
break;
|
|
case 4:
|
|
Layout = DisplayType + "xcam";
|
|
break;
|
|
case 3:
|
|
Layout = DisplayType + "d-box2";
|
|
break;
|
|
case 2:
|
|
Layout = DisplayType + "small";
|
|
break;
|
|
case 1:
|
|
Layout = DisplayType + "large";
|
|
break;
|
|
default:
|
|
Layout = DisplayType + "standard";
|
|
}
|
|
}
|
|
|
|
if (m_Layout.compare(Layout))
|
|
{
|
|
WriteFile(LAYOUT, Layout);
|
|
m_Layout = Layout;
|
|
|
|
if (!firstRun)
|
|
{
|
|
const char *buf = "service lcd4linux reload";
|
|
|
|
//printf("[CLCD4l] %s: executing '%s'\n", __FUNCTION__, buf);
|
|
if (my_system(3,"service", "lcd4linux", "reload") != 0)
|
|
printf("[CLCD4l] %s: executing '%s' failed\n", __FUNCTION__, buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
std::string Event = "";
|
|
std::string Info1 = "";
|
|
std::string Info2 = "";
|
|
int Progress = 0;
|
|
char Duration[sizeof(m_Duration)] = {0};
|
|
char Start[6] = {0};
|
|
char End[6] = {0};
|
|
|
|
if (m_ModeChannel)
|
|
{
|
|
t_channel_id channel_id = parseID & 0xFFFFFFFFFFFFULL;
|
|
|
|
CZapitChannel * channel = CZapit::getInstance()->GetCurrentChannel();
|
|
if (channel)
|
|
channel_id = channel->getEpgID();
|
|
|
|
CSectionsdClient::CurrentNextInfo CurrentNext;
|
|
CEitManager::getInstance()->getCurrentNextServiceKey(channel_id, CurrentNext);
|
|
|
|
if (CSectionsdClient::epgflags::has_current)
|
|
{
|
|
if (!CurrentNext.current_name.empty())
|
|
Event = CurrentNext.current_name;
|
|
|
|
CShortEPGData shortEpgData;
|
|
if (CEitManager::getInstance()->getEPGidShort(CurrentNext.current_uniqueKey, &shortEpgData))
|
|
{
|
|
Info1 = shortEpgData.info1;
|
|
Info2 = shortEpgData.info2;
|
|
}
|
|
|
|
time_t cur_duration = CurrentNext.current_zeit.dauer;
|
|
time_t cur_start_time = CurrentNext.current_zeit.startzeit;
|
|
if ((cur_duration > 0) && (cur_duration < 86400))
|
|
{
|
|
Progress = 100 * (time(NULL) - cur_start_time) / cur_duration;
|
|
|
|
int total = cur_duration / 60;
|
|
int done = (abs(time(NULL) - cur_start_time) + 30) / 60;
|
|
int todo = total - done;
|
|
if ((time(NULL) < cur_start_time) && todo >= 0)
|
|
{
|
|
done = 0;
|
|
todo = cur_duration / 60;
|
|
}
|
|
snprintf(Duration, sizeof(Duration), "%d/%d", done, total);
|
|
}
|
|
|
|
tm_struct = localtime(&cur_start_time);
|
|
snprintf(Start, sizeof(Start), "%02d:%02d", tm_struct->tm_hour, tm_struct->tm_min);
|
|
}
|
|
|
|
if (CSectionsdClient::epgflags::has_next)
|
|
{
|
|
Event += "\n" + CurrentNext.next_name;
|
|
time_t next_start_time = CurrentNext.next_zeit.startzeit;
|
|
tm_struct = localtime(&next_start_time);
|
|
snprintf(End, sizeof(End), "%02d:%02d", tm_struct->tm_hour, tm_struct->tm_min);
|
|
}
|
|
}
|
|
else if (parseID == NeutrinoModes::mode_audio)
|
|
{
|
|
if (CAudioPlayer::getInstance()->getState() == CBaseDec::STOP)
|
|
{
|
|
Event = g_Locale->getText(LOCALE_AUDIOPLAYER_STOP);
|
|
//snprintf(Duration, sizeof(Duration), "-:--");
|
|
}
|
|
else
|
|
{
|
|
const CAudioMetaData meta = CAudioPlayer::getInstance()->getMetaData();
|
|
if ( !meta.artist.empty() )
|
|
Event += meta.artist;
|
|
if ( !meta.artist.empty() && !meta.title.empty() )
|
|
Event += " - ";
|
|
if ( !meta.title.empty() )
|
|
Event += meta.title;
|
|
|
|
if (!meta.album.empty())
|
|
Info1 = meta.album;
|
|
|
|
if (!meta.genre.empty())
|
|
Info2 = meta.genre;
|
|
|
|
time_t total = meta.total_time;
|
|
time_t done = CAudioPlayer::getInstance()->getTimePlayed();
|
|
|
|
if ( (total > 0) && (done > 0) )
|
|
{
|
|
Progress = 100 * done / total;
|
|
snprintf(Duration, sizeof(Duration), "%ld:%02ld/%ld:%02ld", done / 60, done % 60, total / 60, total % 60);
|
|
}
|
|
}
|
|
|
|
time_t sTime = time(NULL);
|
|
tm_struct = localtime(&sTime);
|
|
|
|
snprintf(Start, sizeof(Start), "%02d:%02d", tm_struct->tm_hour, tm_struct->tm_min);
|
|
}
|
|
#if 0
|
|
else if (parseID == NeutrinoModes::mode_pic)
|
|
{
|
|
// TODO: Event = Bildname
|
|
}
|
|
#endif
|
|
else if (parseID == NeutrinoModes::mode_ts)
|
|
{
|
|
if (CMoviePlayerGui::getInstance().p_movie_info)
|
|
{
|
|
if (!CMoviePlayerGui::getInstance().p_movie_info->epgTitle.empty())
|
|
Event = CMoviePlayerGui::getInstance().p_movie_info->epgTitle;
|
|
|
|
if (!CMoviePlayerGui::getInstance().p_movie_info->epgInfo1.empty())
|
|
Info1 = CMoviePlayerGui::getInstance().p_movie_info->epgInfo1;
|
|
|
|
if (!CMoviePlayerGui::getInstance().p_movie_info->epgInfo2.empty())
|
|
Info2 = CMoviePlayerGui::getInstance().p_movie_info->epgInfo2;
|
|
}
|
|
else if (!CMoviePlayerGui::getInstance().GetFile().empty())
|
|
Event = CMoviePlayerGui::getInstance().GetFile();
|
|
|
|
if (Event.empty())
|
|
Event = "MOVIE";
|
|
|
|
if (!ModeTshift)
|
|
{
|
|
int total = CMoviePlayerGui::getInstance().GetDuration();
|
|
int done = CMoviePlayerGui::getInstance().GetPosition();
|
|
snprintf(Duration, sizeof(Duration), "%d/%d", done / (60 * 1000), total / (60 * 1000));
|
|
Progress = CMoviePlayerGui::getInstance().file_prozent;
|
|
}
|
|
|
|
time_t sTime = time(NULL);
|
|
sTime -= (CMoviePlayerGui::getInstance().GetPosition()/1000);
|
|
tm_struct = localtime(&sTime);
|
|
|
|
snprintf(Start, sizeof(Start), "%02d:%02d", tm_struct->tm_hour, tm_struct->tm_min);
|
|
|
|
time_t eTime = time(NULL);
|
|
eTime +=(CMoviePlayerGui::getInstance().GetDuration()/1000) - (CMoviePlayerGui::getInstance().GetPosition()/1000);
|
|
tm_struct = localtime(&eTime);
|
|
|
|
snprintf(End, sizeof(End), "%02d:%02d", tm_struct->tm_hour, tm_struct->tm_min);
|
|
}
|
|
#if 0
|
|
else if (parseID == NeutrinoModes::mode_upnp)
|
|
{
|
|
// TODO?
|
|
}
|
|
#endif
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
Event += "\n"; // make sure we have at least two lines in event-file
|
|
|
|
if (m_Event.compare(Event))
|
|
{
|
|
WriteFile(EVENT, Event, g_settings.lcd4l_convert);
|
|
m_Event = Event;
|
|
|
|
m_ParseID = 0; // reset channelid to get a possible eventlogo
|
|
}
|
|
|
|
if (m_Info1.compare(Info1))
|
|
{
|
|
WriteFile(INFO1, Info1, g_settings.lcd4l_convert);
|
|
m_Info1 = Info1;
|
|
}
|
|
|
|
if (m_Info2.compare(Info2))
|
|
{
|
|
WriteFile(INFO2, Info2, g_settings.lcd4l_convert);
|
|
m_Info2 = Info2;
|
|
}
|
|
|
|
if (m_Start.compare(Start))
|
|
{
|
|
WriteFile(START, (std::string)Start);
|
|
m_Start = (std::string)Start;
|
|
}
|
|
|
|
if (m_End.compare(End))
|
|
{
|
|
WriteFile(END, (std::string)End);
|
|
m_End = (std::string)End;
|
|
}
|
|
|
|
if (Progress > 100)
|
|
Progress = 100;
|
|
|
|
if (m_Progress != Progress)
|
|
{
|
|
WriteFile(PROGRESS, to_string(Progress));
|
|
m_Progress = Progress;
|
|
}
|
|
|
|
if (strcmp(m_Duration, Duration))
|
|
{
|
|
WriteFile(DURATION, (std::string)Duration);
|
|
strcpy(m_Duration, Duration);
|
|
}
|
|
|
|
if (g_settings.weather_enabled && CWeather::getInstance()->checkUpdate(firstRun))
|
|
{
|
|
std::string wcity = CWeather::getInstance()->getCity();
|
|
if (m_wcity.compare(wcity))
|
|
{
|
|
WriteFile(WEATHER_CITY, wcity);
|
|
m_wcity = wcity;
|
|
}
|
|
|
|
int forecast = CWeather::getInstance()->getForecastSize();
|
|
|
|
std::string wtimestamp = to_string((int)CWeather::getInstance()->getCurrentTimestamp());
|
|
for (int i = 0; i < forecast; i++) // 0 is current day
|
|
{
|
|
wtimestamp += "\n" + to_string(CWeather::getInstance()->getForecastWeekday(i));
|
|
}
|
|
if (m_wtimestamp.compare(wtimestamp))
|
|
{
|
|
WriteFile(WEATHER_TIMESTAMP, wtimestamp);
|
|
m_wtimestamp = wtimestamp;
|
|
}
|
|
|
|
std::string wtemp = CWeather::getInstance()->getCurrentTemperature();
|
|
for (int i = 0; i < forecast; i++) // 0 is current day
|
|
{
|
|
wtemp += "\n" + CWeather::getInstance()->getForecastTemperatureMin(i);
|
|
wtemp += "|" + CWeather::getInstance()->getForecastTemperatureMax(i);
|
|
}
|
|
if (m_wtemp.compare(wtemp))
|
|
{
|
|
WriteFile(WEATHER_TEMP, wtemp);
|
|
m_wtemp = wtemp;
|
|
}
|
|
|
|
std::string wwind = CWeather::getInstance()->getCurrentWindSpeed();
|
|
wwind += "|" + CWeather::getInstance()->getCurrentWindBearing();
|
|
for (int i = 0; i < forecast; i++) // 0 is current day
|
|
{
|
|
wwind += "\n" + CWeather::getInstance()->getForecastWindSpeed(i);
|
|
wwind += "|" + CWeather::getInstance()->getForecastWindBearing(i);
|
|
}
|
|
if (m_wwind.compare(wwind))
|
|
{
|
|
WriteFile(WEATHER_WIND, wwind);
|
|
m_wwind = wwind;
|
|
}
|
|
|
|
std::string wicon = CWeather::getInstance()->getCurrentIcon();
|
|
for (int i = 0; i < forecast; i++)
|
|
wicon += "\n" + CWeather::getInstance()->getForecastIcon(i);
|
|
if (m_wicon.compare(wicon))
|
|
{
|
|
WriteFile(WEATHER_ICON, wicon);
|
|
m_wicon = wicon;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ----------------------------------------------------------------- */
|
|
|
|
bool CLCD4l::WriteFile(const char *file, std::string content, bool convert)
|
|
{
|
|
bool ret = true;
|
|
|
|
if (convert) // align to internal lcd4linux font
|
|
{
|
|
strReplace(content, "ä", "\xe4\0");
|
|
strReplace(content, "ö", "\xf6\0");
|
|
strReplace(content, "ü", "\xfc\0");
|
|
strReplace(content, "Ä", "\xc4\0");
|
|
strReplace(content, "Ö", "\xd6\0");
|
|
strReplace(content, "Ü", "\xdc\0");
|
|
if (g_settings.lcd4l_display_type == PEARL320x240)
|
|
strReplace(content, "ß", "\xe2\0");
|
|
|
|
strReplace(content, "Ą", "\x41\0");
|
|
strReplace(content, "ą", "\x61\0");
|
|
strReplace(content, "Ć", "\x43\0");
|
|
strReplace(content, "ć", "\x63\0");
|
|
strReplace(content, "Ę", "\x45\0");
|
|
strReplace(content, "ę", "\x65\0");
|
|
strReplace(content, "Ł", "\x4c\0");
|
|
strReplace(content, "ł", "\x6c\0");
|
|
strReplace(content, "Ń", "\x4e\0");
|
|
strReplace(content, "ń", "\x6e\0");
|
|
strReplace(content, "Ó", "\x4f\0");
|
|
strReplace(content, "ó", "\x6f\0");
|
|
strReplace(content, "Ś", "\x53\0");
|
|
strReplace(content, "ś", "\x73\0");
|
|
strReplace(content, "Ź", "\x5a\0");
|
|
strReplace(content, "ź", "\x7a\0");
|
|
strReplace(content, "Ź", "\x5a\0");
|
|
strReplace(content, "ż", "\x7a\0");
|
|
|
|
strReplace(content, "é", "e");
|
|
}
|
|
|
|
if (FILE *f = fopen(file, "w"))
|
|
{
|
|
//printf("[CLCD4l] %s: %s -> %s\n", __FUNCTION__, content.c_str(), file);
|
|
fprintf(f, "%s\n", content.c_str());
|
|
fclose(f);
|
|
}
|
|
else
|
|
{
|
|
ret = false;
|
|
printf("[CLCD4l] %s: %s failed!\n", __FUNCTION__, file);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
uint64_t CLCD4l::GetParseID()
|
|
{
|
|
uint64_t ID = CNeutrinoApp::getInstance()->getMode();
|
|
m_Mode = (int) ID;
|
|
m_ModeChannel = 0;
|
|
|
|
if (ID == NeutrinoModes::mode_tv || ID == NeutrinoModes::mode_webtv || ID == NeutrinoModes::mode_radio || ID == NeutrinoModes::mode_webradio)
|
|
{
|
|
if (!(g_RemoteControl->subChannels.empty()) && (g_RemoteControl->selected_subchannel > 0))
|
|
m_ModeChannel = 2;
|
|
else
|
|
m_ModeChannel = 1;
|
|
|
|
if (m_ModeChannel > 1)
|
|
ID = g_RemoteControl->subChannels[g_RemoteControl->selected_subchannel].getChannelID();
|
|
else
|
|
ID = CZapit::getInstance()->GetCurrentChannelID();
|
|
}
|
|
//printf("[CLCD4l] %s: %llx\n", __FUNCTION__, ID);
|
|
return ID;
|
|
}
|
|
|
|
bool CLCD4l::CompareParseID(uint64_t &i_ParseID)
|
|
{
|
|
bool ret = false;
|
|
|
|
i_ParseID = GetParseID();
|
|
if (m_ParseID != i_ParseID)
|
|
{
|
|
//printf("[CLCD4l] %s: i_%llx <-> m_%llx\n", __FUNCTION__, i_ParseID, m_ParseID);
|
|
ret = true;
|
|
m_ParseID = i_ParseID;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void CLCD4l::strReplace(std::string &orig, const std::string &fstr, const std::string &rstr)
|
|
{
|
|
size_t pos = 0;
|
|
while ((pos = orig.find(fstr, pos)) != std::string::npos)
|
|
{
|
|
orig.replace(pos, fstr.length(), rstr);
|
|
pos += rstr.length();
|
|
}
|
|
}
|
|
|
|
std::string CLCD4l::hexStr(unsigned char data)
|
|
{
|
|
char hexstr[3];
|
|
snprintf(hexstr, sizeof hexstr, "%02x", (int)data * 255 / 100);
|
|
return std::string(hexstr);
|
|
}
|
|
|
|
std::string CLCD4l::hexStrA2A(unsigned char data)
|
|
{
|
|
char hexstr[3];
|
|
int a = 100 - data;
|
|
int ret = a * 0xFF / 100;
|
|
|
|
if(data == 0)
|
|
ret = 0xFF;
|
|
else if(data >= 100)
|
|
ret = 0x00;
|
|
|
|
snprintf(hexstr, sizeof hexstr, "%02x", ret);
|
|
return std::string(hexstr);
|
|
}
|