diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index a3a470790..ba8f1d949 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -211,6 +211,7 @@ channellist.foot_freq Tuning-Parameter channellist.foot_next Nachfolgesendung channellist.foot_off aus channellist.foot_sort_alpha Sortiert[alpha] +channellist.foot_sort_chnum Sortiert[nummer] channellist.foot_sort_freq Sortiert[freq] channellist.foot_sort_sat Sortiert[sat] channellist.head Alle Kanäle @@ -436,6 +437,7 @@ filesystem.is.utf8 Dateisystem filesystem.is.utf8.option.iso8859.1 ISO-8859-1 filesystem.is.utf8.option.utf8 UTF-8 flashupdate.actionreadflash lese Flash +flashupdate.apply_settings Sollen die aktuellen Einstellungen in das neue Image übernommen werden? flashupdate.cantopenfile kann Datei nicht öffnen flashupdate.cantopenmtd kann MTD nicht öffnen flashupdate.checkupdate_internet Online nach Updates suchen @@ -748,6 +750,7 @@ menu.hint_epg_fonts Ändern Sie für die EPG-Details die Schriftgrößen menu.hint_epg_max_events Maximum an Events im Zwischenspeicher. Nach Erreichen der\nGrenze werden EPG-Daten für zukünftige gelöscht menu.hint_epg_old_events EPG im Speicher behalten in Stunden,\nauch wenn es veraltet ist menu.hint_epg_save Speichert die EPG-Daten auf einer Harddisk oder USB-Stick\nund läd es nach einen Neustart +menu.hint_epg_save_standby Speichert die EPG-Daten in Bereitschaft Modus menu.hint_event_textcolor Ändern Sie die Event-Farbe für farbige Event-Optionen in Kanalliste und Infobar menu.hint_eventlist_fonts Ändern Sie in der Event-Liste die Schriftgrößen menu.hint_extended Energiespar-, EPG-Speicher- / Lade-Optionen,\nHDMI-CEC, Startkanal, Zap-Optionen @@ -1099,6 +1102,7 @@ miscsettings.epg_old_events EPG verwerfen nach (Std.) miscsettings.epg_old_events_hint1 Wie lange abgelaufene EPG-Daten aufheben? miscsettings.epg_old_events_hint2 Angabe in Stunden miscsettings.epg_save EPG zwischenspeichern +miscsettings.epg_save_standby EPG speichern in Standby-Modus miscsettings.general Allgemein miscsettings.head Erweitert miscsettings.infobar Infobar @@ -1318,6 +1322,8 @@ networkmenu.dhcp DHCP networkmenu.error_no_address Keine %s-Adresse angegeben! networkmenu.gateway Standard Gateway networkmenu.hostname Hostname +networkmenu.hostname_hint1 Geben sie den Hostnamen ein +networkmenu.hostname_hint2 Eine Änderung benötigt einen Neustart networkmenu.inactive_network Netzwerk nicht aktiviert! networkmenu.ipaddress IP networkmenu.mount Netzwerkfreigaben bearbeiten diff --git a/data/locale/english.locale b/data/locale/english.locale index b10b81d96..59b3fe7da 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -211,6 +211,7 @@ channellist.foot_freq Sat/Freq Info channellist.foot_next next Event channellist.foot_off off channellist.foot_sort_alpha sorted[alpha] +channellist.foot_sort_chnum sorted[number] channellist.foot_sort_freq sorted[freq] channellist.foot_sort_sat sorted[sat] channellist.head All Services @@ -436,6 +437,7 @@ filesystem.is.utf8 file system filesystem.is.utf8.option.iso8859.1 ISO-8859-1 filesystem.is.utf8.option.utf8 UTF-8 flashupdate.actionreadflash reading +flashupdate.apply_settings Import current settings into new image? flashupdate.cantopenfile can't open file flashupdate.cantopenmtd can't open MTD flashupdate.checkupdate_internet Check for online updates @@ -748,6 +750,7 @@ menu.hint_epg_fonts Change EPG details window font sizes menu.hint_epg_max_events Maximum events to cache. After reaching limit\nEPG cache will remove future events menu.hint_epg_old_events Hours after event end time to consider\nevent old and remove it from cache menu.hint_epg_save Save cached EPG to harddisk or usb flash\nand load it after boot +menu.hint_epg_save_standby Save EPG on soft standby mode menu.hint_event_textcolor Change event color for colored-event options\nin channel list and infobar menu.hint_eventlist_fonts Change event list font sizes menu.hint_extended Power saving, EPG save/load options\nHDMI-CEC, Start channel, zap options @@ -1099,6 +1102,7 @@ miscsettings.epg_old_events EPG remove after (std.) miscsettings.epg_old_events_hint1 How long will EPG-Data be stored after they timed out? miscsettings.epg_old_events_hint2 Set in hours miscsettings.epg_save Save/Restore epg on reboot +miscsettings.epg_save_standby Save epg on soft standby miscsettings.general General miscsettings.head Extended settings miscsettings.infobar Infobar @@ -1318,6 +1322,8 @@ networkmenu.dhcp DHCP networkmenu.error_no_address Missing %s-address! networkmenu.gateway default gateway networkmenu.hostname Hostname +networkmenu.hostname_hint1 enter hostname +networkmenu.hostname_hint2 need reboot after change networkmenu.inactive_network Network inactiv! networkmenu.ipaddress IP address networkmenu.mount Edit network shares diff --git a/data/satellites.xml b/data/satellites.xml index 66bad02de..739e4d754 100755 --- a/data/satellites.xml +++ b/data/satellites.xml @@ -1572,6 +1572,7 @@ + diff --git a/data/settingsupdate.conf b/data/settingsupdate.conf index bae28ab75..795e0025b 100644 --- a/data/settingsupdate.conf +++ b/data/settingsupdate.conf @@ -1,6 +1,6 @@ # settings for logfile -Log=1 -LogFile=/tmp/update.log +#:Log=1 +#:LogFile=/tmp/update.log ## Mögliche Einträge: diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am index 0f6ed16c5..efc14c773 100644 --- a/src/driver/Makefile.am +++ b/src/driver/Makefile.am @@ -25,7 +25,7 @@ libneutrino_driver_a_SOURCES = \ fb_window.cpp \ file.cpp \ fontrenderer.cpp \ - genpsi.c \ + genpsi.cpp \ radiotext.cpp \ radiotools.cpp \ rcinput.cpp \ diff --git a/src/driver/file.h b/src/driver/file.h index 49cdaa04d..0ab9bca9c 100644 --- a/src/driver/file.h +++ b/src/driver/file.h @@ -40,7 +40,7 @@ in __USE_FILE_OFFSET64 mode */ #ifndef __USE_FILE_OFFSET64 -#error not using 64 bit file offsets +#define __USE_FILE_OFFSET64 #endif /* __USE_FILE__OFFSET64 */ #endif diff --git a/src/driver/genpsi.c b/src/driver/genpsi.cpp similarity index 69% rename from src/driver/genpsi.c rename to src/driver/genpsi.cpp index 6724369ea..266b727fd 100644 --- a/src/driver/genpsi.c +++ b/src/driver/genpsi.cpp @@ -1,10 +1,6 @@ /* -$Id: genpsi.c,v 1.2 2006/01/16 12:45:54 sat_man Exp $ - Copyright (c) 2004 gmo18t, Germany. All rights reserved. - - aktuelle Versionen gibt es hier: - $Source: /cvs/tuxbox/apps/tuxbox/neutrino/src/driver/genpsi.c,v $ + Copyright (C) 2012 CoolStream International Ltd This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -20,9 +16,9 @@ $Id: genpsi.c,v 1.2 2006/01/16 12:45:54 sat_man Exp $ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, USA. - Mit diesem Programm koennen Neutrino TS Streams für das Abspielen unter Enigma gepatched werden + Mit diesem Programm koennen Neutrino TS Streams für das Abspielen unter Enigma gepatched werden */ -//#include + #include #include #include @@ -31,26 +27,15 @@ $Id: genpsi.c,v 1.2 2006/01/16 12:45:54 sat_man Exp $ #define OFS_HDR_2 5 #define OFS_PMT_DATA 13 #define OFS_STREAM_TAB 17 -#define SIZE_STREAM_TAB_ROW 5 +#define SIZE_STREAM_TAB_ROW 5 #define OFS_ENIGMA_TAB 31 -#define SIZE_ENIGMA_TAB_ROW 4 +#define SIZE_ENIGMA_TAB_ROW 4 #define ES_TYPE_MPEG12 0x02 #define ES_TYPE_AVC 0x1b #define ES_TYPE_MPA 0x03 #define ES_TYPE_AC3 0x81 -typedef struct -{ - short nba; - uint16_t vpid; - uint8_t vtype; - uint16_t apid[10]; - short isAC3[10]; -} T_AV_PIDS; - -T_AV_PIDS avPids; - static const uint32_t crc_table[256] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, @@ -97,49 +82,6 @@ static const uint32_t crc_table[256] = { 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 }; -uint32_t calc_crc32psi(uint8_t *dst, const uint8_t *src, uint32_t len) -{ - uint32_t i; - uint32_t crc = 0xffffffff; - - for (i=0; i> 24) ^ *src++) & 0xff]; - - if (dst) - { - dst[0] = (crc >> 24) & 0xff; - dst[1] = (crc >> 16) & 0xff; - dst[2] = (crc >> 8) & 0xff; - dst[3] = (crc) & 0xff; - } - - return crc; -} - -void transfer_pids(uint16_t pid,uint16_t pidart,short isAC3) -{ - switch(pidart) - { - case EN_TYPE_VIDEO: - avPids.vpid=pid; - avPids.vtype = ES_TYPE_MPEG12; - break; - case EN_TYPE_AVC: - avPids.vpid=pid; - avPids.vtype = ES_TYPE_AVC; - break; - case EN_TYPE_AUDIO: - avPids.apid[avPids.nba]=pid; - avPids.isAC3[avPids.nba]=isAC3; - avPids.nba++; - break; - case EN_TYPE_TELTEX: - break; - - default: - break; - } -} //-- special enigma stream description packet for -- //-- at least 1 video, 1 audo and 1 PCR-Pid stream -- //------------------------------------------------------------------------------------ @@ -148,13 +90,13 @@ static uint8_t pkt_enigma[] = 0x47, 0x40, 0x1F, 0x10, 0x00, 0x7F, 0x80, 0x24, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x6D, 0x66, 0x30, 0x19, + 0x00, 0x00, 0x6D, 0x66, 0x30, 0x19, 0x80, 0x13, 'N','E','U','T','R','I','N','O','N','G', // tag(8), len(8), text(10) -> NG hihi ;) 0x00, 0x02, 0x00, 0x6e, // cVPID(8), len(8), PID(16) 0x01, 0x03, 0x00, 0x78, 0x00, // cAPID(8), len(8), PID(16), ac3flag(8) // 0x02, 0x02, 0x00, 0x82,// cTPID(8), len(8), ... 0x03, 0x02, 0x00, 0x6e // cPCRPID(8), ... -}; +}; //-- PAT packet for at least 1 PMT -- //---------------------------------------------------------- static uint8_t pkt_pat[] = @@ -165,25 +107,77 @@ static uint8_t pkt_pat[] = 0x6D, 0x66, 0xEF, 0xFF, // PAT-DATA - PMT (PID=0xFFF) entry }; -//-- PMT packet for at least 1 video and 1 audio stream -- +//-- PMT packet for at least 1 video and 1 audio stream -- //-------------------------------------------------------- static uint8_t pkt_pmt[] = { 0x47, 0x4F, 0xFF, 0x10, 0x00, // HEADER-1 0x02, 0xB0, 0x17, // HEADER-2 0x6D, 0x66, 0xE9, 0x00, 0x00, // HEADER-3 - 0xE0, 0x00, 0xF0, 0x00, // PMT-DATA + 0xE0, 0x00, 0xF0, 0x00, // PMT-DATA 0x02, 0xE0, 0x00, 0xF0, 0x00, // (video stream 1) 0x03, 0xE0, 0x00, 0xF0, 0x00 // (audio stream 1) -}; +}; +CGenPsi::CGenPsi() +{ + nba = 0; + vpid = 0; + vtype = 0; + memset(apid, 0, sizeof(apid)); + memset(atypes, 0, sizeof(atypes)); +} + +uint32_t CGenPsi::calc_crc32psi(uint8_t *dst, const uint8_t *src, uint32_t len) +{ + uint32_t i; + uint32_t crc = 0xffffffff; + + for (i=0; i> 24) ^ *src++) & 0xff]; + + if (dst) + { + dst[0] = (crc >> 24) & 0xff; + dst[1] = (crc >> 16) & 0xff; + dst[2] = (crc >> 8) & 0xff; + dst[3] = (crc) & 0xff; + } + + return crc; +} + +void CGenPsi::addPid(uint16_t pid, uint16_t pidtype, short isAC3) +{ + switch(pidtype) + { + case EN_TYPE_VIDEO: + vpid=pid; + vtype = ES_TYPE_MPEG12; + break; + case EN_TYPE_AVC: + vpid=pid; + vtype = ES_TYPE_AVC; + break; + case EN_TYPE_AUDIO: + apid[nba]=pid; + atypes[nba]=isAC3; + nba++; + break; + case EN_TYPE_TELTEX: + break; + + default: + break; + } +} //== setup a new TS packet with format == //== predefined with a template == //======================================= #define COPY_TEMPLATE(dst, src) copy_template(dst, src, sizeof(src)) -static int copy_template(uint8_t *dst, uint8_t *src, int len) +int CGenPsi::copy_template(uint8_t *dst, uint8_t *src, int len) { //-- reset buffer -- memset(dst, 0xFF, SIZE_TS_PKT); @@ -192,92 +186,93 @@ static int copy_template(uint8_t *dst, uint8_t *src, int len) return len; } -int genpsi(int fd2) + +int CGenPsi::genpsi(int fd) { -// int bytes = 0; uint8_t pkt[SIZE_TS_PKT]; int i, data_len, patch_len, ofs; -//-- copy "Enigma"-template -- + //-- copy "Enigma"-template -- data_len = COPY_TEMPLATE(pkt, pkt_enigma); -//-- adjust len dependent to number of audio streams -- - data_len += ((SIZE_ENIGMA_TAB_ROW+1) * (avPids.nba-1)); + //-- adjust len dependent to number of audio streams -- + data_len += ((SIZE_ENIGMA_TAB_ROW+1) * (nba-1)); patch_len = data_len - OFS_HDR_2 + 1; pkt[OFS_HDR_2+1] |= (patch_len>>8); - pkt[OFS_HDR_2+2] = (patch_len & 0xFF); -//-- write row with desc. for video stream -- + pkt[OFS_HDR_2+2] = (patch_len & 0xFF); + //-- write row with desc. for video stream -- ofs = OFS_ENIGMA_TAB; pkt[ofs] = EN_TYPE_VIDEO; pkt[ofs+1] = 0x02; - pkt[ofs+2] = (avPids.vpid>>8); - pkt[ofs+3] = (avPids.vpid & 0xFF); -//-- for each audio stream, write row with desc. -- - ofs += SIZE_ENIGMA_TAB_ROW; - for (i=0; i>8); + pkt[ofs+3] = (vpid & 0xFF); + //-- for each audio stream, write row with desc. -- + ofs += SIZE_ENIGMA_TAB_ROW; + for (i=0; i>8); - pkt[ofs+3] = (avPids.apid[i] & 0xFF); - pkt[ofs+4] = (avPids.isAC3[i]==1)? 0x01 : 0x00; + pkt[ofs+2] = (apid[i]>>8); + pkt[ofs+3] = (apid[i] & 0xFF); + pkt[ofs+4] = (atypes[i]==1)? 0x01 : 0x00; ofs += (SIZE_ENIGMA_TAB_ROW + 1); } -//-- write row with desc. for pcr stream (eq. video) -- + //-- write row with desc. for pcr stream (eq. video) -- pkt[ofs] = EN_TYPE_PCR; pkt[ofs+1] = 0x02; - pkt[ofs+2] = (avPids.vpid>>8); - pkt[ofs+3] = (avPids.vpid & 0xFF); - -//-- calculate CRC -- - calc_crc32psi(&pkt[data_len], &pkt[OFS_HDR_2], data_len-OFS_HDR_2 ); -//-- write TS packet -- - /*bytes +=*/ write(fd2, pkt, SIZE_TS_PKT); -//-- (II) build PAT -- - data_len = COPY_TEMPLATE(pkt, pkt_pat); -//-- calculate CRC -- - calc_crc32psi(&pkt[data_len], &pkt[OFS_HDR_2], data_len-OFS_HDR_2 ); -//-- write TS packet -- - /*bytes +=*/ write(fd2, pkt, SIZE_TS_PKT); + pkt[ofs+2] = (vpid>>8); + pkt[ofs+3] = (vpid & 0xFF); -//-- (III) build PMT -- + //-- calculate CRC -- + calc_crc32psi(&pkt[data_len], &pkt[OFS_HDR_2], data_len-OFS_HDR_2 ); + //-- write TS packet -- + write(fd, pkt, SIZE_TS_PKT); + + //-- (II) build PAT -- + data_len = COPY_TEMPLATE(pkt, pkt_pat); + //-- calculate CRC -- + calc_crc32psi(&pkt[data_len], &pkt[OFS_HDR_2], data_len-OFS_HDR_2 ); + //-- write TS packet -- + write(fd, pkt, SIZE_TS_PKT); + + //-- (III) build PMT -- data_len = COPY_TEMPLATE(pkt, pkt_pmt); -//-- adjust len dependent to count of audio streams -- - data_len += (SIZE_STREAM_TAB_ROW * (avPids.nba-1)); + //-- adjust len dependent to count of audio streams -- + data_len += (SIZE_STREAM_TAB_ROW * (nba-1)); patch_len = data_len - OFS_HDR_2 + 1; pkt[OFS_HDR_2+1] |= (patch_len>>8); - pkt[OFS_HDR_2+2] = (patch_len & 0xFF); -//-- patch pcr PID -- + pkt[OFS_HDR_2+2] = (patch_len & 0xFF); + //-- patch pcr PID -- ofs = OFS_PMT_DATA; - pkt[ofs] |= (avPids.vpid>>8); - pkt[ofs+1] = (avPids.vpid & 0xFF); -//-- write row with desc. for ES video stream -- + pkt[ofs] |= (vpid>>8); + pkt[ofs+1] = (vpid & 0xFF); + //-- write row with desc. for ES video stream -- ofs = OFS_STREAM_TAB; - pkt[ofs] = avPids.vtype; - pkt[ofs+1] = 0xE0 | (avPids.vpid>>8); - pkt[ofs+2] = (avPids.vpid & 0xFF); + pkt[ofs] = vtype; + pkt[ofs+1] = 0xE0 | (vpid>>8); + pkt[ofs+2] = (vpid & 0xFF); pkt[ofs+3] = 0xF0; pkt[ofs+4] = 0x00; -//-- for each ES audio stream, write row with desc. -- - for (i=0; i>8); - pkt[ofs+2] = (avPids.apid[i] & 0xFF); + pkt[ofs] = (atypes[i]==1)? ES_TYPE_AC3 : ES_TYPE_MPA; + pkt[ofs+1] = 0xE0 | (apid[i]>>8); + pkt[ofs+2] = (apid[i] & 0xFF); pkt[ofs+3] = 0xF0; pkt[ofs+4] = 0x00; } -//-- calculate CRC -- + //-- calculate CRC -- calc_crc32psi(&pkt[data_len], &pkt[OFS_HDR_2], data_len-OFS_HDR_2 ); -//-- write TS packet -- - /*bytes +=*/ write(fd2, pkt, SIZE_TS_PKT); -//-- finish -- - avPids.vpid=0; - avPids.nba=0; - fdatasync(fd2); + //-- write TS packet -- + write(fd, pkt, SIZE_TS_PKT); + //-- finish -- + vpid=0; + nba=0; + fdatasync(fd); return 1; } diff --git a/src/driver/genpsi.h b/src/driver/genpsi.h index 113eb883b..3e5c0a051 100644 --- a/src/driver/genpsi.h +++ b/src/driver/genpsi.h @@ -1,10 +1,7 @@ /* -$Id: genpsi.h,v 1.1 2005/08/15 14:47:52 metallica Exp $ Copyright (c) 2004 gmo18t, Germany. All rights reserved. - - aktuelle Versionen gibt es hier: - $Source: /cvs/tuxbox/apps/tuxbox/neutrino/src/driver/genpsi.h,v $ + Copyright (C) 2012 CoolStream International Ltd This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -26,13 +23,26 @@ $Id: genpsi.h,v 1.1 2005/08/15 14:47:52 metallica Exp $ #define __genpsi_h__ #include -int genpsi(int fd2); -void transfer_pids(uint16_t pid,uint16_t pidart,short isAC3); - #define EN_TYPE_VIDEO 0x00 #define EN_TYPE_AUDIO 0x01 #define EN_TYPE_TELTEX 0x02 #define EN_TYPE_PCR 0x03 #define EN_TYPE_AVC 0x04 +class CGenPsi +{ + private: + short nba; + uint16_t vpid; + uint8_t vtype; + uint16_t apid[10]; + short atypes[10]; + static int copy_template(uint8_t *dst, uint8_t *src, int len); + uint32_t calc_crc32psi(uint8_t *dst, const uint8_t *src, uint32_t len); + + public: + CGenPsi(); + void addPid(uint16_t pid,uint16_t pidtype, short isAC3); + int genpsi(int fd); +}; #endif diff --git a/src/driver/record.cpp b/src/driver/record.cpp index 9fdb848bb..1f2b428da 100644 --- a/src/driver/record.cpp +++ b/src/driver/record.cpp @@ -51,6 +51,7 @@ #include +#include #include #include #include @@ -156,15 +157,16 @@ record_error_msg_t CRecordInstance::Start(CZapitChannel * channel) return RECORD_INVALID_DIRECTORY; } + CGenPsi psi; if (allpids.PIDs.vpid != 0) - transfer_pids(allpids.PIDs.vpid, recMovieInfo->VideoType ? EN_TYPE_AVC : EN_TYPE_VIDEO, 0); + psi.addPid(allpids.PIDs.vpid, recMovieInfo->VideoType ? EN_TYPE_AVC : EN_TYPE_VIDEO, 0); numpids = 0; for (unsigned int i = 0; i < recMovieInfo->audioPids.size(); i++) { apids[numpids++] = recMovieInfo->audioPids[i].epgAudioPid; - transfer_pids(recMovieInfo->audioPids[i].epgAudioPid, EN_TYPE_AUDIO, recMovieInfo->audioPids[i].atype); + psi.addPid(recMovieInfo->audioPids[i].epgAudioPid, EN_TYPE_AUDIO, recMovieInfo->audioPids[i].atype); } - genpsi(fd); + psi.genpsi(fd); if ((StreamVTxtPid) && (allpids.PIDs.vtxtpid != 0)) apids[numpids++] = allpids.PIDs.vtxtpid; @@ -231,9 +233,9 @@ bool CRecordInstance::Stop(bool remove_event) CCamManager::getInstance()->Stop(channel_id, CCamManager::RECORD); if((autoshift && g_settings.auto_delete) /* || autoshift_delete*/) { - snprintf(buf,sizeof(buf), "\"%s.ts\"", filename); - my_system("nice", "-n20", "rm", "-f", buf); - snprintf(buf,sizeof(buf), "%s.xml", filename); + snprintf(buf,sizeof(buf), "nice -n 20 rm -f \"%s.ts\" &", filename); + my_system("/bin/sh", "-c", buf); + snprintf(buf,sizeof(buf), "%s.xml", filename); //autoshift_delete = false; unlink(buf); } @@ -1590,12 +1592,16 @@ bool CRecordManager::CutBackNeutrino(const t_channel_id channel_id, CFrontend * * needed, if record frontend same as live, and its on different TP */ bool found = (live_fe != frontend) || SAME_TRANSPONDER(live_channel_id, channel_id); if(found) { + /* stop stream for this channel */ + CStreamManager::getInstance()->StopStream(channel_id); ret = g_Zapit->zapTo_record(channel_id) > 0; printf("%s found same tp, zapTo_record channel_id %" PRIx64 " result %d\n", __func__, channel_id, ret); } else { printf("%s mode %d last_mode %d getLastMode %d\n", __FUNCTION__, mode, last_mode, CNeutrinoApp::getInstance()->getLastMode()); StopAutoRecord(false); + /* stop all streams */ + CStreamManager::getInstance()->StopStream(); if (mode != last_mode && (last_mode != NeutrinoMessages::mode_standby || mode != CNeutrinoApp::getInstance()->getLastMode())) { CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::CHANGEMODE , mode | NeutrinoMessages::norezap ); mode_changed = true; @@ -1619,6 +1625,8 @@ bool CRecordManager::CutBackNeutrino(const t_channel_id channel_id, CFrontend * g_Zapit->stopPlayBack(); if ((live_channel_id == channel_id) && g_Radiotext) g_Radiotext->radiotext_stop(); + /* in case channel_id == live_channel_id */ + CStreamManager::getInstance()->StopStream(channel_id); } if(last_mode == NeutrinoMessages::mode_standby) { //CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::CHANGEMODE , NeutrinoMessages::mode_standby); diff --git a/src/driver/streamts.cpp b/src/driver/streamts.cpp index 83d2ced89..9649e37f8 100644 --- a/src/driver/streamts.cpp +++ b/src/driver/streamts.cpp @@ -1,3 +1,29 @@ +/* + Neutrino-GUI - DBoxII-Project + + Copyright (C) 2011-2012 CoolStream International Ltd + + based on code which is + Copyright (C) 2002 Andreas Oberritter + Copyright (C) 2001 TripleDES + Copyright (C) 2000, 2001 Marcus Metzler + + License: GPLv2 + + 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; + + 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. +*/ + #include #include #include @@ -13,10 +39,8 @@ #include #include -/* work around for building with old kernel headers */ -#ifndef POLLRDHUP -#define POLLRDHUP 0 -#endif +#include +#include #ifdef HAVE_CONFIG_H #include @@ -28,250 +52,238 @@ #include #include #include +#include +#include +#include +#include +/* experimental mode: + * stream not possible, if record running + * pids in url ignored, and added from channel, with fake PAT/PMT + * different channels supported, only from the same transponder - no zap is done, + * with url like http://coolstream:31339/id=c32400030070283e (channel id) + * TODO: multi-tuner support + */ +#define ENABLE_MULTI_CHANNEL #define TS_SIZE 188 -#define IN_SIZE (2048 * TS_SIZE) -//#define IN_SIZE (TS_SIZE * 362) +#define DMX_BUFFER_SIZE (2048*TS_SIZE) +#define IN_SIZE (250*TS_SIZE) -#define DMX_BUFFER_SIZE (2 * 3008 * 62) - -/* maximum number of pes pids */ -#define MAXPIDS 64 - -/* tcp packet data size */ -//#define PACKET_SIZE 1448 -#define PACKET_SIZE 7*TS_SIZE - -//unsigned char * buf; - -extern CCam *cam0; - -//int demuxfd[MAXPIDS]; - -static unsigned char exit_flag = 0; -static unsigned int writebuf_size = 0; -static unsigned char writebuf[PACKET_SIZE]; - -void packet_stdout (int fd, unsigned char * buf, int count, void * /*p*/) +CStreamInstance::CStreamInstance(int clientfd, t_channel_id chid, stream_pids_t &_pids) { - - unsigned int size; - unsigned char * bp; - ssize_t written; - -//printf("packet_stdout count %d\n", count); - /* ensure, that there is always at least one complete - * packet inside of the send buffer */ - while (writebuf_size + count >= PACKET_SIZE) { - - /* how many bytes are to be sent from the input buffer? */ - size = PACKET_SIZE - writebuf_size; - - /* send buffer is not empty, so copy from - input buffer to get a complete packet */ - if (writebuf_size) { - memmove(writebuf + writebuf_size, buf, size); - bp = writebuf; - } - - /* if send buffer is empty, then do not memcopy, - but send directly from input buffer */ - else { - bp = buf; - } - - /* write the packet, count the amount of really written bytes */ - written = write(fd, bp, PACKET_SIZE); - - /* exit on error */ - if (written == -1) { - perror("write"); - exit_flag = 1; - return; - } - - /* if the packet could not be written completely, then - * how many bytes must be stored in the send buffer - * until the next packet is to be sent? */ - writebuf_size = PACKET_SIZE - written; - - /* move all bytes of the packet which were not sent - * to the beginning of the send buffer */ - if (writebuf_size) - memmove(writebuf, bp + written, writebuf_size); - - /* * advance in the input buffer */ - buf += size; - - /* * decrease the todo size */ - count -= size; - } - - /* if there are still some bytes left in the input buffer, - * then store them in the send buffer and increase send - * buffer size */ - if (count) { - memmove(writebuf + writebuf_size, buf, count); - writebuf_size += count; - } + printf("CStreamInstance:: new channel %llx fd %d\n", chid, clientfd); + fds.insert(clientfd); + pids = _pids; + channel_id = chid; + running = false; + dmx = NULL; + buf = NULL; } -int open_incoming_port (int port) +CStreamInstance::~CStreamInstance() { - struct sockaddr_in socketAddr; - int socketOptActive = 1; - int handle; - - if (!port) - return -1; - - if ((handle = socket (AF_INET, SOCK_STREAM, 0)) < 0) - { - fprintf (stderr, "network port %u open: ", port); - perror ("socket"); - return -1; - } - - if (setsockopt (handle, SOL_SOCKET, SO_REUSEADDR, (const void *)&socketOptActive, sizeof (int)) < 0) - { - fprintf (stderr, "network port %u open: error setsockopt\n", port); - close (handle); - return -1; - } - - socketAddr.sin_family = AF_INET; - socketAddr.sin_port = htons (port); - socketAddr.sin_addr.s_addr = htonl (INADDR_ANY); - - if (bind (handle, (struct sockaddr *) &socketAddr, sizeof (socketAddr)) < 0) - { - fprintf (stderr, "network port %u open: ", port); - perror ("bind"); - close (handle); - return -1; - } - - if (listen (handle, 5) < 0) - { - fprintf (stderr, "network port %u open: ", port); - perror ("listen"); - close (handle); - return -1; - } - return handle; + Stop(); + Close(); } -void * streamts_live_thread(void *data); -int streamts_stop; - -void streamts_main_thread(void * /*data*/) +bool CStreamInstance::Start() { - struct sockaddr_in servaddr; - int clilen; + if (running) + return false; - struct pollfd pfd[128]; - int poll_cnt, tcnt; - int listenfd; - int connfd = -1; - int pollres; - int i; - pthread_t st = 0; - - printf("Starting STREAM thread keeper, tid %ld\n", syscall(__NR_gettid)); - - listenfd = open_incoming_port(31339); - if(listenfd < 0) { - printf("Open incoming port failed\n"); - return; + buf = new unsigned char [IN_SIZE]; + if (buf == NULL) { + perror("CStreamInstance::Start: buf"); + return false; } - printf("listenfd %d\n", listenfd); - - clilen = sizeof (servaddr); - pfd[0].fd = listenfd; - pfd[0].events = (POLLIN | POLLPRI); - pfd[0].revents = 0; - tcnt = 1; - streamts_stop = 0; - - while (!streamts_stop) { - poll_cnt = tcnt; -//printf("polling, count= %d\n", poll_cnt); - pollres = poll (pfd, poll_cnt, 1000); - if (pollres < 0) { - perror("streamts_main_thread poll"); - continue; - } - if(pollres == 0) - continue; - for (i = poll_cnt - 1; i >= 0; i--) { - if (pfd[i].revents & (POLLIN | POLLPRI | POLLHUP | POLLRDHUP)) { - printf("fd %d has events %x\n", pfd[i].fd, pfd[i].revents); - if (pfd[i].fd == listenfd) { - connfd = accept (listenfd, (struct sockaddr *) &servaddr, (socklen_t *) & clilen); - printf("new connection, fd %d\n", connfd); - if(connfd < 0) { - perror("accept"); - continue; - } - if(st != 0) { - printf("New connection, stopping stream thread\n"); - exit_flag = 1; - pthread_join(st, NULL); - tcnt --; - } - pfd[tcnt].fd = connfd; - pfd[tcnt].events = POLLRDHUP | POLLHUP; - pfd[tcnt].revents = 0; - tcnt++; - exit_flag = 0; - pthread_create (&st, NULL, streamts_live_thread, &connfd); - } else { - if (pfd[i].revents & (POLLHUP | POLLRDHUP)) { - connfd = -1; - printf("Client disconnected, stopping stream thread\n"); - exit_flag = 1; - if(st) - pthread_join(st, NULL); - st = 0; - tcnt --; - } - } - } - } - } - printf("Stopping STREAM thread keeper\n"); - close(listenfd); - if(st != 0) { - printf("Stopping stream thread\n"); - exit_flag = 1; - pthread_cancel(st); - pthread_join(st, NULL); - close(connfd); - } - return; + running = true; + printf("CStreamInstance::Start: %llx\n", channel_id); + return (OpenThreads::Thread::start() == 0); } -void * streamts_live_thread(void *data) +bool CStreamInstance::Stop() +{ + if (!running) + return false; + + printf("CStreamInstance::Stop: %llx\n", channel_id); + running = false; + return (OpenThreads::Thread::join() == 0); +} + +bool CStreamInstance::Send(ssize_t r) +{ + mutex.lock(); + for (stream_fds_t::iterator it = fds.begin(); it != fds.end(); ++it) { + int ret, i = 10; + do { + ret = send(*it, buf, r, MSG_DONTWAIT); +#if 0 + if (ret != r) + usleep(100); +#endif + } while ((ret != r) && (i-- > 0)); + if (ret != r) { + if (r < 0) + perror("send"); + printf("send err, fd %d: %d\n", *it, r); + } + } + mutex.unlock(); + return true; +} + +void CStreamInstance::Close() +{ + for (stream_fds_t::iterator fit = fds.begin(); fit != fds.end(); ++fit) + close(*fit); + fds.clear(); +} + +void CStreamInstance::AddClient(int clientfd) +{ + mutex.lock(); + fds.insert(clientfd); + printf("CStreamInstance::AddClient: %d (count %d)\n", clientfd, fds.size()); + mutex.unlock(); +} + +void CStreamInstance::RemoveClient(int clientfd) +{ + mutex.lock(); + fds.erase(clientfd); + close(clientfd); + printf("CStreamInstance::RemoveClient: %d (count %d)\n", clientfd, fds.size()); + mutex.unlock(); +} + +void CStreamInstance::run() +{ + printf("CStreamInstance::run: %llx\n", channel_id); + +#ifndef HAVE_COOL_HARDWARE + /* right now, only one stream is possible anyway and it is not possible + * to stream a different channel than the live channel AFAICT, so we can + * as well use the live demux */ + dmx = new cDemux(0); +#else + dmx = new cDemux(STREAM_DEMUX);//FIXME +#endif + + dmx->Open(DMX_TP_CHANNEL, NULL, DMX_BUFFER_SIZE); + + /* pids here cannot be empty */ + stream_pids_t::iterator it = pids.begin(); + printf("CStreamInstance::run: add pid %x\n", *it); + dmx->pesFilter(*it); + ++it; + for (; it != pids.end(); ++it) { + printf("CStreamInstance::run: add pid %x\n", *it); + dmx->addPid(*it); + } +#ifdef ENABLE_MULTI_CHANNEL + dmx->Start();//FIXME +#else + dmx->Start(true);//FIXME +#endif + + CCamManager::getInstance()->Start(channel_id, CCamManager::STREAM); + + while (running) { + ssize_t r = dmx->Read(buf, IN_SIZE, 100); + if(r > 0) + Send(r); + } + + CCamManager::getInstance()->Stop(channel_id, CCamManager::STREAM); + + printf("CStreamInstance::run: exiting %llx (%d fds)\n", channel_id, fds.size()); + + Close(); + delete dmx; + delete []buf; +} + +bool CStreamInstance::HasFd(int fd) +{ + if (fds.find(fd) != fds.end()) + return true; + return false; +} + +/************************************************************************/ +CStreamManager *CStreamManager::sm = NULL; +CStreamManager::CStreamManager() +{ + enabled = true; + running = false; + listenfd = -1; + port = 31339; +} + +CStreamManager::~CStreamManager() +{ + Stop(); +} + +CStreamManager * CStreamManager::getInstance() +{ + if (sm == NULL) + sm = new CStreamManager(); + return sm; +} + +bool CStreamManager::Start(int _port) +{ + if (running) + return false; + + if (_port) + port = _port; + if (!Listen()) + return false; + + running = true; + return (OpenThreads::Thread::start() == 0); +} + +bool CStreamManager::Stop() +{ + if (!running) + return false; + running = false; + return (OpenThreads::Thread::join() == 0); +} + +bool CStreamManager::SetPort(int newport) +{ + bool ret = false; + if (port != newport) { + port = newport; +#if 0 + Stop(); + ret = Start(newport); +#endif + mutex.lock(); + if (listenfd >= 0) + close(listenfd); + ret = Listen(); + mutex.unlock(); + } + return ret; +} + +bool CStreamManager::Parse(int fd, stream_pids_t &pids, t_channel_id &chid) { - unsigned char * buf; - int pid; - int pids[MAXPIDS]; char cbuf[512]; char *bp; - int fd = *((int *)data); - FILE * fp; - unsigned char demuxfd_count = 0; - printf("Starting LIVE STREAM thread, fd %d\n", fd); - fp = fdopen(fd, "r+"); + FILE * fp = fdopen(fd, "r+"); if(fp == NULL) { perror("fdopen"); - return 0; + return false; } - - writebuf_size = 0; - cbuf[0] = 0; bp = &cbuf[0]; @@ -281,7 +293,7 @@ void * streamts_live_thread(void *data) int res = read(fd, &c, 1); if(res < 0) { perror("read"); - return 0; + return false; } if ((*bp++ = c) == '\n') break; @@ -290,7 +302,7 @@ void * streamts_live_thread(void *data) *bp++ = 0; bp = &cbuf[0]; - printf("stream: got %s\n", cbuf); + printf("CStreamManager::Parse: got %s\n", cbuf); /* send response to http client */ if (!strncmp(cbuf, "GET /", 5)) { @@ -299,172 +311,256 @@ void * streamts_live_thread(void *data) bp += 5; } else { printf("Received garbage\n"); - return 0; + return false; } +#ifndef ENABLE_MULTI_CHANNEL /* parse stdin / url path, start dmx filters */ do { + int pid; int res = sscanf(bp, "%x", &pid); if(res == 1) { printf("New pid: 0x%x\n", pid); - pids[demuxfd_count++] = pid; + pids.insert(pid); } } - while ((bp = strchr(bp, ',')) && (bp++) && (demuxfd_count < MAXPIDS)); + while ((bp = strchr(bp, ',')) && (bp++)); +#endif - if(demuxfd_count == 0) { - printf("No pids!\n"); - CZapitChannel * channel = CZapit::getInstance()->GetCurrentChannel(); + chid = CZapit::getInstance()->GetCurrentChannelID(); + CZapitChannel * channel = CZapit::getInstance()->GetCurrentChannel(); + + int mode = CNeutrinoApp::getInstance()->getMode(); + if (mode == NeutrinoMessages::mode_standby && streams.empty()) { + printf("CStreamManager::Parse: wakeup zapit..\n"); + g_Zapit->setStandby(false); + g_Zapit->getMode(); + } + if(pids.empty()) { +#ifdef ENABLE_MULTI_CHANNEL + t_channel_id tmpid; + bp = &cbuf[5]; + if (sscanf(bp, "id=%llx", &tmpid) == 1) { + printf("############################# channel_id %llx\n", tmpid); + + CZapitChannel * tmpchan = CServiceManager::getInstance()->FindChannel(tmpid); + if (tmpchan && (tmpid != chid) && SAME_TRANSPONDER(tmpid, chid)) { + printf("############################# channel_id %llx -> zap\n", tmpid); + bool ret = g_Zapit->zapTo_record(tmpid) > 0; + if (ret) { + channel = tmpchan; + chid = tmpid; + } + } + } + if(CRecordManager::getInstance()->RecordingStatus(tmpid)) { + printf("CStreamManager::Parse: channel %llx recorded, aborting..\n", tmpid); + return false; + } +#endif + + printf("CStreamManager::Parse: no pids in url, using channel %llx pids\n", chid); if(!channel) - return 0; - pids[demuxfd_count++] = 0; - pids[demuxfd_count++] = channel->getPmtPid(); - pids[demuxfd_count++] = channel->getVideoPid(); + return false; + //pids.insert(0); + //pids.insert(channel->getPmtPid()); + pids.insert(channel->getVideoPid()); for (int i = 0; i < channel->getAudioChannelCount(); i++) - pids[demuxfd_count++] = channel->getAudioChannel(i)->pid; + pids.insert(channel->getAudioChannel(i)->pid); } - - buf = (unsigned char *) malloc(IN_SIZE); - if (buf == NULL) { - perror("malloc"); - return 0; + CGenPsi psi; + for (stream_pids_t::iterator it = pids.begin(); it != pids.end(); ++it) { + if (*it == channel->getVideoPid()) { + printf("CStreamManager::Parse: genpsi vpid %x (%d)\n", *it, channel->type); + psi.addPid(*it, channel->type ? EN_TYPE_AVC : EN_TYPE_VIDEO, 0); + } else { + for (int i = 0; i < channel->getAudioChannelCount(); i++) { + if (*it == channel->getAudioChannel(i)->pid) { + CZapitAudioChannel::ZapitAudioChannelType atype = channel->getAudioChannel(i)->audioChannelType; + printf("CStreamManager::Parse: genpsi apid %x (%d)\n", *it, atype); + psi.addPid(*it, EN_TYPE_AUDIO, atype); + } + } + } } + psi.genpsi(fd); -#ifndef HAVE_COOL_HARDWARE - /* right now, only one stream is possible anyway and it is not possible - * to stream a different channel than the live channel AFAICT, so we can - * as well use the live demux */ - cDemux * dmx = new cDemux(0); -#else - cDemux * dmx = new cDemux(STREAM_DEMUX);//FIXME -#endif - - dmx->Open(DMX_TP_CHANNEL, NULL, DMX_BUFFER_SIZE); - - dmx->pesFilter(pids[0]); - for(int i = 1; i < demuxfd_count; i++) - dmx->addPid(pids[i]); - - dmx->Start(true);//FIXME - - CCamManager::getInstance()->Start(CZapit::getInstance()->GetCurrentChannelID(), CCamManager::STREAM); - ssize_t r; - - while (!exit_flag) { - r = dmx->Read(buf, IN_SIZE, 100); - if(r > 0) - packet_stdout(fd, buf, r, NULL); - } - - printf("Exiting LIVE STREAM thread, fd %d\n", fd); - - CCamManager::getInstance()->Stop(CZapit::getInstance()->GetCurrentChannelID(), CCamManager::STREAM); - - delete dmx; - free(buf); - close(fd); - return 0; + return !pids.empty(); } -#if 0 -//never used -void streamts_file_thread(void *data) + +void CStreamManager::run() { - int dvrfd; - unsigned char * buf; - char cbuf[512]; - char *bp; - unsigned char mode = 0; - char tsfile[IN_SIZE]; - int tsfilelen = 0; - int fileslice = 0; - int i = 0; - int fd = *((int *)data); + struct sockaddr_in servaddr; + int clilen = sizeof(servaddr);; - buf = (unsigned char *) malloc(IN_SIZE); + struct pollfd pfd[128]; + int poll_cnt; - if (buf == NULL) { - perror("malloc"); - return; - } + printf("Starting STREAM thread keeper, tid %ld\n", syscall(__NR_gettid)); - bp = &cbuf[0]; - - /* read one line */ - while (bp - &cbuf[0] < IN_SIZE) { - unsigned char c; - read(fd, &c, 1); - if ((*bp++ = c) == '\n') - break; - } - - *bp++ = 0; - bp = &cbuf[0]; - - /* send response to http client */ - if (!strncmp(cbuf, "GET /", 5)) { - printf("HTTP/1.1 200 OK\r\nServer: streamts (%s)\r\n\r\n", "ts" /*&argv[1][1]*/); - fflush(stdout); - bp += 5; - } - - /* ts filename */ - int j = 0; - i = 0; - while (i < (int) strlen(bp) - 3) - { - if ((bp[i] == '.') && (bp[i + 1] == 't') && (bp[i + 2] == 's')) - { - tsfile[j] = bp[i]; - tsfile[j + 1] = bp[i + 1]; - tsfile[j + 2] = bp[i + 2]; - tsfile[j + 3] = '\0'; - break; - } - else - if ((bp[i] == '%') && (bp[i + 1] == '2') && (bp[i + 2] == '0')) - { - tsfile[j++] = ' '; - i += 3; + while (running) { + mutex.lock(); + pfd[0].fd = listenfd; + pfd[0].events = (POLLIN | POLLPRI); + pfd[0].revents = 0; + poll_cnt = 1; + for (streammap_iterator_t it = streams.begin(); it != streams.end(); ++it) { + stream_fds_t fds = it->second->GetFds(); + for (stream_fds_t::iterator fit = fds.begin(); fit != fds.end(); ++fit) { + pfd[poll_cnt].fd = *fit; + pfd[poll_cnt].events = POLLRDHUP | POLLHUP; + pfd[poll_cnt].revents = 0; + poll_cnt++; } - else - tsfile[j++] = bp[i++]; - } - tsfilelen = strlen(tsfile); - /* open ts file */ - if ((dvrfd = open(tsfile, O_RDONLY)) < 0) { - free(buf); - return; - } - - size_t pos; - ssize_t r; - - while (!exit_flag) { - /* always read IN_SIZE bytes */ - for (pos = 0; pos < IN_SIZE; pos += r) { - r = read(dvrfd, buf + pos, IN_SIZE - pos); - if (r == -1) { - /* Error */ - exit_flag = 1; - break; - } else if (r == 0) { - /* End of file */ - if (mode == 3) { - close(dvrfd); - sprintf(&tsfile[tsfilelen], ".%03d", ++fileslice); - dvrfd = open(tsfile, O_RDONLY); - } - if ((dvrfd == -1) || (mode != 3)) { - exit_flag = 1; - break; + } + mutex.unlock(); +//printf("polling, count= %d\n", poll_cnt); + int pollres = poll (pfd, poll_cnt, 1000); + if (pollres < 0) { + perror("CStreamManager::run(): poll"); + continue; + } + if(pollres == 0) + continue; + for (int i = poll_cnt - 1; i >= 0; i--) { + if (pfd[i].revents & (POLLIN | POLLPRI | POLLHUP | POLLRDHUP)) { + printf("fd %d has events %x\n", pfd[i].fd, pfd[i].revents); + if (pfd[i].fd == listenfd) { + int connfd = accept (listenfd, (struct sockaddr *) &servaddr, (socklen_t *) & clilen); + printf("CStreamManager::run(): connection, fd %d\n", connfd); + if(connfd < 0) { + perror("CStreamManager::run(): accept"); + continue; + } + stream_pids_t pids; + t_channel_id channel_id; + if (Parse(connfd, pids, channel_id)) { + mutex.lock(); + streammap_iterator_t it = streams.find(channel_id); + if (it != streams.end()) { + it->second->AddClient(connfd); + } else { + CStreamInstance * stream = new CStreamInstance(connfd, channel_id, pids); + if (stream->Start()) + streams.insert(streammap_pair_t(channel_id, stream)); + else + delete stream; + } + mutex.unlock(); + } else { + close(connfd); + } + } else { + if (pfd[i].revents & (POLLHUP | POLLRDHUP)) { + printf("CStreamManager::run(): POLLHUP, fd %d\n", pfd[i].fd); + mutex.lock(); + for (streammap_iterator_t it = streams.begin(); it != streams.end(); ++it) { + if (it->second->HasFd(pfd[i].fd)) { + CStreamInstance *stream = it->second; + stream->RemoveClient(pfd[i].fd); + if (stream->GetFds().empty()) { + streams.erase(stream->GetChannelId()); + delete stream; + } + break; + } + } + mutex.unlock(); + } } } } - packet_stdout(fd, buf, pos, NULL); } - close(dvrfd); - free(buf); - - return; + printf("CStreamManager::run: stopping...\n"); + close(listenfd); + listenfd = -1; + StopAll(); } + +bool CStreamManager::StopAll() +{ + bool ret = !streams.empty(); + for (streammap_iterator_t it = streams.begin(); it != streams.end(); ++it) { + it->second->Stop(); + delete it->second; + } + streams.clear(); + return ret; +} + +bool CStreamManager::StopStream(t_channel_id channel_id) +{ + bool ret = false; + mutex.lock(); + if (channel_id) { + streammap_iterator_t it = streams.find(channel_id); + if (it != streams.end()) { + delete it->second; + streams.erase(channel_id); + ret = true; + } + } else { + ret = StopAll(); + } + mutex.unlock(); + return ret; +} + +bool CStreamManager::StreamStatus(t_channel_id channel_id) +{ + bool ret; + mutex.lock(); + if (channel_id) + ret = (streams.find(channel_id) != streams.end()); + else + ret = !streams.empty(); + mutex.unlock(); + return ret; +} + +bool CStreamManager::Listen() +{ + struct sockaddr_in socketAddr; + int socketOptActive = 1; + int sendsize = 10*IN_SIZE; + unsigned int m = sizeof(sendsize); + + if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + fprintf (stderr, "network port %u open: ", port); + perror ("socket"); + return false; + } + + if (setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&socketOptActive, sizeof (int)) < 0) { + fprintf (stderr, "network port %u open: error setsockopt\n", port); + perror ("setsockopt"); + goto _error; + } + + socketAddr.sin_family = AF_INET; + socketAddr.sin_port = htons (port); + socketAddr.sin_addr.s_addr = htonl (INADDR_ANY); + + if (bind (listenfd, (struct sockaddr *) &socketAddr, sizeof (socketAddr)) < 0) { + fprintf (stderr, "network port %u open: ", port); + perror ("bind"); + goto _error; + } + + if (listen (listenfd, 5) < 0) { + fprintf (stderr, "network port %u open: ", port); + perror ("listen"); + goto _error; + } + +#if 1 + setsockopt(listenfd, SOL_SOCKET, SO_SNDBUF, (void *)&sendsize, m); + sendsize = 0; + getsockopt(listenfd, SOL_SOCKET, SO_SNDBUF, (void *)&sendsize, &m); + printf("CStreamManager::Listen: on %d, fd %d (%d)\n", port, listenfd, sendsize); #endif + return true; +_error: + close (listenfd); + return false; +} diff --git a/src/driver/streamts.h b/src/driver/streamts.h new file mode 100644 index 000000000..9b10ddeca --- /dev/null +++ b/src/driver/streamts.h @@ -0,0 +1,96 @@ +/* + Neutrino-GUI - DBoxII-Project + + Copyright (C) 2011-2012 CoolStream International Ltd + + License: GPLv2 + + 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; + + 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 __streamts_h__ +#define __streamts_h__ + +#include +#include + +#include +#include +#include +#include + +typedef std::set stream_pids_t; +typedef std::set stream_fds_t; + +class CStreamInstance : public OpenThreads::Thread +{ + private: + bool running; + cDemux * dmx; + OpenThreads::Mutex mutex; + unsigned char * buf; + + t_channel_id channel_id; + stream_pids_t pids; + stream_fds_t fds; + + bool Send(ssize_t r); + void Close(); + void run(); + public: + CStreamInstance(int clientfd, t_channel_id chid, stream_pids_t &pids); + ~CStreamInstance(); + bool Start(); + bool Stop(); + void AddClient(int clientfd); + void RemoveClient(int clientfd); + bool HasFd(int fd); + stream_fds_t & GetFds() { return fds; } + t_channel_id GetChannelId() { return channel_id; } +}; + +typedef std::pair streammap_pair_t; +typedef std::map streammap_t; +typedef streammap_t::iterator streammap_iterator_t; + +class CStreamManager : public OpenThreads::Thread +{ + private: + bool enabled; + bool running; + int listenfd; + int port; + + OpenThreads::Mutex mutex; + static CStreamManager * sm; + + streammap_t streams; + + bool Listen(); + bool Parse(int fd, stream_pids_t &pids, t_channel_id &chid); + bool StopAll(); + void run(); + CStreamManager(); + public: + ~CStreamManager(); + static CStreamManager * getInstance(); + bool Start(int port = 0); + bool Stop(); + bool StopStream(t_channel_id channel_id = 0); + bool StreamStatus(t_channel_id channel_id = 0); + bool SetPort(int newport); + int GetPort() { return port; } +}; + +#endif diff --git a/src/gui/audioplayer.cpp b/src/gui/audioplayer.cpp index f0fa06614..561b9c8e0 100644 --- a/src/gui/audioplayer.cpp +++ b/src/gui/audioplayer.cpp @@ -5,7 +5,7 @@ (C) 2002-2008 the tuxbox project contributors (C) 2008 Novell, Inc. Author: Stefan Seyfried - (C) 2011 Stefan Seyfried + (C) 2011-2012 Stefan Seyfried Homepage: http://dbox.cyberphoria.org/ @@ -21,7 +21,7 @@ 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 3 of the License, or + 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, @@ -65,6 +65,8 @@ #include #include +#include "gui/pictureviewer.h" + #include #include #include @@ -198,6 +200,8 @@ void CAudioPlayerGui::Init(void) m_selected = 0; m_metainfo.clear(); + pictureviewer = false; + m_select_title_by_name = g_settings.audioplayer_select_title_by_name==1; if (strlen(g_settings.network_nfs_audioplayerdir)!=0) @@ -753,6 +757,22 @@ int CAudioPlayerGui::show() } } } + else if ( (msg == CRCInput::RC_info) && (!m_playlist.empty()) ) + { + pictureviewer = true; + m_frameBuffer->Clear(); + videoDecoder->StopPicture(); + CPictureViewerGui * picture = new CPictureViewerGui(); + picture->m_audioPlayer = this; + picture->exec(this, "audio"); + delete picture; + pictureviewer = false; + videoDecoder->setBlank(true); + videoDecoder->ShowPicture(DATADIR "/neutrino/icons/mp3.jpg"); + CVFD::getInstance()->setMode(CVFD::MODE_AUDIO); + paintLCD(); + screensaver(false); + } else if (msg == CRCInput::RC_help) { if (m_key_level == 2) @@ -905,6 +925,17 @@ bool CAudioPlayerGui::playNext(bool allow_rotate) return(result); } +void CAudioPlayerGui::wantNextPlay() +{ + if ((m_state != CAudioPlayerGui::STOP) && + (CAudioPlayer::getInstance()->getState() == CBaseDec::STOP) && + (!m_playlist.empty())) + { + if (m_curr_audiofile.FileType != CFile::STREAM_AUDIO) + playNext(); + } +} + bool CAudioPlayerGui::playPrev(bool allow_rotate) { bool result = false; @@ -1701,10 +1732,11 @@ const struct button_label AudioPlayerButtons[][4] = void CAudioPlayerGui::paintFoot() { // printf("paintFoot{\n"); -const struct button_label ScondLineButtons[2] = +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; @@ -1719,8 +1751,7 @@ const struct button_label ScondLineButtons[2] = m_frameBuffer->paintHLine(m_x, m_x + m_width, top, COL_INFOBAR_SHADOW_PLUS_1); if (!m_playlist.empty()) - ::paintButtons(m_x, top+m_buttonHeight, m_width, 2, ScondLineButtons, m_width, m_buttonHeight); - + ::paintButtons(m_x, top+m_buttonHeight, m_width, 3, ScondLineButtons, m_width, m_buttonHeight); if (m_key_level == 0) { @@ -1949,12 +1980,16 @@ void CAudioPlayerGui::stop() { m_state = CAudioPlayerGui::STOP; m_current = 0; - //LCD - paintLCD(); - //Display - paintInfo(); - m_key_level = 0; - paintFoot(); + + if (!pictureviewer) + { + //LCD + paintLCD(); + //Display + paintInfo(); + m_key_level = 0; + paintFoot(); + } if (CAudioPlayer::getInstance()->getState() != CBaseDec::STOP) CAudioPlayer::getInstance()->stop(); @@ -2028,31 +2063,31 @@ void CAudioPlayerGui::play(unsigned int pos) if (m_selected - m_liststart >= m_listmaxshow && g_settings.audioplayer_follow) { m_liststart = m_selected; - if (!m_screensaver) + if (!m_screensaver && !pictureviewer) paint(); } else if (m_liststart < m_selected && g_settings.audioplayer_follow) { m_liststart = m_selected - m_listmaxshow + 1; - if (!m_screensaver) + if (!m_screensaver && !pictureviewer) paint(); } else { if (old_current >= m_liststart && old_current - m_liststart < m_listmaxshow) { - if (!m_screensaver) + if (!m_screensaver && !pictureviewer) paintItem(old_current - m_liststart); } if (pos >= m_liststart && pos - m_liststart < m_listmaxshow) { - if (!m_screensaver) + if (!m_screensaver && !pictureviewer) paintItem(pos - m_liststart); } if (g_settings.audioplayer_follow) { if (old_selected >= m_liststart && old_selected - m_liststart < m_listmaxshow) - if (!m_screensaver) + if (!m_screensaver && !pictureviewer) paintItem(old_selected - m_liststart); } } @@ -2071,14 +2106,18 @@ void CAudioPlayerGui::play(unsigned int pos) m_curr_audiofile = m_playlist[m_current]; // Play CAudioPlayer::getInstance()->play(&m_curr_audiofile, g_settings.audioplayer_highprio == 1); - //LCD - paintLCD(); - // Display - if (!m_screensaver) - paintInfo(); - m_key_level = 1; - if (!m_screensaver) - paintFoot(); + + if (!pictureviewer) + { + //LCD + paintLCD(); + // Display + if (!m_screensaver) + paintInfo(); + m_key_level = 1; + if (!m_screensaver) + paintFoot(); + } } //------------------------------------------------------------------------ diff --git a/src/gui/audioplayer.h b/src/gui/audioplayer.h index 92ff2a2bb..6a73378e3 100644 --- a/src/gui/audioplayer.h +++ b/src/gui/audioplayer.h @@ -251,11 +251,15 @@ class CAudioPlayerGui : public CMenuTarget bool playNext(bool allow_rotate = false); bool playPrev(bool allow_rotate = false); + bool pictureviewer; + public: CAudioPlayerGui(bool inetmode = false); ~CAudioPlayerGui(); int show(); int exec(CMenuTarget* parent, const std::string & actionKey); + + void wantNextPlay(); }; diff --git a/src/gui/bouquetlist.cpp b/src/gui/bouquetlist.cpp index ec20bfeda..d52910fb6 100644 --- a/src/gui/bouquetlist.cpp +++ b/src/gui/bouquetlist.cpp @@ -385,7 +385,7 @@ int CBouquetList::show(bool bShowChannelList) } else if ((msg == CRCInput::RC_timeout ) || (msg == (neutrino_msg_t)g_settings.key_channelList_cancel) || - (msg == CRCInput::RC_favorites) ) + ((msg == CRCInput::RC_favorites) && (CNeutrinoApp::getInstance()->GetChannelMode() == LIST_MODE_FAV))) { selected = oldselected; if(fader.StartFadeOut()) { diff --git a/src/gui/cec_setup.cpp b/src/gui/cec_setup.cpp index edc861b6b..65c10c9c1 100644 --- a/src/gui/cec_setup.cpp +++ b/src/gui/cec_setup.cpp @@ -52,6 +52,8 @@ extern cVideo *videoDecoder; CCECSetup::CCECSetup() { width = w_max (40, 10); //% + cec1 = NULL; + cec2 = NULL; } CCECSetup::~CCECSetup() diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index ec2ca96c6..5b6bad697 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -223,6 +223,11 @@ void CChannelList::SortTP(void) sort(chanlist.begin(), chanlist.end(), CmpChannelByFreq()); } +void CChannelList::SortChNumber(void) +{ + sort(chanlist.begin(), chanlist.end(), CmpChannelByChNum()); +} + CZapitChannel* CChannelList::getChannel(int number) { for (uint32_t i=0; i< chanlist.size(); i++) { @@ -823,8 +828,8 @@ int CChannelList::show() int mode = CNeutrinoApp::getInstance()->GetChannelMode(); if(mode != LIST_MODE_FAV) { g_settings.channellist_sort_mode++; - if(g_settings.channellist_sort_mode > 2) - g_settings.channellist_sort_mode = 0; + if(g_settings.channellist_sort_mode > SORT_MAX-1) + g_settings.channellist_sort_mode = SORT_ALPHA; CNeutrinoApp::getInstance()->SetChannelMode(mode); paintHead(); // update button bar paint(); @@ -1643,7 +1648,7 @@ void CChannelList::paintButtonBar(bool is_current) struct button_label Button[num_buttons]; const neutrino_locale_t button_ids[] = {LOCALE_INFOVIEWER_NOW,LOCALE_INFOVIEWER_NEXT,LOCALE_MAINMENU_RECORDING,LOCALE_MAINMENU_RECORDING_STOP,NONEXISTANT_LOCALE, - LOCALE_CHANNELLIST_FOOT_SORT_ALPHA,LOCALE_CHANNELLIST_FOOT_SORT_FREQ,LOCALE_CHANNELLIST_FOOT_SORT_SAT}; + LOCALE_CHANNELLIST_FOOT_SORT_ALPHA,LOCALE_CHANNELLIST_FOOT_SORT_FREQ,LOCALE_CHANNELLIST_FOOT_SORT_SAT,LOCALE_CHANNELLIST_FOOT_SORT_CHNUM}; const std::vector buttonID_rest (button_ids, button_ids + sizeof(button_ids) / sizeof(neutrino_locale_t) ); for (int i = 0;i%s<\n", text.c_str() ); if (text==" ") @@ -162,7 +162,7 @@ void CEpgData::addTextToArray(const std::string & text, bool screening) // UTF-8 } } -void CEpgData::processTextToArray(std::string text, bool screening) // UTF-8 +void CEpgData::processTextToArray(std::string text, int screening) // UTF-8 { std::string aktLine = ""; std::string aktWord = ""; @@ -241,7 +241,6 @@ void CEpgData::showText( int startPos, int ypos ) if(epgText[i].second){ std::string::size_type pos1 = epgText[i].first.find_first_not_of(tok, 0); std::string::size_type pos2 = epgText[i].first.find_first_of(tok, pos1); - while( pos2 != string::npos || pos1 != string::npos ){ switch(count){ case 1: @@ -254,7 +253,7 @@ void CEpgData::showText( int startPos, int ypos ) offset += digi; break; } - g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->RenderString(sx+10+offset, y+medlineheight, ox- 15- 15, epgText[i].first.substr(pos1, pos2 - pos1), COL_MENUCONTENT, 0, true); // UTF-8 + g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->RenderString(sx+10+offset, y+medlineheight, ox- 15- 15, epgText[i].first.substr(pos1, pos2 - pos1), (epgText[i].second==2)? COL_MENUCONTENTINACTIVE: COL_MENUCONTENT, 0, true); // UTF-8 count++; pos1 = epgText[i].first.find_first_not_of(tok, pos2); pos2 = epgText[i].first.find_first_of(tok, pos1); @@ -262,8 +261,9 @@ void CEpgData::showText( int startPos, int ypos ) offset = 0; count = 0; } - else + else{ g_Font[( i< info1_lines ) ?SNeutrinoSettings::FONT_TYPE_EPG_INFO1:SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->RenderString(sx+10, y+medlineheight, ox- 15- 15, epgText[i].first, COL_MENUCONTENT, 0, true); // UTF-8 + } } int sbc = ((textSize - 1)/ medlinecount) + 1; @@ -438,12 +438,12 @@ static bool sortByDateTime (const CChannelEvent& a, const CChannelEvent& b) return a.startTime< b.startTime; } -int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_startzeit, bool doLoop ) +int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_startzeit, bool doLoop, bool callFromfollowlist ) { int res = menu_return::RETURN_REPAINT; static uint64_t id; static time_t startzeit; - + call_fromfollowlist = callFromfollowlist; if (a_startzeit) startzeit=*a_startzeit; id=a_id; @@ -660,13 +660,13 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start } GetPrevNextEPGData( epgData.eventID, &epgData.epg_times.startzeit ); - if (prev_id != 0) + if ((prev_id != 0) && !call_fromfollowlist) { frameBuffer->paintBoxRel(sx+ 5, sy+ oy- botboxheight+ 4, botboxheight- 8, botboxheight- 8, COL_MENUCONTENT_PLUS_3); g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+ 10, sy+ oy- 3, widthr, "<", COL_MENUCONTENT + 3); } - if (next_id != 0) + if ((next_id != 0) && !call_fromfollowlist) { frameBuffer->paintBoxRel(sx+ ox- botboxheight+ 8- 5, sy+ oy- botboxheight+ 4, botboxheight- 8, botboxheight- 8, COL_MENUCONTENT_PLUS_3); g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+ ox- botboxheight+ 8, sy+ oy- 3, widthr, ">", COL_MENUCONTENT + 3); @@ -675,10 +675,10 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start frameBuffer->blit(); if ( doLoop ) { - neutrino_msg_t msg; - neutrino_msg_data_t data; + neutrino_msg_t msg = 0; + neutrino_msg_data_t data = 0; - int scrollCount; + int scrollCount = 0; bool loop = true; @@ -718,7 +718,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start CNeutrinoApp::getInstance()->handleMsg(msg, data); break; case CRCInput::RC_left: - if (prev_id != 0) + if ((prev_id != 0) && !call_fromfollowlist) { frameBuffer->paintBoxRel(sx+ 5, sy+ oy- botboxheight+ 4, botboxheight- 8, botboxheight- 8, COL_MENUCONTENT_PLUS_1); g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+ 10, sy+ oy- 3, widthr, "<", COL_MENUCONTENT + 1); @@ -729,7 +729,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start break; case CRCInput::RC_right: - if (next_id != 0) + if ((next_id != 0) && !call_fromfollowlist) { frameBuffer->paintBoxRel(sx+ ox- botboxheight+ 8- 5, sy+ oy- botboxheight+ 4, botboxheight- 8, botboxheight- 8, COL_MENUCONTENT_PLUS_1); g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+ ox- botboxheight+ 8, sy+ oy- 3, widthr, ">", COL_MENUCONTENT + 1); @@ -848,19 +848,24 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start } case CRCInput::RC_blue: { - if(!followlist.empty()){ + if(!followlist.empty() && !call_fromfollowlist){ hide(); - CNeutrinoEventList *ee; - ee = new CNeutrinoEventList; - ee->exec(channel_id, g_Locale->getText(LOCALE_EPGVIEWER_MORE_SCREENINGS_SHORT),"","",followlist); // UTF-8 - delete ee; + time_t tmp_sZeit = epgData.epg_times.startzeit; + uint64_t tmp_eID = epgData.eventID; - if (!bigFonts && g_settings.bigFonts) { - g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->getSize() * BIG_FONT_FAKTOR)); - g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getSize() * BIG_FONT_FAKTOR)); + CNeutrinoEventList *ee = new CNeutrinoEventList; + res = ee->exec(channel_id, g_Locale->getText(LOCALE_EPGVIEWER_MORE_SCREENINGS_SHORT),"","",followlist); // UTF-8 + delete ee; + if (res == menu_return::RETURN_EXIT_ALL) + loop = false; + else { + if (!bigFonts && g_settings.bigFonts) { + g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->getSize() * BIG_FONT_FAKTOR)); + g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getSize() * BIG_FONT_FAKTOR)); + } } bigFonts = g_settings.bigFonts; - show(channel_id,epgData.eventID,&epgData.epg_times.startzeit,false); + show(channel_id,tmp_eID,&tmp_sZeit,false); } break; } @@ -896,8 +901,10 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start break; case CRCInput::RC_favorites: case CRCInput::RC_sat: - g_RCInput->postMsg (msg, 0); - loop = false; + if( !call_fromfollowlist){ + g_RCInput->postMsg (msg, 0); + loop = false; + } break; default: @@ -1028,10 +1035,11 @@ void CEpgData::GetPrevNextEPGData( uint64_t id, time_t* startzeit ) bool CEpgData::hasFollowScreenings(const t_channel_id /*channel_id*/, const std::string &title) { CChannelEventList::iterator e; - followlist.clear(); + if(!followlist.empty()) + followlist.clear(); for (e = evtlist.begin(); e != evtlist.end(); ++e) { - if (e->startTime <= tmp_curent_zeit) + if (e->startTime == tmp_curent_zeit) continue; if (! e->eventID) continue; @@ -1048,6 +1056,7 @@ int CEpgData::FollowScreenings (const t_channel_id /*channel_id*/, const std::st struct tm *tmStartZeit; std::string screening_dates,screening_nodual; int count = 0; + int flag = 1; char tmpstr[256]={0}; screening_dates = screening_nodual = ""; @@ -1067,9 +1076,14 @@ int CEpgData::FollowScreenings (const t_channel_id /*channel_id*/, const std::st strftime(tmpstr, sizeof(tmpstr), ". %H:%M", tmStartZeit ); screening_dates += tmpstr; + if (e->startTime <= tmp_curent_zeit) + flag = 2; + else + flag = 1; + if (screening_dates != screening_nodual) { screening_nodual=screening_dates; - processTextToArray(screening_dates, true ); // UTF-8 + processTextToArray(screening_dates, flag ); // UTF-8 } } return count; @@ -1115,9 +1129,9 @@ void CEpgData::showTimerEventBar (bool pshow) /* 2 * ICON_LARGE_WIDTH for potential 16:9 and DD icons */ int aw = ox - 20 - 2 * (ICON_LARGE_WIDTH + 2); if (g_settings.recording_type != CNeutrinoApp::RECORDING_OFF) - ::paintButtons(x, y, 0, has_follow_screenings ? 3:2, EpgButtons, aw, h); + ::paintButtons(x, y, 0, (has_follow_screenings && !call_fromfollowlist) ? 3:2, EpgButtons, aw, h); else - ::paintButtons(x, y, 0, has_follow_screenings ? 2:1, &EpgButtons[1], aw, h); + ::paintButtons(x, y, 0, (has_follow_screenings && !call_fromfollowlist) ? 2:1, &EpgButtons[1], aw, h); frameBuffer->blit(); #if 0 diff --git a/src/gui/epgview.h b/src/gui/epgview.h index 7b051c024..7492a79b3 100644 --- a/src/gui/epgview.h +++ b/src/gui/epgview.h @@ -63,6 +63,7 @@ class CEpgData int epg_done; bool bigFonts; bool has_follow_screenings; + bool call_fromfollowlist; time_t tmp_curent_zeit; uint64_t prev_id; @@ -73,7 +74,7 @@ class CEpgData int ox, oy, sx, sy, toph, sb; int emptyLineCount, info1_lines; int textCount; - typedef std::pair epg_pair; + typedef std::pair epg_pair; std::vector epgText; int topheight,topboxheight; int buttonheight,botboxheight; @@ -81,8 +82,8 @@ class CEpgData void GetEPGData(const t_channel_id channel_id, uint64_t id, time_t* startzeit, bool clear = true ); void GetPrevNextEPGData( uint64_t id, time_t* startzeit ); - void addTextToArray( const std::string & text, bool screening ); - void processTextToArray(std::string text, bool screening = false); + void addTextToArray( const std::string & text, int screening ); + void processTextToArray(std::string text, int screening = 0); void showText( int startPos, int ypos ); bool hasFollowScreenings(const t_channel_id channel_id, const std::string & title); int FollowScreenings(const t_channel_id channel_id, const std::string & title); @@ -92,7 +93,7 @@ class CEpgData CEpgData(); void start( ); - int show(const t_channel_id channel_id, uint64_t id = 0, time_t* startzeit = NULL, bool doLoop = true ); + int show(const t_channel_id channel_id, uint64_t id = 0, time_t* startzeit = NULL, bool doLoop = true, bool callFromfollowlist = false ); void hide(); }; diff --git a/src/gui/eventlist.cpp b/src/gui/eventlist.cpp index ee468032d..ae0fb78b5 100644 --- a/src/gui/eventlist.cpp +++ b/src/gui/eventlist.cpp @@ -607,7 +607,7 @@ int CNeutrinoEventList::exec(const t_channel_id channel_id, const std::string& c hide(); //FIXME res = g_EpgData->show(evtlist[selected].sub ? GET_CHANNEL_ID_FROM_EVENT_ID(evtlist[selected].eventID) : channel_id, evtlist[selected].eventID, &evtlist[selected].startTime); - res = g_EpgData->show(evtlist[selected].channelID, evtlist[selected].eventID, &evtlist[selected].startTime); + res = g_EpgData->show(evtlist[selected].channelID, evtlist[selected].eventID, &evtlist[selected].startTime, true, showfollow ); if ( res == menu_return::RETURN_EXIT_ALL ) { loop = false; @@ -968,16 +968,11 @@ void CNeutrinoEventList::showFunctionBar (bool show, t_channel_id channel_id) int CEventListHandler::exec(CMenuTarget* parent, const std::string &/*actionkey*/) { int res = menu_return::RETURN_EXIT_ALL; - CNeutrinoEventList *e; - CChannelList *channelList; - - if (parent) { parent->hide(); } - e = new CNeutrinoEventList; - - channelList = CNeutrinoApp::getInstance()->channelList; + CNeutrinoEventList *e = new CNeutrinoEventList; + CChannelList *channelList = CNeutrinoApp::getInstance()->channelList; e->exec(CZapit::getInstance()->GetCurrentChannelID(), channelList->getActiveChannelName()); // UTF-8 delete e; diff --git a/src/gui/ext_update.cpp b/src/gui/ext_update.cpp index 392819871..c8763de72 100644 --- a/src/gui/ext_update.cpp +++ b/src/gui/ext_update.cpp @@ -63,7 +63,7 @@ CExtUpdate::CExtUpdate() mtdRamError = ""; mtdNumber = -1; MTDBufSize = 0xFFFF; - MTDBuf = (char*)malloc(MTDBufSize); + MTDBuf = new char[MTDBufSize]; backupList = CONFIGDIR "/settingsupdate.conf"; defaultBackup = CONFIGDIR; @@ -78,7 +78,7 @@ CExtUpdate::CExtUpdate() CExtUpdate::~CExtUpdate() { if (MTDBuf != NULL) - free(MTDBuf); + delete[] MTDBuf; if(FileHelpers) delete[] FileHelpers; } @@ -121,30 +121,38 @@ bool CExtUpdate::ErrorReset(bool modus, const std::string & msg1, const std::str return false; } -bool CExtUpdate::writemtdExt(const std::string & filename) +bool CExtUpdate::applySettings(const std::string & filename, int mode) { if(!FileHelpers) FileHelpers = new CFileHelpers(); - imgFilename = (std::string)g_settings.update_dir + "/" + FILESYSTEM_ENCODING_TO_UTF8_STRING(filename); + + if (mode == MODE_EXPERT) + imgFilename = (std::string)g_settings.update_dir + "/" + FILESYSTEM_ENCODING_TO_UTF8_STRING(filename); + else + imgFilename = FILESYSTEM_ENCODING_TO_UTF8_STRING(filename); + DBG_TIMER_START() - bool ret = writemtdExt(); + bool ret = applySettings(); DBG_TIMER_STOP("Image editing") if (!ret) { if (mtdRamError != "") DisplayErrorMessage(mtdRamError.c_str()); } else { - if ((mtdNumber < 3) || (mtdNumber > 4)) { - const char *err = "invalid mtdNumber\n"; - printf(err); - DisplayErrorMessage(err); - WRITE_UPDATE_LOG("ERROR: %s", err); - return false; + if (mode == MODE_EXPERT) { + if ((mtdNumber < 3) || (mtdNumber > 4)) { + const char *err = "invalid mtdNumber\n"; + printf(err); + DisplayErrorMessage(err); + WRITE_UPDATE_LOG("ERROR: %s", err); + return false; + } } ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_SUCCESSFULLY), CMessageBox::mbrOk, CMessageBox::mbOk, NEUTRINO_ICON_INFO); WRITE_UPDATE_LOG("\n"); WRITE_UPDATE_LOG("##### Settings taken. #####\n"); - CFlashExpert::getInstance()->writemtd(filename, mtdNumber); + if (mode == MODE_EXPERT) + CFlashExpert::getInstance()->writemtd(filename, mtdNumber); } return ret; } @@ -166,7 +174,7 @@ bool CExtUpdate::isMtdramLoad() return ret; } -bool CExtUpdate::writemtdExt() +bool CExtUpdate::applySettings() { if(!hintBox) hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_PROCESSED)); @@ -185,8 +193,12 @@ bool CExtUpdate::writemtdExt() // get osrelease struct utsname uts_info; - if( uname(&uts_info) == 0 ) + if( uname(&uts_info) == 0 ) { osrelease = uts_info.release; + size_t pos = osrelease.find_first_of(" "); + if (pos != std::string::npos) + osrelease = osrelease.substr(0, pos); + } else return ErrorReset(0, "error no kernel info"); @@ -385,7 +397,7 @@ bool CExtUpdate::copyFileList(const std::string & fileList, const std::string & bool CExtUpdate::findConfigEntry(std::string & line, std::string find) { - if (line.find(find + "=") == 0) { + if (line.find("#:" + find + "=") == 0) { size_t pos = line.find_first_of('='); line = line.substr(pos+1); line = trim(line); @@ -442,21 +454,20 @@ bool CExtUpdate::readBackupList(const std::string & dstPath) size_t pos; while(fgets(buf, sizeof(buf), f1) != NULL) { std::string line = buf; - // remove comments line = trim(line); - if (line.find_first_of("#") == 0) + // remove comments + if (line.find_first_of("#") == 0) { + if (line.find_first_of(":") == 1) { // config vars + if (line.length() > 1) + readConfig(line); + } continue; + } pos = line.find_first_of("#"); if (pos != std::string::npos) { line = line.substr(0, pos); line = trim(line); } - // config vars - if (line.find_first_of("/+-~") != 0) { - if (line.length() > 1) - readConfig(line); - continue; - } // special folders else if ((line == "/") || (line == "/*") || (line == "/*.*") || (line.find("/dev") == 0) || (line.find("/proc") == 0) || (line.find("/sys") == 0) || (line.find("/mnt") == 0) || (line.find("/tmp") == 0)) { diff --git a/src/gui/ext_update.h b/src/gui/ext_update.h index a588cb890..9f0ee6744 100644 --- a/src/gui/ext_update.h +++ b/src/gui/ext_update.h @@ -55,7 +55,7 @@ class CExtUpdate std::string mountPkt; CFileHelpers* FileHelpers; - bool writemtdExt(void); + bool applySettings(void); bool readBackupList(const std::string & dstPath); bool copyFileList(const std::string & fileList, const std::string & dstPath); bool readConfig(const std::string & Config); @@ -69,11 +69,16 @@ class CExtUpdate void updateLog(const char *buf); public: + enum + { + MODE_EXPERT = 0, + MODE_SOFTUPDATE = 1 + }; CExtUpdate(); ~CExtUpdate(); static CExtUpdate* getInstance(); - bool writemtdExt(const std::string & filename); + bool applySettings(const std::string & filename, int mode); bool ErrorReset(bool modus, const std::string & msg1="", const std::string & msg2=""); }; diff --git a/src/gui/infoviewer.cpp b/src/gui/infoviewer.cpp index c95449485..b893dd010 100644 --- a/src/gui/infoviewer.cpp +++ b/src/gui/infoviewer.cpp @@ -96,7 +96,24 @@ CInfoViewer::CInfoViewer () info_CurrentNext.flags = 0; frameBuffer = CFrameBuffer::getInstance(); infoViewerBB = CInfoViewerBB::getInstance(); - + InfoHeightY = 0; + ButtonWidth = 0; + rt_dx = 0; + rt_dy = 0; + ChanNameX = 0; + ChanNameY = 0; + ChanWidth = 0; + ChanHeight = 0; + time_left_width = 0; + time_dot_width = 0; + time_width = 0; + time_height = 0; + old_timestr[0] = 0; + lastsnr = 0; + lastsig = 0; + lasttime = 0; + aspectRatio = 0; + ChanInfoX = 0; Init(); infoViewerBB->Init(); strcpy(old_timestr, ""); diff --git a/src/gui/infoviewer_bb.cpp b/src/gui/infoviewer_bb.cpp index 56c0e4308..0710f9b21 100644 --- a/src/gui/infoviewer_bb.cpp +++ b/src/gui/infoviewer_bb.cpp @@ -87,10 +87,16 @@ CInfoViewerBB::CInfoViewerBB() pthread_detach(scrambledT); } #endif + hddpercent = 0; hddperT = 0; hddperTflag = false; hddscale = NULL; sysscale = NULL; + bbIconInfo[0].x = 0; + bbIconInfo[0].h = 0; + BBarY = 0; + BBarFontY = 0; + Init(); } @@ -596,20 +602,17 @@ void CInfoViewerBB::showSysfsHdd() percent = (u * 100ULL) / t; showBarSys(percent); -#if 0 //HDD info in a seperate thread if(!hddperTflag) { hddperTflag=true; pthread_create(&hddperT, NULL, hddperThread, (void*) this); pthread_detach(hddperT); } -#else - if (!check_dir(g_settings.network_nfs_recordingdir)) { - if (get_fs_usage(g_settings.network_nfs_recordingdir, t, u)) - percent = (u * 100ULL) / t; - showBarHdd(percent); - } -#endif + + if (check_dir(g_settings.network_nfs_recordingdir) == 0) + showBarHdd(hddpercent); + else + showBarHdd(-1); } } @@ -617,11 +620,10 @@ void* CInfoViewerBB::hddperThread(void *arg) { CInfoViewerBB *infoViewerBB = (CInfoViewerBB*) arg; - int percent = 0; + infoViewerBB->hddpercent = 0; long t, u; if (get_fs_usage(g_settings.network_nfs_recordingdir, t, u)) - percent = (u * 100ULL) / t; - infoViewerBB->showBarHdd(percent); + infoViewerBB->hddpercent = (u * 100ULL) / t; infoViewerBB->hddperTflag=false; pthread_exit(NULL); @@ -635,8 +637,14 @@ void CInfoViewerBB::showBarSys(int percent) void CInfoViewerBB::showBarHdd(int percent) { - if (is_visible) - hddscale->paintProgressBar(bbIconMinX, BBarY + InfoHeightY_Info / 2 + 2 + 0, hddwidth, 6, percent, 100); + if (is_visible) { + if (percent >= 0) + hddscale->paintProgressBar(bbIconMinX, BBarY + InfoHeightY_Info / 2 + 2 + 0, hddwidth, 6, percent, 100); + else { + frameBuffer->paintBoxRel(bbIconMinX, BBarY + InfoHeightY_Info / 2 + 2 + 0, hddwidth, 6, COL_INFOBAR_BUTTONS_BACKGROUND); + hddscale->reset(); + } + } } void CInfoViewerBB::paint_ca_icons(int caid, char * icon, int &icon_space_offset) diff --git a/src/gui/infoviewer_bb.h b/src/gui/infoviewer_bb.h index 41bb17cb0..d5f4230c5 100644 --- a/src/gui/infoviewer_bb.h +++ b/src/gui/infoviewer_bb.h @@ -124,6 +124,7 @@ class CInfoViewerBB void showBarSys(int percent = 0); void showBarHdd(int percent = 0); + int hddpercent; pthread_t hddperT; static void* hddperThread(void *arg); bool hddperTflag; diff --git a/src/gui/miscsettings_menu.cpp b/src/gui/miscsettings_menu.cpp index 9a33fea7e..95ec59b46 100644 --- a/src/gui/miscsettings_menu.cpp +++ b/src/gui/miscsettings_menu.cpp @@ -235,6 +235,7 @@ int CMiscMenue::showMiscSettingsMenu() delete sectionsdConfigNotifier; if (miscNotifier) delete miscNotifier; + delete miscEpgNotifier; return res; } @@ -309,33 +310,48 @@ void CMiscMenue::showMiscSettingsMenuEpg(CMenuWidget *ms_epg) { ms_epg->addIntroItems(LOCALE_MISCSETTINGS_EPG_HEAD); - CMenuOptionChooser * mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_EPG_SAVE, &g_settings.epg_save, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); - mc->setHint("", LOCALE_MENU_HINT_EPG_SAVE); - ms_epg->addItem(mc); + + CMenuOptionChooser * mc1 = new CMenuOptionChooser(LOCALE_MISCSETTINGS_EPG_SAVE_STANDBY, &g_settings.epg_save_standby, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, g_settings.epg_save); + mc1->setHint("", LOCALE_MENU_HINT_EPG_SAVE_STANDBY); CStringInput * miscSettings_epg_cache = new CStringInput(LOCALE_MISCSETTINGS_EPG_CACHE, &g_settings.epg_cache, 2,LOCALE_MISCSETTINGS_EPG_CACHE_HINT1, LOCALE_MISCSETTINGS_EPG_CACHE_HINT2 , "0123456789 ", sectionsdConfigNotifier); - CMenuForwarder * mf = new CMenuDForwarder(LOCALE_MISCSETTINGS_EPG_CACHE, true, g_settings.epg_cache, miscSettings_epg_cache); + CMenuForwarder * mf = new CMenuDForwarder(LOCALE_MISCSETTINGS_EPG_CACHE, g_settings.epg_save, g_settings.epg_cache, miscSettings_epg_cache); mf->setHint("", LOCALE_MENU_HINT_EPG_CACHE); - ms_epg->addItem(mf); CStringInput * miscSettings_epg_cache_e = new CStringInput(LOCALE_MISCSETTINGS_EPG_EXTENDEDCACHE, &g_settings.epg_extendedcache, 3,LOCALE_MISCSETTINGS_EPG_EXTENDEDCACHE_HINT1, LOCALE_MISCSETTINGS_EPG_EXTENDEDCACHE_HINT2 , "0123456789 ", sectionsdConfigNotifier); - mf = new CMenuDForwarder(LOCALE_MISCSETTINGS_EPG_EXTENDEDCACHE, true, g_settings.epg_extendedcache, miscSettings_epg_cache_e); - mf->setHint("", LOCALE_MENU_HINT_EPG_EXTENDEDCACHE); - ms_epg->addItem(mf); + CMenuForwarder * mf1 = new CMenuDForwarder(LOCALE_MISCSETTINGS_EPG_EXTENDEDCACHE, g_settings.epg_save, g_settings.epg_extendedcache, miscSettings_epg_cache_e); + mf1->setHint("", LOCALE_MENU_HINT_EPG_EXTENDEDCACHE); CStringInput * miscSettings_epg_old_events = new CStringInput(LOCALE_MISCSETTINGS_EPG_OLD_EVENTS, &g_settings.epg_old_events, 3,LOCALE_MISCSETTINGS_EPG_OLD_EVENTS_HINT1, LOCALE_MISCSETTINGS_EPG_OLD_EVENTS_HINT2 , "0123456789 ", sectionsdConfigNotifier); - mf = new CMenuDForwarder(LOCALE_MISCSETTINGS_EPG_OLD_EVENTS, true, g_settings.epg_old_events, miscSettings_epg_old_events); - mf->setHint("", LOCALE_MENU_HINT_EPG_OLD_EVENTS); - ms_epg->addItem(mf); + CMenuForwarder * mf2 = new CMenuDForwarder(LOCALE_MISCSETTINGS_EPG_OLD_EVENTS, g_settings.epg_save, g_settings.epg_old_events, miscSettings_epg_old_events); + mf2->setHint("", LOCALE_MENU_HINT_EPG_OLD_EVENTS); CStringInput * miscSettings_epg_max_events = new CStringInput(LOCALE_MISCSETTINGS_EPG_MAX_EVENTS, &g_settings.epg_max_events, 6,LOCALE_MISCSETTINGS_EPG_MAX_EVENTS_HINT1, LOCALE_MISCSETTINGS_EPG_MAX_EVENTS_HINT2 , "0123456789 ", sectionsdConfigNotifier); - mf = new CMenuDForwarder(LOCALE_MISCSETTINGS_EPG_MAX_EVENTS, true, g_settings.epg_max_events, miscSettings_epg_max_events); - mf->setHint("", LOCALE_MENU_HINT_EPG_MAX_EVENTS); - ms_epg->addItem(mf); + CMenuForwarder * mf3 = new CMenuDForwarder(LOCALE_MISCSETTINGS_EPG_MAX_EVENTS, g_settings.epg_save, g_settings.epg_max_events, miscSettings_epg_max_events); + mf3->setHint("", LOCALE_MENU_HINT_EPG_MAX_EVENTS); - mf = new CMenuForwarder(LOCALE_MISCSETTINGS_EPG_DIR, true, g_settings.epg_dir, this, "epgdir"); - mf->setHint("", LOCALE_MENU_HINT_EPG_DIR); + CMenuForwarder * mf4 = new CMenuForwarder(LOCALE_MISCSETTINGS_EPG_DIR, g_settings.epg_save, g_settings.epg_dir, this, "epgdir"); + mf4->setHint("", LOCALE_MENU_HINT_EPG_DIR); + + miscEpgNotifier = new COnOffNotifier(); + miscEpgNotifier->addItem(mc1); + miscEpgNotifier->addItem(mf); + miscEpgNotifier->addItem(mf1); + miscEpgNotifier->addItem(mf2); + miscEpgNotifier->addItem(mf3); + miscEpgNotifier->addItem(mf4); + + CMenuOptionChooser * mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_EPG_SAVE, &g_settings.epg_save, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true,miscEpgNotifier); + mc->setHint("", LOCALE_MENU_HINT_EPG_SAVE); + + ms_epg->addItem(mc); + ms_epg->addItem(mc1); ms_epg->addItem(mf); + ms_epg->addItem(mf1); + ms_epg->addItem(mf2); + ms_epg->addItem(mf3); + ms_epg->addItem(mf4); + } //filebrowser settings diff --git a/src/gui/miscsettings_menu.h b/src/gui/miscsettings_menu.h index b05d0c68a..d9c0269fb 100644 --- a/src/gui/miscsettings_menu.h +++ b/src/gui/miscsettings_menu.h @@ -41,7 +41,7 @@ class CMiscMenue : public CMenuTarget CFanControlNotifier *fanNotifier; CSectionsdConfigNotifier* sectionsdConfigNotifier; COnOffNotifier* miscNotifier; - + COnOffNotifier* miscEpgNotifier; int width; int showMiscSettingsMenu(); diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index 994a3d155..8d3ca6e91 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -1113,7 +1113,7 @@ int CMovieBrowser::paint(void) m_pcFilter = new CListFrame(&m_FilterLines, font, CListFrame::SCROLL | CListFrame::TITLE, &m_cBoxFrameFilter, g_Locale->getText(LOCALE_MOVIEBROWSER_HEAD_FILTER), g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]); - m_pcInfo = new CTextBox(" ", NULL, CTextBox::SCROLL, &m_cBoxFrameInfo); + m_pcInfo = new CTextBox(" ", NULL, CTextBox::TOP | CTextBox::SCROLL, &m_cBoxFrameInfo); if( m_pcBrowser == NULL || m_pcLastPlay == NULL || @@ -1625,7 +1625,7 @@ void CMovieBrowser::refreshFoot(void) m_pcFontFoot->RenderString(m_cBoxFrame.iX+xpos1+width*2 + 10 + iw, m_cBoxFrame.iY+m_cBoxFrameFootRel.iY + m_cBoxFrameFootRel.iHeight + 4 , width-30, ok_text.c_str(), (CFBWindow::color_t)color, 0, true); // UTF-8 if (IsRecord == false) { - //delte icon + //delete icon m_pcWindow->getIconSize(NEUTRINO_ICON_BUTTON_MUTE_SMALL, &iw, &ih); m_pcWindow->paintIcon(NEUTRINO_ICON_BUTTON_MUTE_SMALL, m_cBoxFrame.iX+xpos1+width*3, m_cBoxFrame.iY+m_cBoxFrameFootRel.iY, m_cBoxFrameFootRel.iHeight+ 6); m_pcFontFoot->RenderString(m_cBoxFrame.iX+xpos1+width*3 + 10 + iw , m_cBoxFrame.iY+m_cBoxFrameFootRel.iY + m_cBoxFrameFootRel.iHeight + 4 , width-30, g_Locale->getText(LOCALE_FILEBROWSER_DELETE), (CFBWindow::color_t)color, 0, true); // UTF-8 @@ -2053,7 +2053,7 @@ void CMovieBrowser::onDeleteFile(MI_MOVIE_INFO& movieSelectionHandler) msg += "\r\n "; msg += g_Locale->getText(LOCALE_FILEBROWSER_DODELETE2); - if (ShowMsgUTF(LOCALE_FILEBROWSER_DELETE, msg, CMessageBox::mbrNo, CMessageBox::mbYes|CMessageBox::mbNo)==CMessageBox::mbrYes) + if (ShowMsgUTF(LOCALE_FILEBROWSER_DELETE, msg, CMessageBox::mbrYes, CMessageBox::mbYes|CMessageBox::mbNo)==CMessageBox::mbrYes) { delFile(movieSelectionHandler.file); diff --git a/src/gui/network_setup.cpp b/src/gui/network_setup.cpp index 1e77d421e..db7a36d48 100644 --- a/src/gui/network_setup.cpp +++ b/src/gui/network_setup.cpp @@ -238,7 +238,7 @@ int CNetworkSetup::showNetworkSetup() CIPInput networkSettings_NameServer(LOCALE_NETWORKMENU_NAMESERVER, network_nameserver, LOCALE_IPSETUP_HINT_1, LOCALE_IPSETUP_HINT_2); //hostname - CStringInputSMS networkSettings_Hostname(LOCALE_NETWORKMENU_HOSTNAME, &network_hostname, 30, LOCALE_NETWORKMENU_NTPSERVER_HINT1, LOCALE_NETWORKMENU_NTPSERVER_HINT2, "abcdefghijklmnopqrstuvwxyz0123456789-. "); + CStringInputSMS networkSettings_Hostname(LOCALE_NETWORKMENU_HOSTNAME, &network_hostname, 30, LOCALE_NETWORKMENU_HOSTNAME_HINT1, LOCALE_NETWORKMENU_HOSTNAME_HINT2, "abcdefghijklmnopqrstuvwxyz0123456789-. "); //auto start CMenuOptionChooser* o1 = new CMenuOptionChooser(LOCALE_NETWORKMENU_SETUPONSTARTUP, &network_automatic_start, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); diff --git a/src/gui/personalize.cpp b/src/gui/personalize.cpp index 2b089178a..d42abf8f9 100644 --- a/src/gui/personalize.cpp +++ b/src/gui/personalize.cpp @@ -396,9 +396,14 @@ void CPersonalizeGui::ShowUserMenu(CMenuWidget* p_widget, vectoraddItem(new CMenuOptionChooser(usermenu[0].menue_title, &g_settings.personalize[SNeutrinoSettings::P_MAIN_RED_BUTTON], PERSONALIZE_ACTIVE_MODE_OPTIONS, PERSONALIZE_ACTIVE_MODE_MAX, true, user_menu_notifier));/*LOCALE_INFOVIEWER_EVENTLIST*/ + //green + p_widget->addItem(new CMenuOptionChooser(usermenu[1].menue_title, &g_settings.personalize[SNeutrinoSettings::P_MAIN_GREEN_BUTTON], PERSONALIZE_ACTIVE_MODE_OPTIONS, PERSONALIZE_ACTIVE_MODE_MAX, true, user_menu_notifier)); + //yellow + p_widget->addItem(new CMenuOptionChooser(usermenu[2].menue_title, &g_settings.personalize[SNeutrinoSettings::P_MAIN_YELLOW_BUTTON], PERSONALIZE_ACTIVE_MODE_OPTIONS, PERSONALIZE_ACTIVE_MODE_MAX, true, user_menu_notifier)); //blue p_widget->addItem(new CMenuOptionChooser(usermenu[3].menue_title, &g_settings.personalize[SNeutrinoSettings::P_MAIN_BLUE_BUTTON], PERSONALIZE_ACTIVE_MODE_OPTIONS, PERSONALIZE_ACTIVE_MODE_MAX, true, user_menu_notifier));/*LOCALE_INFOVIEWER_STREAMINFO*/ @@ -901,18 +906,22 @@ void CPersonalizeGui::restoreSettings() //helper class to enable/disable some items in usermenu setup -CUserMenuNotifier::CUserMenuNotifier( CMenuItem* i1, CMenuItem* i2) +CUserMenuNotifier::CUserMenuNotifier( CMenuItem* i1, CMenuItem* i2, CMenuItem *i3, CMenuItem *i4) { - toDisable[0]=i1; - toDisable[1]=i2; + toDisable[0]=i1; + toDisable[1]=i2; + toDisable[2]=i3; + toDisable[3]=i4; } bool CUserMenuNotifier::changeNotify(const neutrino_locale_t, void *) { toDisable[0]->setActive(g_settings.personalize[SNeutrinoSettings::P_MAIN_RED_BUTTON]); - toDisable[1]->setActive(g_settings.personalize[SNeutrinoSettings::P_MAIN_BLUE_BUTTON]); - - return false; + toDisable[1]->setActive(g_settings.personalize[SNeutrinoSettings::P_MAIN_GREEN_BUTTON]); + toDisable[2]->setActive(g_settings.personalize[SNeutrinoSettings::P_MAIN_YELLOW_BUTTON]); + toDisable[3]->setActive(g_settings.personalize[SNeutrinoSettings::P_MAIN_BLUE_BUTTON]); + + return false; } //helper class to enable/disable pin setup diff --git a/src/gui/personalize.h b/src/gui/personalize.h index c9c7b4c2e..b3c00ea97 100644 --- a/src/gui/personalize.h +++ b/src/gui/personalize.h @@ -68,9 +68,12 @@ extern CPlugins * g_PluginList; /* neutrino.cpp */ class CUserMenuNotifier : public CChangeObserver { private: - CMenuItem* toDisable[2]; + + CMenuItem* toDisable[4]; + public: - CUserMenuNotifier( CMenuItem*, CMenuItem*); + CUserMenuNotifier( CMenuItem*, CMenuItem*, CMenuItem*, CMenuItem*); + bool changeNotify(const neutrino_locale_t = NONEXISTANT_LOCALE, void *data = NULL); }; diff --git a/src/gui/pictureviewer.cpp b/src/gui/pictureviewer.cpp index 1ec864824..cbbdc961d 100644 --- a/src/gui/pictureviewer.cpp +++ b/src/gui/pictureviewer.cpp @@ -112,8 +112,12 @@ CPictureViewerGui::~CPictureViewerGui() } //------------------------------------------------------------------------ -int CPictureViewerGui::exec(CMenuTarget* parent, const std::string & /*actionKey*/) +int CPictureViewerGui::exec(CMenuTarget* parent, const std::string & actionKey) { + audioplayer = false; + if (actionKey == "audio") + audioplayer = true; + selected = 0; width = w_max (710, 0); height = h_max (570, 0); @@ -159,14 +163,16 @@ int CPictureViewerGui::exec(CMenuTarget* parent, const std::string & /*actionKey // remember last mode m_LastMode=(CNeutrinoApp::getInstance()->getLastMode() | NeutrinoMessages::norezap); - //g_Zapit->setStandby(true); - g_Zapit->lockPlayBack(); + if (!audioplayer) { // !!! why? !!! + //g_Zapit->setStandby(true); + g_Zapit->lockPlayBack(); - // blank background screen - videoDecoder->setBlank(true); + // blank background screen + videoDecoder->setBlank(true); - // Stop Sectionsd - g_Sectionsd->setPauseScanning(true); + // Stop Sectionsd + g_Sectionsd->setPauseScanning(true); + } // Save and Clear background bool usedBackground = frameBuffer->getuseBackground(); @@ -180,11 +186,13 @@ int CPictureViewerGui::exec(CMenuTarget* parent, const std::string & /*actionKey // free picviewer mem m_viewer->Cleanup(); - //g_Zapit->setStandby(false); - g_Zapit->unlockPlayBack(); + if (!audioplayer) { // !!! why? !!! + //g_Zapit->setStandby(false); + g_Zapit->unlockPlayBack(); - // Start Sectionsd - g_Sectionsd->setPauseScanning(false); + // Start Sectionsd + g_Sectionsd->setPauseScanning(false); + } // Restore previous background if (usedBackground) { @@ -227,6 +235,9 @@ int CPictureViewerGui::show() frameBuffer->blit(); } + if (audioplayer) + m_audioPlayer->wantNextPlay(); + if (m_state!=SLIDESHOW) timeout=50; // egal else diff --git a/src/gui/pictureviewer.h b/src/gui/pictureviewer.h index 2a72c7728..0909d6ef4 100644 --- a/src/gui/pictureviewer.h +++ b/src/gui/pictureviewer.h @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -109,10 +110,14 @@ class CPictureViewerGui : public CMenuTarget void showHelp(); void deletePicFile(unsigned int index, bool mode); + bool audioplayer; + public: CPictureViewerGui(); ~CPictureViewerGui(); int exec(CMenuTarget* parent, const std::string & actionKey); + + CAudioPlayerGui *m_audioPlayer; }; diff --git a/src/gui/start_wizard.cpp b/src/gui/start_wizard.cpp index b566c2450..1fd2b1559 100644 --- a/src/gui/start_wizard.cpp +++ b/src/gui/start_wizard.cpp @@ -101,12 +101,6 @@ int CStartUpWizard::exec(CMenuTarget* parent, const string & /*actionKey*/) res = CNetworkSetup::getInstance()->exec(NULL, ""); CNetworkSetup::getInstance()->setWizardMode(CNetworkSetup::N_SETUP_MODE_WIZARD_NO); } - if(res != menu_return::RETURN_EXIT_ALL) - { - CScanSetup::getInstance()->setWizardMode(CScanSetup::SCAN_SETUP_MODE_WIZARD); - res = CScanSetup::getInstance()->exec(NULL, ""); - CScanSetup::getInstance()->setWizardMode(CScanSetup::SCAN_SETUP_MODE_WIZARD_NO); - } bool init_settings = false; if (g_info.delivery_system == DVB_S) init_settings = file_exists("/var/tuxbox/config/initial/"); @@ -121,9 +115,13 @@ int CStartUpWizard::exec(CMenuTarget* parent, const string & /*actionKey*/) CZapit::getInstance()->PrepareChannels(); } } + if(res != menu_return::RETURN_EXIT_ALL) + { + CScanSetup::getInstance()->setWizardMode(CScanSetup::SCAN_SETUP_MODE_WIZARD); + res = CScanSetup::getInstance()->exec(NULL, ""); + CScanSetup::getInstance()->setWizardMode(CScanSetup::SCAN_SETUP_MODE_WIZARD_NO); + } } - - killBackgroundLogo(); return res; diff --git a/src/gui/update.cpp b/src/gui/update.cpp index 61c971baa..591dcaba9 100644 --- a/src/gui/update.cpp +++ b/src/gui/update.cpp @@ -451,16 +451,20 @@ int CFlashUpdate::exec(CMenuTarget* parent, const std::string &) CNeutrinoApp::getInstance()->exec(NULL, "savesettings"); sleep(2); //flash it... -#ifdef DEBUG1 - if(1) -#else - if(!ft.program(filename, 80, 100)) -#endif - { - hide(); - ShowHintUTF(LOCALE_MESSAGEBOX_ERROR, ft.getErrorMessage().c_str()); // UTF-8 + + if (ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_FLASHUPDATE_APPLY_SETTINGS), CMessageBox::mbrYes, CMessageBox::mbYes | CMessageBox::mbNo, NEUTRINO_ICON_UPDATE) == CMessageBox::mbrYes) + if (!CExtUpdate::getInstance()->applySettings(filename, CExtUpdate::MODE_SOFTUPDATE)) return menu_return::RETURN_REPAINT; - } + +#ifdef DEBUG1 + if(1) { +#else + if(!ft.program(filename, 80, 100)) { +#endif + hide(); + ShowHintUTF(LOCALE_MESSAGEBOX_ERROR, ft.getErrorMessage().c_str()); // UTF-8 + return menu_return::RETURN_REPAINT; + } //status anzeigen showGlobalStatus(100); @@ -690,7 +694,7 @@ int CFlashExpert::exec(CMenuTarget* parent, const std::string & actionKey) showFileSelector(""); } else { if(selectedMTD == 10) { - CExtUpdate::getInstance()->writemtdExt(actionKey); + CExtUpdate::getInstance()->applySettings(actionKey, CExtUpdate::MODE_EXPERT); } else if(selectedMTD==-1) { writemtd(actionKey, MTD_OF_WHOLE_IMAGE); diff --git a/src/gui/widget/listframe.h b/src/gui/widget/listframe.h index 0f5a40195..ff457c8dd 100644 --- a/src/gui/widget/listframe.h +++ b/src/gui/widget/listframe.h @@ -96,7 +96,6 @@ class CListFrame int m_nNrOfPages; int m_nNrOfLines; int m_nNrOfRows; - int m_nMaxLineWidth; int m_nLinesPerPage; int m_nCurrentLine; int m_nCurrentPage; @@ -142,7 +141,6 @@ class CListFrame void paint(void); inline CBox getWindowsPos(void) {return(m_cFrame);}; -inline int getMaxLineWidth(void) {return(m_nMaxLineWidth);}; inline int getSelectedLine(void) {return(m_nSelectedLine);}; inline int getLines(void) {return(m_nNrOfLines);}; inline int getPages(void) {return(m_nNrOfPages);}; diff --git a/src/gui/widget/msgbox.cpp b/src/gui/widget/msgbox.cpp index ec8e4932d..9e704ef4f 100644 --- a/src/gui/widget/msgbox.cpp +++ b/src/gui/widget/msgbox.cpp @@ -213,6 +213,7 @@ CMsgBox::~CMsgBox() void CMsgBox::initVar(void) { //TRACE("->CMsgBox::InitVar\r\n"); + m_nResult = mbrYes; m_cTitle = ""; m_cIcon = ""; m_nMode = SCROLL | TITLE | BORDER ; diff --git a/src/gui/widget/msgbox.h b/src/gui/widget/msgbox.h index ead68cda1..a30186389 100644 --- a/src/gui/widget/msgbox.h +++ b/src/gui/widget/msgbox.h @@ -75,7 +75,7 @@ class CMsgBox mbAll = 0x07, mbBack = 0x08 }; - enum mode_ + enum modes { AUTO_WIDTH = 0x01, AUTO_HIGH = 0x02, @@ -85,7 +85,7 @@ class CMsgBox BORDER = 0x20, CENTER = 0x40, NO_AUTO_LINEBREAK= 0x80 - }mode; + }; private: /* Functions */ diff --git a/src/gui/widget/progresswindow.cpp b/src/gui/widget/progresswindow.cpp index 971349742..eb274d559 100644 --- a/src/gui/widget/progresswindow.cpp +++ b/src/gui/widget/progresswindow.cpp @@ -49,6 +49,10 @@ CProgressWindow::CProgressWindow() global_progress = local_progress = 101; statusText = ""; + globalstatusX = 0; + globalstatusY = 0; + localstatusY = 0; + statusTextY = 0; x = frameBuffer->getScreenX() + ((frameBuffer->getScreenWidth() - width ) >> 1 ); y = frameBuffer->getScreenY() + ((frameBuffer->getScreenHeight() - height) >>1 ); diff --git a/src/gui/widget/stringinput.cpp b/src/gui/widget/stringinput.cpp index 1c453579f..1579b0dba 100644 --- a/src/gui/widget/stringinput.cpp +++ b/src/gui/widget/stringinput.cpp @@ -808,7 +808,9 @@ void CStringInputSMS::paint(bool /*unused*/) { CStringInput::paint(true); - frameBuffer->paintIcon(NEUTRINO_ICON_NUMERIC_PAD, x+20+140, y+ hheight+ mheight+ iheight* 3+ 30, 0, COL_MENUCONTENT); + int w = 0, h = 0; + frameBuffer->getIconSize(NEUTRINO_ICON_NUMERIC_PAD, &w, &h); + frameBuffer->paintIcon(NEUTRINO_ICON_NUMERIC_PAD, x + (width/2) - (w/2), y+ hheight+ mheight+ iheight* 3+ 30, 0, COL_MENUCONTENT); //buttonbar ::paintButtons(x, y + height, width, 2, CStringInputSMSButtons, width); diff --git a/src/gui/widget/stringinput_ext.h b/src/gui/widget/stringinput_ext.h index 22ed53bb5..af11089f1 100644 --- a/src/gui/widget/stringinput_ext.h +++ b/src/gui/widget/stringinput_ext.h @@ -108,7 +108,7 @@ class CExtendedInput_Item_Spacer : public CExtendedInput_Item int mSpacingX; int mSpacingY; public: - CExtendedInput_Item_Spacer(){}; + CExtendedInput_Item_Spacer(){mSpacingY = 0;mSpacingX = 0;}; CExtendedInput_Item_Spacer(int spaceX, int spaceY=0){mSpacingX=spaceX;mSpacingY=spaceY;}; virtual void init(int &x, int &y){x+=mSpacingX;y+=mSpacingY;}; virtual bool isSelectable(){return false;}; @@ -119,7 +119,7 @@ class CExtendedInput_Item_newLiner : public CExtendedInput_Item protected: int mSpacingY; public: - CExtendedInput_Item_newLiner(){}; + CExtendedInput_Item_newLiner(){mSpacingY=0;}; CExtendedInput_Item_newLiner(int spaceY){mSpacingY=spaceY;}; virtual void init(int &x, int &y){x=0;y+=mSpacingY;}; virtual bool isSelectable(){return false;}; diff --git a/src/gui/widget/textbox.cpp b/src/gui/widget/textbox.cpp index 02a139261..61c8754b4 100644 --- a/src/gui/widget/textbox.cpp +++ b/src/gui/widget/textbox.cpp @@ -60,8 +60,8 @@ #include "textbox.h" #include -#define SCROLL_FRAME_WIDTH 10 -#define SCROLL_MARKER_BORDER 2 +#define SCROLL_FRAME_WIDTH 10 +#define SCROLL_MARKER_BORDER 2 #define MAX_WINDOW_WIDTH (g_settings.screen_EndX - g_settings.screen_StartX - 40) #define MAX_WINDOW_HEIGHT (g_settings.screen_EndY - g_settings.screen_StartY - 40) @@ -69,52 +69,42 @@ #define MIN_WINDOW_WIDTH ((g_settings.screen_EndX - g_settings.screen_StartX)>>1) #define MIN_WINDOW_HEIGHT 40 + CTextBox::CTextBox(const char * text, Font* font_text, const int pmode, const CBox* position, CFBWindow::color_t textBackgroundColor) { //TRACE("[CTextBox] new\r\n"); initVar(); - frameBuffer = NULL; - max_width = 0; - - if(text != NULL) m_cText = text; - if(font_text != NULL) m_pcFontText = font_text; + if(text != NULL) + m_cText = text; + + if(font_text != NULL) + m_pcFontText = font_text; + if(position != NULL) { - m_cFrame = *position; - m_nMaxHeight = m_cFrame.iHeight; - m_nMaxWidth = m_cFrame.iWidth; + m_cFrame = *position; + m_nMaxHeight = m_cFrame.iHeight; + m_nMaxWidth = m_cFrame.iWidth; } - m_nMode = pmode; + m_nMode = pmode; /* in case of auto line break, we do no support auto width yet */ if( !(pmode & NO_AUTO_LINEBREAK)) - { m_nMode = m_nMode & ~AUTO_WIDTH; /* delete any AUTO_WIDTH*/ - } -#if 0 - TRACE(" Mode: "); - if(pmode & SCROLL) TRACE("SCROLL "); - if(pmode & NO_AUTO_LINEBREAK) TRACE("NO_AUTO_LINEBREAK "); - if(pmode & AUTO_WIDTH) TRACE("AUTO_WIDTH "); - if(pmode & AUTO_HIGH) TRACE("AUTO_HIGH"); - TRACE("\r\n"); - -#endif //TRACE(" CTextBox::m_cText: %d, m_nMode %d\t\r\n",m_cText.size(),m_nMode); - m_textBackgroundColor = textBackgroundColor; - m_nFontTextHeight = m_pcFontText->getHeight(); + m_textBackgroundColor = textBackgroundColor; + m_nFontTextHeight = m_pcFontText->getHeight(); + + //TRACE("[CTextBox] %s Line %d\r\n", __FUNCTION__, __LINE__); //TRACE(" CTextBox::m_nFontTextHeight: %d\t\r\n",m_nFontTextHeight); - - /* Initialise the window frames first */ - initFramesRel(); - - // than refresh text line array - refreshTextLineArray(); + + //Initialise the window frames first and than refresh text line array + initFramesAndTextArray(); } CTextBox::CTextBox(const char * text) @@ -122,23 +112,22 @@ CTextBox::CTextBox(const char * text) //TRACE("[CTextBox] new\r\n"); initVar(); - frameBuffer = NULL; - if(text != NULL) m_cText = *text; + if(text != NULL) + m_cText = *text; + + //TRACE_1("[CTextBox] %s Line %d text: %s\r\n", __FUNCTION__, __LINE__, text); - /* Initialise the window frames first */ - initFramesRel(); - - // than refresh text line array - refreshTextLineArray(); + //Initialise the window frames first and than refresh text line array + initFramesAndTextArray(); } CTextBox::CTextBox() { //TRACE("[CTextBox] new\r\n"); initVar(); - initFramesRel(); - - frameBuffer = NULL; + + //Initialise the window frames first and than refresh text line array + initFramesAndTextArray(); } CTextBox::~CTextBox() @@ -152,35 +141,53 @@ CTextBox::~CTextBox() void CTextBox::initVar(void) { //TRACE("[CTextBox]->InitVar\r\n"); + frameBuffer = NULL; + + m_showTextFrame = 0; + m_nNrOfNewLine = 0; + m_nMaxLineWidth = 0; + m_cText = ""; m_nMode = SCROLL; - m_pcFontText = NULL; - m_pcFontText = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]; - m_nFontTextHeight = m_pcFontText->getHeight(); + m_pcFontText = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]; + m_nFontTextHeight = m_pcFontText->getHeight(); + m_nMaxTextWidth = 0; - m_nNrOfPages = 1; - m_nNrOfLines = 0; - m_nLinesPerPage = 0; - m_nCurrentLine = 0; - m_nCurrentPage = 0; - text_border_width = 8; + m_nNrOfPages = 1; + m_nNrOfLines = 0; + m_nLinesPerPage = 0; + m_nCurrentLine = 0; + m_nCurrentPage = 0; + text_border_width = 8; m_cFrame.iX = g_settings.screen_StartX + ((g_settings.screen_EndX - g_settings.screen_StartX - MIN_WINDOW_WIDTH) >>1); - m_cFrame.iWidth = MIN_WINDOW_WIDTH; + m_cFrame.iWidth = MIN_WINDOW_WIDTH; m_cFrame.iY = g_settings.screen_StartY + ((g_settings.screen_EndY - g_settings.screen_StartY - MIN_WINDOW_HEIGHT) >>1); m_cFrame.iHeight = MIN_WINDOW_HEIGHT; - m_nMaxHeight = MAX_WINDOW_HEIGHT; - m_nMaxWidth = MAX_WINDOW_WIDTH; + m_nMaxHeight = MAX_WINDOW_HEIGHT; + m_nMaxWidth = MAX_WINDOW_WIDTH; + m_nMinHeight = MIN_WINDOW_HEIGHT; + m_nMinWidth = MIN_WINDOW_WIDTH; m_textBackgroundColor = COL_MENUCONTENT_PLUS_0; m_textColor = COL_MENUCONTENT; - m_nPaintBackground = true; - m_nBgRadius = 0; - m_nBgRadiusType = CORNER_ALL; + m_nPaintBackground = true; + m_nBgRadius = 0; + m_nBgRadiusType = CORNER_ALL; m_cLineArray.clear(); + +// max_width = 0; +} + +void CTextBox::initFramesAndTextArray() +{ + /* Initialise the window frames first */ + initFramesRel(); + // than refresh text line array + refreshTextLineArray(); } void CTextBox::setTextFont(Font* font_text) @@ -188,26 +195,42 @@ void CTextBox::setTextFont(Font* font_text) if ((m_pcFontText != font_text) && (font_text != NULL)) { m_pcFontText = font_text; m_nFontTextHeight = m_pcFontText->getHeight(); - initFramesRel(); - refreshTextLineArray(); + //Initialise the window frames first and than refresh text line array + initFramesAndTextArray(); } } void CTextBox::setTextBorderWidth(int border) { text_border_width = border; - initFramesRel(); - refreshTextLineArray(); + //Initialise the window frames first and than refresh text line array + initFramesAndTextArray(); +} + +void CTextBox::setWindowMaxDimensions(const int width, const int height) +{ + m_nMaxHeight = height; + m_nMaxWidth = width; +} + +void CTextBox::setWindowMinDimensions(const int width, const int height) +{ + m_nMinHeight = height; + m_nMinWidth = width; } void CTextBox::reSizeMainFrameWidth(int textWidth) { - //TRACE("[CTextBox]->ReSizeMainFrameWidth: %d, current: %d\r\n",textWidth,m_cFrameTextRel.iWidth); + //TRACE("[CTextBox]->%s: \ntext width: %d\n m_cFrame.iWidth: %d\n m_cFrameTextRel.iWidth: %d\n m_nMaxWidth: %d\n m_nMinWidth: %d\n",__FUNCTION__, textWidth, m_cFrame.iWidth, m_cFrameTextRel.iWidth, m_nMaxWidth, m_nMinWidth); int iNewWindowWidth = textWidth + m_cFrameScrollRel.iWidth + 2*text_border_width; - if( iNewWindowWidth > m_nMaxWidth) iNewWindowWidth = m_nMaxWidth; - if( iNewWindowWidth < MIN_WINDOW_WIDTH) iNewWindowWidth = MIN_WINDOW_WIDTH; + if( iNewWindowWidth > m_nMaxWidth) + iNewWindowWidth = m_nMaxWidth; + + if( iNewWindowWidth < m_nMinWidth) + iNewWindowWidth = m_nMinWidth; + m_cFrame.iWidth = iNewWindowWidth; @@ -217,12 +240,15 @@ void CTextBox::reSizeMainFrameWidth(int textWidth) void CTextBox::reSizeMainFrameHeight(int textHeight) { - TRACE("[CTextBox]->ReSizeMainFrameHeight: %d, current: %d\r\n",textHeight,m_cFrameTextRel.iHeight); + //TRACE("[CTextBox]->ReSizeMainFrameHeight: %d, current: %d\r\n",textHeight,m_cFrameTextRel.iHeight); int iNewWindowHeight = textHeight + 2*text_border_width; - if( iNewWindowHeight > m_nMaxHeight) iNewWindowHeight = m_nMaxHeight; - if( iNewWindowHeight < MIN_WINDOW_HEIGHT) iNewWindowHeight = MIN_WINDOW_HEIGHT; + if( iNewWindowHeight > m_nMaxHeight) + iNewWindowHeight = m_nMaxHeight; + + if( iNewWindowHeight < m_nMinHeight) + iNewWindowHeight = m_nMinHeight; m_cFrame.iHeight = iNewWindowHeight; @@ -282,15 +308,14 @@ void CTextBox::initFramesRel(void) void CTextBox::refreshTextLineArray(void) { //TRACE("[CTextBox]->RefreshLineArray \r\n"); - int loop = true; - int pos_prev = 0; - int pos = 0; - int aktWidth = 0; - int aktWordWidth = 0; - int lineBreakWidth; - int maxTextWidth = 0; + int loop = true; + int pos_prev = 0; + int pos = 0; + int aktWidth = 0; + int aktWordWidth = 0; + int lineBreakWidth = 0; - m_nNrOfNewLine = 0; + m_nNrOfNewLine = 0; std::string aktLine = ""; std::string aktWord = ""; @@ -299,21 +324,34 @@ void CTextBox::refreshTextLineArray(void) m_cLineArray.clear(); m_nNrOfLines = 0; - if( m_nMode & AUTO_WIDTH) + if( m_nMode & AUTO_WIDTH){ /* In case of autowidth, we calculate the max allowed width of the textbox */ - lineBreakWidth = MAX_WINDOW_WIDTH - m_cFrameScrollRel.iWidth - 2*text_border_width; - else + lineBreakWidth = m_nMaxWidth - m_cFrameScrollRel.iWidth - 2*text_border_width; + }else{ /* If not autowidth, we just take the actuall textframe width */ - lineBreakWidth = m_cFrameTextRel.iWidth - 2*text_border_width; - if(max_width) - lineBreakWidth = max_width; - //printf("TextBox: lineBreakWidth %d\n", lineBreakWidth); + lineBreakWidth = std::max(m_nMaxWidth, m_cFrameTextRel.iWidth - 2*text_border_width); + } + + if(m_nMaxTextWidth) + lineBreakWidth = m_nMaxTextWidth; + + //TRACE("[CTextBox] line %d: lineBreakWidth %d\n", __LINE__, lineBreakWidth); + int TextChars = m_cText.size(); // do not parse, if text is empty - if(TextChars > 0) + if(TextChars == 0) + { + m_nNrOfPages = 0; + m_nNrOfLines = 0; + m_nCurrentPage = 0; + m_nCurrentLine = 0; + m_nLinesPerPage = 1; + } + else { while(loop) { + //manage auto linebreak, if(m_nMode & NO_AUTO_LINEBREAK) pos = m_cText.find_first_of("\n",pos_prev); else @@ -328,16 +366,20 @@ void CTextBox::refreshTextLineArray(void) //TRACE_1(" Textend found\r\n"); } + //find current word between start pos and next pos (next possible \n) aktWord = m_cText.substr(pos_prev, pos - pos_prev + 1); + + //calculate length of current found word aktWordWidth = m_pcFontText->getRenderWidth(aktWord, true); + + //set next start pos pos_prev = pos + 1; //if(aktWord.find(""") == ) if(1) { //TRACE_1(" aktWord: >%s< pos:%d\r\n",aktWord.c_str(),pos); - if( aktWidth + aktWordWidth > lineBreakWidth && - !(m_nMode & NO_AUTO_LINEBREAK)) + if( (aktWidth + aktWordWidth) > lineBreakWidth && !(m_nMode & NO_AUTO_LINEBREAK)) { /* we need a new line before we can continue */ m_cLineArray.push_back(aktLine); @@ -346,17 +388,23 @@ void CTextBox::refreshTextLineArray(void) aktLine = ""; aktWidth = 0; - if(pos_prev >= TextChars) loop = false; + if(pos_prev >= TextChars) + loop = false; } + //add current word to current line aktLine += aktWord; + //set current line width aktWidth += aktWordWidth; - if (aktWidth > maxTextWidth) maxTextWidth = aktWidth; + + //set max text width, if required + if (aktWidth > m_nMaxTextWidth) + m_nMaxTextWidth = aktWidth; + //TRACE_1(" aktLine : %s\r\n",aktLine.c_str()); //TRACE_1(" aktWidth: %d aktWordWidth:%d\r\n",aktWidth,aktWordWidth); - if( ((pos < TextChars) && (m_cText[pos] == '\n')) || - loop == false) + if( ((pos < TextChars) && (m_cText[pos] == '\n')) || loop == false) { // current line ends with an carriage return, make new line if ((pos < TextChars) && (m_cText[pos] == '\n')) @@ -366,7 +414,9 @@ void CTextBox::refreshTextLineArray(void) aktLine = ""; aktWidth = 0; m_nNrOfNewLine++; - if(pos_prev >= TextChars) loop = false; + + if(pos_prev >= TextChars) + loop = false; } } } @@ -375,7 +425,7 @@ void CTextBox::refreshTextLineArray(void) /* check if we have to recalculate the window frame size, due to auto width and auto height */ if( m_nMode & AUTO_WIDTH) { - reSizeMainFrameWidth(maxTextWidth); + reSizeMainFrameWidth(m_nMaxTextWidth); } if(m_nMode & AUTO_HIGH) @@ -392,14 +442,7 @@ void CTextBox::refreshTextLineArray(void) m_nCurrentLine = m_nCurrentPage * m_nLinesPerPage; } } - else - { - m_nNrOfPages = 0; - m_nNrOfLines = 0; - m_nCurrentPage = 0; - m_nCurrentLine = 0; - m_nLinesPerPage = 1; - } + #if 0 TRACE_1(" m_nNrOfPages: %d\r\n",m_nNrOfPages); TRACE_1(" m_nNrOfLines: %d\r\n",m_nNrOfLines); @@ -414,8 +457,11 @@ void CTextBox::refreshTextLineArray(void) void CTextBox::refreshScroll(void) { - if( !(m_nMode & SCROLL)) return; - if( frameBuffer == NULL) return; + if(!(m_nMode & SCROLL)) + return; + + if( frameBuffer == NULL) + return; if (m_nNrOfPages > 1) { @@ -439,28 +485,53 @@ void CTextBox::refreshScroll(void) void CTextBox::refreshText(void) { - if( frameBuffer == NULL) return; - //TRACE(" CTextBox::refreshText: %d,%s\r\n",m_nCurrentLine,m_cLineArray[m_nCurrentLine].c_str()); + //TRACE("[CTextBox] %s Line %d\r\n", __FUNCTION__, __LINE__); + + if( frameBuffer == NULL) + return; + + //TRACE("[CTextBox] m_nCurrentLine: %d, m_nNrOfLines %d, m_cLineArray[m_nCurrentLine]: %s\r\n",m_nCurrentLine, m_nNrOfLines, m_cLineArray[m_nCurrentLine].c_str()); + //Paint Text Background if (m_nPaintBackground) frameBuffer->paintBoxRel(m_cFrameTextRel.iX+m_cFrame.iX, /*m_cFrameTextRel.iY+*/m_cFrame.iY, m_cFrameTextRel.iWidth, m_cFrameTextRel.iHeight, m_textBackgroundColor, m_nBgRadius, m_nBgRadiusType); - if( m_nNrOfLines <= 0) return; + if( m_nNrOfLines <= 0) + return; + + int y = m_cFrameTextRel.iY + text_border_width; int i; int x_center = 0; -// y += m_nFontTextHeight + ((m_cFrameTextRel.iHeight - m_nFontTextHeight * std::min(m_nLinesPerPage, m_nNrOfLines)) >> 1) - text_border_width; - y += m_nFontTextHeight + ((m_cFrameTextRel.iHeight - m_nFontTextHeight * m_nLinesPerPage) >> 1) - text_border_width; + // set text y position + if (m_nMode & TOP) + // move to top of frame + y += m_nFontTextHeight + ((m_cFrameTextRel.iHeight - m_nFontTextHeight * m_nLinesPerPage) >> 1) - text_border_width; + else if (m_nMode & BOTTOM) + // move to bottom of frame + y += m_cFrameTextRel.iHeight - text_border_width - (m_nNrOfLines > 1 ? (m_nNrOfLines-1)*m_nFontTextHeight : 0) ; + //m_nFontTextHeight + text_border_width /*- ((m_cFrameTextRel.iHeight + m_nFontTextHeight*/ * m_nLinesPerPage/*) >> 1)*/; + else + // fit into mid of frame space + y += m_nFontTextHeight + ((m_cFrameTextRel.iHeight - m_nFontTextHeight * std::min(m_nLinesPerPage, m_nNrOfLines)) >> 1) - text_border_width; + for(i = m_nCurrentLine; i < m_nNrOfLines && i < m_nCurrentLine + m_nLinesPerPage; i++) { //calculate centered xpos - if( m_nMode & CENTER ) + if( m_nMode & CENTER ){ x_center = (m_cFrameTextRel.iWidth - m_pcFontText->getRenderWidth(m_cLineArray[i], true))>>1; - - m_pcFontText->RenderString(m_cFrameTextRel.iX + text_border_width + x_center+m_cFrame.iX, + } + else if ( m_nMode & RIGHT ){ + x_center = (m_cFrameTextRel.iWidth - m_pcFontText->getRenderWidth(m_cLineArray[i], true)); + if ( m_nMode & SCROLL ) + x_center -= SCROLL_FRAME_WIDTH; + } + + //TRACE("[CTextBox] %s Line %d m_cFrame.iX %d m_cFrameTextRel.iX %d\r\n", __FUNCTION__, __LINE__, m_cFrame.iX, m_cFrameTextRel.iX); + m_pcFontText->RenderString(m_cFrame.iX + m_cFrameTextRel.iX + text_border_width + x_center, y+m_cFrame.iY, m_cFrameTextRel.iWidth, m_cLineArray[i].c_str(), m_textColor, 0, true); // UTF-8 y += m_nFontTextHeight; @@ -470,10 +541,12 @@ void CTextBox::refreshText(void) void CTextBox::scrollPageDown(const int pages) { - if( !(m_nMode & SCROLL)) return; - if( m_nNrOfLines <= 0) return; - TRACE("[CTextBox]->ScrollPageDown \r\n"); - + //TRACE("[CTextBox] %s Line %d\r\n", __FUNCTION__, __LINE__); + if( !(m_nMode & SCROLL)) + return; + + if( m_nNrOfLines <= 0) + return; if(m_nCurrentPage + pages < m_nNrOfPages) { @@ -489,10 +562,12 @@ void CTextBox::scrollPageDown(const int pages) void CTextBox::scrollPageUp(const int pages) { - if( !(m_nMode & SCROLL)) return; - if( m_nNrOfLines <= 0) return; - TRACE("[CTextBox]->ScrollPageUp \r\n"); - + //TRACE("[CTextBox] %s Line %d\r\n", __FUNCTION__, __LINE__); + if( !(m_nMode & SCROLL)) + return; + + if( m_nNrOfLines <= 0) + return; if(m_nCurrentPage - pages > 0) { @@ -508,25 +583,29 @@ void CTextBox::scrollPageUp(const int pages) void CTextBox::refresh(void) { - if( frameBuffer == NULL) return; - //TRACE("[CTextBox]->Refresh\r\n"); -//printf("setText::refresh!\n"); + //TRACE("[CTextBox] %s Line %d\r\n", __FUNCTION__, __LINE__); + if( frameBuffer == NULL) + return; //Paint text refreshScroll(); refreshText(); } -bool CTextBox::setText(const std::string* newText, int _max_width) + +bool CTextBox::setText(const std::string* newText, int max_width) { //TRACE("[CTextBox]->SetText \r\n"); bool result = false; - max_width = _max_width; + m_nMaxTextWidth = max_width; + //printf("setText: _max_width %d max_width %d\n", _max_width, max_width); if (newText != NULL) { m_cText = *newText; //m_cText = *newText + "\n"; //FIXME test + reSizeMainFrameHeight(m_cFrame.iHeight); + //refresh text line array refreshTextLineArray(); refresh(); result = true; @@ -536,16 +615,33 @@ bool CTextBox::setText(const std::string* newText, int _max_width) void CTextBox::paint (void) { - if(frameBuffer != NULL) return; - //TRACE("[CTextBox]->paint \r\n"); + //TRACE("[CTextBox] %s Line %d\r\n", __FUNCTION__, __LINE__); +#if 0 + TRACE(" Mode: "); + if(m_nMode & SCROLL) TRACE("SCROLL "); + if(m_nMode & NO_AUTO_LINEBREAK) TRACE("NO_AUTO_LINEBREAK "); + if(m_nMode & AUTO_WIDTH) TRACE("AUTO_WIDTH "); + if(m_nMode & AUTO_HIGH) TRACE("AUTO_HIGH "); + if(m_nMode & CENTER) TRACE("CENTER "); + if(m_nMode & RIGHT) TRACE("RIGHT "); + if(m_nMode & TOP) TRACE("TOP "); + if(m_nMode & BOTTOM) TRACE("BOTTOM "); + TRACE("\r\n"); + +#endif + if(frameBuffer != NULL) + return; + frameBuffer = CFrameBuffer::getInstance(); refresh(); } void CTextBox::hide (void) { - if(frameBuffer == NULL) return; - //TRACE("[CTextBox]->hide \r\n"); + //TRACE("[CTextBox] %s Line %d\r\n", __FUNCTION__, __LINE__); + if(frameBuffer == NULL) + return; + frameBuffer->paintBackgroundBoxRel(m_cFrame.iX, m_cFrame.iY, m_cFrame.iWidth, m_cFrame.iHeight); frameBuffer->blit(); frameBuffer = NULL; diff --git a/src/gui/widget/textbox.h b/src/gui/widget/textbox.h index fa8ff7ab9..b7e8c1166 100644 --- a/src/gui/widget/textbox.h +++ b/src/gui/widget/textbox.h @@ -72,7 +72,7 @@ class CBox public: /* Constructor */ - inline CBox(){;}; + inline CBox(){iY = 0; iX = 0; iWidth = 0;iHeight = 0;}; inline CBox( const int _iX, const int _iY, const int _iWidth, const int _iHeight){iX=_iX; iY=_iY; iWidth=_iWidth; iHeight=_iHeight;}; inline ~CBox(){;}; /* Functions */ @@ -83,13 +83,28 @@ class CBox int iHeight; }; -class CTextBox +class CTextBox { + public: + /* Variables */ + enum textbox_modes + { + AUTO_WIDTH = 0x01, //auto adapt frame width to max width or max text width, text is painted with auto linebreak + AUTO_HIGH = 0x02, //auto adapt frame height to max height, text is painted with auto linebreak + SCROLL = 0x04, //frame box contains scrollbars on long text + CENTER = 0x40, //paint text centered + RIGHT = 0x80, //paint text right + TOP = 0x100, //paint text on top of frame + BOTTOM = 0x200, //paint text on bottom of frame + NO_AUTO_LINEBREAK = 0x400 //paint text without auto linebreak, cutting text + }; + private: /* Functions */ void refreshTextLineArray(void); void initVar(void); void initFramesRel(void); + void initFramesAndTextArray(); void refreshScroll(void); void refreshText(void); void reSizeMainFrameWidth(int maxTextWidth); @@ -107,6 +122,10 @@ class CTextBox int m_nMaxHeight; int m_nMaxWidth; + int m_nMinHeight; + int m_nMinWidth; + + int m_nMaxTextWidth; int m_nMode; @@ -128,15 +147,17 @@ class CTextBox fb_pixel_t m_textColor; CFrameBuffer * frameBuffer; - int max_width; +/* int max_width;*/ + int text_border_width; + public: /* Constructor */ CTextBox(); CTextBox( const char * text); CTextBox( const char * text, Font* font_text, - const int mode, + const int pmode, const CBox* position, CFBWindow::color_t textBackgroundColor = COL_MENUCONTENT_PLUS_0); @@ -146,12 +167,17 @@ class CTextBox void refresh(void); void scrollPageDown(const int pages); void scrollPageUp(const int pages); - void enableBackgroundPaint(bool enable = true) { m_nPaintBackground = enable; }; - bool setText(const std::string* newText, int _max_width = 0); + void enableBackgroundPaint(bool mode = true){m_nPaintBackground = mode;}; + bool setText(const std::string* newText, int max_width = 0); void setTextColor(fb_pixel_t color_text){ m_textColor = color_text;}; void setBackGroundRadius(const int radius, const int type){m_nBgRadius = radius; m_nBgRadiusType = type;}; void setTextBorderWidth(int border); void setTextFont(Font* font_text); + void setTextMode(const int text_mode){m_nMode = text_mode;}; + void setBackGroundColor(CFBWindow::color_t textBackgroundColor){m_textBackgroundColor = textBackgroundColor;}; + void setWindowPos(const CBox* position){m_cFrame = *position;}; + void setWindowMaxDimensions(const int width, const int height); + void setWindowMinDimensions(const int width, const int height); inline bool isPainted(void) {if( frameBuffer == NULL) return (false); else return (true);}; inline CBox getWindowsPos(void) {return(m_cFrame);}; @@ -162,17 +188,6 @@ class CTextBox void paint (void); void hide (void); - - - /* Variables */ - typedef enum mode_ - { - AUTO_WIDTH = 0x01, - AUTO_HIGH = 0x02, - SCROLL = 0x04, - CENTER = 0x40, - NO_AUTO_LINEBREAK = 0x80 - } mode; }; #endif // !defined(AFX_TEXTBOX_H__208DED01_ABEC_491C_A632_5B21057DC5D8__INCLUDED_) diff --git a/src/gui/zapit_setup.cpp b/src/gui/zapit_setup.cpp index 8d8430024..db105e7c7 100644 --- a/src/gui/zapit_setup.cpp +++ b/src/gui/zapit_setup.cpp @@ -67,38 +67,32 @@ void CZapitSetup::showMenu() //menue init CMenuWidget *zapit = new CMenuWidget(LOCALE_MAINMENU_SETTINGS, NEUTRINO_ICON_SETTINGS, width, MN_WIDGET_ID_ZAPIT); zapit->addIntroItems(LOCALE_ZAPITSETUP_INFO); - + COnOffNotifier* miscZapitNotifier = new COnOffNotifier(1); //zapit - CMenuOptionChooser * mc = new CMenuOptionChooser(LOCALE_ZAPITSETUP_LAST_USE, &g_settings.uselastchannel, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true, this, CRCInput::RC_red, NEUTRINO_ICON_BUTTON_RED); + CMenuOptionChooser * mc = new CMenuOptionChooser(LOCALE_ZAPITSETUP_LAST_USE, &g_settings.uselastchannel, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true, miscZapitNotifier, CRCInput::RC_red, NEUTRINO_ICON_BUTTON_RED); mc->setHint("", LOCALE_MENU_HINT_LAST_USE); - zapit->addItem(mc); + CSelectChannelWidget select; - zapit->addItem(GenericMenuSeparatorLine); - - zapit1 = new CMenuForwarder(LOCALE_ZAPITSETUP_LAST_TV , !g_settings.uselastchannel, g_settings.StartChannelTV, &select, "tv", CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN ); + CMenuForwarder *zapit1 = new CMenuForwarder(LOCALE_ZAPITSETUP_LAST_TV , !g_settings.uselastchannel, g_settings.StartChannelTV, &select, "tv", CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN ); zapit1->setHint("", LOCALE_MENU_HINT_LAST_TV); - zapit->addItem(zapit1); - zapit2 = new CMenuForwarder(LOCALE_ZAPITSETUP_LAST_RADIO , !g_settings.uselastchannel, g_settings.StartChannelRadio, &select, "radio", CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW ); + CMenuForwarder *zapit2 = new CMenuForwarder(LOCALE_ZAPITSETUP_LAST_RADIO , !g_settings.uselastchannel, g_settings.StartChannelRadio, &select, "radio", CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW ); zapit2->setHint("", LOCALE_MENU_HINT_LAST_RADIO); + + miscZapitNotifier->addItem(zapit1); + miscZapitNotifier->addItem(zapit2); + + zapit->addItem(mc); + zapit->addItem(GenericMenuSeparatorLine); + zapit->addItem(zapit1); zapit->addItem(zapit2); zapit->exec(NULL, ""); + delete miscZapitNotifier; delete zapit; } -bool CZapitSetup::changeNotify(const neutrino_locale_t OptionName, void *) -{ - if (ARE_LOCALES_EQUAL(OptionName, LOCALE_ZAPITSETUP_LAST_USE)) - { - zapit1->setActive(!g_settings.uselastchannel); - zapit2->setActive(!g_settings.uselastchannel); - } - - return false; -} - //select menu CSelectChannelWidget::CSelectChannelWidget() { diff --git a/src/gui/zapit_setup.h b/src/gui/zapit_setup.h index 8e8c7f3db..95636611e 100644 --- a/src/gui/zapit_setup.h +++ b/src/gui/zapit_setup.h @@ -31,10 +31,9 @@ #include #include -class CZapitSetup : public CMenuTarget, CChangeObserver +class CZapitSetup : public CMenuTarget { private: - CMenuForwarder *zapit1, *zapit2; int width; @@ -44,7 +43,6 @@ public: CZapitSetup(); ~CZapitSetup(); int exec(CMenuTarget* parent, const std::string & actionKey); - virtual bool changeNotify(const neutrino_locale_t , void *); }; class CSelectChannelWidget : public CMenuWidget diff --git a/src/neutrino.cpp b/src/neutrino.cpp index c87e3406c..97fbc52a2 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -59,6 +59,7 @@ #include #endif #include +#include #include "gui/audioplayer.h" #include "gui/bouquetlist.h" @@ -136,10 +137,6 @@ t_channel_id standby_channel_id; static pthread_t timer_thread; void * timerd_main_thread(void *data); -extern int streamts_stop; -void * streamts_main_thread(void *data); -static pthread_t stream_thread ; - void * nhttpd_main_thread(void *data); static pthread_t nhttpd_thread ; @@ -217,6 +214,7 @@ CNeutrinoApp::CNeutrinoApp() RADIOchannelList = NULL; skipShutdownTimer = false; skipSleepTimer = false; + lockStandbyCall = false; current_muted = 0; recordingstatus = 0; g_channel_list_changed = 0; @@ -455,7 +453,7 @@ int CNeutrinoApp::loadSetup(const char * fname) snprintf(g_settings.ifname, sizeof(g_settings.ifname), "%s", configfile.getString("ifname", "eth0").c_str());; g_settings.epg_save = configfile.getBool("epg_save", false); - + g_settings.epg_save_standby = configfile.getBool("epg_save_standby", true); //widget settings g_settings.widget_fade = false; g_settings.widget_fade = configfile.getBool("widget_fade" , false ); @@ -579,7 +577,9 @@ int CNeutrinoApp::loadSetup(const char * fname) std::string filename = e->d_name; if ((filename.find("_temp.ts") == filename.size() - 8) || (filename.find("_temp.xml") == filename.size() - 9)) { - remove(filename.c_str()); + std::string timeshiftDir_filename= timeshiftDir; + timeshiftDir_filename+= "/" + filename; + remove(timeshiftDir_filename.c_str()); } } closedir(d); @@ -900,6 +900,7 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setString("timezone", g_settings.timezone); // epg configfile.setBool("epg_save", g_settings.epg_save); + configfile.setBool("epg_save_standby", g_settings.epg_save_standby); configfile.setString("epg_cache_time" ,g_settings.epg_cache ); configfile.setString("epg_extendedcache_time" ,g_settings.epg_extendedcache); configfile.setString("epg_old_events" ,g_settings.epg_old_events ); @@ -1434,16 +1435,18 @@ void CNeutrinoApp::SetChannelMode(int newmode) break; } INFO("newmode %d sort old %d new %d", newmode, sortmode[newmode], g_settings.channellist_sort_mode); - if(newmode != LIST_MODE_FAV && sortmode[newmode] != g_settings.channellist_sort_mode && g_settings.channellist_sort_mode < 3) { + if(newmode != LIST_MODE_FAV && sortmode[newmode] != g_settings.channellist_sort_mode && g_settings.channellist_sort_mode < CChannelList::SORT_MAX) { sortmode[newmode] = g_settings.channellist_sort_mode; INFO("sorting, mode %d, %d bouquets\n", g_settings.channellist_sort_mode, (int)bouquetList->Bouquets.size()); for (uint32_t i = 0; i < bouquetList->Bouquets.size(); i++) { - if(g_settings.channellist_sort_mode == 0) + if(g_settings.channellist_sort_mode == CChannelList::SORT_ALPHA) bouquetList->Bouquets[i]->channelList->SortAlpha(); - if(g_settings.channellist_sort_mode == 1) + if(g_settings.channellist_sort_mode == CChannelList::SORT_TP) bouquetList->Bouquets[i]->channelList->SortTP(); - if(g_settings.channellist_sort_mode == 2) + if(g_settings.channellist_sort_mode == CChannelList::SORT_SAT) bouquetList->Bouquets[i]->channelList->SortSat(); + if(g_settings.channellist_sort_mode == CChannelList::SORT_CH_NUMBER) + bouquetList->Bouquets[i]->channelList->SortChNumber(); } channelList->adjustToChannelID(channelList->getActiveChannel_ChannelID()); } @@ -1896,7 +1899,7 @@ fprintf(stderr, "[neutrino start] %d -> %5ld ms\n", __LINE__, time_monotonic_ms pthread_create (&nhttpd_thread, NULL, nhttpd_main_thread, (void *) NULL); - pthread_create (&stream_thread, NULL, streamts_main_thread, (void *) NULL); + CStreamManager::getInstance()->Start(); #ifndef DISABLE_SECTIONSD CSectionsdClient::epg_config config; @@ -2203,6 +2206,33 @@ void CNeutrinoApp::RealRun(CMenuWidget &mainMenu) else ShowHintUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_PERSONALIZE_MENUDISABLEDHINT),450, 10); } + else if ((msg == CRCInput::RC_audio) && !g_settings.audio_run_player) + { + StopSubtitles(); + usermenu.showUserMenu(SNeutrinoSettings::BUTTON_GREEN); + StartSubtitles(); + } + else if( msg == CRCInput::RC_green) + { + if (g_settings.personalize[SNeutrinoSettings::P_MAIN_GREEN_BUTTON] == CPersonalizeGui::PERSONALIZE_ACTIVE_MODE_ENABLED) + { + StopSubtitles(); + usermenu.showUserMenu(SNeutrinoSettings::BUTTON_GREEN); + StartSubtitles(); + } + else + ShowHintUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_PERSONALIZE_MENUDISABLEDHINT),450, 10); + } + else if( msg == CRCInput::RC_yellow ) { // NVODs + if (g_settings.personalize[SNeutrinoSettings::P_MAIN_YELLOW_BUTTON] == CPersonalizeGui::PERSONALIZE_ACTIVE_MODE_ENABLED) + { + StopSubtitles(); + usermenu.showUserMenu(SNeutrinoSettings::BUTTON_YELLOW); + StartSubtitles(); + } + else + ShowHintUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_PERSONALIZE_MENUDISABLEDHINT),450, 10); + } else if( (msg == CRCInput::RC_green) || ((msg == CRCInput::RC_audio) && !g_settings.audio_run_player) ) { StopSubtitles(); @@ -2720,14 +2750,25 @@ _repeat: } else if( msg == NeutrinoMessages::ANNOUNCE_SLEEPTIMER) { if( mode != mode_scart && mode != mode_standby) - skipSleepTimer = (ShowLocalizedMessage(LOCALE_MESSAGEBOX_INFO, LOCALE_SLEEPTIMERBOX_ANNOUNCE,CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo, NULL, 450, 30, true) == CMessageBox::mbrYes); + skipSleepTimer = (ShowLocalizedMessage(LOCALE_MESSAGEBOX_INFO, g_settings.shutdown_real ? LOCALE_SHUTDOWNTIMER_ANNOUNCE:LOCALE_SLEEPTIMERBOX_ANNOUNCE,CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo, NULL, 450, 30, true) == CMessageBox::mbrYes); return messages_return::handled; } else if( msg == NeutrinoMessages::SLEEPTIMER) { - if(skipSleepTimer) { - printf("NeutrinoMessages::SLEEPTIMER: skiping\n"); - skipSleepTimer = false; - return messages_return::handled; + if(data) {//INACTIVITY SLEEPTIMER + skipShutdownTimer = + (ShowLocalizedMessage(LOCALE_MESSAGEBOX_INFO, g_settings.shutdown_real ? LOCALE_SHUTDOWNTIMER_ANNOUNCE:LOCALE_SLEEPTIMERBOX_ANNOUNCE, + CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo, NULL, 450, 30, true) == CMessageBox::mbrYes);//FIXME + if(skipShutdownTimer) { + printf("NeutrinoMessages::INACTIVITY SLEEPTIMER: skiping\n"); + skipShutdownTimer = false; + return messages_return::handled; + } + }else{ //MAIN-MENU SLEEPTIMER + if(skipSleepTimer) { + printf("NeutrinoMessages::SLEEPTIMER: skiping\n"); + skipSleepTimer = false; + return messages_return::handled; + } } if (g_settings.shutdown_real && can_deepstandby) ExitRun(true, can_deepstandby); @@ -3183,6 +3224,11 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) //static bool wasshift = false; INFO("%s", bOnOff ? "ON" : "OFF" ); + if(lockStandbyCall) + return; + + lockStandbyCall = true; + if( bOnOff ) { CVFD::getInstance()->ShowText("standby... "); if( mode == mode_scart ) { @@ -3203,7 +3249,8 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) g_Radiotext->radiotext_stop(); - if(!fromDeepStandby && !CRecordManager::getInstance()->RecordingStatus()) { + bool stream_status = CStreamManager::getInstance()->StreamStatus(); + if(!fromDeepStandby && !CRecordManager::getInstance()->RecordingStatus() && !stream_status) { g_Zapit->setStandby(true); } else { g_Zapit->stopPlayBack(); @@ -3219,7 +3266,7 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) if(!CRecordManager::getInstance()->RecordingStatus() ) { //only save epg when not recording - if(g_settings.epg_save && !fromDeepStandby) { + if(g_settings.epg_save && !fromDeepStandby && g_settings.epg_save_standby) { saveEpg(false);//false CVFD::MODE_STANDBY } } @@ -3314,6 +3361,7 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) g_volume->AudioMute(current_muted, true); StartSubtitles(); } + lockStandbyCall = false; } void CNeutrinoApp::radioMode( bool rezap) @@ -3542,7 +3590,6 @@ bool CNeutrinoApp::changeNotify(const neutrino_locale_t OptionName, void * /*dat **************************************************************************************/ void stop_daemons(bool stopall) { - streamts_stop = 1; dvbsub_close(); tuxtxt_stop(); tuxtxt_close(); @@ -3555,7 +3602,7 @@ void stop_daemons(bool stopall) pthread_cancel(nhttpd_thread); pthread_join(nhttpd_thread, NULL); printf("httpd shutdown done\n"); - pthread_join(stream_thread, NULL); + CStreamManager::getInstance()->Stop(); if(stopall) { printf("timerd shutdown\n"); g_Timerd->shutdown(); diff --git a/src/neutrino.h b/src/neutrino.h index b129adfe6..c36dd2406 100644 --- a/src/neutrino.h +++ b/src/neutrino.h @@ -119,6 +119,7 @@ private: bool skipShutdownTimer; bool skipSleepTimer; + bool lockStandbyCall; bool pbBlinkChange; int tvsort[LIST_MODE_LAST]; int radiosort[LIST_MODE_LAST]; diff --git a/src/nhttpd/yhttpd_core/yconnection.cpp b/src/nhttpd/yhttpd_core/yconnection.cpp index e41b7d3e3..7c035c12d 100644 --- a/src/nhttpd/yhttpd_core/yconnection.cpp +++ b/src/nhttpd/yhttpd_core/yconnection.cpp @@ -22,6 +22,11 @@ long CWebserverConnection::GConnectionNumber = 0; // Constructor & Destructor & Initialization //============================================================================= CWebserverConnection::CWebserverConnection(CWebserver *pWebserver) { + sock = 0; + ConnectionNumber = 0; + enlapsed_request = 0; + enlapsed_response = 0; + Webserver = pWebserver; Request.Webserver = pWebserver; Request.Connection = this; @@ -39,6 +44,12 @@ CWebserverConnection::CWebserverConnection(CWebserver *pWebserver) { //------------------------------------------------------------------------- CWebserverConnection::CWebserverConnection() { // aprintf("test CWebserverConnection::CWebserverConnection()\n"); + sock = 0; + RequestCanceled = 0; + keep_alive = 0; + HttpStatus = 0; + enlapsed_request = 0; + enlapsed_response = 0; ConnectionNumber = ++GConnectionNumber; } //------------------------------------------------------------------------- diff --git a/src/nhttpd/yhttpd_core/yhook.h b/src/nhttpd/yhttpd_core/yhook.h index 3c0306811..9556be9f5 100644 --- a/src/nhttpd/yhttpd_core/yhook.h +++ b/src/nhttpd/yhttpd_core/yhook.h @@ -141,7 +141,7 @@ public: CStringList HookVarList; // Variables in Hook-Handling passing to other Hooks THttp_Method Method; // HTTP Method (requested) // constructor & deconstructor - CyhookHandler(){}; + CyhookHandler(){ContentLength = 0; keep_alive = 0; _outIndent = 0;}; virtual ~CyhookHandler(){}; // hook slot handler diff --git a/src/system/configure_network.cpp b/src/system/configure_network.cpp index 0e0040454..30c347c5f 100644 --- a/src/system/configure_network.cpp +++ b/src/system/configure_network.cpp @@ -6,7 +6,7 @@ * * 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 3 of the License, or + * 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, @@ -217,11 +217,11 @@ void CNetworkConfig::commitConfig(void) void CNetworkConfig::startNetwork(void) { - const char _ifup[] = "/sbin/ifup"; + std::string cmd = "/sbin/ifup " + ifname; #ifdef DEBUG - printf("CNetworkConfig::startNetwork: %s %s\n",_ifup, ifname.c_str()); + printf("CNetworkConfig::startNetwork: %s\n", cmd.c_str()); #endif - my_system(_ifup, ifname.c_str()); + my_system("/bin/sh", "-c", cmd.c_str()); if (!inet_static) { init_vars(); @@ -231,11 +231,11 @@ void CNetworkConfig::startNetwork(void) void CNetworkConfig::stopNetwork(void) { - const char _ifdown[] = "/sbin/ifdown"; + std::string cmd = "/sbin/ifdown " + ifname; #ifdef DEBUG - printf("CNetworkConfig::stopNetwork: %s %s\n",_ifdown, ifname.c_str()); + printf("CNetworkConfig::stopNetwork: %s\n", cmd.c_str()); #endif - my_system(_ifdown, ifname.c_str()); + my_system("/bin/sh", "-c", cmd.c_str()); } diff --git a/src/system/locals.h b/src/system/locals.h index 14f9d4d6f..495ed1c55 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -238,6 +238,7 @@ typedef enum LOCALE_CHANNELLIST_FOOT_NEXT, LOCALE_CHANNELLIST_FOOT_OFF, LOCALE_CHANNELLIST_FOOT_SORT_ALPHA, + LOCALE_CHANNELLIST_FOOT_SORT_CHNUM, LOCALE_CHANNELLIST_FOOT_SORT_FREQ, LOCALE_CHANNELLIST_FOOT_SORT_SAT, LOCALE_CHANNELLIST_HEAD, @@ -463,6 +464,7 @@ typedef enum LOCALE_FILESYSTEM_IS_UTF8_OPTION_ISO8859_1, LOCALE_FILESYSTEM_IS_UTF8_OPTION_UTF8, LOCALE_FLASHUPDATE_ACTIONREADFLASH, + LOCALE_FLASHUPDATE_APPLY_SETTINGS, LOCALE_FLASHUPDATE_CANTOPENFILE, LOCALE_FLASHUPDATE_CANTOPENMTD, LOCALE_FLASHUPDATE_CHECKUPDATE_INTERNET, @@ -775,6 +777,7 @@ typedef enum LOCALE_MENU_HINT_EPG_MAX_EVENTS, LOCALE_MENU_HINT_EPG_OLD_EVENTS, LOCALE_MENU_HINT_EPG_SAVE, + LOCALE_MENU_HINT_EPG_SAVE_STANDBY, LOCALE_MENU_HINT_EVENT_TEXTCOLOR, LOCALE_MENU_HINT_EVENTLIST_FONTS, LOCALE_MENU_HINT_EXTENDED, @@ -1126,6 +1129,7 @@ typedef enum LOCALE_MISCSETTINGS_EPG_OLD_EVENTS_HINT1, LOCALE_MISCSETTINGS_EPG_OLD_EVENTS_HINT2, LOCALE_MISCSETTINGS_EPG_SAVE, + LOCALE_MISCSETTINGS_EPG_SAVE_STANDBY, LOCALE_MISCSETTINGS_GENERAL, LOCALE_MISCSETTINGS_HEAD, LOCALE_MISCSETTINGS_INFOBAR, @@ -1345,6 +1349,8 @@ typedef enum LOCALE_NETWORKMENU_ERROR_NO_ADDRESS, LOCALE_NETWORKMENU_GATEWAY, LOCALE_NETWORKMENU_HOSTNAME, + LOCALE_NETWORKMENU_HOSTNAME_HINT1, + LOCALE_NETWORKMENU_HOSTNAME_HINT2, LOCALE_NETWORKMENU_INACTIVE_NETWORK, LOCALE_NETWORKMENU_IPADDRESS, LOCALE_NETWORKMENU_MOUNT, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index d86a33a85..5f7098601 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -238,6 +238,7 @@ const char * locale_real_names[] = "channellist.foot_next", "channellist.foot_off", "channellist.foot_sort_alpha", + "channellist.foot_sort_chnum", "channellist.foot_sort_freq", "channellist.foot_sort_sat", "channellist.head", @@ -463,6 +464,7 @@ const char * locale_real_names[] = "filesystem.is.utf8.option.iso8859.1", "filesystem.is.utf8.option.utf8", "flashupdate.actionreadflash", + "flashupdate.apply_settings", "flashupdate.cantopenfile", "flashupdate.cantopenmtd", "flashupdate.checkupdate_internet", @@ -775,6 +777,7 @@ const char * locale_real_names[] = "menu.hint_epg_max_events", "menu.hint_epg_old_events", "menu.hint_epg_save", + "menu.hint_epg_save_standby", "menu.hint_event_textcolor", "menu.hint_eventlist_fonts", "menu.hint_extended", @@ -1126,6 +1129,7 @@ const char * locale_real_names[] = "miscsettings.epg_old_events_hint1", "miscsettings.epg_old_events_hint2", "miscsettings.epg_save", + "miscsettings.epg_save_standby", "miscsettings.general", "miscsettings.head", "miscsettings.infobar", @@ -1345,6 +1349,8 @@ const char * locale_real_names[] = "networkmenu.error_no_address", "networkmenu.gateway", "networkmenu.hostname", + "networkmenu.hostname_hint1", + "networkmenu.hostname_hint2", "networkmenu.inactive_network", "networkmenu.ipaddress", "networkmenu.mount", diff --git a/src/system/settings.cpp b/src/system/settings.cpp index 15c32b6cb..d9d45c3e9 100644 --- a/src/system/settings.cpp +++ b/src/system/settings.cpp @@ -35,6 +35,8 @@ const struct personalize_settings_t personalize_settings[SNeutrinoSettings::P_SE //user menu {"personalize_bluebutton" , CPersonalizeGui::PERSONALIZE_ACTIVE_MODE_ENABLED}, // features + {"personalize_yellowbutton" , CPersonalizeGui::PERSONALIZE_ACTIVE_MODE_ENABLED}, // features + {"personalize_greenbutton" , CPersonalizeGui::PERSONALIZE_ACTIVE_MODE_ENABLED}, // features {"personalize_redbutton" , CPersonalizeGui::PERSONALIZE_ACTIVE_MODE_ENABLED}, // epg/info //main menu diff --git a/src/system/settings.h b/src/system/settings.h index 3db2dd469..a232ad80d 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -128,6 +128,7 @@ struct SNeutrinoSettings // EPG int epg_save; + int epg_save_standby; std::string epg_cache; std::string epg_old_events; std::string epg_max_events; @@ -147,9 +148,11 @@ struct SNeutrinoSettings //user menu P_MAIN_BLUE_BUTTON, - P_MAIN_RED_BUTTON, - - //main menu + P_MAIN_YELLOW_BUTTON, + P_MAIN_GREEN_BUTTON, + P_MAIN_RED_BUTTON, + + //main menu P_MAIN_TV_MODE, P_MAIN_TV_RADIO_MODE, //togglemode P_MAIN_RADIO_MODE, diff --git a/src/zapit/src/capmt.cpp b/src/zapit/src/capmt.cpp index 86a8ab8d6..9a4af5284 100644 --- a/src/zapit/src/capmt.cpp +++ b/src/zapit/src/capmt.cpp @@ -33,7 +33,7 @@ #include #include -#define DEBUG_CAPMT +//#define DEBUG_CAPMT CCam::CCam() {