diff --git a/configure.ac b/configure.ac index 85bff557a..5e00a3065 100644 --- a/configure.ac +++ b/configure.ac @@ -35,6 +35,17 @@ else rm -f local_build_config.h.tmp fi +AC_ARG_ENABLE(ffmpegdec, + AS_HELP_STRING(--enable-ffmpegdec,include ffmpeg decoder support), + ,[enable_ffmpegdec=no]) + +AM_CONDITIONAL(ENABLE_FFMPEGDEC,test "$enable_ffmpegdec" = "yes") +if test "$enable_ffmpegdec" = "yes"; then + AC_DEFINE(ENABLE_FFMPEGDEC,1,[include ffmpeg decoder support]) +fi + +if test x"$enable_ffmpegdec" != xyes; then + AC_ARG_WITH([tremor], [AS_HELP_STRING([--with-tremor], [use libvorbisidec instead of libogg/libvorbis])], [TREMOR="$withval"], @@ -45,10 +56,6 @@ AC_ARG_WITH([tremor-static], [AS_HELP_STRING([--with-tremor-static], [TREMOR_STATIC="$withval"], [TREMOR_STATIC=no]) -if test "$BOXTYPE" = "tripledragon"; then - TUXBOX_APPS_LIB_PKGCONFIG(DIRECTFB, directfb) -fi - if test "$TREMOR_STATIC" = "yes"; then TREMOR=yes fi @@ -63,23 +70,34 @@ if test "$TREMOR_STATIC" = "yes"; then VORBISIDEC_LIBS="$(echo $VORBISIDEC_LIBS | sed 's@-L@@; s@ -l.*@/libvorbisidec.a@;')" fi -AM_CONDITIONAL(USE_TREMOR, test "$TREMOR" = "yes") - -TUXBOX_APPS_LIB_CONFIG(CURL,curl-config) -TUXBOX_APPS_LIB_CONFIG(FREETYPE,freetype-config) -# TUXBOX_APPS_LIB_PKGCONFIG(OPENSSL,openssl) TUXBOX_APPS_LIB_PKGCONFIG_CHECK(ID3TAG,libid3tag) if test x"$ID3TAG_EXISTS" != xyes; then TUXBOX_APPS_LIB_PKGCONFIG(ID3TAG,id3tag) fi + TUXBOX_APPS_LIB_PKGCONFIG_CHECK(MAD,libmad) if test x"$MAD_EXISTS" != xyes; then TUXBOX_APPS_LIB_PKGCONFIG(MAD,mad) fi + TUXBOX_APPS_LIB_PKGCONFIG_CHECK(OGG,ogg) if test -z "$OGG_CFLAGS" ; then TUXBOX_APPS_LIB_PKGCONFIG(OGG,ogg) fi +else +TUXBOX_APPS_LIB_PKGCONFIG(SWRESAMPLE,libswresample) +fi + +if test "$BOXTYPE" = "tripledragon"; then + TUXBOX_APPS_LIB_PKGCONFIG(DIRECTFB, directfb) +fi + +AM_CONDITIONAL(USE_TREMOR, test "$TREMOR" = "yes") + +# TUXBOX_APPS_LIB_PKGCONFIG(OPENSSL,openssl) +TUXBOX_APPS_LIB_CONFIG(CURL,curl-config) +TUXBOX_APPS_LIB_CONFIG(FREETYPE,freetype-config) + TUXBOX_APPS_LIB_PKGCONFIG(PNG,libpng) TUXBOX_APPS_LIB_PKGCONFIG(AVFORMAT,libavformat) TUXBOX_APPS_LIB_PKGCONFIG(AVCODEC,libavcodec) diff --git a/data/cables.xml b/data/cables.xml index e992a06bc..ea6f28f32 100644 --- a/data/cables.xml +++ b/data/cables.xml @@ -512,7 +512,13 @@ - + + + + + + + @@ -541,6 +547,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 52fffd1d9..b3fc76430 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -256,7 +256,8 @@ ci.reset_standby Reset nach Standby ci.settings Zugangskontrolle ci.timeout CAM antwortet nicht ci.waiting Warte auf CAM-Antwort -clock_size Info Uhr +clock_background Hintergrund anzeigen +clock_seconds Sekunden anzeigen clock_size_height Höhe der Anzeige clock_switch_off Uhr ausblenden clock_switch_on Uhr einblenden @@ -433,7 +434,7 @@ extra.volume_pos Lautstärkeanzeige extra.volume_size Höhe der Anzeige extra.west Westen extra.zap_cycle Zap nur in Bouquet -extra.zapit_fe_timeout Tuning Timeout (1=10ms) +extra.zapit_fe_timeout Tuning Timeout extra.zapit_hvoltage High (13.5/ 18.5) Voltage extra.zapit_make_bouquet Kanalliste auffüllen extra.zapit_motor_speed Rotor Drehzeit (10 = 1°/ sec) @@ -812,7 +813,10 @@ menu.hint_channellist_foot Definiert, welche Informationen im unteren Sendungsfe menu.hint_channellist_setup Wählen Sie die Anzeigeoptionen für die Kanalliste menu.hint_channels Kanalliste öffnen menu.hint_ci Conditional-Access-Menü zum Einrichten Ihres CI-Moduls oder der eingebetteten Conax-Karte -menu.hint_clock_size Stellen Sie die Größe der Info Uhr ein. +menu.hint_clock_background Lassen Sie die Uhr mit Hintergrund anzeigen +menu.hint_clock_mode Schalten Sie die Uhr ein oder aus +menu.hint_clock_seconds Legen Sie fest, ob die Sekunden angezeigt werden sollen +menu.hint_clock_size Stellen Sie die Größe der Uhr ein menu.hint_colors Konfigurieren Sie die Menü-Farben menu.hint_content_back Ändern Sie die Hintergrundfarbe für den Fensterinhalt menu.hint_content_textcolor Ändern Sie die Textfarbe für den Fensterinhalt @@ -1242,7 +1246,7 @@ miscsettings.infobar_show_res Auflösung anzeigen miscsettings.infobar_show_res_simple einfach miscsettings.infobar_show_sysfs_hdd Füllstandanzeige (sysFS & hdd) miscsettings.infobar_show_tuner Aktiven Tuner anzeigen -miscsettings.infoclock Info Uhr +miscsettings.infoclock Uhr miscsettings.progressbar Fortschrittsbalken miscsettings.progressbar_color Farbe miscsettings.progressbar_design Design @@ -1945,6 +1949,11 @@ timing.volumebar Lautstärkeanzeige unicable.lnb Unicable Eingang unicable.qrg Unicable Frequenz unicable.scr Unicable SCR +unit.decimal , +unit.short.hour h +unit.short.millisecond ms +unit.short.minute min +unit.short.second s upnpbrowser.head UPnP Browser upnpbrowser.noservers Kein UPnP-Server gefunden upnpbrowser.rescan Neue Suche diff --git a/data/locale/english.locale b/data/locale/english.locale index 72bef7ade..81a9fdad7 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -256,7 +256,8 @@ ci.reset_standby Reset after standby ci.settings Conditional access ci.timeout Timeout waiting CI menu ready ci.waiting Waiting for CI answer -clock_size Info clock +clock_background Show background +clock_seconds Show seconds clock_size_height Display height clock_switch_off Clock off clock_switch_on Clock on @@ -433,7 +434,7 @@ extra.volume_pos Volumebar extra.volume_size Height of display extra.west West extra.zap_cycle Zap cycle -extra.zapit_fe_timeout Tune timeout (1 = 10 msec) +extra.zapit_fe_timeout Tune timeout extra.zapit_hvoltage 18V for rotor moving extra.zapit_make_bouquet Make Remaining Channels list extra.zapit_motor_speed Motor moving speed (10 = 1deg/sec) @@ -812,7 +813,10 @@ menu.hint_channellist_foot Show additional information\nin bottom box menu.hint_channellist_setup Configure channel list GUI options menu.hint_channels Open channel list menu.hint_ci Conditional access menu\nto setup your CI CAM or embeded Conax card -menu.hint_clock_size Set the size of the info clock. +menu.hint_clock_background Show clock with theme's background color +menu.hint_clock_mode Switch clock on or off +menu.hint_clock_seconds Show time format with seconds +menu.hint_clock_size Set the size of the info clock menu.hint_colors Configure GUI colors menu.hint_content_back Change GUI window background color menu.hint_content_textcolor Change GUI window text color @@ -1242,7 +1246,7 @@ miscsettings.infobar_show_res show resolution on infobar miscsettings.infobar_show_res_simple simple miscsettings.infobar_show_sysfs_hdd Fill level (sysFS & hdd) miscsettings.infobar_show_tuner Display active tuner -miscsettings.infoclock Info clock +miscsettings.infoclock Clock miscsettings.progressbar Progressbar miscsettings.progressbar_color Color miscsettings.progressbar_design Design @@ -1945,6 +1949,11 @@ timing.volumebar Volume bar unicable.lnb Unicable Input unicable.qrg Unicable Frequency unicable.scr Unicable SCR +unit.decimal . +unit.short.hour h +unit.short.millisecond ms +unit.short.minute min +unit.short.second s upnpbrowser.head UPnP Browser upnpbrowser.noservers No UPnP servers found upnpbrowser.rescan Scan again diff --git a/src/Makefile.am b/src/Makefile.am index db50c59c1..ad69b8376 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,11 +41,21 @@ rcsim_SOURCES = rcsim.c rcsim.h if ENABLE_FLAC FLACLIBS = -lFLAC -AM_CPPFLAGS += -DENABLE_FLAC else FLACLIBS = endif +if ENABLE_FFMPEGDEC +ADEC_LIBS = @SWRESAMPLE_LIBS@ +else +ADEC_LIBS = @MAD_LIBS@ \ + @ID3TAG_LIBS@ \ + $(FLACLIBS) \ + $(VORBISLIBS) +endif + +AM_CPPFLAGS += -D_FILE_OFFSET_BITS=64 + if BOXMODEL_APOLLO MTDUTILSLIBS = \ system/mtdutils/libneutrino_system_mtdutils.a \ @@ -91,11 +101,11 @@ neutrino_LDADD = \ @CURL_LIBS@ \ @FREETYPE_LIBS@ \ @PNG_LIBS@ \ - @MAD_LIBS@ \ - @ID3TAG_LIBS@ \ @LIBCS_LIBS@ \ - $(FLACLIBS) \ - $(VORBISLIBS) \ + @AVFORMAT_LIBS@ \ + @AVUTIL_LIBS@ \ + @AVCODEC_LIBS@ \ + $(ADEC_LIBS) \ -ldvbsi++ \ -ljpeg \ -lOpenThreads \ diff --git a/src/driver/audiodec/Makefile.am b/src/driver/audiodec/Makefile.am index 6bfe9e451..fe2691f3b 100644 --- a/src/driver/audiodec/Makefile.am +++ b/src/driver/audiodec/Makefile.am @@ -9,22 +9,22 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/zapit/include \ -I$(top_srcdir)/lib/libconfigfile \ @FREETYPE_CFLAGS@ \ - @VORBISIDEC_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libneutrino_driver_audiodec.a -if ENABLE_FLAC -FLACdec= flacdec.cpp -endif - -libneutrino_driver_audiodec_a_SOURCES = \ - basedec.cpp \ - cdrdec.cpp \ +if ENABLE_FFMPEGDEC +ASOURCES = ffmpegdec.cpp +else +ASOURCES = cdrdec.cpp \ crc.c \ - $(FLACdec) \ + flacdec.cpp \ mp3dec.cpp \ oggdec.cpp \ tag.c \ wavdec.cpp -# vis.cpp +endif + +libneutrino_driver_audiodec_a_SOURCES = \ + basedec.cpp \ + $(ASOURCES) diff --git a/src/driver/audiodec/basedec.cpp b/src/driver/audiodec/basedec.cpp index c38752464..0c4c1bd52 100644 --- a/src/driver/audiodec/basedec.cpp +++ b/src/driver/audiodec/basedec.cpp @@ -27,13 +27,11 @@ #ifdef HAVE_CONFIG_H #include #endif -#ifdef ENABLE_FLAC -#include -#endif #include #include #include #include +#include #include // for ShoutcastCallback() @@ -42,13 +40,23 @@ #include #include "basedec.h" +#ifdef ENABLE_FFMPEGDEC +#include "ffmpegdec.h" +#else #include "cdrdec.h" #include "mp3dec.h" #include "oggdec.h" #include "wavdec.h" +#ifdef ENABLE_FLAC +#include "flacdec.h" +#endif +#endif + #include unsigned int CBaseDec::mSamplerate=0; +OpenThreads::Mutex CBaseDec::metaDataMutex; +std::map CBaseDec::metaDataCache; void ShoutcastCallback(void *arg) { @@ -79,57 +87,43 @@ CBaseDec::RetCode CBaseDec::DecoderBase(CAudiofile* const in, if ( Status == OK ) { +#ifndef ENABLE_FFMPEGDEC if( in->FileType == CFile::STREAM_AUDIO ) { if ( fstatus( fp, ShoutcastCallback ) < 0 ) - { fprintf( stderr, "Error adding shoutcast callback: %s", - err_txt ); - } + err_txt ); + if (ftype(fp, "ogg")) - { Status = COggDec::getInstance()->Decoder( fp, OutputFd, state, - &in->MetaData, t, - secondsToSkip ); - } + &in->MetaData, t, + secondsToSkip ); else - { Status = CMP3Dec::getInstance()->Decoder( fp, OutputFd, state, - &in->MetaData, t, - secondsToSkip ); - } + &in->MetaData, t, + secondsToSkip ); } else if( in->FileType == CFile::FILE_MP3) - { Status = CMP3Dec::getInstance()->Decoder( fp, OutputFd, state, - &in->MetaData, t, - secondsToSkip ); - } + &in->MetaData, t, + secondsToSkip ); else if( in->FileType == CFile::FILE_OGG ) - { Status = COggDec::getInstance()->Decoder( fp, OutputFd, state, - &in->MetaData, t, - secondsToSkip ); - } + &in->MetaData, t, + secondsToSkip ); else if( in->FileType == CFile::FILE_WAV ) - { Status = CWavDec::getInstance()->Decoder( fp, OutputFd, state, - &in->MetaData, t, - secondsToSkip ); - } + &in->MetaData, t, + secondsToSkip ); else if( in->FileType == CFile::FILE_CDR ) - { Status = CCdrDec::getInstance()->Decoder( fp, OutputFd, state, - &in->MetaData, t, - secondsToSkip ); - } + &in->MetaData, t, + secondsToSkip ); #ifdef ENABLE_FLAC else if (in->FileType == CFile::FILE_FLAC) - { Status = CFlacDec::getInstance()->Decoder(fp, OutputFd, state, - &in->MetaData, t, - secondsToSkip ); - } + &in->MetaData, t, + secondsToSkip ); #endif else { @@ -138,55 +132,118 @@ CBaseDec::RetCode CBaseDec::DecoderBase(CAudiofile* const in, Status = INTERNAL_ERR; } +#else + CFile::FileType ft = in->FileType; + if( in->FileType == CFile::STREAM_AUDIO ) + { + if ( fstatus( fp, ShoutcastCallback ) < 0 ) + fprintf( stderr, "Error adding shoutcast callback: %s", err_txt ); + + if (ftype(fp, "ogg")) + ft = CFile::FILE_OGG; + else if (ftype(fp, "mpeg")) + ft = CFile::FILE_MP3; + else + ft = CFile::FILE_UNKNOWN; + } + else + { + struct stat st; + if (!fstat(fileno(fp), &st)) + in->MetaData.filesize = st.st_size; + + } + in->MetaData.type = ft; + + Status = CFfmpegDec::getInstance()->Decoder(fp, OutputFd, state, &in->MetaData, t, secondsToSkip ); +#endif + if ( fclose( fp ) == EOF ) { - fprintf( stderr, "Could not close file %s.\n", - in->Filename.c_str() ); + fprintf( stderr, "Could not close file %s.\n", in->Filename.c_str() ); } } return Status; } +bool CBaseDec::LookupMetaData(CAudiofile* const in) +{ + bool res = false; + metaDataMutex.lock(); + std::map::const_iterator it = metaDataCache.find(in->Filename); + if (it != metaDataCache.end()) { + *in = it->second; + res = true; + } + metaDataMutex.unlock(); + return res; +} + +void CBaseDec::CacheMetaData(CAudiofile* const in) +{ + metaDataMutex.lock(); + // FIXME: This places a limit on the cache size. A LRU scheme would be more appropriate. + if (metaDataCache.size() > 128) + metaDataCache.clear(); + metaDataCache[in->Filename] = *in; + metaDataMutex.unlock(); +} + +void CBaseDec::ClearMetaData() +{ + metaDataMutex.lock(); + metaDataCache.clear(); + metaDataMutex.unlock(); +} + bool CBaseDec::GetMetaDataBase(CAudiofile* const in, const bool nice) { - bool Status = true; + if (in->FileType == CFile::STREAM_AUDIO) + return true; + if (LookupMetaData(in)) + return true; + + bool Status = true; +#ifndef ENABLE_FFMPEGDEC if (in->FileType == CFile::FILE_MP3 || in->FileType == CFile::FILE_OGG - || in->FileType == CFile::FILE_WAV || in->FileType == CFile::FILE_CDR + || in->FileType == CFile::FILE_WAV || in->FileType == CFile::FILE_CDR #ifdef ENABLE_FLAC - || in->FileType == CFile::FILE_FLAC + || in->FileType == CFile::FILE_FLAC #endif ) +#endif { FILE* fp = fopen( in->Filename.c_str(), "r" ); if ( fp == NULL ) { fprintf( stderr, "Error opening file %s for meta data reading.\n", - in->Filename.c_str() ); + in->Filename.c_str() ); Status = false; } else { +#ifndef ENABLE_FFMPEGDEC if(in->FileType == CFile::FILE_MP3) { Status = CMP3Dec::getInstance()->GetMetaData(fp, nice, - &in->MetaData); + &in->MetaData); } else if(in->FileType == CFile::FILE_OGG) { Status = COggDec::getInstance()->GetMetaData(fp, nice, - &in->MetaData); + &in->MetaData); } else if(in->FileType == CFile::FILE_WAV) { Status = CWavDec::getInstance()->GetMetaData(fp, nice, - &in->MetaData); + &in->MetaData); } else if(in->FileType == CFile::FILE_CDR) { Status = CCdrDec::getInstance()->GetMetaData(fp, nice, - &in->MetaData); + &in->MetaData); } #ifdef ENABLE_FLAC else if (in->FileType == CFile::FILE_FLAC) @@ -195,68 +252,39 @@ bool CBaseDec::GetMetaDataBase(CAudiofile* const in, const bool nice) Status = FlacDec.GetMetaData(fp, nice, &in->MetaData); } #endif +#else + struct stat st; + if (!fstat(fileno(fp), &st)) + in->MetaData.filesize = st.st_size; + in->MetaData.type = in->FileType; + + CFfmpegDec d; + Status = d.GetMetaData(fp, nice, &in->MetaData); +#endif + if (Status) + CacheMetaData(in); if ( fclose( fp ) == EOF ) { fprintf( stderr, "Could not close file %s.\n", - in->Filename.c_str() ); + in->Filename.c_str() ); } } } +#ifndef ENABLE_FFMPEGDEC else { fprintf( stderr, "GetMetaDataBase: Filetype is not supported for " ); fprintf( stderr, "meta data reading.\n" ); Status = false; } +#endif return Status; } -bool CBaseDec::SetDSP(int soundfd, int fmt, unsigned int dsp_speed, unsigned int channels) -{ - bool crit_error=false; - - if (::ioctl(soundfd, SNDCTL_DSP_RESET)) - printf("reset failed\n"); - if(::ioctl(soundfd, SNDCTL_DSP_SETFMT, &fmt)) - printf("setfmt failed\n"); - if(::ioctl(soundfd, SNDCTL_DSP_CHANNELS, &channels)) - printf("channel set failed\n"); - if (dsp_speed != mSamplerate) - { - // mute audio to reduce pops when changing samplerate (avia_reset) - //bool was_muted = avs_mute(true); - if (::ioctl(soundfd, SNDCTL_DSP_SPEED, &dsp_speed)) - { - printf("speed set failed\n"); - crit_error=true; - } - else - { -#if 0 - unsigned int rs = 0; - ::ioctl(soundfd, SNDCTL_DSP_SPEED, &rs); - mSamplerate = dsp_speed; - // disable iec aka digi out (avia reset enables it again) - //g_Zapit->IecOff(); -#endif - } - //usleep(400000); - //if (!was_muted) - // avs_mute(false); - } -//printf("Debug: SNDCTL_DSP_RESET %d / SNDCTL_DSP_SPEED %d / SNDCTL_DSP_CHANNELS %d / SNDCTL_DSP_SETFMT %d\n", -// SNDCTL_DSP_RESET, SNDCTL_DSP_SPEED, SNDCTL_DSP_CHANNELS, SNDCTL_DSP_SETFMT); - return crit_error; -} - -bool CBaseDec::avs_mute(bool /*mute*/) -{ - return true; -} - void CBaseDec::Init() { mSamplerate=0; } +// vim:ts=4 diff --git a/src/driver/audiodec/basedec.h b/src/driver/audiodec/basedec.h index 5715e3e7f..7e5bd3c27 100644 --- a/src/driver/audiodec/basedec.h +++ b/src/driver/audiodec/basedec.h @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include class CBaseDec { @@ -51,10 +54,14 @@ public: static bool GetMetaDataBase(CAudiofile* const in, const bool nice); static void Init(); - CBaseDec(){}; - static bool SetDSP(int soundfd, int fmt, unsigned int dsp_speed, unsigned int channels); + CBaseDec() {}; + + static OpenThreads::Mutex metaDataMutex; + static std::map metaDataCache; + static void CacheMetaData(CAudiofile* const in); + static bool LookupMetaData(CAudiofile* const in); + static void ClearMetaData(); private: - static bool avs_mute(bool mute); unsigned static int mSamplerate; }; diff --git a/src/driver/audiodec/ffmpegdec.cpp b/src/driver/audiodec/ffmpegdec.cpp new file mode 100644 index 000000000..7f0bb32fb --- /dev/null +++ b/src/driver/audiodec/ffmpegdec.cpp @@ -0,0 +1,543 @@ +/* + Neutrino-GUI - DBoxII-Project + + Copyright (C) 2004 Zwen + Copyright (C) 2013 martii + + ffmpeg audio decoder layer + Homepage: http://forum.tuxbox.org/forum + + 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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include // UTF8 +#include "ffmpegdec.h" +extern "C" { +#include +#include +#include +} +#include + +#include +#include + +extern cAudio * audioDecoder; + +//#define FFDEC_DEBUG + +#define ProgName "FfmpegDec" + +#define COVERDIR "/tmp/cover" + +static OpenThreads::Mutex mutex; + +static int cover_count = 0; + +#if 0 +static void log_callback(void *, int, const char *format, va_list ap) +{ + vfprintf(stderr, format, ap); +} +#endif + +CFfmpegDec::CFfmpegDec(void) +{ + //av_log_set_callback(log_callback); + meta_data_valid = false; + buffer_size = 0x1000; + buffer = NULL; + avc = NULL; + avcodec_register_all(); + av_register_all(); +} + +CFfmpegDec::~CFfmpegDec(void) +{ + DeInit(); +} + +int CFfmpegDec::Read(void *buf, size_t buf_size) +{ + return (int) fread(buf, 1, buf_size, (FILE *) in); +} + +static int read_packet(void *opaque, uint8_t *buf, int buf_size) +{ + return ((CFfmpegDec *) opaque)->Read(buf, (size_t) buf_size); +} + +int64_t CFfmpegDec::Seek(int64_t offset, int whence) +{ + if (whence == AVSEEK_SIZE) + return (int64_t) -1; + + fseek((FILE *) in, (long) offset, whence); + return (int64_t) ftell((FILE *) in); +} + +static int64_t seek_packet(void *opaque, int64_t offset, int whence) +{ + return ((CFfmpegDec *) opaque)->Seek(offset, whence); +} + +bool CFfmpegDec::Init(void *_in, const CFile::FileType /* ft */) +{ + title = ""; + artist = ""; + date = ""; + album = ""; + genre = ""; + type_info = ""; + total_time = 0; + bitrate = 0; + +#ifdef FFDEC_DEBUG + av_log_set_level(AV_LOG_DEBUG); +#endif + + AVIOContext *avioc = NULL; + in = _in; + is_stream = fseek((FILE *)in, 0, SEEK_SET); + buffer = (unsigned char *) av_malloc(buffer_size); + if (!buffer) + return false; + avc = avformat_alloc_context(); + if (!avc) { + av_freep(&buffer); + return false; + } + + if (is_stream) + avc->probesize = 128 * 1024; + + av_opt_set_int(avc, "analyzeduration", 1000000, 0); + + avioc = avio_alloc_context (buffer, buffer_size, 0, this, read_packet, NULL, seek_packet); + if (!avioc) { + av_freep(&buffer); + avformat_free_context(avc); + return false; + } + avc->pb = avioc; + avc->flags |= AVFMT_FLAG_CUSTOM_IO|AVFMT_FLAG_KEEP_SIDE_DATA; + + AVInputFormat *input_format = NULL; + +#if 0 + switch (ft) { + case CFile::FILE_OGG: + input_format = av_find_input_format("ogg"); + break; + case CFile::FILE_MP3: + input_format = av_find_input_format("mp3"); + break; + case CFile::FILE_WAV: + input_format = av_find_input_format("wav"); + break; + case CFile::FILE_FLAC: + input_format = av_find_input_format("flac"); + break; + case CFile::FILE_AAC: + input_format = av_find_input_format("aac"); + break; + default: + break; + } +#endif + + int r = avformat_open_input(&avc, "", input_format, NULL); + if (r) { + char buf[200]; av_strerror(r, buf, sizeof(buf)); + fprintf(stderr, "%d %s %d: %s\n", __LINE__, __func__,r,buf); + if (avioc) + av_freep(avioc); + if (avc) { + avformat_close_input(&avc); + avformat_free_context(avc); + avc = NULL; + } + return false; + } + return true; +} + +void CFfmpegDec::DeInit(void) +{ + if (avc) { + avformat_close_input(&avc); +#if 0 + av_freep(&avc->pb); +#endif + avformat_free_context(avc); + avc = NULL; + } +// if (buffer) +// av_freep(&buffer); + in = NULL; +} + +CBaseDec::RetCode CFfmpegDec::Decoder(FILE *_in, int /*OutputFd*/, State* state, CAudioMetaData* _meta_data, time_t* time_played, unsigned int* secondsToSkip) +{ + in = _in; + RetCode Status=OK; + is_stream = fseek((FILE *)in, 0, SEEK_SET); + + if (!SetMetaData((FILE *)in, _meta_data, true)) { + DeInit(); + Status=DATA_ERR; + return Status; + } + + AVCodecContext *c = avc->streams[best_stream]->codec; + + mutex.lock(); + int r = avcodec_open2(c, codec, NULL); + mutex.unlock(); + if (r) + { + DeInit(); + Status=DATA_ERR; + return Status; + } + + SwrContext *swr = swr_alloc(); + if (!swr) { + mutex.lock(); + avcodec_close(c); + mutex.unlock(); + DeInit(); + Status=DATA_ERR; + return Status; + } + + mSampleRate = samplerate; + mChannels = av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO); +#if __BYTE_ORDER == __LITTLE_ENDIAN + audioDecoder->PrepareClipPlay(mChannels, mSampleRate, 16, 1); +#else + audioDecoder->PrepareClipPlay(mChannels, mSampleRate, 16, 0); +#endif + + AVFrame *frame = NULL; + AVPacket rpacket; + av_init_packet(&rpacket); + + av_opt_set_int(swr, "in_channel_layout", c->channel_layout, 0); + //av_opt_set_int(swr, "out_channel_layout", c->channel_layout, 0); + av_opt_set_int(swr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0); + av_opt_set_int(swr, "in_sample_rate", c->sample_rate, 0); + av_opt_set_int(swr, "out_sample_rate", c->sample_rate, 0); + av_opt_set_int(swr, "in_sample_fmt", c->sample_fmt, 0); + av_opt_set_int(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); + + swr_init(swr); + + uint8_t *outbuf = NULL; + int outsamples = 0; + int outsamples_max = 0; + + int64_t pts = 0, start_pts = 0, next_skip_pts = 0; + uint64_t skip = 0; + int seek_flags = 0; + + do + { + int actSecsToSkip = *secondsToSkip; + if (!is_stream && (actSecsToSkip || *state==FF || *state==REV) && avc->streams[best_stream]->time_base.num) { + if (!next_skip_pts || pts >= next_skip_pts) { + skip = avc->streams[best_stream]->time_base.den / avc->streams[best_stream]->time_base.num; + if (actSecsToSkip) + skip *= actSecsToSkip; + if (*state == REV) { + next_skip_pts = pts - skip; + pts = next_skip_pts - skip/4; + seek_flags = AVSEEK_FLAG_BACKWARD; + if (pts < start_pts) { + pts = start_pts; + *state = PAUSE; + } + } else { + pts += skip; + next_skip_pts = pts + skip/4; + seek_flags = 0; + } + av_seek_frame(avc, best_stream, pts, seek_flags); + skip = 0; + // if a custom value was set we only jump once + if (actSecsToSkip != 0) { + *state=PLAY; + *secondsToSkip = 0; + } + } + } + + while(*state==PAUSE && !is_stream) + usleep(10000); + + if (av_read_frame(avc, &rpacket)) { + Status=DATA_ERR; + break; + } + + if (rpacket.stream_index != best_stream) { + av_free_packet(&rpacket); + continue; + } + + AVPacket packet = rpacket; + while (packet.size > 0) { + int got_frame = 0; + if (!frame) { + if (!(frame = avcodec_alloc_frame())) { + Status=DATA_ERR; + break; + } + } else + avcodec_get_frame_defaults(frame); + + int len = avcodec_decode_audio4(c, frame, &got_frame, &packet); + if (len < 0) { + // skip frame + packet.size = 0; + avcodec_flush_buffers(c); + mutex.lock(); + avcodec_close(c); + avcodec_open2(c, codec, NULL); + mutex.unlock(); + continue; + } + if (got_frame && *state!=PAUSE) { + int out_samples; + outsamples = av_rescale_rnd(swr_get_delay(swr, c->sample_rate) + frame->nb_samples, + c->sample_rate, c->sample_rate, AV_ROUND_UP); + if (outsamples > outsamples_max) { + av_free(outbuf); + if (av_samples_alloc(&outbuf, &out_samples, mChannels, //c->channels, + frame->nb_samples, AV_SAMPLE_FMT_S16, 1) < 0) { + Status=WRITE_ERR; + packet.size = 0; + break; + } + outsamples_max = outsamples; + } + outsamples = swr_convert(swr, &outbuf, outsamples, + (const uint8_t **) &frame->data[0], frame->nb_samples); + int outbuf_size = av_samples_get_buffer_size(&out_samples, mChannels, //c->channels, + outsamples, AV_SAMPLE_FMT_S16, 1); + + if(audioDecoder->WriteClip((unsigned char*) outbuf, outbuf_size) != outbuf_size) + { + fprintf(stderr,"%s: PCM write error (%s).\n", ProgName, strerror(errno)); + Status=WRITE_ERR; + } + pts = av_frame_get_best_effort_timestamp(frame); + if (!start_pts) + start_pts = pts; + } + packet.size -= len; + packet.data += len; + } + if (time_played && avc->streams[best_stream]->time_base.den) + *time_played = (pts - start_pts) * avc->streams[best_stream]->time_base.num / avc->streams[best_stream]->time_base.den; + av_free_packet(&rpacket); + } while (*state!=STOP_REQ && Status==OK); + + audioDecoder->StopClip(); + meta_data_valid = false; + + swr_free(&swr); + av_free(outbuf); + av_free_packet(&rpacket); + avcodec_free_frame(&frame); + avcodec_close(c); + //av_free(avcc); + + DeInit(); + if (_meta_data->cover_temporary && !_meta_data->cover.empty()) { + _meta_data->cover_temporary = false; + unlink(_meta_data->cover.c_str()); + } + return Status; +} + +bool CFfmpegDec::GetMetaData(FILE *_in, const bool /*nice*/, CAudioMetaData* m) +{ + return SetMetaData(_in, m); +} + +CFfmpegDec* CFfmpegDec::getInstance() +{ + static CFfmpegDec* FfmpegDec = NULL; + if(FfmpegDec == NULL) + { + FfmpegDec = new CFfmpegDec(); + } + return FfmpegDec; +} + +bool CFfmpegDec::SetMetaData(FILE *_in, CAudioMetaData* m, bool save_cover) +{ + if (!meta_data_valid) + { + if (!Init(_in, (const CFile::FileType) m->type)) + return false; + + mutex.lock(); + int ret = avformat_find_stream_info(avc, NULL); + if (ret < 0) { + mutex.unlock(); + DeInit(); + printf("avformat_find_stream_info error %d\n", ret); + return false; + } + mutex.unlock(); + if (!is_stream) { + GetMeta(avc->metadata); + for(unsigned int i = 0; i < avc->nb_streams; i++) { + if (avc->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) + GetMeta(avc->streams[i]->metadata); + } + } + + //fseek((FILE *) in, 0, SEEK_SET); +#ifdef FFDEC_DEBUG + av_dump_format(avc, 0, "", 0); +#endif + + codec = NULL; + best_stream = av_find_best_stream(avc, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0); + + if (best_stream < 0) { + DeInit(); + return false; + } + + if (!codec) + codec = avcodec_find_decoder(avc->streams[best_stream]->codec->codec_id); + samplerate = avc->streams[best_stream]->codec->sample_rate; + mChannels = av_get_channel_layout_nb_channels(avc->streams[best_stream]->codec->channel_layout); + + std::stringstream ss; + + if (codec && codec->long_name != NULL) + type_info = codec->long_name; + else if(codec && codec->name != NULL) + type_info = codec->name; + else + type_info = "unknown"; + ss << " / " << mChannels << " channel" << ( mChannels > 1 ? "s" : ""); + type_info += ss.str(); + + bitrate = 0; + total_time = 0; + + if (avc->duration != int64_t(AV_NOPTS_VALUE)) + total_time = avc->duration / int64_t(AV_TIME_BASE); + printf("CFfmpegDec: format %s (%s) duration %ld\n", avc->iformat->name, type_info.c_str(), total_time); + + for(unsigned int i = 0; i < avc->nb_streams; i++) { + if (avc->streams[i]->codec->bit_rate > 0) + bitrate += avc->streams[i]->codec->bit_rate; + if (save_cover && (avc->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC)) { + mkdir(COVERDIR, 0755); + std::string cover(COVERDIR); + cover += "/" + to_string(cover_count++) + ".jpg"; + FILE *f = fopen(cover.c_str(), "wb"); + if (f) { + AVPacket *pkt = &avc->streams[i]->attached_pic; + fwrite(pkt->data, pkt->size, 1, f); + fclose(f); + m->cover = cover; + m->cover_temporary = true; + } + } + } + if(!total_time && m->filesize && bitrate) + total_time = 8 * m->filesize / bitrate; + + meta_data_valid = true; + m->changed = true; + } + if (!is_stream) { + m->title = title; + m->artist = artist; + m->date = date; + m->album = album; + m->genre = genre; + m->total_time = total_time; + } + m->type_info = type_info; + // make sure bitrate is set to prevent refresh metadata from gui, its a flag + m->bitrate = bitrate ? bitrate : 1; + m->samplerate = samplerate; + + return true; +} + +void CFfmpegDec::GetMeta(AVDictionary * metadata) +{ + AVDictionaryEntry *tag = NULL; + while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + if(!strcasecmp(tag->key,"Title")) { + if (title.empty()) { + title = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value); + title = trim(title); + } + continue; + } + if(!strcasecmp(tag->key,"Artist")) { + if (artist.empty()) { + artist = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value); + artist = trim(artist); + } + continue; + } + if(!strcasecmp(tag->key,"Year")) { + if (date.empty()) { + date = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value); + date = trim(date); + } + continue; + } + if(!strcasecmp(tag->key,"Album")) { + if (album.empty()) { + album = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value); + album = trim(album); + } + continue; + } + if(!strcasecmp(tag->key,"Genre")) { + if (genre.empty()) { + genre = isUTF8(tag->value) ? tag->value : convertLatin1UTF8(tag->value); + genre = trim(genre); + } + continue; + } + } +} diff --git a/src/driver/audiodec/ffmpegdec.h b/src/driver/audiodec/ffmpegdec.h new file mode 100644 index 000000000..7cafb6e85 --- /dev/null +++ b/src/driver/audiodec/ffmpegdec.h @@ -0,0 +1,86 @@ +/* + Neutrino-GUI - DBoxII-Project + + Copyright (C) 2004 Zwen + Copyright (C) 2013 martii + + ffmpeg audio decoder layer + Homepage: http://forum.tuxbox.org/forum + + 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. +*/ + + +#ifndef __FFMPEG_DEC__ +#define __FFMPEG_DEC__ + +#include +#include +#include +#include "basedec.h" +# if __WORDSIZE == 64 +# define UINT64_C(c) c ## UL +# else +# define UINT64_C(c) c ## ULL +# endif +extern "C" { +#include +} +#include +#include + +class CFfmpegDec : public CBaseDec +{ +private: + bool meta_data_valid; + bool is_stream; + + int mChannels; + int mSampleRate; + size_t buffer_size; + unsigned char *buffer; + AVFormatContext *avc; + AVCodec *codec; + int best_stream; + void *in; + bool Init(void *_in, const CFile::FileType ft); + void DeInit(void); + void GetMeta(AVDictionary * metadata); + + std::string title; + std::string artist; + std::string date; + std::string album; + std::string genre; + std::string type_info; + time_t total_time; + int bitrate; + int samplerate; + +public: + static CFfmpegDec* getInstance(); + virtual RetCode Decoder(FILE *, int, State*, CAudioMetaData* m, time_t* t, unsigned int* secondsToSkip); + bool GetMetaData(FILE *in, const bool nice, CAudioMetaData* m); + CFfmpegDec(); + ~CFfmpegDec(); + int Read(void *buf, size_t buf_size); + int64_t Seek(int64_t offset, int whence); + +protected: + virtual bool SetMetaData(FILE* in, CAudioMetaData* m, bool save_cover = false); +}; +#endif diff --git a/src/driver/audiodec/mp3dec.cpp b/src/driver/audiodec/mp3dec.cpp index 07a315fd9..1084e94b6 100644 --- a/src/driver/audiodec/mp3dec.cpp +++ b/src/driver/audiodec/mp3dec.cpp @@ -396,6 +396,7 @@ CBaseDec::RetCode CMP3Dec::Decoder(FILE *InputFp, const int /*OutputFd*/, #endif signed short ll, rr; + SaveCover(InputFp, meta_data); /* First the structures used by libmad must be initialized. */ mad_stream_init(&Stream); mad_frame_init(&Frame); @@ -925,6 +926,8 @@ q * next mad_frame_decode() invocation. (See the comments marked // fprintf(stderr,"%s: %lu frames decoded (%s).\n", // ProgName,FrameCount,Buffer); } + if (!meta_data->cover.empty()) + unlink(meta_data->cover.c_str()); /* That's the end of the world (in the H. G. Wells way). */ return Status; @@ -947,7 +950,7 @@ bool CMP3Dec::GetMetaData(FILE* in, const bool nice, CAudioMetaData* const m) { res = GetMP3Info(in, nice, m); GetID3(in, m); - SaveCover(in, m); + //SaveCover(in, m); } else { @@ -1396,6 +1399,7 @@ bool CMP3Dec::SaveCover(FILE * in, CAudioMetaData * const m) fwrite (data , 1 , size , pFile ); fclose (pFile); m->cover = cover.str().c_str(); + m->changed = true; } } break; diff --git a/src/driver/audiometadata.cpp b/src/driver/audiometadata.cpp index 92c6a78fc..043effd60 100644 --- a/src/driver/audiometadata.cpp +++ b/src/driver/audiometadata.cpp @@ -34,6 +34,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include // constructor @@ -42,6 +43,13 @@ CAudioMetaData::CAudioMetaData() clear(); } +// destructor +CAudioMetaData::~CAudioMetaData() +{ + if (cover_temporary && !cover.empty()) + unlink(cover.c_str()); +} + // copy constructor CAudioMetaData::CAudioMetaData( const CAudioMetaData& src ) : type( src.type ), type_info( src.type_info ), @@ -52,6 +60,7 @@ CAudioMetaData::CAudioMetaData( const CAudioMetaData& src ) hasInfoOrXingTag( src.hasInfoOrXingTag ), artist( src.artist ), title( src.title ), album( src.album ), sc_station( src.sc_station ), date( src.date ), genre( src.genre ), track( src.track ),cover(src.cover), + cover_temporary( false ), changed( src.changed ) { } @@ -84,11 +93,13 @@ void CAudioMetaData::operator=( const CAudioMetaData& src ) cover = src.cover; sc_station = src.sc_station; changed = src.changed; + changed = src.changed; + cover_temporary = false; } void CAudioMetaData::clear() { - type=NONE; + type=0; type_info.clear(); filesize=0; bitrate=0; @@ -105,6 +116,9 @@ void CAudioMetaData::clear() date.clear(); genre.clear(); track.clear(); + if (cover_temporary && !cover.empty()) + unlink(cover.c_str()); cover.clear(); + cover_temporary=false; changed=false; } diff --git a/src/driver/audiometadata.h b/src/driver/audiometadata.h index ba2a58e0c..5d93a4639 100644 --- a/src/driver/audiometadata.h +++ b/src/driver/audiometadata.h @@ -44,6 +44,8 @@ class CAudioMetaData public: // constructor CAudioMetaData(); + // destructor + ~CAudioMetaData(); // copy constructor CAudioMetaData( const CAudioMetaData& src ); // assignment operator @@ -59,7 +61,7 @@ public: WAV, FLAC }; - AudioType type; + int type; std::string type_info; long filesize; /* filesize in bits (for mp3: without leading id3 tag) */ @@ -85,6 +87,7 @@ public: std::string genre; std::string track; std::string cover; + bool cover_temporary; bool changed; }; #endif /* __AUDIO_METADATA__ */ diff --git a/src/driver/audioplay.cpp b/src/driver/audioplay.cpp index 5dea17d17..4359956ba 100644 --- a/src/driver/audioplay.cpp +++ b/src/driver/audioplay.cpp @@ -42,6 +42,7 @@ #include #include #include +#include // UTF8 void CAudioPlayer::stop() { @@ -163,30 +164,37 @@ void CAudioPlayer::init() CBaseDec::Init(); state = CBaseDec::STOP; thrPlay = 0; + m_SecondsToSkip = 0; } void CAudioPlayer::sc_callback(void *arg) { bool changed=false; CSTATE *stat = (CSTATE*)arg; - if(m_Audiofile.MetaData.artist != stat->artist) + + const std::string artist = isUTF8(stat->artist) ? stat->artist : convertLatin1UTF8(stat->artist); + const std::string title = isUTF8(stat->title) ? stat->title : convertLatin1UTF8(stat->title); + const std::string station = isUTF8(stat->station) ? stat->station : convertLatin1UTF8(stat->station); + const std::string genre = isUTF8(stat->genre) ? stat->artist : convertLatin1UTF8(stat->genre); + + if(m_Audiofile.MetaData.artist != artist) { - m_Audiofile.MetaData.artist = stat->artist; + m_Audiofile.MetaData.artist = artist; changed=true; } - if (m_Audiofile.MetaData.title != stat->title) + if (m_Audiofile.MetaData.title != title) { - m_Audiofile.MetaData.title = stat->title; + m_Audiofile.MetaData.title = title; changed=true; } - if (m_Audiofile.MetaData.sc_station != stat->station) + if (m_Audiofile.MetaData.sc_station != station) { - m_Audiofile.MetaData.sc_station = stat->station; + m_Audiofile.MetaData.sc_station = station; changed=true; } - if (m_Audiofile.MetaData.genre != stat->genre) + if (m_Audiofile.MetaData.genre != genre) { - m_Audiofile.MetaData.genre = stat->genre; + m_Audiofile.MetaData.genre = genre; changed=true; } if(changed) @@ -203,6 +211,7 @@ void CAudioPlayer::clearFileData() m_Audiofile.clear(); m_played_time=0; m_sc_buffered=0; + m_SecondsToSkip = 0; } CAudioMetaData CAudioPlayer::getMetaData() diff --git a/src/driver/audioplay.h b/src/driver/audioplay.h index e56516a97..651acead5 100644 --- a/src/driver/audioplay.h +++ b/src/driver/audioplay.h @@ -37,9 +37,7 @@ class CAudioPlayer private: time_t m_played_time; int m_sc_buffered; - FILE *soundfd; pthread_t thrPlay; - FILE *fp; CBaseDec::State state; static void* PlayThread(void*); void clearFileData(); @@ -47,7 +45,6 @@ private: protected: CAudiofile m_Audiofile; - bool SetDSP(int soundfd, int fmt, unsigned int dsp_speed, unsigned int channels); public: static CAudioPlayer* getInstance(); diff --git a/src/driver/file.cpp b/src/driver/file.cpp index 775332ee6..8bbb099b5 100644 --- a/src/driver/file.cpp +++ b/src/driver/file.cpp @@ -42,9 +42,9 @@ /* ATTENTION: the array file_extension_list MUST BE SORTED ASCENDING (cf. sort, man bsearch) - otherwise bsearch will not work correctly! */ const char * const file_extension_list[] = { - "asf", "avi", "bmp", "cdr", "crw", - "flac", "gif", "imu", "jpeg", "jpg", - "m2a", "m3u", "mkv", "mp2", "mp3", + "aac", "asf", "avi", "bmp", "cdr", "crw", + "dts", "flac", "gif", "imu", "jpeg", "jpg", + "m2a", "m3u", "m4a", "mkv", "mp2", "mp3", "mpa", "ogg", "pls", "png", "sh", "txt", "url", "wav", "xml" }; @@ -52,9 +52,9 @@ const char * const file_extension_list[] = const CFile::FileType file_type_list[] = { - CFile::FILE_ASF , CFile::FILE_AVI , CFile::FILE_PICTURE , CFile::FILE_CDR , CFile::FILE_PICTURE , - CFile::FILE_FLAC , CFile::FILE_PICTURE , CFile::STREAM_PICTURE, CFile::FILE_PICTURE , CFile::FILE_PICTURE , - CFile::FILE_MP3 , CFile::FILE_PLAYLIST , CFile::FILE_MKV , CFile::FILE_MP3 , CFile::FILE_MP3 , + CFile::FILE_AAC , CFile::FILE_ASF , CFile::FILE_AVI , CFile::FILE_PICTURE , CFile::FILE_CDR , CFile::FILE_PICTURE , + CFile::FILE_WAV , CFile::FILE_FLAC , CFile::FILE_PICTURE , CFile::STREAM_PICTURE, CFile::FILE_PICTURE , CFile::FILE_PICTURE , + CFile::FILE_MP3 , CFile::FILE_PLAYLIST , CFile::FILE_AAC , CFile::FILE_MKV , CFile::FILE_MP3 , CFile::FILE_MP3 , CFile::FILE_MP3 , CFile::FILE_OGG , CFile::FILE_PLAYLIST, CFile::FILE_PICTURE , CFile::FILE_TEXT , CFile::FILE_TEXT , CFile::STREAM_AUDIO , CFile::FILE_WAV , CFile::FILE_XML }; diff --git a/src/driver/file.h b/src/driver/file.h index 49cdaa04d..c807d1bae 100644 --- a/src/driver/file.h +++ b/src/driver/file.h @@ -56,6 +56,7 @@ public: enum FileType { FILE_UNKNOWN = 0, + FILE_AAC, FILE_AVI, FILE_ASF, FILE_DIR, diff --git a/src/driver/netfile.cpp b/src/driver/netfile.cpp index 75a79f9c7..4cb2bf7a2 100644 --- a/src/driver/netfile.cpp +++ b/src/driver/netfile.cpp @@ -543,7 +543,7 @@ int request_file(URL *url) #define getHeaderVal(a,b) { \ char *_ptr; \ - _ptr = strstr(header, a); \ + _ptr = strcasestr(header, a); \ if(_ptr) \ { \ _ptr = strchr(_ptr, ':'); \ @@ -553,7 +553,7 @@ int request_file(URL *url) #define getHeaderStr(a,b) { \ char *_ptr; \ - _ptr = strstr(header, a); \ + _ptr = strcasestr(header, a); \ if(_ptr) \ { \ unsigned int i; \ @@ -570,14 +570,13 @@ void readln(int fd, char *buf) *buf = 0; } -int parse_response(URL *url, void *opt, CSTATE *state) +int parse_response(URL *url, void * /*opt*/, CSTATE *state) { char header[2049], /*str[255]*/ str[2048]; // combined with 2nd local str from id3 part char *ptr, chr=0, lastchr=0; int hlen = 0, response; int meta_interval = 0, rval; int fd = url->fd; - ID3 *id3 = (ID3*)opt; memset(header, 0, 2048); ptr = header; @@ -671,6 +670,8 @@ int parse_response(URL *url, void *opt, CSTATE *state) getHeaderStr("icy-url:", state->station_url); getHeaderVal("icy-br:", state->bitrate); } +#if 0 + ID3 *id3 = (ID3*)opt; /********************* dirty hack **********************/ /* we parse the stream header sent by the server and */ /* build based on this information an arteficial id3 */ @@ -755,6 +756,7 @@ int parse_response(URL *url, void *opt, CSTATE *state) id3->len = 14 + cnt; } +#endif return meta_interval; } diff --git a/src/driver/pictureviewer/pictureviewer.h b/src/driver/pictureviewer/pictureviewer.h index 0c6550160..71d8d256f 100644 --- a/src/driver/pictureviewer/pictureviewer.h +++ b/src/driver/pictureviewer/pictureviewer.h @@ -50,7 +50,7 @@ class CPictureViewer COLOR=2 }; CPictureViewer(); - ~CPictureViewer(); + virtual~CPictureViewer(); bool ShowImage(const std::string & filename, bool unscaled=false); bool DecodeImage(const std::string & name, bool showBusySign=false, bool unscaled=false); bool DisplayNextImage(); diff --git a/src/driver/scanepg.cpp b/src/driver/scanepg.cpp index 954645d64..beecd5679 100644 --- a/src/driver/scanepg.cpp +++ b/src/driver/scanepg.cpp @@ -38,6 +38,8 @@ #include #include +#define EPG_RESCAN_TIME (24*60*60) + extern CBouquetList * bouquetList; extern CBouquetList * TVfavList; @@ -45,6 +47,8 @@ CEpgScan::CEpgScan() { current_mode = 0; standby = false; + rescan_timer = 0; + scan_in_progress = false; Clear(); } @@ -108,7 +112,6 @@ void CEpgScan::AddTransponders() current_mode = g_settings.epg_scan; Clear(); } - /* TODO: add interval check to clear scanned ? */ int mode = CNeutrinoApp::getInstance()->GetChannelMode(); if ((g_settings.epg_scan == 1) || (mode == LIST_MODE_FAV)) { @@ -129,45 +132,69 @@ void CEpgScan::AddTransponders() } } -void CEpgScan::StartStandby() +void CEpgScan::Start(bool instandby) { if (!g_settings.epg_scan) return; + if (!standby && (CFEManager::getInstance()->getEnabledCount() <= 1)) + return; live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); AddTransponders(); - INFO("starting standby scan, scan map size: %d", scanmap.size()); - if (!scanmap.empty()) { - standby = true; + standby = instandby; + //g_RCInput->killTimer(rescan_timer); + INFO("starting %s scan, scanning %d, scan map size: %d", standby ? "standby" : "live", scan_in_progress, scanmap.size()); + if (standby || !scan_in_progress) Next(); - } } -void CEpgScan::StopStandby() +void CEpgScan::Stop() { if (!g_settings.epg_scan) return; - INFO("stopping standby scan..."); - standby = false; - CZapit::getInstance()->SetCurrentChannelID(live_channel_id); + INFO("stopping %s scan...", standby ? "standby" : "live"); + if (standby) { + standby = false; + CZapit::getInstance()->SetCurrentChannelID(live_channel_id); + } } int CEpgScan::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data) { + if ((msg == NeutrinoMessages::EVT_TIMER) && (data == rescan_timer)) { + INFO("rescan timer in %s mode, scanning %d", standby ? "standby" : "live", scan_in_progress); + scanned.clear(); + Clear(); + g_RCInput->killTimer(rescan_timer); + if (standby || (CFEManager::getInstance()->getEnabledCount() > 1)) { + if (standby) + g_Zapit->setStandby(false); + Start(standby); + } + return messages_return::handled; + } if (!g_settings.epg_scan || (!standby && (CFEManager::getInstance()->getEnabledCount() <= 1))) { - if ((msg == NeutrinoMessages::EVT_EIT_COMPLETE) || (msg == NeutrinoMessages::EVT_BACK_ZAP_COMPLETE)) - return messages_return::handled; - return messages_return::unhandled; + int ret = messages_return::handled; + if (msg == NeutrinoMessages::EVT_EIT_COMPLETE) + scan_in_progress = false; + else if (msg == NeutrinoMessages::EVT_BACK_ZAP_COMPLETE) + scan_in_progress = true; + else + ret = messages_return::unhandled; + return ret; } CZapitChannel * newchan; - if(msg == NeutrinoMessages::EVT_ZAP_COMPLETE) { + if (msg == NeutrinoMessages::EVT_ZAP_COMPLETE) { + /* live channel changed, block scan channel change by timer */ + scan_in_progress = true; AddTransponders(); INFO("EVT_ZAP_COMPLETE, scan map size: %d\n", scanmap.size()); return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_EIT_COMPLETE) { + scan_in_progress = false; t_channel_id chid = *(t_channel_id *)data; newchan = CServiceManager::getInstance()->FindChannel(chid); if (newchan) { @@ -180,6 +207,7 @@ int CEpgScan::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data) return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_BACK_ZAP_COMPLETE) { + scan_in_progress = true; t_channel_id chid = *(t_channel_id *)data; INFO("EVT_BACK_ZAP_COMPLETE [" PRINTF_CHANNEL_ID_TYPE "]", chid); if (next_chid) { @@ -208,10 +236,14 @@ void CEpgScan::EnterStandby() { if (standby) { CZapit::getInstance()->SetCurrentChannelID(live_channel_id); - CZapit::getInstance()->EnablePlayback(true); + //CZapit::getInstance()->EnablePlayback(true); g_Zapit->setStandby(true); g_Sectionsd->setPauseScanning(true); } + //g_RCInput->killTimer(rescan_timer); + if (rescan_timer == 0) + rescan_timer = g_RCInput->addTimer(EPG_RESCAN_TIME*1000ULL*1000ULL, true); + INFO("rescan timer id %d", rescan_timer); } void CEpgScan::Next() diff --git a/src/driver/scanepg.h b/src/driver/scanepg.h index 9625b2cb7..07057494e 100644 --- a/src/driver/scanepg.h +++ b/src/driver/scanepg.h @@ -38,6 +38,9 @@ class CEpgScan t_channel_id next_chid; t_channel_id live_channel_id; std::set scanned; + uint32_t rescan_timer; + bool scan_in_progress; + void AddBouquet(CChannelList * clist); bool AddFavorites(); void AddTransponders(); @@ -51,8 +54,8 @@ class CEpgScan int handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data); void Next(); void Clear(); - void StartStandby(); - void StopStandby(); + void Start(bool instandby = false); + void Stop(); bool Running(); }; diff --git a/src/eitd/sectionsd.cpp b/src/eitd/sectionsd.cpp index c8695403f..27b11bc84 100644 --- a/src/eitd/sectionsd.cpp +++ b/src/eitd/sectionsd.cpp @@ -68,7 +68,8 @@ static bool notify_complete = false; #define HOUSEKEEPING_SLEEP (5 * 60) // sleep 5 minutes //#define HOUSEKEEPING_SLEEP (30) // FIXME 1 min for testing /* period to clean cached sections and force restart sections read */ -#define META_HOUSEKEEPING (24 * 60 * 60) / HOUSEKEEPING_SLEEP // meta housekeeping after XX housekeepings - every 24h - +#define META_HOUSEKEEPING_COUNT (24 * 60 * 60) / HOUSEKEEPING_SLEEP // meta housekeeping after XX housekeepings - every 24h - +#define STANDBY_HOUSEKEEPING_COUNT (60 * 60) / HOUSEKEEPING_SLEEP // Timeout bei tcp/ip connections in ms #define READ_TIMEOUT_IN_SECONDS 2 @@ -612,6 +613,7 @@ static void removeOldEvents(const long seconds) time_t zeit = time(NULL); writeLockEvents(); + unsigned total_events = mySIeventsOrderUniqueKey.size(); MySIeventsOrderFirstEndTimeServiceIDEventUniqueKey::iterator e = mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.begin(); @@ -633,6 +635,9 @@ static void removeOldEvents(const long seconds) deleteEvent(*i); unlockEvents(); + readLockEvents(); + xprintf("[sectionsd] Removed %d old events (%d left), zap detected %d.\n", (int)(total_events - mySIeventsOrderUniqueKey.size()), (int)mySIeventsOrderUniqueKey.size(), messaging_zap_detected); + unlockEvents(); return; } @@ -854,6 +859,9 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng #endif #endif scanning = 0; + writeLockMessaging(); + messaging_zap_detected = false; + unlockMessaging(); } else if (!pause && !scanning) { @@ -877,6 +885,7 @@ static void commandPauseScanning(int connfd, char *data, const unsigned dataLeng writeLockMessaging(); messaging_have_CN = 0x00; messaging_got_CN = 0x00; + messaging_zap_detected = true; unlockMessaging(); scanning = 1; @@ -904,6 +913,9 @@ static void commandserviceChanged(int connfd, char *data, const unsigned dataLen if (cmd->dnum) { /* dont wakeup EIT, if we have max events allready */ if (max_events == 0 || (mySIeventsOrderUniqueKey.size() < max_events)) { + writeLockMessaging(); + messaging_zap_detected = true; + unlockMessaging(); threadEIT.setDemux(cmd->dnum); threadEIT.setCurrentService(uniqueServiceKey); } @@ -2015,14 +2027,14 @@ static void print_meminfo(void) //--------------------------------------------------------------------- static void *houseKeepingThread(void *) { - int count = 0; + int count = 0, scount = 0; dprintf("housekeeping-thread started.\n"); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); while (!sectionsd_stop) { - if (count == META_HOUSEKEEPING) { + if (count == META_HOUSEKEEPING_COUNT) { dprintf("meta housekeeping - deleting all transponders, services, bouquets.\n"); deleteSIexceptEPG(); count = 0; @@ -2037,53 +2049,28 @@ static void *houseKeepingThread(void *) if (sectionsd_stop) break; - while (!scanning) { - sleep(1); // wait for streaming to end... - if (sectionsd_stop) - break; + if (!scanning) { + scount++; + if (scount < STANDBY_HOUSEKEEPING_COUNT) + continue; } + scount = 0; dprintf("housekeeping.\n"); - // TODO: maybe we need to stop scanning here?... - - readLockEvents(); - - unsigned anzEventsAlt = mySIeventsOrderUniqueKey.size(); - dprintf("before removeoldevents\n"); - unlockEvents(); - removeOldEvents(oldEventsAre); // alte Events - dprintf("after removeoldevents\n"); - readLockEvents(); - printf("[sectionsd] Removed %d old events (%d left).\n", (int)(anzEventsAlt - mySIeventsOrderUniqueKey.size()), (int)mySIeventsOrderUniqueKey.size()); - if (mySIeventsOrderUniqueKey.size() != anzEventsAlt) - { - print_meminfo(); - dprintf("Removed %d old events.\n", (int)(anzEventsAlt - mySIeventsOrderUniqueKey.size())); - } - anzEventsAlt = mySIeventsOrderUniqueKey.size(); - unlockEvents(); readLockEvents(); - if (mySIeventsOrderUniqueKey.size() != anzEventsAlt) - { - print_meminfo(); - dprintf("Removed %d waste events.\n", (int)(anzEventsAlt - mySIeventsOrderUniqueKey.size())); - } - dprintf("Number of sptr events (event-ID): %u\n", (unsigned)mySIeventsOrderUniqueKey.size()); dprintf("Number of sptr events (service-id, start time, event-id): %u\n", (unsigned)mySIeventsOrderServiceUniqueKeyFirstStartTimeEventUniqueKey.size()); dprintf("Number of sptr events (end time, service-id, event-id): %u\n", (unsigned)mySIeventsOrderFirstEndTimeServiceIDEventUniqueKey.size()); dprintf("Number of sptr nvod events (event-ID): %u\n", (unsigned)mySIeventsNVODorderUniqueKey.size()); dprintf("Number of cached meta-services: %u\n", (unsigned)mySIeventUniqueKeysMetaOrderServiceUniqueKey.size()); - unlockEvents(); print_meminfo(); count++; - } // for endlos dprintf("housekeeping-thread ended.\n"); diff --git a/src/gui/audioplayer.cpp b/src/gui/audioplayer.cpp index d267edfd6..184623686 100644 --- a/src/gui/audioplayer.cpp +++ b/src/gui/audioplayer.cpp @@ -80,21 +80,10 @@ extern CPictureViewer * g_PicViewer; #include #include -#if 0 -#ifdef ENABLE_LIRC -#include -#endif - -#if 1 -#include -#include -#include -#define ADAP "/dev/dvb/adapter0" -#define ADEC ADAP "/audio0" -#define VDEC ADAP "/video0" -#define DMX ADAP "/demux0" -#define DVR ADAP "/dvr0" -#endif +#include +#include +#if LIBCURL_VERSION_NUM < 0x071507 +#include #endif #include @@ -103,7 +92,7 @@ extern cVideo * videoDecoder; #define AUDIOPLAYERGUI_SMSKEY_TIMEOUT 1000 #define SHOW_FILE_LOAD_LIMIT 50 -//#define AUDIOPLAYER_TIME_DEBUG +#define AUDIOPLAYER_TIME_DEBUG // check if files to be added are already in the playlist #define AUDIOPLAYER_CHECK_FOR_DUPLICATES @@ -136,17 +125,6 @@ void CAudiofileExt::operator=(const CAudiofileExt& src) firstChar = src.firstChar; } - -//------------------------------------------------------------------------ - - -#include -#include - -#if LIBCURL_VERSION_NUM < 0x071507 -#include -#endif - struct MemoryStruct { char *memory; size_t size; @@ -221,28 +199,26 @@ void CAudioPlayerGui::Init(void) audiofilefilter.addFilter("m3u"); audiofilefilter.addFilter("ogg"); audiofilefilter.addFilter("wav"); -#ifdef ENABLE_FLAC audiofilefilter.addFilter("flac"); +#ifdef ENABLE_FFMPEGDEC + audiofilefilter.addFilter("aac"); + audiofilefilter.addFilter("dts"); + audiofilefilter.addFilter("m4a"); #endif } m_SMSKeyInput.setTimeout(AUDIOPLAYERGUI_SMSKEY_TIMEOUT); } -//------------------------------------------------------------------------ - CAudioPlayerGui::~CAudioPlayerGui() { m_playlist.clear(); m_radiolist.clear(); m_filelist.clear(); m_title2Pos.clear(); -// g_Zapit->setStandby (false); -// g_Sectionsd->setPauseScanning (false); delete dline; delete ibox; } -//------------------------------------------------------------------------ int CAudioPlayerGui::exec(CMenuTarget* parent, const std::string &actionKey) { @@ -300,9 +276,7 @@ int CAudioPlayerGui::exec(CMenuTarget* parent, const std::string &actionKey) m_screensaver=false; if (parent) - { parent->hide(); - } bool usedBackground = m_frameBuffer->getuseBackground(); if (usedBackground) @@ -349,8 +323,6 @@ int CAudioPlayerGui::exec(CMenuTarget* parent, const std::string &actionKey) return res; } -//------------------------------------------------------------------------ - int CAudioPlayerGui::show() { neutrino_msg_t msg; @@ -377,11 +349,10 @@ int CAudioPlayerGui::show() updateTimes(); + // stop if mode was changed in another thread if (CNeutrinoApp::getInstance()->getMode() != NeutrinoMessages::mode_audio) - { - // stop if mode was changed in another thread loop = false; - } + if ((m_state != CAudioPlayerGui::STOP) && (CAudioPlayer::getInstance()->getState() == CBaseDec::STOP) && (!m_playlist.empty())) @@ -468,9 +439,7 @@ int CAudioPlayerGui::show() else if (!m_playlist.empty()) { if (m_selected < m_listmaxshow) - { m_selected = m_playlist.size()-1; - } else m_selected -= m_listmaxshow; m_liststart = (m_selected / m_listmaxshow) * m_listmaxshow; @@ -518,17 +487,7 @@ int CAudioPlayerGui::show() m_selected -= step; if ((prevselected-step) < 0) m_selected = m_playlist.size()-1; -#if 0 - if (m_selected == 0) - { - m_selected = m_playlist.size()-1; - } - else - { - m_selected--; - } -#endif - paintItem(prevselected - m_liststart); + unsigned int oldliststart = m_liststart; m_liststart = (m_selected/m_listmaxshow)*m_listmaxshow; if (oldliststart != m_liststart) @@ -537,6 +496,7 @@ int CAudioPlayerGui::show() } else { + paintItem(prevselected - m_liststart); paintItem(m_selected - m_liststart); } } @@ -557,7 +517,6 @@ int CAudioPlayerGui::show() } //m_selected = (m_selected + 1) % m_playlist.size(); - paintItem(prevselected - m_liststart); unsigned int oldliststart = m_liststart; m_liststart = (m_selected/m_listmaxshow)*m_listmaxshow; if (oldliststart != m_liststart) @@ -566,6 +525,7 @@ int CAudioPlayerGui::show() } else { + paintItem(prevselected - m_liststart); paintItem(m_selected - m_liststart); } } @@ -585,13 +545,10 @@ int CAudioPlayerGui::show() { if (!m_playlist.empty()) { - //xx CPlayList::iterator p = m_playlist.begin()+selected; removeFromPlaylist(m_selected); if ((int)m_selected == m_current) - { m_current--; - //stop(); // Stop if song is deleted, next song will be startet automat. - } + if (m_selected >= m_playlist.size()) m_selected = m_playlist.empty() ? m_playlist.size() : m_playlist.size() - 1; update = true; @@ -708,9 +665,9 @@ int CAudioPlayerGui::show() //InputSelector.addItem(GenericMenuSeparator); hide(); InputSelector.exec(NULL, ""); - + delete InetRadioInputChanger; - + if (select >= 0) old_select = select; switch (select) { @@ -863,9 +820,6 @@ int CAudioPlayerGui::show() CVFD::getInstance()->setMode(CVFD::MODE_AUDIO); paintLCD(); update = true; - //pushback key if... - //g_RCInput->postMsg( msg, data ); - //loop = false; } #endif else if (msg == NeutrinoMessages::CHANGEMODE) @@ -880,13 +834,13 @@ int CAudioPlayerGui::show() msg == NeutrinoMessages::ZAPTO || msg == NeutrinoMessages::STANDBY_ON || msg == NeutrinoMessages::SHUTDOWN || - msg == NeutrinoMessages::SLEEPTIMER) + ((msg == NeutrinoMessages::SLEEPTIMER) && !data)) { if(msg != NeutrinoMessages::RECORD_START ) ret = menu_return::RETURN_EXIT_ALL; // Exit for Record/Zapto Timers loop = false; - + g_RCInput->postMsg(msg, data); } else if (msg == NeutrinoMessages::EVT_TIMER) @@ -966,8 +920,11 @@ bool CAudioPlayerGui::clearPlaylist(void) bool result = false; CAudioPlayList::const_iterator it; - for (it = m_playlist.begin(); it!=m_playlist.end(); ++it) +#if 0 + for (it = m_playlist.begin(); it!=m_playlist.end(); ++it) { unlink(it->MetaData.cover.c_str()); + } +#endif if (!(m_playlist.empty())) { @@ -994,9 +951,8 @@ bool CAudioPlayerGui::shufflePlaylist(void) std::random_shuffle((m_current != 0) ? m_playlist.begin() : m_playlist.begin() + 1, m_playlist.end(), rnd); if (m_select_title_by_name) - { buildSearchTree(); - } + m_playlistHasChanged = true; m_selected = 0; @@ -1005,7 +961,8 @@ bool CAudioPlayerGui::shufflePlaylist(void) return(result); } -void CAudioPlayerGui::addUrl2Playlist(const char *url, const char *name, const time_t bitrate) { +void CAudioPlayerGui::addUrl2Playlist(const char *url, const char *name, const time_t bitrate) +{ CAudiofileExt mp3( url, CFile::STREAM_AUDIO ); // tmp = tmp.substr(0,tmp.length()-4); //remove .url //printf("[addUrl2Playlist], name = %s, url = %s\n", name, url); @@ -1020,12 +977,12 @@ void CAudioPlayerGui::addUrl2Playlist(const char *url, const char *name, const t else mp3.MetaData.total_time = 0; - if (url[0] != '#') { + if (url[0] != '#') addToPlaylist(mp3); - } } -void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, const time_t tim) { +void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, const time_t tim) +{ CURL *curl_handle; struct MemoryStruct chunk; const long int GET_PLAYLIST_TIMEOUT = 2; @@ -1111,7 +1068,6 @@ void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, cons curl_global_cleanup(); } - void CAudioPlayerGui::readDir_ic(void) { const std::string icecasturl = "http://dir.xiph.org/yp.xml"; @@ -1306,9 +1262,10 @@ bool CAudioPlayerGui::openFilebrowser(void) || (files->getType() == CFile::FILE_OGG) || (files->getType() == CFile::FILE_MP3) || (files->getType() == CFile::FILE_WAV) -#ifdef ENABLE_FLAC - || (files->getType() == CFile::FILE_FLAC) +#ifdef ENABLE_FFMPEGDEC + || (files->getType() == CFile::FILE_AAC) #endif + || (files->getType() == CFile::FILE_FLAC) ) { CAudiofileExt audiofile(files->Name, @@ -1399,9 +1356,7 @@ bool CAudioPlayerGui::openFilebrowser(void) || fileType == CFile::FILE_MP3 || fileType == CFile::FILE_OGG || fileType == CFile::FILE_WAV -#ifdef ENABLE_FLAC || fileType == CFile::FILE_FLAC -#endif ) { CAudiofileExt audioFile(filename,fileType); @@ -1422,21 +1377,22 @@ bool CAudioPlayerGui::openFilebrowser(void) else if (files->getType() == CFile::FILE_XML) { if (!files->Name.empty()) - { scanXmlFile(files->Name); - } } } if (m_select_title_by_name) - { buildSearchTree(); - } + #ifdef AUDIOPLAYER_TIME_DEBUG timeval end; gettimeofday(&end,NULL); printf("adding %ld files took: ",maxProgress+1); printTimevalDiff(start,end); #endif + //store last dir + if( (sizeof(g_settings.network_nfs_audioplayerdir)) > m_Path.size() && (strcmp(g_settings.network_nfs_audioplayerdir,m_Path.c_str()) != 0)) + strcpy(g_settings.network_nfs_audioplayerdir,m_Path.c_str()); + result = true; } CVFD::getInstance()->setMode(CVFD::MODE_AUDIO); @@ -1448,8 +1404,6 @@ bool CAudioPlayerGui::openFilebrowser(void) return ( result); } -//------------------------------------------------------------------------ - bool CAudioPlayerGui::openSCbrowser(void) { bool result = false; @@ -1503,9 +1457,7 @@ bool CAudioPlayerGui::openSCbrowser(void) g_RCInput->getMsg(&msg, &data, 0); } if (m_select_title_by_name) - { buildSearchTree(); - } #ifdef AUDIOPLAYER_TIME_DEBUG timeval end; gettimeofday(&end,NULL); @@ -1523,9 +1475,6 @@ bool CAudioPlayerGui::openSCbrowser(void) return ( result); } -//------------------------------------------------------------------------ - - void CAudioPlayerGui::hide() { // printf("hide(){\n"); @@ -1539,8 +1488,6 @@ void CAudioPlayerGui::hide() } } -//------------------------------------------------------------------------ - void CAudioPlayerGui::paintItem(int pos) { if (!m_show_playlist) @@ -1602,14 +1549,6 @@ void CAudioPlayerGui::paintItem(int pos) if ((pos + m_liststart) < m_playlist.size()) { - if (m_playlist[pos + m_liststart].FileType != CFile::STREAM_AUDIO && - !m_playlist[pos + m_liststart].MetaData.bitrate) - { - // id3tag noch nicht geholt - GetMetaData(m_playlist[pos + m_liststart]); - if (m_state != CAudioPlayerGui::STOP && !g_settings.audioplayer_highprio) - usleep(100*1000); - } char sNr[20]; sprintf(sNr, "%2d : ", pos + m_liststart + 1); std::string tmp = sNr; @@ -1629,17 +1568,13 @@ void CAudioPlayerGui::paintItem(int pos) if ((pos + m_liststart) == m_selected) { if (m_state == CAudioPlayerGui::STOP) - { CVFD::getInstance()->showAudioTrack(m_playlist[pos + m_liststart].MetaData.artist, m_playlist[pos + m_liststart].MetaData.title, m_playlist[pos + m_liststart].MetaData.album); - } } } } -//--------------playlist---------------------------------------------------------- - void CAudioPlayerGui::paintHead() { if (!m_show_playlist || m_screensaver) @@ -1659,7 +1594,6 @@ void CAudioPlayerGui::paintHead() header.paint(CC_SAVE_SCREEN_NO); } -//------------------------------------------------------------------------ const struct button_label AudioPlayerButtons[][4] = { { @@ -1705,19 +1639,18 @@ const struct button_label AudioPlayerButtons[][4] = { NEUTRINO_ICON_BUTTON_BLUE , LOCALE_INETRADIO_NAME }, }, }; -//------------------------------------------------------------------------ void CAudioPlayerGui::paintFoot() { if (m_screensaver) return; -const struct button_label ScondLineButtons[3] = -{ - { NEUTRINO_ICON_BUTTON_OKAY , LOCALE_AUDIOPLAYER_PLAY }, - { NEUTRINO_ICON_BUTTON_HELP , LOCALE_AUDIOPLAYER_KEYLEVEL }, - { NEUTRINO_ICON_BUTTON_INFO , LOCALE_PICTUREVIEWER_HEAD}, -}; + const struct button_label ScondLineButtons[3] = + { + { NEUTRINO_ICON_BUTTON_OKAY , LOCALE_AUDIOPLAYER_PLAY }, + { NEUTRINO_ICON_BUTTON_HELP , LOCALE_AUDIOPLAYER_KEYLEVEL }, + { NEUTRINO_ICON_BUTTON_INFO , LOCALE_PICTUREVIEWER_HEAD}, + }; int top; int c_rad_mid = RADIUS_MID; @@ -1726,8 +1659,6 @@ const struct button_label ScondLineButtons[3] = else top = m_y + (m_height - 2 * m_buttonHeight); - //int ButtonWidth = (m_width - 20) / 5; - m_frameBuffer->paintBoxRel(m_x, top, m_width, 2 * m_buttonHeight, COL_INFOBAR_SHADOW_PLUS_1, c_rad_mid, (m_show_playlist ? CORNER_BOTTOM : CORNER_ALL)); // why? m_frameBuffer->paintHLine(m_x, m_x + m_width, top, COL_INFOBAR_SHADOW_PLUS_1); @@ -1774,7 +1705,24 @@ const struct button_label ScondLineButtons[3] = } } } -//------------------------------------------------------------------------ + +void CAudioPlayerGui::paintCover() +{ + int c_rad_mid = RADIUS_MID; + int title_height = m_title_height; + const CAudioMetaData meta = CAudioPlayer::getInstance()->getMetaData(); + + if (!m_show_playlist) // no playlist -> smaller Info-Box + title_height -= m_fheight; + + std::string cover = m_curr_audiofile.Filename.substr(0, m_curr_audiofile.Filename.rfind('/')) + "/folder.jpg"; + if (!meta.cover.empty()) + cover = meta.cover; + + if (access(cover.c_str(), F_OK) == 0) + g_PicViewer->DisplayImage(cover, m_x + 2 + c_rad_mid/2, m_y + 2 + c_rad_mid/2, title_height - 14 - c_rad_mid, title_height - 14 - c_rad_mid, m_frameBuffer->TM_NONE); +} + void CAudioPlayerGui::paintInfo() { if (m_screensaver) @@ -1793,13 +1741,7 @@ void CAudioPlayerGui::paintInfo() m_frameBuffer->paintBoxRel(m_x + 1, m_y + 1 , m_width - 2, title_height - 12, COL_MENUCONTENTSELECTED_PLUS_0, c_rad_mid); m_frameBuffer->paintBoxFrame(m_x, m_y, m_width, title_height - 10, 2, COL_MENUCONTENT_PLUS_6, c_rad_mid); - std::string cover = m_curr_audiofile.Filename.substr(0, m_curr_audiofile.Filename.rfind('/')) + "/folder.jpg"; - - if (!m_curr_audiofile.MetaData.cover.empty()) - cover = m_curr_audiofile.MetaData.cover; - - if (access(cover.c_str(), F_OK) == 0) - g_PicViewer->DisplayImage(cover, m_x + 2 + c_rad_mid/2, m_y + 2 + c_rad_mid/2, title_height - 14 - c_rad_mid, title_height - 14 - c_rad_mid, m_frameBuffer->TM_NONE); + paintCover(); // first line (Track number) std::string tmp; @@ -1820,11 +1762,7 @@ void CAudioPlayerGui::paintInfo() tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 // second line (Artist/Title...) - if (m_curr_audiofile.FileType != CFile::STREAM_AUDIO && - !m_curr_audiofile.MetaData.bitrate) - { - GetMetaData(m_curr_audiofile); - } + GetMetaData(m_curr_audiofile); if (m_curr_audiofile.MetaData.title.empty()) tmp = m_curr_audiofile.MetaData.artist; @@ -1857,7 +1795,6 @@ void CAudioPlayerGui::paintInfo() updateTimes(true); } } -//------------------------------------------------------------------------ void CAudioPlayerGui::paint() { @@ -1866,9 +1803,7 @@ void CAudioPlayerGui::paint() m_liststart = (m_selected / m_listmaxshow) * m_listmaxshow; paintHead(); for (unsigned int count=0; counthide(); + dline->kill(); // clear infobox if (ibox != NULL) - ibox->hide(); + ibox->kill(); // paint Line if detail info (and not valid list pos) and info box if (!m_playlist.empty() && (pos >= 0)) @@ -1919,7 +1850,7 @@ void CAudioPlayerGui::paintItemID3DetailsLine (int pos) if (dline == NULL) dline = new CComponentsDetailLine(xpos, ypos1a, ypos2a, m_fheight/2+1, m_fheight); dline->setYPos(ypos1a); - dline->paint(); + dline->paint(false); // paint id3 infobox if (ibox == NULL) @@ -1958,12 +1889,11 @@ void CAudioPlayerGui::paintItemID3DetailsLine (int pos) else { if (dline != NULL) - dline->hide(); + dline->kill(); if (ibox != NULL) - ibox->hide(); + ibox->kill(); } } -//------------------------------------------------------------------------ void CAudioPlayerGui::stop() { @@ -1983,7 +1913,6 @@ void CAudioPlayerGui::stop() if (CAudioPlayer::getInstance()->getState() != CBaseDec::STOP) CAudioPlayer::getInstance()->stop(); } -//------------------------------------------------------------------------ void CAudioPlayerGui::pause() { @@ -2001,7 +1930,6 @@ void CAudioPlayerGui::pause() } paintLCD(); } -//------------------------------------------------------------------------ void CAudioPlayerGui::ff(unsigned int seconds) { @@ -2019,7 +1947,6 @@ void CAudioPlayerGui::ff(unsigned int seconds) } paintLCD(); } -//------------------------------------------------------------------------ void CAudioPlayerGui::rev(unsigned int seconds) { @@ -2037,7 +1964,6 @@ void CAudioPlayerGui::rev(unsigned int seconds) } paintLCD(); } -//------------------------------------------------------------------------ void CAudioPlayerGui::play(unsigned int pos) { @@ -2081,13 +2007,8 @@ void CAudioPlayerGui::play(unsigned int pos) } } - if (m_playlist[pos].FileType != CFile::STREAM_AUDIO && - !m_playlist[pos].MetaData.bitrate) - { - // id3tag noch nicht geholt - //printf("play: need getMetaData\n"); - GetMetaData(m_playlist[pos]); - } + GetMetaData(m_playlist[pos]); + m_metainfo.clear(); m_time_played = 0; m_time_total = m_playlist[m_current].MetaData.total_time; @@ -2106,7 +2027,6 @@ void CAudioPlayerGui::play(unsigned int pos) paintFoot(); } } -//------------------------------------------------------------------------ int CAudioPlayerGui::getNext() { @@ -2122,7 +2042,7 @@ int CAudioPlayerGui::getNext() } return ret; } -//------------------------------------------------------------------------ + void CAudioPlayerGui::updateMetaData(bool screen_saver) { bool updateMeta = false; @@ -2159,37 +2079,38 @@ void CAudioPlayerGui::updateMetaData(bool screen_saver) { m_curr_audiofile.MetaData.artist = meta.artist; - if ( !screen_saver) + if ( !screen_saver) updateScreen = true; updateLcd = true; } - + if (!meta.title.empty() && meta.title != m_curr_audiofile.MetaData.title) { m_curr_audiofile.MetaData.title = meta.title; - if ( !screen_saver) + if ( !screen_saver) updateScreen = true; updateLcd = true; } - + if (!meta.sc_station.empty() && meta.sc_station != m_curr_audiofile.MetaData.album) { m_curr_audiofile.MetaData.album = meta.sc_station; updateLcd = true; } + + paintCover(); } - //if (CAudioPlayer::getInstance()->getScBuffered() != 0) if (CAudioPlayer::getInstance()->hasMetaDataChanged() != 0) updateLcd = true; //printf("CAudioPlayerGui::updateMetaData: updateLcd %d\n", updateLcd); if (updateLcd) paintLCD(); - + if (updateScreen) paintInfo(); - + if (updateMeta || updateScreen) { m_frameBuffer->paintBoxRel(m_x + 10 + m_title_height, m_y + 4 + 2*m_fheight, m_width - 20 - m_title_height, m_sheight, COL_MENUCONTENTSELECTED_PLUS_0); @@ -2199,7 +2120,6 @@ void CAudioPlayerGui::updateMetaData(bool screen_saver) m_width- 2*xstart, m_metainfo, COL_MENUCONTENTSELECTED_TEXT); } } -//------------------------------------------------------------------------ void CAudioPlayerGui::updateTimes(const bool force) { @@ -2265,8 +2185,6 @@ void CAudioPlayerGui::updateTimes(const bool force) } } -//------------------------------------------------------------------------ - void CAudioPlayerGui::paintLCD() { switch (m_state) @@ -2305,7 +2223,6 @@ void CAudioPlayerGui::paintLCD() break; } } -//------------------------------------------------------------------------ void CAudioPlayerGui::screensaver(bool on) { @@ -2325,14 +2242,12 @@ void CAudioPlayerGui::screensaver(bool on) m_idletime = time(NULL); } } -//------------------------------------------------------------------------ void CAudioPlayerGui::GetMetaData(CAudiofileExt &File) { - // printf("GetMetaData\n"); bool ret = 1; - if (CFile::STREAM_AUDIO != File.FileType) + if (File.FileType != CFile::STREAM_AUDIO && !File.MetaData.bitrate) ret = CAudioPlayer::getInstance()->readMetaData( &File, m_state != CAudioPlayerGui::STOP && !g_settings.audioplayer_highprio); @@ -2363,7 +2278,6 @@ void CAudioPlayerGui::GetMetaData(CAudiofileExt &File) File.MetaData.title = FILESYSTEM_ENCODING_TO_UTF8_STRING(File.MetaData.title ); } } -//------------------------------------------------------------------------ bool CAudioPlayerGui::getNumericInput(neutrino_msg_t& msg, int& val) { @@ -2396,12 +2310,9 @@ bool CAudioPlayerGui::getNumericInput(neutrino_msg_t& msg, int& val) { return (msg == CRCInput::RC_ok); } -//------------------------------------------------------------------------ - - -void CAudioPlayerGui::getFileInfoToDisplay(std::string &info, CAudiofileExt &file) +void CAudioPlayerGui::getFileInfoToDisplay(std::string &fileInfo, CAudiofileExt &file) { - std::string fileInfo; + //std::string fileInfo; std::string artist; std::string title; @@ -2410,10 +2321,7 @@ void CAudioPlayerGui::getFileInfoToDisplay(std::string &info, CAudiofileExt &fil title = "Title?"; } - if (!file.MetaData.bitrate) - { - GetMetaData(file); - } + GetMetaData(file); if (!file.MetaData.artist.empty()) artist = file.MetaData.artist; @@ -2445,35 +2353,30 @@ void CAudioPlayerGui::getFileInfoToDisplay(std::string &info, CAudiofileExt &fil fileInfo += "Unknown"; } file.firstChar = tolower(fileInfo[0]); - info += fileInfo; + //info += fileInfo; } -//------------------------------------------------------------------------ void CAudioPlayerGui::addToPlaylist(CAudiofileExt &file) { //printf("add2Playlist: %s\n", file.Filename.c_str()); - if (m_select_title_by_name) - { - if (!file.MetaData.bitrate) - { - std::string t = ""; - getFileInfoToDisplay(t,file); - } - } + if (m_select_title_by_name) { + std::string t = ""; + getFileInfoToDisplay(t,file); + } else + GetMetaData(file); + m_playlist.push_back(file); m_playlistHasChanged = true; } -//------------------------------------------------------------------------ void CAudioPlayerGui::removeFromPlaylist(long pos) { unsigned char firstChar = ' '; + // must be called before m_playlist.erase() if (m_select_title_by_name) - { - // must be called before m_playlist.erase() firstChar = getFirstChar(m_playlist[pos]); - } - unlink(m_playlist[pos].MetaData.cover.c_str()); + + //unlink(m_playlist[pos].MetaData.cover.c_str()); m_playlist.erase(m_playlist.begin() + pos); m_playlistHasChanged = true; @@ -2489,14 +2392,11 @@ void CAudioPlayerGui::removeFromPlaylist(long pos) CTitle2Pos::iterator item = m_title2Pos.find(firstChar); if (item != m_title2Pos.end()) { - //const CPosList::size_type del = item->second.erase(pos); // delete empty entries if (item->second.empty()) - { m_title2Pos.erase(item); - } } else { @@ -2518,7 +2418,6 @@ void CAudioPlayerGui::removeFromPlaylist(long pos) // old list is sorted so we can give a hint to insert at the end newList.insert(newList.end(), p); } - //title->second.clear(); title->second = newList; } #ifdef AUDIOPLAYER_TIME_DEBUG @@ -2527,14 +2426,9 @@ void CAudioPlayerGui::removeFromPlaylist(long pos) printf("delete took: "); printTimevalDiff(start,end); #endif - } } - - -//------------------------------------------------------------------------ - void CAudioPlayerGui::selectTitle(unsigned char selectionChar) { unsigned long i; @@ -2574,7 +2468,6 @@ void CAudioPlayerGui::selectTitle(unsigned char selectionChar) int prevselected = m_selected; m_selected = i; - paintItem(prevselected - m_liststart); unsigned int oldliststart = m_liststart; m_liststart = (m_selected / m_listmaxshow)*m_listmaxshow; //printf("before paint\n"); @@ -2584,10 +2477,10 @@ void CAudioPlayerGui::selectTitle(unsigned char selectionChar) } else { + paintItem(prevselected - m_liststart); paintItem(m_selected - m_liststart); } } -//------------------------------------------------------------------------ void CAudioPlayerGui::printSearchTree() { @@ -2608,8 +2501,6 @@ void CAudioPlayerGui::printSearchTree() } } -//------------------------------------------------------------------------ - void CAudioPlayerGui::buildSearchTree() { @@ -2633,11 +2524,8 @@ void CAudioPlayerGui::buildSearchTree() for (CAudioPlayList::iterator it=m_playlist.begin(); it!=m_playlist.end(); ++it) { - // if (m_state == CAudioPlayerGui::PLAY) - // usleep(10*1000); listPos++; progress.showGlobalStatus(100*listPos / maxProgress); - //std::string info; progress.showStatusMessageUTF(it->Filename); unsigned char firstChar = getFirstChar(*it); const std::pair item = @@ -2657,8 +2545,6 @@ void CAudioPlayerGui::buildSearchTree() //printSearchTree(); } -//------------------------------------------------------------------------ - unsigned char CAudioPlayerGui::getFirstChar(CAudiofileExt &file) { if (file.firstChar == '\0') @@ -2670,8 +2556,6 @@ unsigned char CAudioPlayerGui::getFirstChar(CAudiofileExt &file) return file.firstChar; } - -//------------------------------------------------------------------------ #ifdef AUDIOPLAYER_TIME_DEBUG void CAudioPlayerGui::printTimevalDiff(timeval &start, timeval &end) { @@ -2687,8 +2571,6 @@ void CAudioPlayerGui::printTimevalDiff(timeval &start, timeval &end) } #endif -//------------------------------------------------------------------------ - void CAudioPlayerGui::savePlaylist() { const char *path; @@ -2719,9 +2601,8 @@ void CAudioPlayerGui::savePlaylist() // add a trailing slash if necessary if ((absPlaylistDir.empty()) || ((*(absPlaylistDir.rbegin()) != '/'))) - { absPlaylistDir += '/'; - } + absPlaylistDir += file->getFileName(); const int filenamesize = 30; @@ -2735,9 +2616,8 @@ void CAudioPlayerGui::savePlaylist() name += file->getFileName(); bool overwrite = askToOverwriteFile(name); if (!overwrite) - { return; - } + snprintf(filename, name.size(), "%s", name.c_str()); } else if (file->getType() == CFile::FILE_DIR) @@ -2764,9 +2644,7 @@ void CAudioPlayerGui::savePlaylist() { bool overwrite = askToOverwriteFile(name); if (!overwrite) - { return; - } } input.close(); } @@ -2816,9 +2694,9 @@ void CAudioPlayerGui::savePlaylist() } this->paint(); } -//------------------------------------------------------------------------ -bool CAudioPlayerGui::askToOverwriteFile(const std::string& filename) { +bool CAudioPlayerGui::askToOverwriteFile(const std::string& filename) +{ char msg[filename.length() + 127]; snprintf(msg, @@ -2832,10 +2710,10 @@ bool CAudioPlayerGui::askToOverwriteFile(const std::string& filename) { this->paint(); return res; } -//------------------------------------------------------------------------ std::string CAudioPlayerGui::absPath2Rel(const std::string& fromDir, - const std::string& absFilename) { + const std::string& absFilename) +{ std::string res = ""; int length = fromDir.length() < absFilename.length() ? fromDir.length() : absFilename.length(); @@ -2849,9 +2727,7 @@ std::string CAudioPlayerGui::absPath2Rel(const std::string& fromDir, if (fromDir[i] == absFilename[i]) { if (fromDir[i] == '/') - { lastSlash = i; - } } else { @@ -2871,9 +2747,7 @@ std::string CAudioPlayerGui::absPath2Rel(const std::string& fromDir, for (unsigned int i=0; igetRenderWidth("0"); - else if(lastnum<100) - numwidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getRenderWidth("00"); - else if(lastnum<1000) - numwidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getRenderWidth("000"); - else if(lastnum<10000) - numwidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getRenderWidth("0000"); - else // if(lastnum<100000) - numwidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getRenderWidth("00000"); + numwidth = 0; + int maxDigitWidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getMaxDigitWidth(); + int _lastnum = lastnum; + while (_lastnum) { + numwidth += maxDigitWidth; + _lastnum /= 10; + } for(unsigned int count=0;countgetRenderWidth("0"); - else if(lastnum<100) - numwidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getRenderWidth("00"); - else if(lastnum<1000) - numwidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getRenderWidth("000"); - else if(lastnum<10000) - numwidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getRenderWidth("0000"); - else // if(lastnum<100000) - numwidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getRenderWidth("00000"); + numwidth = 0; + int maxDigitWidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getMaxDigitWidth(); + int _lastnum = lastnum; + while (_lastnum) { + numwidth += maxDigitWidth; + _lastnum /= 10; + } frameBuffer->paintBoxRel(x, y+theight, width, height - theight - footerHeight, COL_MENUCONTENT_PLUS_0); diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index 36274304e..745b7450e 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -129,20 +129,22 @@ CChannelList::~CChannelList() { //printf("************ DELETE LIST %s : %x\n", name.c_str(), this);fflush(stdout); chanlist.clear(); - delete dline; - if (cc_minitv) + if(dline){ + delete dline; + dline = NULL; + } + if (cc_minitv){ delete cc_minitv; + cc_minitv = NULL; + } if (headerClock) { headerClock->Stop(); if (headerClock->isPainted()) headerClock->hide(); if (headerClock->isClockRun()) headerClock->stopThread(); - delete headerClock; - headerClock = NULL; } } - void CChannelList::ClearList(void) { //printf("************ CLEAR LIST %s : %x\n", name.c_str(), this);fflush(stdout); @@ -2129,9 +2131,11 @@ void CChannelList::paintHead() if (g_Sectionsd->getIsTimeSet()) { if (headerClock == NULL) { headerClock = new CComponentsFrmClock(0, 0, 0, 0, "%H:%M"); - headerClock->setClockIntervall(10); + headerClock->setClockBlink("%H %M"); + headerClock->setClockIntervall(1); } + headerClock->setClockFormat("%H:%M"); headerClock->setClockFont(SNeutrinoSettings::FONT_TYPE_MENU_TITLE); headerClock->setCorner(RADIUS_LARGE, CORNER_TOP_RIGHT); headerClock->setYPos(y); diff --git a/src/gui/components/cc_base.cpp b/src/gui/components/cc_base.cpp index 0e01f5e34..f2bb38dba 100644 --- a/src/gui/components/cc_base.cpp +++ b/src/gui/components/cc_base.cpp @@ -91,7 +91,7 @@ void CComponents::paintFbItems(bool do_save_bg) for(size_t i=0; isave screen: %d, fbdata_type: %d\n", __FUNCTION__, __LINE__, firstPaint, v_fbdata[i].fbdata_type); + printf(" [CComponents]\n [%s - %d] firstPaint->save screen: %d, fbdata_type: %d\n", __func__, __LINE__, firstPaint, v_fbdata[i].fbdata_type); #endif saved_screen.x = v_fbdata[i].x; saved_screen.y = v_fbdata[i].y; @@ -109,12 +109,12 @@ void CComponents::paintFbItems(bool do_save_bg) // Don't paint if dx or dy are 0 if ((v_fbdata[i].dx == 0) || (v_fbdata[i].dy == 0)){ #ifdef DEBUG_CC - printf(" [CComponents] WARNING: [%s - %d], dx = %d dy = %d\n", __FUNCTION__, __LINE__, v_fbdata[i].dx, v_fbdata[i].dy); + printf(" [CComponents] WARNING: [%s - %d], dx = %d dy = %d\n", __func__, __LINE__, v_fbdata[i].dx, v_fbdata[i].dy); #endif continue; } if ((v_fbdata[i].x == 0) || (v_fbdata[i].y == 0)){ - printf(" [CComponents] WARNING: [%s - %d], x = %d y = %d\n", __FUNCTION__, __LINE__, v_fbdata[i].x, v_fbdata[i].y); + printf(" [CComponents] WARNING: [%s - %d], x = %d y = %d\n", __func__, __LINE__, v_fbdata[i].x, v_fbdata[i].y); } diff --git a/src/gui/components/cc_frm.cpp b/src/gui/components/cc_frm.cpp index b479986bd..ce7418d78 100644 --- a/src/gui/components/cc_frm.cpp +++ b/src/gui/components/cc_frm.cpp @@ -72,7 +72,7 @@ CComponentsForm::~CComponentsForm() void CComponentsForm::cleanCCForm() { #ifdef DEBUG_CC - printf("[CComponentsForm] [%s - %d] clean up...\n", __FUNCTION__, __LINE__); + printf("[CComponentsForm] [%s - %d] clean up...\n", __func__, __LINE__); #endif clearCCItems(); @@ -130,7 +130,7 @@ void CComponentsForm::addCCItem(CComponentsItem* cc_Item) { if (cc_Item){ #ifdef DEBUG_CC - printf(" [CComponentsForm] %s-%d try to add cc_Item [type %d] to form [current index=%d] \n", __FUNCTION__, __LINE__, cc_Item->getItemType(), cc_item_index); + printf(" [CComponentsForm] %s-%d try to add cc_Item [type %d] to form [current index=%d] \n", __func__, __LINE__, cc_Item->getItemType(), cc_item_index); #endif cc_Item->setParent(this); v_cc_items.push_back(cc_Item); @@ -142,12 +142,12 @@ void CComponentsForm::addCCItem(CComponentsItem* cc_Item) int new_index = genIndex(); cc_Item->setIndex(new_index); #ifdef DEBUG_CC - printf(" %s-%d parent index = %d, assigned index ======> %d\n", __FUNCTION__, __LINE__, cc_item_index, new_index); + printf(" %s-%d parent index = %d, assigned index ======> %d\n", __func__, __LINE__, cc_item_index, new_index); #endif } #ifdef DEBUG_CC else - printf(" [CComponentsForm] %s-%d tried to add an empty or invalide cc_item !!!\n", __FUNCTION__, __LINE__); + printf(" [CComponentsForm] %s-%d tried to add an empty or invalide cc_item !!!\n", __func__, __LINE__); #endif } @@ -193,7 +193,7 @@ void CComponentsForm::replaceCCItem(const uint& cc_item_id, CComponentsItem* new } #ifdef DEBUG_CC else - printf("[CComponentsForm] %s replace cc_Item not possible, v_cc_items is empty\n", __FUNCTION__); + printf("[CComponentsForm] %s replace cc_Item not possible, v_cc_items is empty\n", __func__); #endif } @@ -216,7 +216,7 @@ void CComponentsForm::insertCCItem(const uint& cc_item_id, CComponentsItem* cc_I if (v_cc_items.empty()){ addCCItem(cc_Item); #ifdef DEBUG_CC - printf("[CComponentsForm] %s insert cc_Item not possible, v_cc_items is empty, cc_Item added\n", __FUNCTION__); + printf("[CComponentsForm] %s insert cc_Item not possible, v_cc_items is empty, cc_Item added\n", __func__); #endif }else{ v_cc_items.insert(v_cc_items.begin()+cc_item_id, cc_Item); @@ -238,7 +238,7 @@ void CComponentsForm::removeCCItem(const uint& cc_item_id) } #ifdef DEBUG_CC else - printf("[CComponentsForm] %s removing cc_Item not possible, v_cc_items is empty...\n", __FUNCTION__); + printf("[CComponentsForm] %s removing cc_Item not possible, v_cc_items is empty...\n", __func__); #endif } @@ -301,7 +301,7 @@ void CComponentsForm::paintCCItems() //append vertical if (xpos == CC_APPEND){ auto_x += append_h_offset; - cc_item->setRealXPos(auto_x + xpos + 1); + cc_item->setRealXPos(auto_x + xpos); auto_x += w_item; } //positionize vertical centered @@ -318,7 +318,7 @@ void CComponentsForm::paintCCItems() //append hor if (ypos == CC_APPEND){ auto_y += append_v_offset; - cc_item->setRealYPos(auto_y + ypos + 1); + cc_item->setRealYPos(auto_y + ypos); auto_y += h_item; } //positionize hor centered @@ -336,24 +336,24 @@ void CComponentsForm::paintCCItems() //Is it too wide or too high, it will be shortened and displayed in the log. //This should be avoid! //checkwidth and adapt if required - int right_frm = (cc_parent ? cc_xr : x) + width - fr_thickness; + int right_frm = (cc_parent ? cc_xr : x) + width - 2*fr_thickness; int right_item = cc_item->getRealXPos() + w_item; int w_diff = right_item - right_frm; int new_w = w_item - w_diff; if (right_item > right_frm){ printf("[CComponentsForm] %s: [form: %d] [item-index %d] [type=%d] width is too large, definied width=%d, possible width=%d \n", - __FUNCTION__, cc_item_index, cc_item->getIndex(), cc_item->getItemType(), w_item, new_w); + __func__, cc_item_index, cc_item->getIndex(), cc_item->getItemType(), w_item, new_w); cc_item->setWidth(new_w); } //check height and adapt if required - int bottom_frm = (cc_parent ? cc_yr : y) + height - fr_thickness; + int bottom_frm = (cc_parent ? cc_yr : y) + height - 2*fr_thickness; int bottom_item = cc_item->getRealYPos() + h_item; int h_diff = bottom_item - bottom_frm; int new_h = h_item - h_diff; if (bottom_item > bottom_frm){ printf("[CComponentsForm] %s: [form: %d] [item-index %d] [type=%d] height is too large, definied height=%d, possible height=%d \n", - __FUNCTION__, cc_item_index, cc_item->getIndex(), cc_item->getItemType(), h_item, new_h); + __func__, cc_item_index, cc_item->getIndex(), cc_item->getItemType(), h_item, new_h); cc_item->setHeight(new_h); } diff --git a/src/gui/components/cc_frm.h b/src/gui/components/cc_frm.h index f97e15e23..6b2bd31cc 100644 --- a/src/gui/components/cc_frm.h +++ b/src/gui/components/cc_frm.h @@ -127,6 +127,7 @@ class CComponentsHeader : public CComponentsForm std::vector v_cch_btn; int cch_size_mode; int cch_caption_align; + bool userHeight; void initIcon(); void initCaption(); diff --git a/src/gui/components/cc_frm_clock.cpp b/src/gui/components/cc_frm_clock.cpp index 9b960aae7..3f3b45c6d 100644 --- a/src/gui/components/cc_frm_clock.cpp +++ b/src/gui/components/cc_frm_clock.cpp @@ -37,6 +37,7 @@ #include #include #include +#include using namespace std; @@ -84,6 +85,9 @@ void CComponentsFrmClock::initVarClock() cl_thread = 0; cl_interval = 1; + + activeClock = true; + cl_blink_str = ""; } CComponentsFrmClock::~CComponentsFrmClock() @@ -97,7 +101,7 @@ void CComponentsFrmClock::initTimeString() struct tm t; time_t ltime; ltime=time(<ime); - strftime((char*) &cl_timestr, sizeof(cl_timestr), cl_format_str, localtime_r(<ime, &t)); + strftime((char*) &cl_timestr, sizeof(cl_timestr), cl_format_str.c_str(), localtime_r(<ime, &t)); } // How does it works? @@ -152,9 +156,11 @@ void CComponentsFrmClock::initCCLockItems() } } - //calculate minimal separator width, we use a space char...should be enough + //calculate minimal separator width, we use char size of some possible chars int minSepWidth = 0; - minSepWidth = max((*getClockFont())->getRenderWidth("\x20", true), minSepWidth); + string sep[] ={" ", ".", ":"}; + for (size_t i = 0; i < sizeof(sep)/sizeof(sep[0]); i++) + minSepWidth = max((*getClockFont())->getRenderWidth(sep[i], true), minSepWidth); //modify available label items with current segment chars for (size_t i = 0; i < v_cc_items.size(); i++) @@ -260,9 +266,19 @@ void* CComponentsFrmClock::initClockThread(void *arg) CComponentsFrmClock *clock = static_cast(arg); time_t count = time(0); + std::string format_str_save = clock->cl_format_str; //start loop for paint - while(1) { + while(clock != NULL) { if (clock->paintClock) { + // Blinking depending on the blink format string + if (!clock->cl_blink_str.empty() && (clock->cl_format_str.length() == clock->cl_blink_str.length())) { + if (clock->cl_format_str == clock->cl_blink_str.c_str()) + clock->cl_format_str = format_str_save; + else { + format_str_save = clock->cl_format_str; + clock->cl_format_str = clock->cl_blink_str; + } + } //paint segements, but wihtout saved backgrounds clock->paint(CC_SAVE_SCREEN_NO); count = time(0); @@ -271,7 +287,7 @@ void* CComponentsFrmClock::initClockThread(void *arg) clock->cl_thread = 0; break; } - sleep(clock->cl_interval); + mySleep(clock->cl_interval); } return 0; } @@ -284,7 +300,7 @@ bool CComponentsFrmClock::startThread() if(!cl_thread) { int res = pthread_create (&cl_thread, NULL, initClockThread, ptr) ; if (res != 0){ - printf("[CComponentsFrmClock] [%s] pthread_create %s\n", __FUNCTION__, strerror(errno)); + printf("[CComponentsFrmClock] [%s] pthread_create %s\n", __func__, strerror(errno)); return false; } } @@ -297,13 +313,13 @@ bool CComponentsFrmClock::stopThread() if(cl_thread) { int res = pthread_cancel(cl_thread); if (res != 0){ - printf("[CComponentsFrmClock] [%s] pthread_cancel %s\n", __FUNCTION__, strerror(errno)); + printf("[CComponentsFrmClock] [%s] pthread_cancel %s\n", __func__, strerror(errno)); return false; } res = pthread_join(cl_thread, NULL); if (res != 0){ - printf("[CComponentsFrmClock] [%s] pthread_join %s\n", __FUNCTION__, strerror(errno)); + printf("[CComponentsFrmClock] [%s] pthread_join %s\n", __func__, strerror(errno)); return false; } } diff --git a/src/gui/components/cc_frm_clock.h b/src/gui/components/cc_frm_clock.h index 860126edc..44fd7ffe0 100644 --- a/src/gui/components/cc_frm_clock.h +++ b/src/gui/components/cc_frm_clock.h @@ -57,8 +57,9 @@ class CComponentsFrmClock : public CComponentsForm ///raw time chars char cl_timestr[20]; - //TODO: please add comments! + ///allow to paint clock within thread and is not similar to cc_allow_paint bool paintClock; + //TODO: please add comments! bool activeClock; ///object: font render object @@ -70,7 +71,9 @@ class CComponentsFrmClock : public CComponentsForm ///text color int cl_col_text; ///time format - const char* cl_format_str; + std::string cl_format_str; + ///time format for blink + std::string cl_blink_str; ///time string align, default allign is ver and hor centered int cl_align; @@ -80,7 +83,7 @@ class CComponentsFrmClock : public CComponentsForm ///initialize clock contents void initCCLockItems(); ///initialize timestring, called in initCCLockItems() - void initTimeString(); + virtual void initTimeString(); ///initialize of general alignment of timestring segments within form area void initSegmentAlign(int* segment_width, int* segment_height); @@ -107,6 +110,9 @@ class CComponentsFrmClock : public CComponentsForm ///use string expession: "%H:%M" = 12:22, "%H:%M:%S" = 12:22:12 virtual void setClockFormat(const char* format_str){cl_format_str = format_str;}; + ///time format for blink ("%H %M", "%H:%M %S" etc.) + virtual void setClockBlink(const char* format_str){cl_blink_str = format_str;}; + ///start ticking clock thread, returns true on success, if false causes log output virtual bool startThread(); ///stop ticking clock thread, returns true on success, if false causes log output @@ -125,6 +131,9 @@ class CComponentsFrmClock : public CComponentsForm ///reinitialize clock contents virtual void refresh() { initCCLockItems(); } + + ///set clock activ/inactiv + virtual void setClockActiv(bool activ = true){activeClock = activ;}; }; #endif diff --git a/src/gui/components/cc_frm_header.cpp b/src/gui/components/cc_frm_header.cpp index 421f9c2da..0270fe618 100644 --- a/src/gui/components/cc_frm_header.cpp +++ b/src/gui/components/cc_frm_header.cpp @@ -51,7 +51,10 @@ CComponentsHeader::CComponentsHeader( const int x_pos, const int y_pos, const in x = x_pos; y = y_pos; width = w; - height = h > 0 ? h : height; + if (h > 0) { + userHeight = true; + height = h; + } shadow = has_shadow; col_frame = color_frame; col_body = color_body; @@ -74,7 +77,10 @@ CComponentsHeader::CComponentsHeader( const int x_pos, const int y_pos, const in x = x_pos; y = y_pos; width = w; - height = h > 0 ? h : height; + if (h > 0) { + userHeight = true; + height = h; + } shadow = has_shadow; col_frame = color_frame; col_body = color_body; @@ -99,6 +105,7 @@ void CComponentsHeader::initVarHeader() cch_size_mode = CC_HEADER_SIZE_LARGE; cch_font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]; height = cch_font->getHeight(); + userHeight = false; //CComponentsHeader cch_icon_obj = NULL; @@ -123,7 +130,7 @@ void CComponentsHeader::initVarHeader() CComponentsHeader::~CComponentsHeader() { #ifdef DEBUG_CC - printf("[~CComponentsHeader] [%s - %d] delete...\n", __FUNCTION__, __LINE__); + printf("[~CComponentsHeader] [%s - %d] delete...\n", __func__, __LINE__); #endif v_cch_btn.clear(); } @@ -165,7 +172,7 @@ void CComponentsHeader::initIcon() //create instance for cch_icon_obj if (cch_icon_obj == NULL){ #ifdef DEBUG_CC - printf(" [CComponentsHeader]\n [%s - %d] init header icon: %s\n", __FUNCTION__, __LINE__, cch_icon_name); + printf(" [CComponentsHeader]\n [%s - %d] init header icon: %s\n", __func__, __LINE__, cch_icon_name); #endif cch_icon_obj = new CComponentsPicture(cch_icon_x, cch_items_y, 0, 0, cch_icon_name); } @@ -272,7 +279,7 @@ void CComponentsHeader::initButtons() if (cch_btn_obj == NULL){ cch_btn_obj = new CComponentsIconForm(); #ifdef DEBUG_CC - printf(" [CComponentsHeader]\n [%s - %d] init header buttons...\n", __FUNCTION__, __LINE__); + printf(" [CComponentsHeader]\n [%s - %d] init header buttons...\n", __func__, __LINE__); #endif } @@ -325,7 +332,7 @@ void CComponentsHeader::initCaption() //create cch_text_obj and add to collection if (cch_text_obj == NULL){ #ifdef DEBUG_CC - printf(" [CComponentsHeader]\n [%s - %d] init header text: %s [ x %d w %d ]\n", __FUNCTION__, __LINE__, cch_text.c_str(), cch_text_x, cc_text_w); + printf(" [CComponentsHeader]\n [%s - %d] init header text: %s [ x %d w %d ]\n", __func__, __LINE__, cch_text.c_str(), cch_text_x, cc_text_w); #endif cch_text_obj = new CComponentsText(); } @@ -360,7 +367,10 @@ void CComponentsHeader::initCaption() void CComponentsHeader::initCCItems() { //set size - cch_font = (cch_size_mode == CC_HEADER_SIZE_LARGE? g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE] : g_Font[SNeutrinoSettings::FONT_TYPE_MENU]); + if (!userHeight) { + cch_font = (cch_size_mode == CC_HEADER_SIZE_LARGE? g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE] : g_Font[SNeutrinoSettings::FONT_TYPE_MENU]); + height = cch_font->getHeight(); + } //init icon initIcon(); diff --git a/src/gui/components/cc_frm_signalbars.cpp b/src/gui/components/cc_frm_signalbars.cpp index a7f94baec..a046e10da 100644 --- a/src/gui/components/cc_frm_signalbars.cpp +++ b/src/gui/components/cc_frm_signalbars.cpp @@ -257,9 +257,10 @@ void CSignalNoiseRatioBar::Refresh() //********************************************************************************************************************** -CSignalBox::CSignalBox(const int& xpos, const int& ypos, const int& w, const int& h, CFrontend *frontend_ref) +CSignalBox::CSignalBox(const int& xpos, const int& ypos, const int& w, const int& h, CFrontend *frontend_ref, const bool vert) { initVarSigBox(); + vertical = vert; sbx_frontend = frontend_ref; x = xpos; @@ -267,14 +268,19 @@ CSignalBox::CSignalBox(const int& xpos, const int& ypos, const int& w, const int width = w; height = h; - sbx_bar_height = height/2; - sbx_bar_width = width-2*corner_rad; + if (vertical) { + sbx_bar_height = height/2; + sbx_bar_width = width-2*corner_rad; + } else { + sbx_bar_height = height; + sbx_bar_width = width/2-2*corner_rad; + } sbar = new CSignalBar(sbx_bar_x, 0, sbx_bar_width, sbx_bar_height, sbx_frontend); sbar->doPaintBg(false); addCCItem(sbar); - snrbar = new CSignalNoiseRatioBar(sbx_bar_x, CC_APPEND, sbx_bar_width, sbx_bar_height, sbx_frontend); + snrbar = new CSignalNoiseRatioBar(vertical ? sbx_bar_x : CC_APPEND, vertical ? CC_APPEND : 0, sbx_bar_width, sbx_bar_height, sbx_frontend); snrbar->doPaintBg(false); addCCItem(snrbar); @@ -293,6 +299,7 @@ void CSignalBox::initVarSigBox() sbx_bar_x = corner_rad; sbx_caption_color = COL_INFOBAR_TEXT; sbx_scale_w_percent = 60; + vertical = true; } void CSignalBox::initSignalItems() @@ -314,7 +321,7 @@ void CSignalBox::initSignalItems() sbar->setScaleHeight(scale_h); sbar->setScaleWidth(sbx_scale_w_percent); - snrbar->setDimensionsAll(sbar_x, CC_APPEND, sbar_w, sbar_h); + snrbar->setDimensionsAll(vertical ? sbar_x : CC_APPEND, vertical ? CC_APPEND : fr_thickness, sbar_w, sbar_h); snrbar->setFrontEnd(sbx_frontend); snrbar->setCorner(0); snrbar->setScaleHeight(scale_h); diff --git a/src/gui/components/cc_frm_signalbars.h b/src/gui/components/cc_frm_signalbars.h index 3945cdbb8..846e0707e 100644 --- a/src/gui/components/cc_frm_signalbars.h +++ b/src/gui/components/cc_frm_signalbars.h @@ -139,6 +139,9 @@ class CSignalBar : public CComponentsForm ///paint this items virtual void paint(bool do_save_bg); + + //returns the current signal value + uint16_t getValue(void) { return sb_signal; } }; /// Sub class of CSignalBar() @@ -256,6 +259,9 @@ class CSignalBox : public CComponentsForm ///allowed width of scale bar from full width in %, rest used by caption, default value = 60% of width, use setScaleWidth() to set this value short sbx_scale_w_percent; + // true if vertical arrangement, false if horizontal + bool vertical; + ///initialize all needed basic attributes and objects void initVarSigBox(); ///initialize general properties of signal items @@ -266,7 +272,7 @@ class CSignalBox : public CComponentsForm public: ///class constructor for signal noise ratio. - CSignalBox(const int& xpos, const int& ypos, const int& w, const int& h, CFrontend *frontend_ref); + CSignalBox(const int& xpos, const int& ypos, const int& w, const int& h, CFrontend *frontend_ref, const bool vertical = true); ///returns the signal object, type = CSignalBar* CSignalBar* getScaleObject(){return sbar;}; @@ -283,6 +289,14 @@ class CSignalBox : public CComponentsForm ///paint items void paint(bool do_save_bg); + + ///return current signal value + uint16_t getSignalValue(void) { return sbar->getValue();} + + ///return current snr value + uint16_t getSNRValue(void) { return snrbar->getValue();} + + ///return current snr value }; #endif diff --git a/src/gui/components/cc_frm_window.cpp b/src/gui/components/cc_frm_window.cpp index 5fa98de8a..fd24999cf 100644 --- a/src/gui/components/cc_frm_window.cpp +++ b/src/gui/components/cc_frm_window.cpp @@ -117,7 +117,7 @@ CComponentsWindow::CComponentsWindow( const int x_pos, const int y_pos, const in CComponentsWindow::~CComponentsWindow() { #ifdef DEBUG_CC - printf("[~CComponentsWindow] [%s - %d] delete...\n", __FUNCTION__, __LINE__); + printf("[~CComponentsWindow] [%s - %d] delete...\n", __func__, __LINE__); #endif } @@ -218,7 +218,7 @@ void CComponentsWindow::addWindowItem(CComponentsItem* cc_Item) void CComponentsWindow::initCCWItems() { #ifdef DEBUG_CC - printf("[CComponentsWindow] [%s - %d] init items...\n", __FUNCTION__, __LINE__); + printf("[CComponentsWindow] [%s - %d] init items...\n", __func__, __LINE__); #endif //add header if required if (ccw_show_header){ diff --git a/src/gui/components/cc_item.cpp b/src/gui/components/cc_item.cpp index 30fccdfa4..9a3ecdb86 100644 --- a/src/gui/components/cc_item.cpp +++ b/src/gui/components/cc_item.cpp @@ -100,7 +100,7 @@ void CComponentsItem::paintInit(bool do_save_bg) v_fbdata.push_back(fbdata[i]); } #ifdef DEBUG_CC - printf("[CComponentsItem] %s:\ncc_item_type: %d\ncc_item_index = %d\nheight = %d\nwidth = %d\n", __FUNCTION__, cc_item_type, cc_item_index, height, width); + printf("[CComponentsItem] %s:\ncc_item_type: %d\ncc_item_index = %d\nheight = %d\nwidth = %d\n", __func__, cc_item_type, cc_item_index, height, width); #endif paintFbItems(do_save_bg); } @@ -150,7 +150,7 @@ int CComponentsItem::getItemType() return i; } #ifdef DEBUG_CC - printf("[CComponentsItem] %s: unknown item type requested...\n", __FUNCTION__); + printf("[CComponentsItem] %s: unknown item type requested...\n", __func__); #endif return -1; } diff --git a/src/gui/components/cc_item_picture.cpp b/src/gui/components/cc_item_picture.cpp index 8d66f43f8..ea9e661e3 100644 --- a/src/gui/components/cc_item_picture.cpp +++ b/src/gui/components/cc_item_picture.cpp @@ -138,7 +138,7 @@ void CComponentsPicture::initVarPicture() #ifdef DEBUG_CC if (pic_width == 0 || pic_height == 0) - printf("[CComponentsPicture] %s file: %s, no icon dimensions found! width = %d, height = %d\n", __FUNCTION__, pic_name.c_str(), pic_width, pic_height); + printf("[CComponentsPicture] %s file: %s, no icon dimensions found! width = %d, height = %d\n", __func__, pic_name.c_str(), pic_width, pic_height); #endif initPosition(); @@ -181,7 +181,7 @@ void CComponentsPicture::paintPicture() if (do_paint && cc_allow_paint){ #ifdef DEBUG_CC - printf(" [CComponentsPicture] %s: paint image: %s (do_paint=%d)\n", __FUNCTION__, pic_name.c_str(), do_paint); + printf(" [CComponentsPicture] %s: paint image: %s (do_paint=%d)\n", __func__, pic_name.c_str(), do_paint); #endif if (pic_paint_mode == CC_PIC_IMAGE_MODE_OFF) pic_painted = frameBuffer->paintIcon(pic_name, pic_x, pic_y, 0 /*pic_max_h*/, pic_offset, pic_paint, pic_paintBg, col_body); diff --git a/src/gui/components/cc_item_text.cpp b/src/gui/components/cc_item_text.cpp index 4e6db142c..e681dbca5 100644 --- a/src/gui/components/cc_item_text.cpp +++ b/src/gui/components/cc_item_text.cpp @@ -169,7 +169,7 @@ void CComponentsText::initCCText() ct_old_col_text = ct_col_text; } #ifdef DEBUG_CC - printf(" [CComponentsText] [%s - %d] init text: %s [x %d, y %d, w %d, h %d]\n", __FUNCTION__, __LINE__, ct_text.c_str(), this->iX, this->iY, this->iWidth, this->iHeight); + printf(" [CComponentsText] [%s - %d] init text: %s [x %d, y %d, w %d, h %d]\n", __func__, __LINE__, ct_text.c_str(), this->iX, this->iY, this->iWidth, this->iHeight); #endif } @@ -187,7 +187,7 @@ void CComponentsText::setText(const std::string& stext, const int mode, Font* fo ct_text_mode = mode; ct_font = font_text; #ifdef DEBUG_CC - printf(" [CComponentsText] [%s - %d] ct_text: %s \n", __FUNCTION__, __LINE__, ct_text.c_str()); + printf(" [CComponentsText] [%s - %d] ct_text: %s \n", __func__, __LINE__, ct_text.c_str()); #endif } @@ -215,7 +215,7 @@ string CComponentsText::getTextFromFile(const string& path_to_textfile) ifstream in (file.c_str(), ios::in); if (!in){ - printf("[CComponentsText] [%s - %d] error while open %s -> %s\n", __FUNCTION__, __LINE__, file.c_str(), strerror(errno)); + printf("[CComponentsText] [%s - %d] error while open %s -> %s\n", __func__, __LINE__, file.c_str(), strerror(errno)); return ""; } string line; diff --git a/src/gui/filebrowser.cpp b/src/gui/filebrowser.cpp index 26165a01b..7a726cb0c 100644 --- a/src/gui/filebrowser.cpp +++ b/src/gui/filebrowser.cpp @@ -1083,7 +1083,15 @@ bool CFileBrowser::exec(const char * const dirname) } else { - filelist[selected].Marked = true; + bool has_selected = false; + for(unsigned int i = 0; i < filelist.size();i++) { + if(filelist[i].Marked) { + has_selected = true; + break; + } + } + if (!has_selected) + filelist[selected].Marked = true; loop = false; res = true; } @@ -1239,68 +1247,60 @@ void CFileBrowser::hide() void CFileBrowser::paintItem(unsigned int pos) { int colwidth1, colwidth2, colwidth3; - int c_rad_small; + int c_rad_small = 0; fb_pixel_t color; fb_pixel_t bgcolor; int ypos = y+ theight+0 + pos*fheight; CFile * actual_file = NULL; std::string fileicon; + unsigned int curr = liststart + pos; - if (liststart + pos == selected) + frameBuffer->paintBoxRel(x,ypos, width- 15, fheight, COL_MENUCONTENT_PLUS_0/*DARK*/); + + if (curr >= filelist.size()) + return; + + actual_file = &filelist[curr]; + if (curr == selected) { - color = COL_MENUCONTENTSELECTED_TEXT; - bgcolor = COL_MENUCONTENTSELECTED_PLUS_0; + color = actual_file->Marked ? COL_MENUCONTENTINACTIVE_TEXT : COL_MENUCONTENTSELECTED_TEXT; + bgcolor = actual_file->Marked ? COL_MENUCONTENTSELECTED_PLUS_2 : COL_MENUCONTENTSELECTED_PLUS_0; c_rad_small = RADIUS_SMALL; -// paintFoot(); + } + else if (actual_file->Marked) + { + color = COL_MENUCONTENT_TEXT; + bgcolor = COL_MENUCONTENT_PLUS_2; } else { color = COL_MENUCONTENT_TEXT;//DARK; bgcolor = COL_MENUCONTENT_PLUS_0;//DARK; - c_rad_small = 0; } - - frameBuffer->paintBoxRel(x,ypos, width- 15, fheight, COL_MENUCONTENT_PLUS_0); + frameBuffer->paintBoxRel(x,ypos, width- 15, fheight, bgcolor, c_rad_small); - if( (liststart + pos) < filelist.size() ) + if (g_settings.filebrowser_showrights == 0 && S_ISREG(actual_file->Mode)) + colwidth2 = 0; + else + colwidth2 = fnt_item->getRenderWidth("rwxrwxrwx"); + colwidth3 = fnt_item->getRenderWidth("222.222G"); + colwidth1 = width - 35 - colwidth2 - colwidth3 - 10; + + if ( actual_file->Name.length() > 0 ) { - actual_file = &filelist[liststart+pos]; - if (actual_file->Marked) + if (curr == selected) + CVFD::getInstance()->showMenuText(0, FILESYSTEM_ENCODING_TO_UTF8_STRING(actual_file->getFileName()).c_str(), -1, true); // UTF-8 + + switch(actual_file->getType()) { - if (liststart + pos == selected) { - color = COL_MENUCONTENTINACTIVE_TEXT; - bgcolor = COL_MENUCONTENTSELECTED_PLUS_2; - } - else { - color = COL_MENUCONTENT_TEXT; - bgcolor = COL_MENUCONTENT_PLUS_2; - } - } - - if (g_settings.filebrowser_showrights == 0 && S_ISREG(actual_file->Mode)) - colwidth2 = 0; - else - colwidth2 = fnt_item->getRenderWidth("rwxrwxrwx"); - colwidth3 = fnt_item->getRenderWidth("222.222G"); - colwidth1 = width - 35 - colwidth2 - colwidth3 - 10; - - if ( actual_file->Name.length() > 0 ) - { - if (liststart+pos==selected) - CVFD::getInstance()->showMenuText(0, FILESYSTEM_ENCODING_TO_UTF8_STRING(actual_file->getFileName()).c_str(), -1, true); // UTF-8 - - switch(actual_file->getType()) - { case CFile::FILE_CDR: case CFile::FILE_MP3: case CFile::FILE_OGG: case CFile::FILE_WAV: -#ifdef ENABLE_FLAC case CFile::FILE_FLAC: -#endif + case CFile::FILE_AAC: fileicon = NEUTRINO_ICON_MP3; -// color = COL_MENUCONTENT_TEXT; break; case CFile::FILE_DIR: @@ -1311,75 +1311,72 @@ void CFileBrowser::paintItem(unsigned int pos) case CFile::FILE_TEXT: default: fileicon = NEUTRINO_ICON_FILE; - } - frameBuffer->paintIcon(fileicon, x+5 , ypos + (fheight-16) / 2 ); + } + frameBuffer->paintIcon(fileicon, x+5 , ypos + (fheight-16) / 2 ); - fnt_item->RenderString(x + 35, ypos + fheight, colwidth1 - 10 , FILESYSTEM_ENCODING_TO_UTF8_STRING(actual_file->getFileName()), color, 0, true); // UTF-8 + fnt_item->RenderString(x + 35, ypos + fheight, colwidth1 - 10 , FILESYSTEM_ENCODING_TO_UTF8_STRING(actual_file->getFileName()), color, 0, true); // UTF-8 - if( S_ISREG(actual_file->Mode) ) + if( S_ISREG(actual_file->Mode) ) + { + if (g_settings.filebrowser_showrights != 0) { - if (g_settings.filebrowser_showrights != 0) + const char * attribute = "xwr"; + char modestring[9 + 1]; + for (int m = 8; m >= 0; m--) { - const char * attribute = "xwr"; - char modestring[9 + 1]; - for (int m = 8; m >= 0; m--) - { - modestring[8 - m] = (actual_file->Mode & (1 << m)) ? attribute[m % 3] : '-'; - } - modestring[9] = 0; - - fnt_item->RenderString(x + width - 25 - colwidth3 - colwidth2 , ypos+ fheight, colwidth2, modestring, color, 0, true); // UTF-8 + modestring[8 - m] = (actual_file->Mode & (1 << m)) ? attribute[m % 3] : '-'; } + modestring[9] = 0; + + fnt_item->RenderString(x + width - 25 - colwidth3 - colwidth2 , ypos+ fheight, colwidth2, modestring, color, 0, true); // UTF-8 + } #define GIGABYTE 1073741824LL #define MEGABYTE 1048576LL #define KILOBYTE 1024LL - char tmpstr[256]; - const char *unit = ""; - int64_t factor = 0; - if (actual_file->Size >= GIGABYTE) - { - factor = GIGABYTE; - unit = "G"; - } - else if (actual_file->Size >= MEGABYTE) - { - factor = MEGABYTE; - unit = "M"; - } - else if (actual_file->Size >= KILOBYTE) - { - factor = KILOBYTE; - unit = "k"; - } - if (factor) - { - int a = actual_file->Size / factor; - int b = (actual_file->Size - a * factor) * 1000 / factor; - snprintf(tmpstr, sizeof(tmpstr), "%d.%03d%s", a, b, unit); - } - else - snprintf(tmpstr,sizeof(tmpstr),"%d", (int)actual_file->Size); - - /* right align file size */ - int sz_w = fnt_item->getRenderWidth(tmpstr); - fnt_item->RenderString(x + width - sz_w - 25, ypos+ fheight, sz_w, tmpstr, color); - } - - if( S_ISDIR(actual_file->Mode) ) + char tmpstr[256]; + const char *unit = ""; + int64_t factor = 0; + if (actual_file->Size >= GIGABYTE) { - char timestring[18]; - time_t rawtime; - rawtime = actual_file->Time; - strftime(timestring, 18, "%d-%m-%Y %H:%M", gmtime(&rawtime)); - /* right align directory time */ - int time_w = fnt_item->getRenderWidth(timestring); - fnt_item->RenderString(x + width - time_w - 25, ypos+ fheight, time_w, timestring, color); + factor = GIGABYTE; + unit = "G"; } + else if (actual_file->Size >= MEGABYTE) + { + factor = MEGABYTE; + unit = "M"; + } + else if (actual_file->Size >= KILOBYTE) + { + factor = KILOBYTE; + unit = "k"; + } + if (factor) + { + int a = actual_file->Size / factor; + int b = (actual_file->Size - a * factor) * 1000 / factor; + snprintf(tmpstr, sizeof(tmpstr), "%d.%03d%s", a, b, unit); + } + else + snprintf(tmpstr,sizeof(tmpstr),"%d", (int)actual_file->Size); + + /* right align file size */ + int sz_w = fnt_item->getRenderWidth(tmpstr); + fnt_item->RenderString(x + width - sz_w - 25, ypos+ fheight, sz_w, tmpstr, color); + } + + if( S_ISDIR(actual_file->Mode) ) + { + char timestring[18]; + time_t rawtime; + rawtime = actual_file->Time; + strftime(timestring, 18, "%d-%m-%Y %H:%M", gmtime(&rawtime)); + /* right align directory time */ + int time_w = fnt_item->getRenderWidth(timestring); + fnt_item->RenderString(x + width - time_w - 25, ypos+ fheight, time_w, timestring, color); } } - else - frameBuffer->paintBoxRel(x,ypos, width- 15, fheight, COL_MENUCONTENT_PLUS_0/*DARK*/); } //------------------------------------------------------------------------ diff --git a/src/gui/infoclock.cpp b/src/gui/infoclock.cpp index e7d690546..5ccf65f4f 100644 --- a/src/gui/infoclock.cpp +++ b/src/gui/infoclock.cpp @@ -36,7 +36,7 @@ -CInfoClock::CInfoClock():CComponentsFrmClock( 0, 0, 0, 50, "%H:%M:%S", true, CC_SHADOW_OFF, COL_LIGHT_GRAY, COL_MENUCONTENT_PLUS_0,COL_MENUCONTENTDARK_PLUS_0) +CInfoClock::CInfoClock():CComponentsFrmClock( 0, 0, 0, 50, "%H:%M:%S", true, CC_SHADOW_ON, COL_LIGHT_GRAY, COL_MENUCONTENT_PLUS_0,COL_MENUCONTENTDARK_PLUS_0) { initVarInfoClock(); } @@ -65,6 +65,15 @@ void CInfoClock::Init() //use current theme colors syncSysColors(); + paint_bg = g_settings.infoClockBackground; + + if (g_settings.infoClockSeconds) + setClockFormat("%H:%M:%S"); + else { + setClockFormat("%H:%M"); + setClockBlink("%H %M"); + } + int x_old = x, y_old = y, width_old = width, height_old = height; CVolumeHelper::getInstance()->refresh(cl_font); CVolumeHelper::getInstance()->getInfoClockDimensions(&x, &y, &width, &height); diff --git a/src/gui/infoviewer.cpp b/src/gui/infoviewer.cpp index 6767e09eb..becf84e51 100644 --- a/src/gui/infoviewer.cpp +++ b/src/gui/infoviewer.cpp @@ -266,6 +266,7 @@ void CInfoViewer::paintTime (bool show_dot) if (clock == NULL){ clock = new CComponentsFrmClock(); clock->doPaintBg(false); + clock->setClockActiv(false); } clock->setColorBody(COL_INFOBAR_PLUS_0); diff --git a/src/gui/motorcontrol.cpp b/src/gui/motorcontrol.cpp index 68ae0add9..ab86826c2 100644 --- a/src/gui/motorcontrol.cpp +++ b/src/gui/motorcontrol.cpp @@ -65,8 +65,6 @@ CMotorControl::CMotorControl(int tnum) CMotorControl::~CMotorControl() { printf("CMotorControl::~CMotorControl\n"); - delete sigscale; - delete snrscale; } void CMotorControl::Init(void) @@ -91,10 +89,7 @@ void CMotorControl::Init(void) motorPosition = 1; satellitePosition = 0; stepDelay = 10; - sigscale = new CProgressBar(/*true, BAR_WIDTH, BAR_HEIGHT*/); - sigscale->setBlink(); - snrscale = new CProgressBar(/*true, BAR_WIDTH, BAR_HEIGHT*/); - snrscale->setBlink(); + signalbox = NULL; } int CMotorControl::exec(CMenuTarget* parent, const std::string &) @@ -313,6 +308,8 @@ int CMotorControl::exec(CMenuTarget* parent, const std::string &) } } + delete signalbox; + signalbox = NULL; hide(); frontend->setTsidOnid(0); @@ -456,10 +453,6 @@ void CMotorControl::paintHead() void CMotorControl::paintMenu() { - sigscale->reset(); - snrscale->reset(); - lastsnr = lastsig = -1; - frameBuffer->paintBoxRel(x, y + hheight, width, height - hheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM); ypos = y + hheight + (mheight >> 1) - 10; @@ -584,55 +577,19 @@ void CMotorControl::stopSatFind(void) #endif } -void CMotorControl::showSNR() +void CMotorControl::showSNR () { - char percent[10]; - int barwidth = 100; - uint16_t ssig, ssnr; - int sig, snr; - int posx_sig, posx_snr, posy; - - int sw; - - ssig = frontend->getSignalStrength(); - ssnr = frontend->getSignalNoiseRatio(); - - snr = (ssnr & 0xFFFF) * 100 / 65535; - sig = (ssig & 0xFFFF) * 100 / 65535; - if(sig < 5) - return; - g_sig = ssig & 0xFFFF; - g_snr = snr; - - posy = y + height - mheight - 5; - //TODO: move sig/snr display into its own class, similar or same code also to find in scan.cpp - if (lastsig != sig) { - lastsig = sig; - posx_sig = x + 10; - sprintf(percent, "%d%% SIG", sig); - sw = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth ("100% SIG"); - - sigscale->setProgress(posx_sig-1, posy, BAR_WIDTH, BAR_HEIGHT, sig, 100); - sigscale->paint(); - - posx_sig += barwidth + 3; - frameBuffer->paintBoxRel(posx_sig, posy - 2, sw+4, mheight, COL_MENUCONTENT_PLUS_0); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString (posx_sig+2, posy + mheight, sw, percent, COL_MENUCONTENT_TEXT); + if (signalbox == NULL){ + int xpos1 = x + 10; + signalbox = new CSignalBox(xpos1, y + height - mheight - 5, width - 2*(xpos1-x), g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(), frontend, false); + signalbox->setScaleWidth(60); /*%*/ + signalbox->setColorBody(COL_MENUCONTENT_PLUS_0); + signalbox->setTextColor(COL_MENUCONTENT_TEXT); + signalbox->doPaintBg(true); } - if (lastsnr != snr) { - lastsnr = snr; - posx_snr = x + 10 + 210; - sprintf(percent, "%d%% SNR", snr); - sw = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth ("100% SNR"); - - snrscale->setProgress(posx_snr-1, posy, BAR_WIDTH, BAR_HEIGHT, snr, 100); - snrscale->paint(); - - posx_snr += barwidth + 3; - frameBuffer->paintBoxRel(posx_snr, posy - 2, sw+4, mheight, COL_MENUCONTENT_PLUS_0); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString (posx_snr+2, posy + mheight, sw, percent, COL_MENUCONTENT_TEXT); - } + signalbox->paint(false); + g_snr = signalbox->getSNRValue(); } void CMotorControl::readNetwork() diff --git a/src/gui/motorcontrol.h b/src/gui/motorcontrol.h index c595308ee..5ca924dc8 100644 --- a/src/gui/motorcontrol.h +++ b/src/gui/motorcontrol.h @@ -66,10 +66,9 @@ class CMotorControl : public CMenuTarget uint8_t motorPosition; int32_t satellitePosition; int satfindpid; - int lastsnr, lastsig; int g_sig, g_snr, last_snr, moving; std::string network; - CProgressBar *snrscale, *sigscale; + CSignalBox *signalbox; void paintHead(void); void paintMenu(void); void paintStatus(void); diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index 3973f0b04..dd76c58ae 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -408,8 +408,7 @@ void CMovieBrowser::fileInfoStale(void) void CMovieBrowser::init(void) { bool reinit_rows = false; - int i; - + int i = 0; //TRACE("[mb]->init\r\n"); initGlobalSettings(); loadSettings(&m_settings); @@ -612,6 +611,8 @@ void CMovieBrowser::initGlobalSettings(void) m_settings.ytregion = "default"; m_settings.ytquality = 37; m_settings.ytconcconn = 4; + m_settings.ytsearch_history_max = 0; + m_settings.ytsearch_history_size = 0; } void CMovieBrowser::initFrames(void) @@ -3272,7 +3273,8 @@ int CMovieBrowser::showStartPosSelectionMenu(void) // P2 startPosSelectionMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_BOOK_LASTMOVIESTOP, true, play_pos)); position[menu_nr++] = m_movieSelectionHandler->bookmarks.lastPlayStop; } - startPosSelectionMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_START_RECORD_START, true,NULL)); + + startPosSelectionMenu.addItem(new CMenuForwarder(LOCALE_MOVIEBROWSER_START_RECORD_START, true,NULL), true); position[menu_nr++] = 0; for(int i =0 ; i < MI_MOVIE_BOOK_USER_MAX && menu_nr < MAX_NUMBER_OF_BOOKMARK_ITEMS; i++ ) @@ -3765,7 +3767,7 @@ bool CMovieBrowser::showYTMenu() mainMenu.addItem(new CMenuOptionNumberChooser(LOCALE_MOVIEBROWSER_YT_MAX_RESULTS, &m_settings.ytresults, true, 10, 50, NULL)); mainMenu.addItem(new CMenuOptionNumberChooser(LOCALE_MOVIEBROWSER_YT_MAX_HISTORY, &m_settings.ytsearch_history_max, true, 10, 50, NULL)); - char rstr[20]; + char rstr[20] = {0}; sprintf(rstr, "%s", m_settings.ytregion.c_str()); CMenuOptionStringChooser * region = new CMenuOptionStringChooser(LOCALE_MOVIEBROWSER_YT_REGION, rstr, true, NULL, CRCInput::RC_nokey, "", true); region->addOption("default"); @@ -3828,7 +3830,11 @@ bool CMovieBrowser::showYTMenu() else ++it; } - m_settings.ytsearch_history_size = m_settings.ytsearch_history.size(); + if(m_settings.ytsearch_history.empty()) + m_settings.ytsearch_history_size = 0; + else + m_settings.ytsearch_history_size = m_settings.ytsearch_history.size(); + if (m_settings.ytsearch_history_size > m_settings.ytsearch_history_max) m_settings.ytsearch_history_size = m_settings.ytsearch_history_max; } diff --git a/src/gui/movieplayer.cpp b/src/gui/movieplayer.cpp index c073dde40..e94cdf93c 100644 --- a/src/gui/movieplayer.cpp +++ b/src/gui/movieplayer.cpp @@ -156,6 +156,11 @@ void CMoviePlayerGui::Init(void) timeshift = 0; numpida = 0; showStartingHint = false; + + min_x = 0; + max_x = 0; + min_y = 0; + max_y = 0; } void CMoviePlayerGui::cutNeutrino() @@ -622,6 +627,7 @@ void CMoviePlayerGui::PlayFile(void) if ((playstate >= CMoviePlayerGui::PLAY) && (timeshift || (playstate != CMoviePlayerGui::PAUSE))) { if(playback->GetPosition(position, duration)) { + FileTime.update(position, duration); if(duration > 100) file_prozent = (unsigned char) (position / (duration / 100)); #if HAVE_TRIPLEDRAGON diff --git a/src/gui/movieplayer.h b/src/gui/movieplayer.h index 46282be89..5cab46337 100644 --- a/src/gui/movieplayer.h +++ b/src/gui/movieplayer.h @@ -154,6 +154,7 @@ class CMoviePlayerGui : public CMenuTarget int exec(CMenuTarget* parent, const std::string & actionKey); bool Playing() { return playing; }; + bool osdTimeVisible() { return FileTime.IsVisible(); }; std::string CurrentAudioName() { return currentaudioname; }; int GetSpeed() { return speed; } int GetPosition() { return position; } diff --git a/src/gui/osd_setup.cpp b/src/gui/osd_setup.cpp index 7915c23c8..53f83c7bc 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -833,13 +833,6 @@ void COsdSetup::showOsdFontSizeSetup(CMenuWidget *menu_fonts) fontSettings->addItem(mf); w_index++; } -#if 0 - // size of info clock - fontSettings->addItem(GenericMenuSeparatorLine); - CMenuOptionNumberChooser* mn = new CMenuOptionNumberChooser(LOCALE_CLOCK_SIZE, &g_settings.infoClockFontSize, true, 30, 120); - mn->setHint("", LOCALE_MENU_HINT_CLOCK_SIZE); - fontSettings->addItem(mn); -#endif } //osd timeouts @@ -1055,10 +1048,26 @@ void COsdSetup::showOsdInfoclockSetup(CMenuWidget *menu_infoclock) { menu_infoclock->addIntroItems(LOCALE_MISCSETTINGS_INFOCLOCK); + CMenuOptionChooser *mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOCLOCK, &g_settings.mode_clock, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true, NULL, CRCInput::RC_red, NEUTRINO_ICON_BUTTON_RED); + mc->setHint("", LOCALE_MENU_HINT_CLOCK_MODE); + menu_infoclock->addItem(mc); + + menu_infoclock->addItem(GenericMenuSeparatorLine); + // size of info clock CMenuOptionNumberChooser* mn = new CMenuOptionNumberChooser(LOCALE_CLOCK_SIZE_HEIGHT, &g_settings.infoClockFontSize, true, 30, 120); mn->setHint("", LOCALE_MENU_HINT_CLOCK_SIZE); menu_infoclock->addItem(mn); + + // clock with seconds + mc = new CMenuOptionChooser(LOCALE_CLOCK_SECONDS, &g_settings.infoClockSeconds, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + mc->setHint("", LOCALE_MENU_HINT_CLOCK_SECONDS); + menu_infoclock->addItem(mc); + + // clock with background + mc = new CMenuOptionChooser(LOCALE_CLOCK_BACKGROUND, &g_settings.infoClockBackground, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + mc->setHint("", LOCALE_MENU_HINT_CLOCK_BACKGROUND); + menu_infoclock->addItem(mc); } bool COsdSetup::changeNotify(const neutrino_locale_t OptionName, void * data) diff --git a/src/gui/scan.cpp b/src/gui/scan.cpp index 3dbddc3d1..855d98220 100644 --- a/src/gui/scan.cpp +++ b/src/gui/scan.cpp @@ -72,20 +72,13 @@ CScanTs::CScanTs(int dtype) radar = 0; total = done = 0; freqready = 0; - deltype = dtype; - sigscale = new CProgressBar(); - sigscale->setBlink(); - - snrscale = new CProgressBar(); - snrscale->setBlink(); + signalbox = NULL; memset(&TP, 0, sizeof(TP)); // valgrind } CScanTs::~CScanTs() { - delete sigscale; - delete snrscale; } void CScanTs::prev_next_TP( bool up) @@ -218,10 +211,6 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) ypos_radar = y + hheight + (mheight >> 1); xpos1 = x + 10; - sigscale->reset(); - snrscale->reset(); - lastsig = lastsnr = -1; - if (!frameBuffer->getActive()) return menu_return::RETURN_EXIT_ALL; @@ -380,6 +369,8 @@ int CScanTs::exec(CMenuTarget* /*parent*/, const std::string & actionKey) } while (!(msg == CRCInput::RC_timeout)); } + delete signalbox; + signalbox = NULL; hide(); CZapit::getInstance()->scanPids(scan_pids); @@ -592,51 +583,14 @@ int CScanTs::greater_xpos(int xpos, const neutrino_locale_t txt) void CScanTs::showSNR () { - char percent[10]; - int barwidth = BAR_WIDTH; - uint16_t ssig, ssnr; - int sig, snr; - int posx, posy; - int sw; - - CFrontend * frontend = CServiceScan::getInstance()->GetFrontend(); - ssig = frontend->getSignalStrength(); - ssnr = frontend->getSignalNoiseRatio(); - snr = (ssnr & 0xFFFF) * 100 / 65535; - sig = (ssig & 0xFFFF) * 100 / 65535; - - posy = y + height - mheight - 5; - //TODO: move sig/snr display into its own class, similar or same code also to find in motorcontrol - if (lastsig != sig) { - lastsig = sig; - posx = x + 20; - sprintf(percent, "%d%%", sig); - sw = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth ("100%"); - sigscale->setProgress(posx - 1, posy+2, BAR_WIDTH, BAR_HEIGHT, sig, 100); - sigscale->paint(); - - posx = posx + barwidth + 3; - frameBuffer->paintBoxRel(posx, posy -1, sw, mheight-8, COL_MENUCONTENT_PLUS_0); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString (posx+2, posy + mheight-(mheight-BAR_HEIGHT)/4, sw, percent, COL_MENUCONTENTDARK_TEXT); - - frameBuffer->paintBoxRel(posx+(4*fw), posy - 2, 4*fw, mheight, COL_MENUCONTENT_PLUS_0); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString (posx+2+(4*fw), posy + mheight-(mheight-BAR_HEIGHT)/4, 4*fw, "SIG", COL_MENUCONTENT_TEXT); - + if (signalbox == NULL){ + CFrontend * frontend = CServiceScan::getInstance()->GetFrontend(); + signalbox = new CSignalBox(xpos1, y + height - mheight - 5, width - 2*(xpos1-x), g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(), frontend, false); + signalbox->setScaleWidth(60); /*%*/ + signalbox->setColorBody(COL_MENUCONTENT_PLUS_0); + signalbox->setTextColor(COL_MENUCONTENT_TEXT); + signalbox->doPaintBg(true); } - if (lastsnr != snr) { - lastsnr = snr; - posx = x + 20 + barwidth + 3 + 4 * fw + 4 * fw; - sprintf(percent, "%d%%", snr); - sw = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth ("100%"); - snrscale->setProgress(posx - 1, posy+2, BAR_WIDTH, BAR_HEIGHT, snr, 100); - snrscale->paint(); - posx = posx + barwidth + 3; - frameBuffer->paintBoxRel(posx, posy - 1, sw, mheight-8, COL_MENUCONTENT_PLUS_0, 0, true); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString (posx + 2, posy + mheight-(mheight-BAR_HEIGHT)/4, sw, percent, COL_MENUCONTENTDARK_TEXT, 0, true); - - frameBuffer->paintBoxRel(posx+(4*fw), posy - 2, 4*fw, mheight, COL_MENUCONTENT_PLUS_0); - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString (posx+2+(4*fw), posy + mheight-(mheight-BAR_HEIGHT)/4, 4*fw, "SNR", COL_MENUCONTENT_TEXT); - - } + signalbox->paint(false); } diff --git a/src/gui/scan.h b/src/gui/scan.h index 5cc2bd069..54263898f 100644 --- a/src/gui/scan.h +++ b/src/gui/scan.h @@ -65,9 +65,8 @@ class CScanTs : public CMenuTarget bool istheend; uint32_t total; uint32_t done; - int lastsnr, lastsig; int tuned; - CProgressBar *snrscale, *sigscale; + CSignalBox *signalbox; void paint(bool fortest = false); void paintLineLocale(int x, int * y, int width, const neutrino_locale_t l); diff --git a/src/gui/scan_setup.cpp b/src/gui/scan_setup.cpp index 6fd0c13ba..99d158287 100644 --- a/src/gui/scan_setup.cpp +++ b/src/gui/scan_setup.cpp @@ -448,6 +448,7 @@ printf("C: %d S: %d T: %d\n", CFEManager::getInstance()->haveCable(),CFEManager: //tune timeout if(CFEManager::getInstance()->getFrontendCount() <= 1) { CMenuOptionNumberChooser * nc = new CMenuOptionNumberChooser(LOCALE_EXTRA_ZAPIT_FE_TIMEOUT, (int *)&zapitCfg.feTimeout, true, 6, 100); + nc->setNumberFormat(std::string("%d0 ") + g_Locale->getText(LOCALE_UNIT_SHORT_MILLISECOND)); nc->setHint("", LOCALE_MENU_HINT_SCAN_FETIMEOUT); settings->addItem(nc); } @@ -597,6 +598,7 @@ int CScanSetup::showScanMenuFrontendSetup() frontendSetup = mf; } CMenuOptionNumberChooser * nc = new CMenuOptionNumberChooser(LOCALE_EXTRA_ZAPIT_FE_TIMEOUT, (int *)&zapitCfg.feTimeout, true, 6, 100); + nc->setNumberFormat(std::string("%d0 ") + g_Locale->getText(LOCALE_UNIT_SHORT_MILLISECOND)); nc->setHint("", LOCALE_MENU_HINT_SCAN_FETIMEOUT); setupMenu->addItem(nc); diff --git a/src/gui/streaminfo2.h b/src/gui/streaminfo2.h index cbd0a45b0..1124568ba 100644 --- a/src/gui/streaminfo2.h +++ b/src/gui/streaminfo2.h @@ -27,7 +27,6 @@ #include #include -#include #include diff --git a/src/gui/timeosd.cpp b/src/gui/timeosd.cpp index beb571812..a6312102a 100644 --- a/src/gui/timeosd.cpp +++ b/src/gui/timeosd.cpp @@ -1,23 +1,28 @@ /* Neutrino-GUI - DBoxII-Project - Timerliste by Zwen + TimeOSD by Zwen + + Copyright (C) 2013, Thilo Graf 'dbt' + Copyright (C) 2013, Michael Liebmann 'micha-bbg' + Copyright (C) 2013, martii 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 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. + 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. + 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., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H @@ -26,136 +31,131 @@ #include #include +#include #include -#include -#include -#include -#define TIMEOSD_FONT SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME -#define BARLEN 200 -extern CInfoClock *InfoClock; -CTimeOSD::CTimeOSD() +CTimeOSD::CTimeOSD():CComponentsFrmClock( 0, 0, 0, 50, "%H:%M:%S", true, CC_SHADOW_ON, COL_LIGHT_GRAY, COL_MENUCONTENT_PLUS_0,COL_MENUCONTENTDARK_PLUS_0) { - frameBuffer = CFrameBuffer::getInstance(); - visible=false; - m_mode=MODE_ASC; - GetDimensions(); - timescale = new CProgressBar(); + Init(); +} + +void CTimeOSD::Init() +{ + static int oldSize = 0; + + m_mode = MODE_HIDE; m_time_show = 0; + + if (oldSize != g_settings.infoClockFontSize) { + oldSize = g_settings.infoClockFontSize; + setClockFontSize(g_settings.infoClockFontSize); + } + + //use current theme colors + syncSysColors(); + + paint_bg = g_settings.infoClockBackground; + + setClockFormat("%H:%M:%S"); + + int x_old = x, y_old = y, width_old = width, height_old = height; + CVolumeHelper::getInstance()->refresh(cl_font); + CVolumeHelper::getInstance()->getTimeDimensions(&x, &y, &width, &height); + if ((x_old != x) || (y_old != y) || (width_old != width) || (height_old != height)) { + cleanCCForm(); + clearCCItems(); + } + + // set corner radius depending on clock height + corner_rad = (g_settings.rounded_corners) ? std::max(height/10, CORNER_RADIUS_SMALL) : 0; + + initCCLockItems(); } CTimeOSD::~CTimeOSD() { hide(); - delete timescale; } -void CTimeOSD::show(time_t time_show) +void CTimeOSD::initTimeString() { - InfoClock->enableInfoClock(false); - - GetDimensions(); - visible = true; - SetMode(CTimeOSD::MODE_ASC); - m_time_show = 0; - frameBuffer->paintBoxRel(m_xstart-2, m_y, 2+BARLEN+2, m_height, COL_INFOBAR_SHADOW_PLUS_0); //border - timescale->reset(); - update(time_show); + struct tm t; + strftime((char*) &cl_timestr, sizeof(cl_timestr), cl_format_str.c_str(), gmtime_r(&m_time_show, &t)); } -void CTimeOSD::GetDimensions() +void CTimeOSD::show(time_t time_show, bool force) { - m_xstart = g_settings.screen_StartX + 10; - m_xend = frameBuffer->getScreenWidth(); - m_height = g_Font[TIMEOSD_FONT]->getHeight(); - if(m_height < 10) - m_height = 10; - m_y = frameBuffer->getScreenY(); - m_width = g_Font[TIMEOSD_FONT]->getRenderWidth("00:00:00"); - t1 = g_Font[TIMEOSD_FONT]->getMaxDigitWidth(); - m_width += t1; -} - -void CTimeOSD::update(time_t time_show) -{ - char cDisplayTime[8+1]; - fb_pixel_t color1, color2; - - if(!visible) - return; - time_show /= 1000; - if(m_time_show == time_show) + if (!force && (m_mode == MODE_HIDE || m_time_show == time_show)) return; - - //printf("CTimeOSD::update time %ld -> %ld\n", m_time_show, time_show); m_time_show = time_show; - - if(m_mode == MODE_ASC) { - color1 = COL_MENUCONTENT_PLUS_0; - color2 = COL_MENUCONTENT_TEXT; - } else { - color1 = COL_MENUCONTENTSELECTED_PLUS_0; - color2 = COL_MENUCONTENTSELECTED_TEXT; - } - strftime(cDisplayTime, 9, "%T", gmtime(&time_show)); - frameBuffer->paintBoxRel(m_xend - m_width - t1, m_y, m_width, m_height, color1,RADIUS_SMALL); - g_Font[TIMEOSD_FONT]->RenderString(m_xend - m_width - (t1/2), m_y + m_height, m_width, cDisplayTime, color2); + paint(false); } -void CTimeOSD::updatePos(short runningPercent) +void CTimeOSD::updatePos(int position, int duration) { - if(!visible) - return; + int percent = (duration && duration > 100) ? (position * 100 / duration) : 0; + if(percent > 100) + percent = 100; + else if(percent < 0) + percent = 0; - if(runningPercent > 100 || runningPercent < 0) - runningPercent = 0; - - timescale->setProgress(m_xstart, m_y, BARLEN, m_height -5, runningPercent, 100); - timescale->setBlink(); - timescale->setRgb(0, 100, 70); - timescale->paint(); + timescale.setProgress(x, y + height/4, width, height/2, percent, 100); + timescale.setBlink(); + timescale.setRgb(0, 100, 70); + timescale.paint(); + frameBuffer->blit(); } void CTimeOSD::update(int position, int duration) { - if(!visible) - return; - - short percent = 0; - if(duration > 100) - percent = (unsigned char) (position / (duration / 100)); - if(m_mode == CTimeOSD::MODE_ASC) - update(position /* / 1000*/); - else - update((duration - position)/* / 1000 */); - updatePos(percent); -} - -void CTimeOSD::hide() -{ - if(!visible) - return; - - //GetDimensions(); - frameBuffer->paintBackgroundBoxRel(m_xend - m_width - t1, m_y, m_width, m_height); - timescale->reset(); - frameBuffer->paintBackgroundBoxRel(m_xstart-2, m_y, 2+BARLEN+2, m_height); //clear border - visible=false; - - InfoClock->enableInfoClock(true); + switch(m_mode) { + case MODE_ASC: + show(position, false); + break; + case MODE_DESC: + show(duration - position, false); + break; + case MODE_BAR: + updatePos(position, duration); + break; + default: + ; + } } void CTimeOSD::switchMode(int position, int duration) { - if(visible) { - if (GetMode() == CTimeOSD::MODE_ASC) { - SetMode(CTimeOSD::MODE_DESC); - update(position, duration); - } else - hide(); - } else - show(position); + switch (m_mode) { + case MODE_ASC: + m_mode = MODE_DESC; + break; + case MODE_DESC: + m_mode = MODE_BAR; + kill(); + break; + case MODE_BAR: + m_mode = MODE_HIDE; + timescale.kill(); + timescale.reset(); + frameBuffer->blit(); + return; + default: + m_mode = MODE_ASC; + } + + update(position, duration); +} + +void CTimeOSD::hide(void) +{ + if (m_mode != MODE_HIDE) { + m_mode = MODE_HIDE; + timescale.kill(); + timescale.reset(); + kill(); + frameBuffer->blit(); + } } diff --git a/src/gui/timeosd.h b/src/gui/timeosd.h index e986fed2e..3f98bf47e 100644 --- a/src/gui/timeosd.h +++ b/src/gui/timeosd.h @@ -2,62 +2,59 @@ Neutrino-GUI - DBoxII-Project TimeOSD by Zwen - + Homepage: http://dbox.cyberphoria.org/ 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 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. + 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. + 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., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifndef __timeosd__ #define __timeosd__ -#include -#include #include +#include -class CTimeOSD +class CTimeOSD : public CComponentsFrmClock { public: enum mode { MODE_ASC, - MODE_DESC + MODE_DESC, + MODE_BAR, + MODE_HIDE }; private: - CFrameBuffer *frameBuffer; - CProgressBar *timescale; - - time_t m_time_show; - bool visible; - int m_xstart,m_xend,m_y,m_height, m_width, t1; + CProgressBar timescale; mode m_mode; - void GetDimensions(); + time_t m_time_show; + + void Init(); + void initTimeString(); + void updatePos(int position, int duration); public: CTimeOSD(); ~CTimeOSD(); - void show(time_t time_show); - void update(time_t time_show); - void updatePos(short runningPercent); + void show(time_t time_show, bool force = true); void hide(); - bool IsVisible() {return visible;} - void SetMode(mode m) { m_mode = m;} - mode GetMode() { return m_mode;} + bool IsVisible() {return m_mode != MODE_HIDE;} void update(int position, int duration); void switchMode(int position, int duration); }; diff --git a/src/gui/volumebar.cpp b/src/gui/volumebar.cpp index 1a264f139..db88a3cbc 100644 --- a/src/gui/volumebar.cpp +++ b/src/gui/volumebar.cpp @@ -29,6 +29,7 @@ #endif #include "gui/volumebar.h" +#include "gui/movieplayer.h" #include #include @@ -124,12 +125,14 @@ void CVolumeBar::initVolumeBarPosition() if ((neutrino->isMuted()) && (!g_settings.mode_clock)) x_corr = mute_dx + h_spacer; if (g_settings.mode_clock) - y = clock_y + clock_height + v_spacer; + y = clock_y + clock_height + v_spacer + SHADOW_OFFSET; } x = sw - width - x_corr; break; } case VOLUMEBAR_POS_TOP_LEFT: + if (CMoviePlayerGui::getInstance().osdTimeVisible()) + y = clock_y + clock_height + v_spacer + SHADOW_OFFSET; break; case VOLUMEBAR_POS_BOTTOM_LEFT: y = (sh + frameBuffer->getScreenY()) - height - v_spacer; @@ -298,7 +301,10 @@ void CVolumeHelper::initInfoClock(Font** font) int t1 = (*clock_font)->getMaxDigitWidth(); int t2 = (*clock_font)->getRenderWidth(":"); clock_dy = digit_h + (int)((float)digit_offset * 1.3); - clock_dx = t1*7 + t2*2; + if (g_settings.infoClockSeconds) + clock_dx = t1*7 + t2*2; + else + clock_dx = t1*5 + t2*1; clock_ax = sw - clock_dx; clock_ay = y; vol_ay = y; @@ -316,6 +322,9 @@ void CVolumeHelper::initInfoClock(Font** font) else mute_corrY = (vol_height - mute_dy) / 2; } + + time_dx = t1*7 + t2*2; + time_ax = frameBuffer->getScreenX() + h_spacer; } void CVolumeHelper::initMuteIcon() diff --git a/src/gui/volumebar.h b/src/gui/volumebar.h index b028da0a5..2ec76ddbb 100644 --- a/src/gui/volumebar.h +++ b/src/gui/volumebar.h @@ -102,6 +102,7 @@ class CVolumeHelper int x, y, sw, sh; int mute_ax, mute_ay, mute_dx, mute_dy, mute_corrY; int clock_ax, clock_ay, clock_dx, clock_dy, digit_h, digit_offset; + int time_ax, time_dx; int icon_width, icon_height, digit_width; int h_spacer, v_spacer; int vol_ay, vol_height; @@ -126,6 +127,7 @@ class CVolumeHelper void getMuteIconDimensions(int *_x, int *_y, int *w, int *h) { *_x = mute_ax; *_y = mute_ay+mute_corrY; *w = mute_dx; *h = mute_dy; } int getInfoClockX(); void getInfoClockDimensions(int *_x, int *_y, int *w, int *h) { *_x = getInfoClockX(); *_y = clock_ay; *w = clock_dx; *h = clock_dy; } + void getTimeDimensions(int *_x, int *_y, int *w, int *h) { *_x = time_ax; *_y = clock_ay; *w = time_dx; *h = clock_dy; } void getVolBarDimensions(int *_y, int *_dy) { *_y = vol_ay; *_dy = vol_height; } void setMuteIconCorrY(int corr) { mute_corrY = corr; } void refresh(Font** font=NULL); diff --git a/src/gui/widget/menue.cpp b/src/gui/widget/menue.cpp index 3fd2d508d..371f74407 100644 --- a/src/gui/widget/menue.cpp +++ b/src/gui/widget/menue.cpp @@ -1018,6 +1018,7 @@ void CMenuWidget::addIntroItems(neutrino_locale_t subhead_text, neutrino_locale_ { if (subhead_text != NONEXISTANT_LOCALE) addItem(new CMenuSeparator(CMenuSeparator::ALIGN_LEFT | CMenuSeparator::SUB_HEAD | CMenuSeparator::STRING, subhead_text)); + addItem(GenericMenuSeparator); if (buttontype != BTN_TYPE_NO) @@ -1039,7 +1040,7 @@ void CMenuWidget::addIntroItems(neutrino_locale_t subhead_text, neutrino_locale_ if (section_text != NONEXISTANT_LOCALE) addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, section_text)); - else + else if (buttontype != BTN_TYPE_NO) addItem(GenericMenuSeparatorLine); } @@ -1085,7 +1086,7 @@ void CMenuWidget::paintHint(int pos) if (details_line) savescreen ? details_line->hide() : details_line->kill(); /* clear info box */ - if ((info_box) && (pos == -1)) + if ((info_box) && (pos < 0)) savescreen ? info_box->hide(true) : info_box->kill(); hint_painted = false; } @@ -1095,8 +1096,10 @@ void CMenuWidget::paintHint(int pos) CMenuItem* item = items[pos]; if (item->hintIcon.empty() && item->hint == NONEXISTANT_LOCALE) { - if (info_box) - info_box->hide(false); + if (info_box) { + savescreen ? info_box->hide(false) : info_box->kill(); + hint_painted = false; + } return; } @@ -1170,6 +1173,7 @@ CMenuOptionNumberChooser::CMenuOptionNumberChooser(const neutrino_locale_t name, localized_value_name = special_value_name; optionString = non_localized_name; + numberFormat = "%d"; observ = Observ; slider_on = sliderOn; } @@ -1202,7 +1206,7 @@ int CMenuOptionNumberChooser::paint(bool selected) if ((localized_value_name == NONEXISTANT_LOCALE) || ((*optionValue) != localized_value)) { - sprintf(option_value, "%d", ((*optionValue) + display_offset)); + sprintf(option_value, numberFormat.c_str(), ((*optionValue) + display_offset)); l_option = option_value; } else @@ -1254,6 +1258,12 @@ int CMenuOptionNumberChooser::getWidth(void) width += (w1 > w2) ? w1 : w2; + if (numberFormat != "%d") { + char format[numberFormat.length()]; + snprintf(format, numberFormat.length(), numberFormat.c_str(), 0); + width += g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(format, true) - g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth("0", true); + } + return width + 10; /* min 10 pixels between option name and value. enough? */ } diff --git a/src/gui/widget/menue.h b/src/gui/widget/menue.h index 6ee0da92f..21e5e7297 100644 --- a/src/gui/widget/menue.h +++ b/src/gui/widget/menue.h @@ -298,6 +298,7 @@ private: neutrino_locale_t localized_value_name; bool slider_on; CChangeObserver * observ; + std::string numberFormat; public: CMenuOptionNumberChooser(const neutrino_locale_t name, int * const OptionValue, const bool Active, const int min_value, const int max_value, CChangeObserver * const Observ = NULL, const int print_offset = 0, const int special_value = 0, const neutrino_locale_t special_value_name = NONEXISTANT_LOCALE, const char * non_localized_name = NULL, bool sliderOn = false ); @@ -307,6 +308,7 @@ private: int exec(CMenuTarget* parent); int isMenueOptionChooser(void) const{return 1;} int getWidth(void); + void setNumberFormat(std::string format) { numberFormat = format; } }; class CMenuOptionChooser : public CAbstractMenuOptionChooser diff --git a/src/gui/widget/stringinput.cpp b/src/gui/widget/stringinput.cpp index c610717d9..52d409eff 100644 --- a/src/gui/widget/stringinput.cpp +++ b/src/gui/widget/stringinput.cpp @@ -135,6 +135,8 @@ CStringInput::~CStringInput() if(head) { free(head); } + + g_RCInput->killTimer (smstimer); } #define CStringInputSMSButtonsCount 2 @@ -198,6 +200,7 @@ void CStringInput::init() x = getScreenStartX(width); y = getScreenStartY(height); selected = 0; + smstimer = 0; } void CStringInput::NormalKeyPressed(const neutrino_msg_t key) @@ -473,6 +476,12 @@ int CStringInput::exec( CMenuTarget* parent, const std::string & ) if ( msg <= CRCInput::RC_MaxRC ) timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU] == 0 ? 0xFFFF : g_settings.timing[SNeutrinoSettings::TIMING_MENU]); + if ((msg == NeutrinoMessages::EVT_TIMER) && (data == smstimer)) + msg = CRCInput::RC_right; + + if (msg < CRCInput::RC_nokey) + g_RCInput->killTimer (smstimer); + if (msg==CRCInput::RC_left) { keyLeftPressed(); @@ -645,7 +654,7 @@ void CStringInput::paint(bool sms) if (sms) { frameBuffer->getIconSize(NEUTRINO_ICON_NUMERIC_PAD, &icol_w, &icol_h); - frameBuffer->paintIcon(NEUTRINO_ICON_NUMERIC_PAD, x + (width/2) - (icol_w/2), tmp_y, 0, COL_MENUCONTENT_TEXT); + frameBuffer->paintIcon(NEUTRINO_ICON_NUMERIC_PAD, x + (width/2) - (icol_w/2), tmp_y, 0, 1, true, true, COL_MENUCONTENT_TEXT); //buttonbar ::paintButtons(x, y+ hheight+ bheight, width, CStringInputSMSButtonsCount, CStringInputSMSButtons, width, fheight); @@ -767,6 +776,8 @@ void CStringInputSMS::NormalKeyPressed(const neutrino_msg_t key) value[selected] = Chars[numericvalue][keyCounter]; last_digit = numericvalue; paintChar(selected); + g_RCInput->killTimer (smstimer); + smstimer = g_RCInput->addTimer(2*1000*1000); } else { diff --git a/src/gui/widget/stringinput.h b/src/gui/widget/stringinput.h index 47d5d692a..c7391dad3 100644 --- a/src/gui/widget/stringinput.h +++ b/src/gui/widget/stringinput.h @@ -51,6 +51,8 @@ class CStringInput : public CMenuTarget int lower_bound; int upper_bound; + uint32_t smstimer; + char * head; neutrino_locale_t name; neutrino_locale_t hint_1, hint_2; diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 461c611c9..f6d178c83 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -877,7 +877,9 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.pip_height = configfile.getInt32("pip_height", 200); #endif - g_settings.infoClockFontSize = configfile.getInt32("infoClockFontSize", 34); + g_settings.infoClockFontSize = configfile.getInt32("infoClockFontSize", 30); + g_settings.infoClockBackground = configfile.getInt32("infoClockBackground", 0); + g_settings.infoClockSeconds = configfile.getInt32("infoClockSeconds", 1); if(erg) configfile.setModifiedFlag(true); @@ -1296,6 +1298,8 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt32("pip_height", g_settings.pip_height); #endif configfile.setInt32("infoClockFontSize", g_settings.infoClockFontSize); + configfile.setInt32("infoClockBackground", g_settings.infoClockBackground); + configfile.setInt32("infoClockSeconds", g_settings.infoClockSeconds); configfile.setInt32("easymenu", g_settings.easymenu); if(strcmp(fname, NEUTRINO_SETTINGS_FILE)) configfile.saveConfig(fname); @@ -2208,12 +2212,17 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) StopSubtitles(); InfoClock->enableInfoClock(false); int old_ttx = g_settings.cacheTXT; + int old_epg = g_settings.epg_scan; mainMenu.exec(NULL, ""); InfoClock->enableInfoClock(true); StartSubtitles(); saveSetup(NEUTRINO_SETTINGS_FILE); - if (!g_settings.epg_scan) - CEpgScan::getInstance()->Clear(); + if (old_epg != g_settings.epg_scan) { + if (g_settings.epg_scan) + CEpgScan::getInstance()->Start(); + else + CEpgScan::getInstance()->Clear(); + } if (old_ttx != g_settings.cacheTXT) { if(g_settings.cacheTXT) { tuxtxt_init(); @@ -2275,12 +2284,9 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) } else if( msg == (neutrino_msg_t) g_settings.key_zaphistory ) { // Zap-History "Bouquet" - if(g_settings.mode_clock && g_settings.key_zaphistory == CRCInput::RC_home) { - InfoClock->enableInfoClock(false); - g_settings.mode_clock = false; - } else { - numericZap( msg ); - } + InfoClock->enableInfoClock(false); + numericZap( msg ); + InfoClock->enableInfoClock(true); } #ifdef SCREENSHOT else if (msg == (neutrino_msg_t) g_settings.key_screenshot) { @@ -2441,10 +2447,6 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) scartMode(true); else { if (msg == CRCInput::RC_home) { - if(g_settings.mode_clock && g_settings.key_zaphistory == CRCInput::RC_home) { - InfoClock->enableInfoClock(false); - g_settings.mode_clock = false; - } CVFD::getInstance()->setMode(CVFD::MODE_TVRADIO); } handleMsg(msg, data); @@ -3496,8 +3498,8 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) videoDecoder->Standby(true); - g_Sectionsd->setPauseScanning(!fromDeepStandby); g_Sectionsd->setServiceChanged(0, false); + g_Sectionsd->setPauseScanning(!fromDeepStandby); lastMode = mode; mode = mode_standby; @@ -3534,7 +3536,7 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) frameBuffer->setActive(false); // Active standby on powerManager->SetStandby(false, false); - CEpgScan::getInstance()->StartStandby(); + CEpgScan::getInstance()->Start(true); } else { // Active standby off powerManager->SetStandby(false, false); @@ -3542,7 +3544,7 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) CVFD::getInstance()->ShowText("resume... "); cpuFreq->SetCpuFreq(g_settings.cpufreq * 1000 * 1000); videoDecoder->Standby(false); - CEpgScan::getInstance()->StopStandby(); + CEpgScan::getInstance()->Stop(); CSectionsdClient::CurrentNextInfo dummy; g_InfoViewer->getEPG(0, dummy); diff --git a/src/nhttpd/yhttpd_mods/mod_auth.cpp b/src/nhttpd/yhttpd_mods/mod_auth.cpp index 89dc65f1b..c11a0f046 100644 --- a/src/nhttpd/yhttpd_mods/mod_auth.cpp +++ b/src/nhttpd/yhttpd_mods/mod_auth.cpp @@ -14,10 +14,10 @@ THandleStatus CmAuth::Hook_PrepareResponse(CyhookHandler *hh) { THandleStatus status = HANDLED_CONTINUE; + // dont check local calls or calls from NoAuthClient if (authenticate) { if ((hh->UrlData["clientaddr"]).find(IADDR_LOCAL) > 0 - && (no_auth_client == "" || (hh->UrlData["clientaddr"]).find( - no_auth_client) > 0)) // dont check local calls or calls from NoAuthClient + && (no_auth_client == "" || (hh->UrlData["clientaddr"]).compare(no_auth_client) != 0)) { if (!CheckAuth(hh)) { hh->SetError(HTTP_UNAUTHORIZED); diff --git a/src/system/helpers.cpp b/src/system/helpers.cpp index 921a7bfca..f1ad53548 100644 --- a/src/system/helpers.cpp +++ b/src/system/helpers.cpp @@ -43,6 +43,14 @@ #include #include +void mySleep(int sec) { + struct timeval timeout; + + timeout.tv_sec = sec; + timeout.tv_usec = 0; + select(0,0,0,0, &timeout); +} + off_t file_size(const char *filename) { struct stat stat_buf; diff --git a/src/system/helpers.h b/src/system/helpers.h index 9639c39bf..2fbac55cd 100644 --- a/src/system/helpers.h +++ b/src/system/helpers.h @@ -39,6 +39,7 @@ void wakeup_hdd(const char *hdd_dir); int check_dir(const char * dir, bool allow_tmp = false); bool get_fs_usage(const char * dir, uint64_t &btotal, uint64_t &bused, long *bsize=NULL); bool get_mem_usage(unsigned long &total, unsigned long &free); +void mySleep(int sec); std::string getPathName(std::string &path); std::string getBaseName(std::string &path); @@ -64,7 +65,6 @@ class CFileHelpers bool copyDir(const char *Src, const char *Dst, bool backupMode=false); bool createDir(const char *Dir, mode_t mode); bool removeDir(const char *Dir); - }; template std::string to_string(C i) diff --git a/src/system/locals.h b/src/system/locals.h index 85e9442dc..b8fb0fc24 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -283,7 +283,8 @@ typedef enum LOCALE_CI_SETTINGS, LOCALE_CI_TIMEOUT, LOCALE_CI_WAITING, - LOCALE_CLOCK_SIZE, + LOCALE_CLOCK_BACKGROUND, + LOCALE_CLOCK_SECONDS, LOCALE_CLOCK_SIZE_HEIGHT, LOCALE_CLOCK_SWITCH_OFF, LOCALE_CLOCK_SWITCH_ON, @@ -839,6 +840,9 @@ typedef enum LOCALE_MENU_HINT_CHANNELLIST_SETUP, LOCALE_MENU_HINT_CHANNELS, LOCALE_MENU_HINT_CI, + LOCALE_MENU_HINT_CLOCK_BACKGROUND, + LOCALE_MENU_HINT_CLOCK_MODE, + LOCALE_MENU_HINT_CLOCK_SECONDS, LOCALE_MENU_HINT_CLOCK_SIZE, LOCALE_MENU_HINT_COLORS, LOCALE_MENU_HINT_CONTENT_BACK, @@ -1972,6 +1976,11 @@ typedef enum LOCALE_UNICABLE_LNB, LOCALE_UNICABLE_QRG, LOCALE_UNICABLE_SCR, + LOCALE_UNIT_DECIMAL, + LOCALE_UNIT_SHORT_HOUR, + LOCALE_UNIT_SHORT_MILLISECOND, + LOCALE_UNIT_SHORT_MINUTE, + LOCALE_UNIT_SHORT_SECOND, LOCALE_UPNPBROWSER_HEAD, LOCALE_UPNPBROWSER_NOSERVERS, LOCALE_UPNPBROWSER_RESCAN, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index e4ac4f635..808e8fe4b 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -283,7 +283,8 @@ const char * locale_real_names[] = "ci.settings", "ci.timeout", "ci.waiting", - "clock_size", + "clock_background", + "clock_seconds", "clock_size_height", "clock_switch_off", "clock_switch_on", @@ -839,6 +840,9 @@ const char * locale_real_names[] = "menu.hint_channellist_setup", "menu.hint_channels", "menu.hint_ci", + "menu.hint_clock_background", + "menu.hint_clock_mode", + "menu.hint_clock_seconds", "menu.hint_clock_size", "menu.hint_colors", "menu.hint_content_back", @@ -1972,6 +1976,11 @@ const char * locale_real_names[] = "unicable.lnb", "unicable.qrg", "unicable.scr", + "unit.decimal", + "unit.short.hour", + "unit.short.millisecond", + "unit.short.minute", + "unit.short.second", "upnpbrowser.head", "upnpbrowser.noservers", "upnpbrowser.rescan", diff --git a/src/system/settings.h b/src/system/settings.h index 3472df627..b4fc77683 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -39,6 +39,7 @@ #include #include #include +#include // UTF8 #include @@ -544,6 +545,8 @@ struct SNeutrinoSettings }; int infoClockFontSize; + int infoClockSeconds; + int infoClockBackground; // lcdd enum LCD_SETTINGS { @@ -572,9 +575,11 @@ struct SNeutrinoSettings int backlight_tv; int backlight_standby; int backlight_deepstandby; -#define FILESYSTEM_ENCODING_TO_UTF8(a) (g_settings.filesystem_is_utf8 ? (a) : ZapitTools::Latin1_to_UTF8(a).c_str()) +//#define FILESYSTEM_ENCODING_TO_UTF8(a) (g_settings.filesystem_is_utf8 ? (a) : ZapitTools::Latin1_to_UTF8(a).c_str()) +#define FILESYSTEM_ENCODING_TO_UTF8(a) (isUTF8(a) ? (a) : ZapitTools::Latin1_to_UTF8(a).c_str()) #define UTF8_TO_FILESYSTEM_ENCODING(a) (g_settings.filesystem_is_utf8 ? (a) : ZapitTools::UTF8_to_Latin1(a).c_str()) -#define FILESYSTEM_ENCODING_TO_UTF8_STRING(a) (g_settings.filesystem_is_utf8 ? (a) : ZapitTools::Latin1_to_UTF8(a)) +//#define FILESYSTEM_ENCODING_TO_UTF8_STRING(a) (g_settings.filesystem_is_utf8 ? (a) : ZapitTools::Latin1_to_UTF8(a)) +#define FILESYSTEM_ENCODING_TO_UTF8_STRING(a) (isUTF8(a) ? (a) : ZapitTools::Latin1_to_UTF8(a)) // pictureviewer char picviewer_slide_time[3];