diff --git a/.gitignore b/.gitignore index b2acf5b02..f72cf9363 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ src/zapit/src/pzapit src/zapit/src/udpstreampes src/drivertool src/gui/svn_version.h +src/gui/git_version.h diff --git a/data/Makefile.am b/data/Makefile.am index 7519719cd..468993836 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -5,4 +5,4 @@ SUBDIRS += lcd endif configdir = $(CONFIGDIR) -config_DATA = cables.xml satellites.xml encoding.conf tobackup.conf providermap.xml +config_DATA = cables.xml satellites.xml encoding.conf tobackup.conf providermap.xml settingsupdate.conf diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am index 66dc9a37d..4dd2afa5f 100644 --- a/data/icons/Makefile.am +++ b/data/icons/Makefile.am @@ -1,6 +1,29 @@ installdir = $(DATADIR)/neutrino/icons -install_DATA = \ +locale = \ + locale/deutsch.png \ + locale/english.png + +locale_unmaintained = \ + locale/unmaintained/bayrisch.png \ + locale/unmaintained/bosanski.png \ + locale/unmaintained/ch-baslerdeutsch.png \ + locale/unmaintained/ch-berndeutsch.png \ + locale/unmaintained/czech.png \ + locale/unmaintained/francais.png \ + locale/unmaintained/italiano.png \ + locale/unmaintained/nederlands.png \ + locale/unmaintained/polski.png \ + locale/unmaintained/portugues.png \ + locale/unmaintained/russkij.png \ + locale/unmaintained/slovak.png \ + locale/unmaintained/suomi.png \ + locale/unmaintained/svenska.png + +install_DATA = $(locale) +install_DATA += $(locale_unmaintained) + +install_DATA += \ 0.png \ 1.png \ 16_9.png \ @@ -16,7 +39,6 @@ install_DATA = \ ats.png \ ats_gray.png \ audio.png \ - bayrisch.png \ biss_green.png \ biss_white.png \ biss_yellow.png \ @@ -24,15 +46,12 @@ install_DATA = \ bookmarkmanager.png \ border_lr.png \ border_ul.png \ - bosanski.png \ btn_record_active.png \ btn_record_inactive.png \ btn_stop.png \ ca.png \ ca2.png \ ca2_gray.png \ - ch-baslerdeutsch.png \ - ch-berndeutsch.png \ colors.png \ conax_green.png \ conax_white.png \ @@ -40,7 +59,6 @@ install_DATA = \ cw_green.png \ cw_white.png \ cw_yellow.png \ - czech.png \ d_green.png \ d_white.png \ d_yellow.png \ @@ -48,17 +66,11 @@ install_DATA = \ dd_avail.png \ dd_gray.png \ ddfill.png \ - deutsch.png \ down.png \ - dutch.png \ - ellinika.png \ - english.png \ error.png \ features.png \ file.png \ folder.png \ - francais.png \ - french.png \ games.png \ gelb.png \ gruen.png \ @@ -108,7 +120,6 @@ install_DATA = \ hint_vfd.png \ hint_video.png \ home.png \ - hungarian.png \ icon_green.png \ icon_movieplayer.png \ icon_red.png \ @@ -120,7 +131,6 @@ install_DATA = \ ird_green.png \ ird_white.png \ ird_yellow.png \ - italiano.png \ keybinding.png \ language.png \ lcd.png \ @@ -157,16 +167,12 @@ install_DATA = \ nds_green.png \ nds_white.png \ nds_yellow.png \ - nederlands.png \ network.png \ - norsk.png \ not_mounted.png \ notyet.png \ numericpad.png \ ok.png \ personalize.png \ - polski.png \ - portugues.png \ power.png \ powervu_green.png \ powervu_white.png \ @@ -208,9 +214,7 @@ install_DATA = \ res_hd.png \ res_sd.png \ right.png \ - romania.png \ rot.png \ - russkij.png \ scan.jpg \ seca_green.png \ seca_white.png \ @@ -218,14 +222,11 @@ install_DATA = \ settings.png \ shell.png \ shutdown.jpg \ - slovak.png \ softupdate.png \ start.jpg \ streaming.png \ subt.png \ subt_gray.png \ - suomi.png \ - svenska.png \ timer.png \ tuner_1.png \ tuner_2.png \ diff --git a/data/icons/deutsch.png b/data/icons/locale/deutsch.png similarity index 100% rename from data/icons/deutsch.png rename to data/icons/locale/deutsch.png diff --git a/data/icons/english.png b/data/icons/locale/english.png similarity index 100% rename from data/icons/english.png rename to data/icons/locale/english.png diff --git a/data/icons/ellinika.png b/data/icons/locale/orphaned/ellinika.png similarity index 100% rename from data/icons/ellinika.png rename to data/icons/locale/orphaned/ellinika.png diff --git a/data/icons/norsk.png b/data/icons/locale/orphaned/norsk.png similarity index 100% rename from data/icons/norsk.png rename to data/icons/locale/orphaned/norsk.png diff --git a/data/icons/romania.png b/data/icons/locale/orphaned/romania.png similarity index 100% rename from data/icons/romania.png rename to data/icons/locale/orphaned/romania.png diff --git a/data/icons/bayrisch.png b/data/icons/locale/unmaintained/bayrisch.png similarity index 100% rename from data/icons/bayrisch.png rename to data/icons/locale/unmaintained/bayrisch.png diff --git a/data/icons/bosanski.png b/data/icons/locale/unmaintained/bosanski.png similarity index 100% rename from data/icons/bosanski.png rename to data/icons/locale/unmaintained/bosanski.png diff --git a/data/icons/ch-baslerdeutsch.png b/data/icons/locale/unmaintained/ch-baslerdeutsch.png similarity index 100% rename from data/icons/ch-baslerdeutsch.png rename to data/icons/locale/unmaintained/ch-baslerdeutsch.png diff --git a/data/icons/ch-berndeutsch.png b/data/icons/locale/unmaintained/ch-berndeutsch.png similarity index 100% rename from data/icons/ch-berndeutsch.png rename to data/icons/locale/unmaintained/ch-berndeutsch.png diff --git a/data/icons/czech.png b/data/icons/locale/unmaintained/czech.png similarity index 100% rename from data/icons/czech.png rename to data/icons/locale/unmaintained/czech.png diff --git a/data/icons/dutch.png b/data/icons/locale/unmaintained/dutch.png similarity index 100% rename from data/icons/dutch.png rename to data/icons/locale/unmaintained/dutch.png diff --git a/data/icons/francais.png b/data/icons/locale/unmaintained/francais.png similarity index 100% rename from data/icons/francais.png rename to data/icons/locale/unmaintained/francais.png diff --git a/data/icons/french.png b/data/icons/locale/unmaintained/french.png similarity index 100% rename from data/icons/french.png rename to data/icons/locale/unmaintained/french.png diff --git a/data/icons/hungarian.png b/data/icons/locale/unmaintained/hungarian.png similarity index 100% rename from data/icons/hungarian.png rename to data/icons/locale/unmaintained/hungarian.png diff --git a/data/icons/italiano.png b/data/icons/locale/unmaintained/italiano.png similarity index 100% rename from data/icons/italiano.png rename to data/icons/locale/unmaintained/italiano.png diff --git a/data/icons/nederlands.png b/data/icons/locale/unmaintained/nederlands.png similarity index 100% rename from data/icons/nederlands.png rename to data/icons/locale/unmaintained/nederlands.png diff --git a/data/icons/polski.png b/data/icons/locale/unmaintained/polski.png similarity index 100% rename from data/icons/polski.png rename to data/icons/locale/unmaintained/polski.png diff --git a/data/icons/portugues.png b/data/icons/locale/unmaintained/portugues.png similarity index 100% rename from data/icons/portugues.png rename to data/icons/locale/unmaintained/portugues.png diff --git a/data/icons/russkij.png b/data/icons/locale/unmaintained/russkij.png similarity index 100% rename from data/icons/russkij.png rename to data/icons/locale/unmaintained/russkij.png diff --git a/data/icons/slovak.png b/data/icons/locale/unmaintained/slovak.png similarity index 100% rename from data/icons/slovak.png rename to data/icons/locale/unmaintained/slovak.png diff --git a/data/icons/suomi.png b/data/icons/locale/unmaintained/suomi.png similarity index 100% rename from data/icons/suomi.png rename to data/icons/locale/unmaintained/suomi.png diff --git a/data/icons/svenska.png b/data/icons/locale/unmaintained/svenska.png similarity index 100% rename from data/icons/svenska.png rename to data/icons/locale/unmaintained/svenska.png diff --git a/data/locale/Makefile.am b/data/locale/Makefile.am index 50d9e1356..feed9a7bc 100644 --- a/data/locale/Makefile.am +++ b/data/locale/Makefile.am @@ -1,55 +1,70 @@ installdir = $(DATADIR)/neutrino/locale -install_DATA = \ - bayrisch.locale \ - bosanski.locale \ - ch-baslerdeutsch.locale \ - ch-berndeutsch.locale \ - czech.locale \ +locale = \ deutsch.locale \ - english.locale \ - francais.locale \ - italiano.locale \ - nederlands.locale \ - polski.locale \ - portugues.locale \ - russkij.locale \ - slovak.locale \ - suomi.locale \ - svenska.locale + english.locale + +locale_unmaintained = \ + unmaintained/bayrisch.locale \ + unmaintained/bosanski.locale \ + unmaintained/ch-baslerdeutsch.locale \ + unmaintained/ch-berndeutsch.locale \ + unmaintained/czech.locale \ + unmaintained/francais.locale \ + unmaintained/italiano.locale \ + unmaintained/nederlands.locale \ + unmaintained/polski.locale \ + unmaintained/portugues.locale \ + unmaintained/russkij.locale \ + unmaintained/slovak.locale \ + unmaintained/suomi.locale \ + unmaintained/svenska.locale + +install_DATA = $(locale) +install_DATA += $(locale_unmaintained) if MAINTAINER_MODE -locals: sort-locals locals.h locals_intern.h install-locals +master.locale=english.locale -sort-locals: $(top_srcdir)/data/locale/deutsch.locale $(top_srcdir)/data/locale/english.locale - cat $(top_srcdir)/data/locale/deutsch.locale | LC_ALL=C sort | uniq > deutsch.locale - cat $(top_srcdir)/data/locale/english.locale | LC_ALL=C sort | uniq > english.locale - cp -f deutsch.locale english.locale $(top_srcdir)/data/locale +locals: sort-locals work-locals locals.h locals_intern.h -ordercheck: $(top_srcdir)/data/locale/deutsch.locale - cut -d' ' -f1 $(top_srcdir)/data/locale/deutsch.locale | LC_ALL=C sort | uniq > /tmp/log - cut -d' ' -f1 $(top_srcdir)/data/locale/deutsch.locale | uniq | diff - /tmp/log || \ - (echo "ERROR: deutsch.locale not ordered or contains empty lines" && false) +$(master.locale) \ +sort-locals: $(top_srcdir)/data/locale/$(master.locale) + for locale in $(locale); do \ + cat $(top_srcdir)/data/locale/$${locale} | LC_ALL=C sort | uniq > $${locale}; \ + done -locals.h: ordercheck $(top_srcdir)/data/locale/deutsch.locale - cut -d' ' -f1 $(top_srcdir)/data/locale/deutsch.locale | LC_ALL=C sort | uniq | tr [:lower:] [:upper:] | tr \. \_ | tr \- \_ | tr -d \? | $(top_srcdir)/data/locale/create.locals.h +work-locals: $(master.locale) + for locale in $(locale); do \ + $(top_srcdir)/data/locale/helpers/create-locals-work $${locale}; \ + done -locals_intern.h: ordercheck $(top_srcdir)/data/locale/deutsch.locale - cut -d' ' -f1 $(top_srcdir)/data/locale/deutsch.locale | LC_ALL=C sort | uniq | $(top_srcdir)/data/locale/create.locals_intern.h +ordercheck: $(master.locale) + cut -d' ' -f1 $(master.locale) | LC_ALL=C sort | uniq > /tmp/log + cut -d' ' -f1 $(master.locale) | uniq | diff - /tmp/log || \ + (echo "ERROR: $(master.locale) not ordered or contains empty lines" && false) + +locals.h: ordercheck + cut -d' ' -f1 $(top_srcdir)/data/locale/$(master.locale) | LC_ALL=C sort | uniq | tr [:lower:] [:upper:] | tr \. \_ | tr \- \_ | tr -d \? | \ + $(top_srcdir)/data/locale/helpers/create-locals.h + +locals_intern.h: ordercheck + cut -d' ' -f1 $(top_srcdir)/data/locale/$(master.locale) | LC_ALL=C sort | uniq | \ + $(top_srcdir)/data/locale/helpers/create-locals_intern.h check: locals.h locals_intern.h diff locals.h $(top_srcdir)/src/system diff locals_intern.h $(top_srcdir)/src/system -install-locals: locals.h locals_intern.h +install-locals: $(locale) locals.h locals_intern.h cp locals.h locals_intern.h $(top_srcdir)/src/system - @echo "Consider committing src/system/[locals.h,locals_intern.h]" - cp -f deutsch.locale english.locale $(top_srcdir)/data/locale - @echo "Consider committing data/locale/[deutsch.locale,english.locale]" + @echo "Consider committing src/system/[locals.h locals_intern.h]" + cp -f $(locale) $(top_srcdir)/data/locale + @echo "Consider committing data/locale/[$(locale)]" locals-clean: - rm -f locals.h locals_intern.h deutsch.locale english.locale + rm -f locals.h locals_intern.h $(locale) endif diff --git a/data/locale/_readme.txt b/data/locale/_readme.txt index cd4366866..8c47c902f 100644 --- a/data/locale/_readme.txt +++ b/data/locale/_readme.txt @@ -12,12 +12,12 @@ directory: /var/tuxbox/config/locale or /share/tuxbox/neutrino/locale Master file: ------------ -deutsch.locale is considered the master file. +english.locale is considered the master file. Verfication of .locale files: ----------------------------- -Use the check.locale.files shell script for detecting +Use ./helpers/check-locale for detecting in master file - violations of the sorting order, - missing translations and - legacy strings. @@ -27,32 +27,31 @@ Use the check.locale.files shell script for detecting How do I add a new locale string? --------------------------------- 1.) -First of all, add the new string to deutsch.locale while preserving +First of all, add the new string to english.locale while preserving the ordering. Do not add any empty lines. 2.) Enter the directory build_tmp/neutrino-hd/data/locale. 3.) -Use for sorting (deutsch.locale,english.locale) 'make sort-locals', use 'make ordercheck' to for -verification. +Use for sorting 'make sort-locals', use 'make ordercheck' to for verification. 4.) +To the extent possible, update other locale file. For this, 'make work-locals' +may be useful. if you find a file called *.locale-work, merge this into *.locale + +5.) Create new versions of the files src/system/locals.h and src/system/locals_intern.h using the command 'make locals.h locals_intern.h'. -5.) -Check the modifications with 'make check' - 6.) -Copy the replacement file to their destination with 'make install-locals' +Check the modifications with 'make check' 7.) Or use for item 3-6 'make locals' 8.) -To the extent possible, update other locale file. For this, the -Perl-script create-locals-update.pl may be useful. +Copy the replacement file to their destination with 'make install-locals' 9.) If committing the changes to Git, commit both the involved @@ -60,7 +59,7 @@ locale-files, src/system/locals.h, and src/system/locals_intern.h. Useful tools: ------------- -- emacs (add '(file-coding-system-alist (quote (("\\.locale\\'" . utf-8-unix) ("" undecided)))) to .emacs or use "C-x c utf-8 C-x C-f deutsch.locale") +- emacs (add '(file-coding-system-alist (quote (("\\.locale\\'" . utf-8-unix) ("" undecided)))) to .emacs or use "C-x c utf-8 C-x C-f english.locale") - iconv - sort - uxterm diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 8d3fea58e..0d1ab625b 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -436,8 +436,9 @@ 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 das MTD-Device nicht öffnen +flashupdate.cantopenmtd kann MTD nicht öffnen flashupdate.checkupdate_internet Online nach Updates suchen flashupdate.checkupdate_local Lokales Update flashupdate.currentversion_sep Installierte Version @@ -484,6 +485,9 @@ flashupdate.settings Update-Einstellungen flashupdate.squashfs.noversion Bei Updates werden Versionsüberprüfungen derzeit nur über Web-Updates unterstützt.\nWollen Sie das ausgewählte Image wirklich installieren? flashupdate.titlereadflash Flash auslesen flashupdate.titlewriteflash Flash schreiben +flashupdate.update_with_settings_processed Image wird bearbeitet... +flashupdate.update_with_settings_skipped Ordner [%s] kann nicht gesichert werden. Eintrag wird übersprungen. +flashupdate.update_with_settings_successfully Settingsübernahme erfolgreich.\nDas Image kann jetzt geflasht werden. flashupdate.updatemode Updatemodus flashupdate.updatemode_internet Internet flashupdate.updatemode_manual von lokalem Update-Verzeichnis @@ -538,7 +542,7 @@ hdd_60min 60 min. hdd_activate Übernehmen hdd_check Dateisystemprüfung hdd_check_failed Festplattenprüfung fehlgeschlagen -hdd_ext3 Ext3fs +hdd_ext3 ext3 hdd_extended_settings Erweiterte Festplatteneinstellungen hdd_fast Schnell hdd_format Formatiere Festplatte @@ -771,7 +775,7 @@ menu.hint_hdd_tools Hier können Sie die gefundenen Festplatten formatieren bzw. menu.hint_head_back Ändern Sie die Titel-Hintergrundfarbe menu.hint_head_textcolor Ändern Sie die Titel-Textfarbe menu.hint_imageinfo Informationen über die installierte Software -menu.hint_inact_timer Ausschalten der Box nach Inaktivität in Minuten,\ndie Box geht automatisch in den Deep-Standby +menu.hint_inact_timer Ausschalten der Box nach Inaktivität in Minuten,\ndie Box geht automatisch in den Standby-Modus menu.hint_inactive_back Ändern Sie die Hintergrundfarbe für deaktivierte Fensterinhalte menu.hint_inactive_textcolor Ändern Sie die Textfarbe für deaktivierte Fensterinhalte menu.hint_inet_radio Internetradio @@ -925,6 +929,7 @@ menu.hint_record_apply Hiermit werden die Aufnahmeoptionen übernommen menu.hint_record_chandir Diese Option speichert Aufnahmen mit dem Namen des Kanals\nin ein eigenes Verzeichnis menu.hint_record_dir Hier wählen Sie das Aufnahmeverzeichnis menu.hint_record_end Hier können Sie wählen zwischen max. Aufnahmezeit\noder anhand der EPG-Daten +menu.hint_record_slow_warn Zeige Warnung, wenn Aufnahmepuffer zu überlaufen droht menu.hint_record_tdir Wählen Sie eine Verzeichnis für Ihre Timeshift-Aufnahmen\nim temporären Timeshiftmodus menu.hint_record_time Hier wird die maximale Zeit in Stunden eingetragen außer\nSie stoppen die Aufnahme vorzeitig menu.hint_record_timeafter Hier kann die Endzeit für den Aufnahmetimer eingestellt werden,\nein Wert von 2, beendet die Aufnahme 2 Minuten nach dem Sendungsende @@ -1314,6 +1319,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 @@ -1491,6 +1498,7 @@ recordingmenu.save_in_channeldir Speichere im Kanalverzeichnis recordingmenu.server Server recordingmenu.server_mac MAC-Adresse recordingmenu.setupnow Einstellungen jetzt übernehmen +recordingmenu.slow_warn Warnung bei langsamen Aufnahmemedien recordingmenu.timeshift Timeshift recordingmenu.tsdir Timeshift Aufnahmeverzeichnis recordingmenu.vcr Videorekorder @@ -1513,7 +1521,7 @@ satsetup.diseqc11 DiSEqC 1.1 satsetup.diseqc12 DiSEqC 1.2 satsetup.diseqc_advanced Erweiterte Auswahl satsetup.diseqc_com_uncom Committed/Uncommitted -satsetup.diseqc_input Diseqc Einspeisung +satsetup.diseqc_input DiSEqC Einspeisung satsetup.diseqc_uncom_com Uncommitted/Committed satsetup.diseqcrepeat DiSEqC-Wiederholungen satsetup.extended DiSEqC-Einstellungen @@ -1629,7 +1637,7 @@ settings.restore Image-Einstellungen: Wiederherstellen settings.restore_warn Alle Settings werden ersetzt.\nDie Box wird neu gestartet.\nWeiter? shutdown.recoding_query Aufnahme läuft. Trotzdem beenden? shutdowntimer.announce Die Box wird in 1 Min. heruntergefahren.\nShutdown abbrechen? -sleeptimerbox.announce Sleeptimer in 1 min +sleeptimerbox.announce Die Box wird in 1 Min. in Standby-Betrieb gehen.\nStandby-Betrieb abbrechen? sleeptimerbox.hint1 Ausschaltzeit in Min. (000=aus) sleeptimerbox.hint2 Die Box schaltet sich nach dieser Standby-Zeit aus. sleeptimerbox.hint3 Die Box schaltet sich bei Nichtbenutzen der FB aus. @@ -1664,6 +1672,7 @@ timerbar.recordevent Aufnehmen timerlist.alarmtime Alarmzeit timerlist.apids Audio PIDs timerlist.apids_dflt Voreingestellte Tonspuren aufn. +timerlist.ask_to_delete Das Löschen des Timers beendet auch die laufende Aufnahme!\n%sTrotzdem fortsetzen? timerlist.bouquetselect Bouquet wählen timerlist.channel Kanal timerlist.channelselect Kanal wählen @@ -1799,6 +1808,8 @@ videomenu.videoformat_149 14:9 videomenu.videoformat_169 16:9 videomenu.videoformat_43 4:3 videomenu.videomode Videosystem +wizard.initial_settings Grundeinstellungen gefunden +wizard.install_settings Kanalliste für Astra 19.2°E installieren? wizard.welcome_head Willkommen zur Ersteinrichtung Ihres Receivers! wizard.welcome_text Wir gratulieren Ihnen zum Kauf Ihrer Coolstream. In den nun folgenden\nSchritten begleiten wir Sie durch die Erstinstallation des Gerätes.\nWir wünschen Ihnen viel Freude mit dem wohl einzigartigsten Receiver!\nBeachten Sie: Ihre Coolstream Set-Top-Box lässt sich bequem per Webinterface\nsteuern, um zum Beispiel die Timer-Verwaltung zu nutzen oder Live-TV im Web-Browser zu schauen.\nZugriff erhalten Sie mit dem Benutzernamen: root und dem Passwort: coolstream\nAchten Sie darauf, dass Ihre Gerät nicht von aussen zugänglich ist,\nda sonst ein Zugriff über das Internet nicht ausgeschlossen werden kann!\nNächster Schritt? word.from ab diff --git a/data/locale/english.locale b/data/locale/english.locale index d9d25012b..48bad20a2 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -254,23 +254,23 @@ colormenu.menucolors Colors colormenu.osd_preset TV preset colormenu.sd_preset CRT colormenu.textcolor Text color -colormenu.themeselect select theme +colormenu.themeselect Select theme colormenu.timing OSD Timeouts colormenusetup.menucontent Content colormenusetup.menucontent_inactive Content inactive colormenusetup.menucontent_selected Content selected colormenusetup.menuhead Header colorstatusbar.text Infobar -colorthememenu.head Theme auswählen -colorthememenu.head2 Themes laden -colorthememenu.name Themename +colorthememenu.head Select theme +colorthememenu.head2 Load themes +colorthememenu.name Theme name colorthememenu.neutrino_theme Neutrino Theme -colorthememenu.question Aktuelles Theme beibehalten? -colorthememenu.save aktuelles Theme speichern -colorthememenu.select1 Benutzer Theme +colorthememenu.question Use selected theme? +colorthememenu.save Save current theme +colorthememenu.select1 User Theme colorthememenu.select2 Standard Theme -cpu.freq Cpu frequency -cpu.freq_default default frequency +cpu.freq CPU frequency +cpu.freq_default Default frequency cpu.freq_normal Normal frequency cpu.freq_standby Standby frequency date.Apr Apr @@ -303,7 +303,7 @@ epglist.noevents EPG is not available... epgviewer.More_Screenings More Screenings on this Channel epgviewer.More_Screenings_short More Screenings epgviewer.nodetailed No detailed informations available -epgviewer.notfound no epg found +epgviewer.notfound No EPG found eventfinder.head Search in EPG eventfinder.keyword Keyword eventfinder.search Search @@ -436,8 +436,9 @@ 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-device +flashupdate.cantopenmtd can't open MTD flashupdate.checkupdate_internet Check for online updates flashupdate.checkupdate_local Local update flashupdate.currentversion_sep Current version @@ -484,6 +485,9 @@ flashupdate.settings Update settings flashupdate.squashfs.noversion SquashFS version checks are currently only supported when updating over the web.\nAre you sure that you wish to install this image? flashupdate.titlereadflash Reading Flash flashupdate.titlewriteflash Writing Flash +flashupdate.update_with_settings_processed Image is being processed... +flashupdate.update_with_settings_skipped Folder [%s] can not be saved. Entry is skipped. +flashupdate.update_with_settings_successfully Setting takeover successfully.\nThe image can now be flashed. flashupdate.updatemode Updatemode flashupdate.updatemode_internet internet flashupdate.updatemode_manual from local update directory @@ -538,7 +542,7 @@ hdd_60min 60 min. hdd_activate Apply settings hdd_check Check filesystem hdd_check_failed HDD-check failed! -hdd_ext3 Ext3fs +hdd_ext3 ext3 hdd_extended_settings Extended HDD-Settings hdd_fast Fast hdd_format Formating drive... @@ -925,6 +929,7 @@ menu.hint_record_apply Apply record options menu.hint_record_chandir Create directory with name of channel\nto store recording menu.hint_record_dir Select directory to store recordings menu.hint_record_end Stop direct record after max. time\nor after current event end time +menu.hint_record_slow_warn Show warning, when record buffer is close to overflow menu.hint_record_tdir Select directory to save timeshift recordings\nin temporary timeshift mode menu.hint_record_time Record time before stop when\nusing direct record with record button menu.hint_record_timeafter Stop record after event end\nin minutes @@ -1314,6 +1319,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 @@ -1491,6 +1498,7 @@ recordingmenu.save_in_channeldir Save in channel dir recordingmenu.server server recordingmenu.server_mac MAC address recordingmenu.setupnow activate changes +recordingmenu.slow_warn Enable slow record warning recordingmenu.timeshift Timeshift recordingmenu.tsdir Timeshift directory recordingmenu.vcr vcr @@ -1513,7 +1521,7 @@ satsetup.diseqc11 DiSEqC 1.1 satsetup.diseqc12 DiSEqC 1.2 satsetup.diseqc_advanced Advanced satsetup.diseqc_com_uncom Commited/Uncommited -satsetup.diseqc_input Diseqc input +satsetup.diseqc_input DiSEqC input satsetup.diseqc_uncom_com Uncommited/Commited satsetup.diseqcrepeat DiSEqC-repeats satsetup.extended DiSEqC-Settings @@ -1629,7 +1637,7 @@ settings.restore Image-Settings: Restore settings.restore_warn This will replace all settings and reboot\nContinue ? shutdown.recoding_query You really want to to stop record ? shutdowntimer.announce Box will shutdown in 1 min.\nCancel Shutdown ? -sleeptimerbox.announce Sleeptimer in 1 min +sleeptimerbox.announce Box will standby in 1 min.\nCancel Standby ? sleeptimerbox.hint1 Shutdown time in min. (000=off) sleeptimerbox.hint2 The STB will shutdown after this time in standby. sleeptimerbox.hint3 The STB will shutdown, if remote not used. @@ -1664,6 +1672,7 @@ timerbar.recordevent Record timerlist.alarmtime Alarm time timerlist.apids Audio PIDs timerlist.apids_dflt record default audio streams +timerlist.ask_to_delete Deletion of timer stops current recording!\n%sContinue anyway? timerlist.bouquetselect choose bouquet timerlist.channel Channel timerlist.channelselect choose channel @@ -1800,7 +1809,7 @@ videomenu.videoformat_169 16:9 videomenu.videoformat_43 4:3 videomenu.videomode Digital video mode wizard.initial_settings Initial settings found -wizard.install_settings Do you want to install channels for Astra 19.2°E ? +wizard.install_settings Do you want to install channels for Astra 19.2°E? wizard.welcome_head Welcome to the Setup Wizard wizard.welcome_text Next steps will guide you through initial installation of the device.\nImportant: Your CoolStream set-top box can be conveniently controlled\nwith the web interface for timer management or live TV on the Web browser.\nDo not make it accessible to untrusted networks!\nDo you want to continue? word.from from diff --git a/data/locale/check.locale.files b/data/locale/helpers/check-locale similarity index 81% rename from data/locale/check.locale.files rename to data/locale/helpers/check-locale index ef63e8cfd..5b3cf27d1 100755 --- a/data/locale/check.locale.files +++ b/data/locale/helpers/check-locale @@ -1,5 +1,5 @@ #!/bin/sh -cut -d' ' -f1 deutsch.locale | sort | uniq > /tmp/log +cut -d' ' -f1 english.locale | sort | uniq > /tmp/log for i in *.locale; do \ echo $i:; \ echo "----------------"; \ diff --git a/data/locale/create-locals-update.pl b/data/locale/helpers/create-locals-work similarity index 88% rename from data/locale/create-locals-update.pl rename to data/locale/helpers/create-locals-work index 7abc7aaad..4c9fba0f1 100755 --- a/data/locale/create-locals-update.pl +++ b/data/locale/helpers/create-locals-work @@ -7,9 +7,9 @@ # Written by Barf on 2005-12-10. -$masterfilename = "deutsch.locale"; +$masterfilename = "english.locale"; -$#ARGV == 0 || die("Usage: create-locals-update.pl file.locale."); +$#ARGV == 0 || die("Usage: create-locals-work file.locale."); $no_errors = 0; $last_was_ok = 1; @@ -43,7 +43,7 @@ while () { close(outfile); -print "There were ", $no_errors, " error(s).\n"; +print "There were ", $no_errors, " error(s) in ", $localefilename, ".\n"; if ($no_errors == 0) { unlink($outfilename); diff --git a/data/locale/create.locals.h b/data/locale/helpers/create-locals.h similarity index 76% rename from data/locale/create.locals.h rename to data/locale/helpers/create-locals.h index 6f0bbb788..946b43138 100755 --- a/data/locale/create.locals.h +++ b/data/locale/helpers/create-locals.h @@ -1,6 +1,6 @@ #!/bin/bash -# usage: cut -d' ' -f1 deutsch.locale | LC_ALL=C sort | uniq | tr [:lower:] [:upper:] | tr \. \_ | tr \- \_ | tr -d \? | ./create.locals.h -cat > locals.h < locals.h < locals.h <> locals.h; - fi + echo $'\t'"LOCALE_$id," >> locals.h; done + cat >> locals.h < locals_intern.h < locals_intern.h < locals_intern.h <> locals_intern.h; - fi + echo $'\t'"\"$id\"," >> locals_intern.h; done + cat >> locals_intern.h < - + @@ -1572,6 +1572,7 @@ + diff --git a/data/settingsupdate.conf b/data/settingsupdate.conf new file mode 100644 index 000000000..795e0025b --- /dev/null +++ b/data/settingsupdate.conf @@ -0,0 +1,28 @@ +# settings for logfile +#:Log=1 +#:LogFile=/tmp/update.log + + +## Mögliche Einträge: +#==================== +# ganzes Verzeichnis +#------------------- +# /var/etc + +# einzelne Datei +#---------------- +# /etc/init.d/rcS + +# Wildcards +#---------- +# /bin/*.sh + +#------------------------------------------------------------------------------------------------ +## Die Verzeichnisse "/", "/dev", "/proc", "/sys", "/mnt", "/tmp" können nicht gesichert werden!! +#------------------------------------------------------------------------------------------------ + +## Sicherungen +/etc/network +/etc/wpa_supplicant.conf +/var/etc +/var/tuxbox/config diff --git a/src/daemonc/remotecontrol.cpp b/src/daemonc/remotecontrol.cpp index a9f1937a8..11e5373f9 100644 --- a/src/daemonc/remotecontrol.cpp +++ b/src/daemonc/remotecontrol.cpp @@ -298,8 +298,8 @@ int CRemoteControl::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data tuxtxt_start(current_PIDs.PIDs.vtxtpid); } #endif - t_channel_id * p = new t_channel_id; - *p = current_channel_id; + char *p = new char[sizeof(t_channel_id)]; + memcpy(p, ¤t_channel_id, sizeof(t_channel_id)); g_RCInput->postMsg(NeutrinoMessages::EVT_ZAP_GOTPIDS, (const neutrino_msg_data_t)p, false); processAPIDnames(); @@ -335,8 +335,8 @@ int CRemoteControl::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data { //printf("new program !\n"); - t_channel_id * p = new t_channel_id; - *p = current_channel_id; + char *p = new char[sizeof(t_channel_id)]; + memcpy(p, ¤t_channel_id, sizeof(t_channel_id)); g_RCInput->postMsg(NeutrinoMessages::EVT_NEXTPROGRAM, (const neutrino_msg_data_t)p, false); // data is pointer to allocated memory return messages_return::handled; @@ -382,8 +382,8 @@ void CRemoteControl::getSubChannels() } copySubChannelsToZapit(); - t_channel_id * p = new t_channel_id; - *p = current_channel_id; + char *p = new char[sizeof(t_channel_id)]; + memcpy(p, ¤t_channel_id, sizeof(t_channel_id)); g_RCInput->postMsg(NeutrinoMessages::EVT_ZAP_GOT_SUBSERVICES, (const neutrino_msg_data_t)p, false); // data is pointer to allocated memory } } @@ -424,8 +424,8 @@ void CRemoteControl::getNVODs() copySubChannelsToZapit(); - t_channel_id * p = new t_channel_id; - *p = current_channel_id; + char *p = new char[sizeof(t_channel_id)]; + memcpy(p, ¤t_channel_id, sizeof(t_channel_id)); g_RCInput->postMsg(NeutrinoMessages::EVT_ZAP_GOT_SUBSERVICES, (const neutrino_msg_data_t)p, false); // data is pointer to allocated memory if ( selected_subchannel == -1 ) @@ -570,8 +570,8 @@ void CRemoteControl::processAPIDnames() setAPID( 0 ); } - t_channel_id * p = new t_channel_id; - *p = current_channel_id; + char *p = new char[sizeof(t_channel_id)]; + memcpy(p, ¤t_channel_id, sizeof(t_channel_id)); g_RCInput->postMsg(NeutrinoMessages::EVT_ZAP_GOTAPIDS, (const neutrino_msg_data_t)p, false); // data is pointer to allocated memory } diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am index 617c4be36..1216726f1 100644 --- a/src/driver/Makefile.am +++ b/src/driver/Makefile.am @@ -26,7 +26,7 @@ libneutrino_driver_a_SOURCES = \ file.cpp \ fontrenderer.cpp \ framebuffer.cpp \ - genpsi.c \ + genpsi.cpp \ radiotext.cpp \ radiotools.cpp \ rcinput.cpp \ diff --git a/src/driver/file.h b/src/driver/file.h index 6d62e8e46..5cd11121c 100644 --- a/src/driver/file.h +++ b/src/driver/file.h @@ -37,7 +37,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 */ #include 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 381f0ac50..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,91 +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; + //-- 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/radiotext.cpp b/src/driver/radiotext.cpp index a32cc059e..1c0a8461a 100644 --- a/src/driver/radiotext.cpp +++ b/src/driver/radiotext.cpp @@ -2288,97 +2288,31 @@ eOSState cRTplusList::ProcessKey(eKeys Key) //--------------- End ----------------------------------------------------------------- #endif - -//static int pes_SyncBufferRead (cDemux *audioDemux, ringbuffer_t *buf, u_long *skipped_bytes); - -static bool rtThreadRunning; - -void *RadioTextThread(void *data) -{ - CRadioText *rt = ((CRadioText::s_rt_thread*)data)->rt_object; - int fd = ((CRadioText::s_rt_thread*)data)->fd; - // struct dmx_pes_filter_params flt; - cDemux *audioDemux = rt->audioDemux; - printf("in RadioTextThread fd = %d\n", fd); - - bool ret = false; - - printf("\nRadioTextThread: ###################### Setting PID 0x%x ######################\n", rt->getPid()); - - audioDemux->Stop(); - if (audioDemux->pesFilter(rt->getPid())) - { - /* start demux filter */ - if (audioDemux->Start()) - ret = true; - } - if (!ret) { - perror("RadiotextThread Audiodemuxer"); - perror("DMX_SET_PES_FILTER"); - audioDemux->Stop(); - pthread_exit(NULL); - } - /* - -- read PES packet for pid - */ -#if 0 - ringbuffer_t *buf_in = ringbuffer_create(0x1FFFF); - char *b; /* ptr to packet start */ - long count = 0; -#endif - rtThreadRunning = true; - while(rtThreadRunning) - { - int n; - unsigned char buf[0x1FFFF]; -#if 0 - int offset; - size_t rd; - u_long skipped_bytes = 0; -#endif - //printf("."); fflush(stdout); - // -- Read PES packet (sync Read) - //n = pes_SyncBufferRead (audioDemux, buf_in, &skipped_bytes); - n = audioDemux->Read(buf, sizeof(buf), 500 /*5000*/); - - // -- error or eof? - if (n <= 0) { - usleep(10000); /* save CPU if nothing read */ - continue; - } - rt->PES_Receive(buf, n); -#if 0 - rd = ringbuffer_get_readpointer(buf_in, &b, n); - /* this can not happen, because pes_SyncBufferRead() returns -1 if ringbuffer is empty - if (rd <= 0) { - continue; - } - */ - count ++; - // -- skipped Data to get sync byte? - offset = rt->PES_Receive(b, n); - - ringbuffer_read_advance(buf_in, offset); -#endif - } - - audioDemux->Stop(); - -#if 0 - ringbuffer_free(buf_in); - fprintf(stderr, "RT %s: exit\n", __FUNCTION__); -#endif - printf("\nRadioTextThread: ###################### exit ######################\n"); - pthread_exit(NULL); -} - CRadioText::CRadioText(void) { - pid = 0; - dmxfd = -1; + pid = 0; + audioDemux = NULL; + init(); + + running = true; + start(); +} + +CRadioText::~CRadioText(void) +{ + printf("CRadioText::~CRadioText\n"); + running = false; + radiotext_stop(); + cond.broadcast(); + OpenThreads::Thread::join(); + printf("CRadioText::~CRadioText done\n"); +} + +void CRadioText::init() +{ S_Verbose = 0; S_RtFunc = 1; - S_RtOsd = 1; + S_RtOsd = 0; S_RtOsdTitle = 1; S_RtOsdTags = 2; S_RtOsdPos = 2; @@ -2391,7 +2325,6 @@ CRadioText::CRadioText(void) S_RtFgCol = 1; S_RtDispl = 1; S_RtMsgItems = 0; -//int S_RtpMemNo = 25; RT_Index = 0; RT_PTY = 0; @@ -2401,265 +2334,87 @@ CRadioText::CRadioText(void) RT_PlusShow = false; RT_Replay = false; RT_ReOpen = false; - for (int i=0; i<5; i++) strcpy(RT_Text[i], ""); - strcpy(RDS_PTYN, ""); + for (int i = 0; i < 5; i++) + RT_Text[i][0] = 0; + RDS_PTYN[0] = 0; + +#if ENABLE_RASS + // Rass ... + Rass_Show = -1; // -1=No, 0=Yes, 1=display + Rass_Archiv = -1; // -1=Off, 0=Index, 1000-9990=Slidenr. +#endif + RT_MsgShow = false; // clear entries from old channel have_radiotext = false; - audioDemux = NULL; } void CRadioText::radiotext_stop(void) { - printf("\nCRadioText::radiotext_stop: ###################### pid 0x%x ######################\n", getPid()); + printf("CRadioText::radiotext_stop: ###################### pid 0x%x ######################\n", getPid()); if (getPid() != 0) { - // this stuff takes a while sometimes - look for a better syncronisation - printf("Stopping RT Thread\n"); - rtThreadRunning = false; - pthread_join(getThread(), NULL); + mutex.lock(); pid = 0; have_radiotext = false; - audioDemux->Stop(); S_RtOsd = 0; + mutex.unlock(); } - } -CRadioText::~CRadioText(void) -{ - radiotext_stop(); - pid = 0; -// printf("Deleting RT object\n"); - -// close(dmxfd); - delete audioDemux; - audioDemux = NULL; - dmxfd = -1; -} - - void CRadioText::setPid(uint inPid) { - uint oldPid = pid; - - printf("\nCRadioText::setPid: ###################### old pid 0x%x new pid 0x%x ######################\n", oldPid, inPid); - if (pid != inPid) - { - int rc; - - printf("CRadioText::setPid: setting pid 0x%x\n", inPid); + printf("CRadioText::setPid: ###################### old pid 0x%x new pid 0x%x ######################\n", pid, inPid); + if (pid != inPid) { + mutex.lock(); pid = inPid; - - // open the device if first pid - if (0 == oldPid) - { - if (audioDemux == NULL) { - audioDemux = new cDemux(1); - //audioDemux->Open(DMX_TP_CHANNEL /*DMX_AUDIO_CHANNEL*/,0,128*1024); - audioDemux->Open(DMX_PES_CHANNEL,0,128*1024); -#if 0 - bool ret = false; - if (audioDemux->pesFilter(pid)) - { - /* start demux filter */ - if (audioDemux->Start()) - ret = true; - } - if (!ret) { - perror("Radiotext Audiodemuxer"); - return; - } -#endif - // audioDemux->Stop() -#if 0 - dmxfd = open(DMXDEV, O_RDWR|O_NONBLOCK); - if (dmxfd < 0) { - perror(DMXDEV); - pthread_exit(NULL); - } -#endif - } - rt.rt_object = this; - rt.fd = dmxfd; - } - - // Setup-Params - // S_Activate = false; - // S_HMEntry = false; - S_RtFunc = 1; - S_RtOsd = 0; - S_RtOsdTitle = 1; - S_RtOsdTags = 2; - S_RtOsdPos = 2; - S_RtOsdRows = 3; - S_RtOsdLoop = 1; - S_RtOsdTO = 60; - S_RtSkinColor = false; - S_RtBgCol = 0; - S_RtBgTra = 0xA0; - S_RtFgCol = 1; - S_RtDispl = 1; - S_RtMsgItems = 0; - //int S_RtpMemNo = 25; - RT_Index = RT_PTY = 0; - - // Radiotext - RTP_ItemToggle = 1; - RTP_TToggle = 0; - RT_PlusShow = false; - RT_Replay = false; - RT_ReOpen = false; - for (int i=0; i<5; i++) strcpy(RT_Text[i], ""); - strcpy(RDS_PTYN, ""); - -#if ENABLE_RASS - // Rass ... - Rass_Show = -1; // -1=No, 0=Yes, 1=display - Rass_Archiv = -1; // -1=Off, 0=Index, 1000-9990=Slidenr. -#endif - RT_MsgShow = false; // clear entries from old channel - - rc = pthread_create(&threadRT, 0, RadioTextThread, (void *) &rt); - - if (rc) { - printf("failed to create RadioText Thread (rc=%d)\n", rc); - return; - } + init(); + mutex.unlock(); + cond.broadcast(); } } - -// ----------------------------------------------------------- -// following functions are ripped from dvbsnoop: http://dvbsnoop.sourceforge.net - -/* - -- read PES packet (Synced) - -- buffer pre-read bytes for next execution - -- return: len // read()-return code -*/ - -#if 0 -static int pes_SyncBufferRead(cDemux *audioDemux, ringbuffer_t *buf, /*u_long max_len,*/ u_long *skipped_bytes) +void CRadioText::run() { - ringbuffer_data_t vec; - int rd; - char *ppes; + uint current_pid = 0; - // -- simple PES sync... seek for 0x000001 (PES_SYNC_BYTE) - // ISO/IEC 13818-1: - // -- packet_start_code_prefix -- The packet_start_code_prefix is - // -- a 24-bit code. Together with the stream_id that follows it constitutes - // -- a packet start code that identifies the beginning of a packet. - // -- The packet_start_code_prefix is the bit stream - // -- '0000 0000 0000 0000 0000 0001' (0x000001). + printf("CRadioText::run: ###################### Starting thread ######################\n"); + audioDemux = new cDemux(1); + audioDemux->Open(DMX_PES_CHANNEL,0,128*1024); - *skipped_bytes = 0; - ringbuffer_get_write_vector(buf, &vec); - if (vec.len == 0) - { - fprintf(stderr, "RT %s: ringbuffer full\n", __FUNCTION__); - /* do not read anything from demux, but continue with sync */ - } - else - { - rd = audioDemux->Read((unsigned char*)vec.buf, vec.len, 5000); - if (rd < 0) - { - if (errno != EAGAIN) - { - fprintf(stderr, "RT %s: read %d errno %d (%m)\n", __FUNCTION__, rd, errno); - return rd; - } - /* if EAGAIN, still process contents of ringbuffer */ - rd = 0; + while(running) { + mutex.lock(); + if (pid == 0) { + mutex.unlock(); + audioDemux->Stop(); + pidmutex.lock(); + printf("CRadioText::run: ###################### waiting for pid.. ######################\n"); + cond.wait(&pidmutex); + pidmutex.unlock(); + mutex.lock(); } - - ringbuffer_write_advance(buf, rd); - } - - rd = ringbuffer_get_readpointer(buf, &ppes, 6); - if (rd < 6) - { -// fprintf(stderr, "RT %s: ringbuffer empty (%d < 6)\n", __FUNCTION__, rd); - return -1; - } - - if ((ppes[0] != 0x00) || (ppes[1] != 0x00) || (ppes[2] != 0x01)) - { - //INFO("async, not 000001: %02x%02x%02x ", ppes[0], ppes[1], ppes[2]); - int deleted = 0; - do { - ringbuffer_read_advance(buf, 1); // remove 1 Byte - rd = ringbuffer_get_readpointer(buf, &ppes, 6); - deleted++; - (*skipped_bytes)++; - //fprintf(stderr, "%d", rd); - if ((ppes[0] == 0x00) || (ppes[1] == 0x00) || (ppes[2] == 0x01)) - { - deleted = 0; - break; + if (pid && (current_pid != pid)) { + current_pid = pid; + printf("CRadioText::run: ###################### Setting PID 0x%x ######################\n", getPid()); + audioDemux->Stop(); + if (!audioDemux->pesFilter(getPid()) || !audioDemux->Start()) { + pid = 0; + printf("CRadioText::run: ###################### failed to start PES filter ######################\n"); } } - while (rd == 6); - //fprintf(stderr, "\n"); - if (deleted > 0) - { -// fprintf(stderr, "RT %s: No valid PES signature found. %d Bytes deleted.\n", __FUNCTION__, deleted); - return -1; + mutex.unlock(); + if (pid) { + int n; + unsigned char buf[0x1FFFF]; + + n = audioDemux->Read(buf, sizeof(buf), 500 /*5000*/); + + if (n > 0) { + //printf("."); fflush(stdout); + mutex.lock(); + PES_Receive(buf, n); + mutex.unlock(); + } } } - - // -- Sync found! - // -- evaluate packet_id and seek packet end (next sync) - if (ppes[3] >= 0xBC) { // PES system packet with length - unsigned int l; - l = (ppes[4] << 8) + ppes[5]; // PES packet size... - - if (l > 0) { - if (ringbuffer_read_space(buf) >= l + 6) - return (l + 6); - else - return 0; - } else - ringbuffer_read_advance(buf, 6); - } else { - // will resync automatically on next invocation. Enough? - ringbuffer_read_advance(buf, 4); - } - -#if 0 - // -- seek packet end (sync to next packet) - // -- ISO 13818-1 length=0 packets (unbound video streams) - // -- ISO 13818-2 packets - - sync = 0xFFFFFFFF; - while (max_len > 0) { - u_char c; - int n; - - // $$$ TODO: may be optimized - n = pes_rawBufferedRead (fd, buf,1); - if (n < 0) return n; - - c = *buf++; - max_len -= n; - - // -- EOF - if (n == 0) { - return (long) (buf - org_buf); - } - - - // -- next packet found? (sync detected) - sync = (sync << 8) | c; - if ( (sync & 0x00FFFFFF) == 0x000001 ) { - pes_rawBufferedPushByte (*(--buf)); // push back sync bytes - pes_rawBufferedPushByte (*(--buf)); - pes_rawBufferedPushByte (*(--buf)); - return (long) (buf - org_buf); - } - } -#endif - -// fprintf(stderr, "RT %s: unsynced, ret = -1! (this never happens) ppes[3] = 0x%02x\n", __FUNCTION__, ppes[3]); - return -1; // buffer overflow + delete audioDemux; + audioDemux = NULL; + printf("CRadioText::run: ###################### exit ######################\n"); } -#endif diff --git a/src/driver/radiotext.h b/src/driver/radiotext.h index 5b6af9726..0a2b64ae9 100644 --- a/src/driver/radiotext.h +++ b/src/driver/radiotext.h @@ -59,6 +59,8 @@ #endif #include +#include +#include //#define ENABLE_RASS @@ -88,13 +90,8 @@ public: #define RT_MEL 65 #define tr(a) a -class CRadioText { - -public: - typedef struct { - CRadioText *rt_object; - int fd; - } s_rt_thread; +class CRadioText : public OpenThreads::Thread +{ private: bool enabled; @@ -107,17 +104,26 @@ private: int first_packets; //Radiotext +#if 0 // cDevice *rdsdevice; void RadiotextCheckPES(const uchar *Data, int Length); - void RadioStatusMsg(void); void AudioRecorderService(void); +#endif + void RadioStatusMsg(void); void RassDecode(uchar *Data, int Length); bool DividePes(unsigned char *data, int length, int *substart, int *subend); uint pid; - pthread_t threadRT; - int dmxfd; + //pthread_t threadRT; + //int dmxfd; + OpenThreads::Mutex mutex; + OpenThreads::Mutex pidmutex; + OpenThreads::Condition cond; + bool running; + + void run(); + void init(); public: CRadioText(void); ~CRadioText(void); @@ -133,15 +139,11 @@ public: void setPid(uint inPid); uint getPid(){ return pid; } - int run(void); - int getDMXfd(void) { return dmxfd; } -// s_rt_thread& getThreadParams(void) { return rt; } - pthread_t getThread(void) { return threadRT; } + void radiotext_stop(void); bool haveRadiotext(void) {return have_radiotext; } cDemux *audioDemux; - s_rt_thread rt; //Setup-Params int S_RtFunc; diff --git a/src/driver/rcinput.cpp b/src/driver/rcinput.cpp index f4047ecba..116feb8b6 100644 --- a/src/driver/rcinput.cpp +++ b/src/driver/rcinput.cpp @@ -1084,7 +1084,8 @@ printf("[neutrino] CSectionsdClient::EVT_GOT_CN_EPG\n"); break; case CTimerdClient::EVT_ANNOUNCE_ZAPTO : *msg = NeutrinoMessages::ANNOUNCE_ZAPTO; - *data = 0; + *data = (neutrino_msg_data_t)p; + dont_delete_p = true; break; case CTimerdClient::EVT_ANNOUNCE_SHUTDOWN : *msg = NeutrinoMessages::ANNOUNCE_SHUTDOWN; diff --git a/src/driver/record.cpp b/src/driver/record.cpp index 222f956e5..93403f3fa 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); } @@ -1096,6 +1098,18 @@ bool CRecordManager::Stop(const t_channel_id channel_id) return (inst != NULL); } +bool CRecordManager::IsRecording(const CTimerd::RecordingStopInfo * recinfo) +{ + bool ret = false; + mutex.lock(); + CRecordInstance * inst = FindInstanceID(recinfo->eventID); + if(inst != NULL && recinfo->eventID == inst->GetRecordingId()) + ret = true; + mutex.unlock(); + printf("[%s] eventID: %d, channel_id: 0x%llx, ret: %d\n", __FUNCTION__, recinfo->eventID, recinfo->channel_id, ret); + return ret; +} + bool CRecordManager::Stop(const CTimerd::RecordingStopInfo * recinfo) { bool ret = false; @@ -1182,7 +1196,7 @@ int CRecordManager::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data error_display = false; warn_display = false; DisplayErrorMessage(g_Locale->getText(LOCALE_STREAMING_OVERFLOW)); - } else if (warn_display) { + } else if (g_settings.recording_slow_warning && warn_display) { warn_display = false; DisplayErrorMessage(g_Locale->getText(LOCALE_STREAMING_SLOW)); } @@ -1578,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 %llx result %d\n", __FUNCTION__, 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; @@ -1605,6 +1623,10 @@ bool CRecordManager::CutBackNeutrino(const t_channel_id channel_id, CFrontend * g_Zapit->setRecordMode( true ); if(last_mode == NeutrinoMessages::mode_standby) 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/record.h b/src/driver/record.h index 60d9e03fd..ac5ebc311 100644 --- a/src/driver/record.h +++ b/src/driver/record.h @@ -187,6 +187,7 @@ class CRecordManager : public CMenuTarget /*, public CChangeObserver*/ bool Record(const t_channel_id channel_id, const char * dir = NULL, bool timeshift = false); bool Stop(const t_channel_id channel_id); bool Stop(const CTimerd::RecordingStopInfo * recinfo); + bool IsRecording(const CTimerd::RecordingStopInfo * recinfo); bool Update(const t_channel_id channel_id); bool ShowMenu(void); bool AskToStop(const t_channel_id channel_id, const int recid = 0); diff --git a/src/driver/shutdown_count.cpp b/src/driver/shutdown_count.cpp index 9bf77c2f1..a7b092022 100644 --- a/src/driver/shutdown_count.cpp +++ b/src/driver/shutdown_count.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -106,6 +107,11 @@ void SHTDCNT::shutdown_counter() sleep_cnt--; } else if(sleeptimer_active && !CNeutrinoApp::getInstance ()->recordingstatus) { sleeptimer_active = false; + + puts("[SHTDCNT] executing " NEUTRINO_ENTER_INACTIVITY_SCRIPT "."); + if (my_system(NEUTRINO_ENTER_INACTIVITY_SCRIPT) != 0) + perror(NEUTRINO_ENTER_INACTIVITY_SCRIPT " failed"); + printf("[SHTDCNT] sleep-timer send NeutrinoMessages::SLEEPTIMER\n"); g_RCInput->postMsg(NeutrinoMessages::SLEEPTIMER, 1); } diff --git a/src/driver/streamts.cpp b/src/driver/streamts.cpp index ec2633bc0..0e3142c5c 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,249 +52,231 @@ #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, (void *) 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_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); + + dmx = new cDemux(STREAM_DEMUX);//FIXME + + 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]; @@ -280,7 +286,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; @@ -289,7 +295,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)) { @@ -298,165 +304,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); - cDemux * dmx = new cDemux(STREAM_DEMUX);//FIXME - - 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; } -#endif \ No newline at end of file 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/driver/vfd.cpp b/src/driver/vfd.cpp index 82d59f54d..130e5357c 100644 --- a/src/driver/vfd.cpp +++ b/src/driver/vfd.cpp @@ -73,8 +73,10 @@ CVFD::CVFD() CVFD::~CVFD() { - if(fd > 0) + if(fd > 0){ close(fd); + fd = -1; + } } CVFD* CVFD::getInstance() @@ -678,7 +680,7 @@ void CVFD::Clear() void CVFD::ShowIcon(fp_icon icon, bool show) { - if(!has_lcd) return; + if(!has_lcd || fd < 0) return; //printf("CVFD::ShowIcon %s %x\n", show ? "show" : "hide", (int) icon); int ret = ioctl(fd, show ? IOC_FP_SET_ICON : IOC_FP_CLEAR_ICON, icon); if(ret < 0) diff --git a/src/driver/volume.cpp b/src/driver/volume.cpp index 35f75ea4e..c3ccf34c3 100644 --- a/src/driver/volume.cpp +++ b/src/driver/volume.cpp @@ -63,6 +63,8 @@ CVolume::CVolume() m_mode = CNeutrinoApp::getInstance()->getMode(); channel_id = 0; apid = 0; + digit_h = 0; + digit_offset = 0; Init(); } @@ -92,16 +94,18 @@ void CVolume::Init() y = sy = frameBuffer->getScreenY() + spacer / 2; sw = g_settings.screen_EndX - spacer; sh = frameBuffer->getScreenHeight(); - + icon_w = icon_h = 0; frameBuffer->getIconSize(NEUTRINO_ICON_VOLUME, &icon_w, &icon_h); - vbar_h = std::max((icon_h * faktor_h) / 10, digit_h+digit_offset); + if (paintDigits) { + digit_offset = g_Font[VolumeFont]->getDigitOffset(); + digit_h = g_Font[VolumeFont]->getDigitHeight(); + } + vbar_h = std::max((icon_h * faktor_h) / 10, digit_h + digit_offset); progress_h = icon_h - 2*pB; progress_w = 200; vbar_w = spacer + icon_w + spacer + progress_w + spacer; if (paintDigits) { digit_w = g_Font[VolumeFont]->getRenderWidth("100"); - digit_offset = g_Font[VolumeFont]->getDigitOffset(); - digit_h = g_Font[VolumeFont]->getDigitHeight(); progress_h = std::max(icon_h, digit_h) - 2*pB; vbar_w += digit_w; } diff --git a/src/global.h b/src/global.h index e0fe58160..cd6a8499c 100644 --- a/src/global.h +++ b/src/global.h @@ -66,6 +66,9 @@ #define NEUTRINO_RECORDING_ENDED_SCRIPT CONFIGDIR "/recording.end" #define NEUTRINO_ENTER_STANDBY_SCRIPT CONFIGDIR "/standby.on" #define NEUTRINO_LEAVE_STANDBY_SCRIPT CONFIGDIR "/standby.off" +#define NEUTRINO_ENTER_INACTIVITY_SCRIPT CONFIGDIR "/inactivity.on" +#define NEUTRINO_ENTER_DEEPSTANDBY_SCRIPT CONFIGDIR "/deepstandby.on" +#define NEUTRINO_LEAVE_DEEPSTANDBY_SCRIPT CONFIGDIR "/deepstandby.off" #define MOVIEPLAYER_START_SCRIPT CONFIGDIR "/movieplayer.start" #define MOVIEPLAYER_END_SCRIPT CONFIGDIR "/movieplayer.end" diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 629a488f2..39c5967a5 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -1,16 +1,22 @@ AM_CPPFLAGS = -fno-rtti -fno-exceptions #AM_CPPFLAGS = -fno-rtti - -BUILT_SOURCES = svn_version.h - -svn_version.h: - @if test -d .svn ; then \ - sleep 180 && rm svn_version.h & echo "#define SVNVERSION \"$$(svnversion -n || echo svn_oops!)\" " > svn_version.h ; \ +BUILT_SOURCES = git_version.h +git_version.h: makeversion + @if test -d ../../.git; then \ + echo "#define GITVERSION \"$$(git describe --dirty || echo `date` )\" " > git_version.h.tmp ; \ + if diff -q git_version.h git_version.h.tmp >/dev/null 2>&1 ; then \ + rm -f git_version.h.tmp ; \ + else \ + rm -f git_version.h ; \ + mv git_version.h.tmp git_version.h ; \ + fi; \ else \ - rm svn_version.h; echo '#define BUILT_DATE "'`date`'"' > svn_version.h ; \ + rm git_version.h; echo '#define BUILT_DATE "'`date`'"' > git_version.h ; \ fi +noinst_HEADERS = git_version.h + +.PHONY: makeversion -noinst_HEADERS = svn_version.h SUBDIRS = widget bedit @@ -23,6 +29,7 @@ INCLUDES = \ -I$(top_srcdir)/lib/libeventserver \ -I$(top_srcdir)/lib/libnet \ -I$(top_srcdir)/lib/libconfigfile \ + -I$(top_srcdir)/lib/connection \ -I$(top_srcdir)/lib/xmltree \ -I$(top_srcdir)/lib/libupnpclient \ @CURL_CFLAGS@ \ @@ -50,6 +57,7 @@ libneutrino_gui_a_SOURCES = \ epgplus.cpp \ epgview.cpp \ eventlist.cpp \ + ext_update.cpp \ favorites.cpp \ filebrowser.cpp \ imageinfo.cpp \ diff --git a/src/gui/audioplayer.cpp b/src/gui/audioplayer.cpp index c16d70b09..c7e82d9ba 100644 --- a/src/gui/audioplayer.cpp +++ b/src/gui/audioplayer.cpp @@ -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) @@ -700,6 +704,9 @@ int CAudioPlayerGui::show() //InputSelector.addItem(GenericMenuSeparator); hide(); InputSelector.exec(NULL, ""); + + delete InetRadioInputChanger; + if (select >= 0) old_select = select; switch (select) { @@ -750,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) @@ -901,6 +924,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; @@ -1695,10 +1729,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; @@ -1714,8 +1749,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_buttonHeight, ButtonWidth); - + ::paintButtons(m_x, top+m_buttonHeight, m_width, 3, ScondLineButtons, m_buttonHeight, ButtonWidth); if (m_key_level == 0) { @@ -1940,12 +1974,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(); @@ -2019,31 +2057,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); } } @@ -2062,14 +2100,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 009885b51..a3fefe005 100644 --- a/src/gui/bouquetlist.cpp +++ b/src/gui/bouquetlist.cpp @@ -71,9 +71,9 @@ CBouquetList::CBouquetList(const char * const Name) CBouquetList::~CBouquetList() { - for (std::vector::iterator it = Bouquets.begin(); it != Bouquets.end(); ++it) { - delete (*it); - } + for (std::vector::iterator it = Bouquets.begin(); it != Bouquets.end(); ++it) + delete (*it); + Bouquets.clear(); } @@ -144,7 +144,6 @@ bool CBouquetList::hasChannelID(t_channel_id channel_id) return false; } -extern CBouquetList * TVfavList; bool CBouquetList::adjustToChannelID(t_channel_id channel_id) { //printf("CBouquetList::adjustToChannelID [%s] to %llx, selected %d size %d\n", name.c_str(), channel_id, selected, Bouquets.size()); @@ -172,7 +171,7 @@ bool CBouquetList::adjustToChannelID(t_channel_id channel_id) /* used in channellist to switch bouquets up/down */ int CBouquetList::showChannelList( int nBouquet) { - if (nBouquet == -1) + if ((nBouquet < 0)|| (nBouquet >= (int) Bouquets.size())) nBouquet = selected; int nNewChannel = Bouquets[nBouquet]->channelList->exec(); @@ -187,7 +186,7 @@ int CBouquetList::activateBouquet( int id, bool bShowChannelList) { int res = -1; - if(id < (int) Bouquets.size()) + if((id >= 0) && (id < (int) Bouquets.size())) selected = id; if (bShowChannelList) { @@ -292,24 +291,56 @@ int CBouquetList::doMenu() return 0; } +const struct button_label CBouquetListButtons[4] = +{ + { NEUTRINO_ICON_BUTTON_RED, LOCALE_CHANNELLIST_FAVS}, + { NEUTRINO_ICON_BUTTON_GREEN, LOCALE_CHANNELLIST_PROVS}, + { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_CHANNELLIST_SATS}, + { NEUTRINO_ICON_BUTTON_BLUE, LOCALE_CHANNELLIST_HEAD} +}; + +void CBouquetList::updateSelection(int newpos) +{ + if((int) selected != newpos) { + int prev_selected = selected; + unsigned int oldliststart = liststart; + + selected = newpos; + liststart = (selected/listmaxshow)*listmaxshow; + if (oldliststart != liststart) + paint(); + else { + paintItem(prev_selected - liststart); + paintItem(selected - liststart); + } + } +} + /* bShowChannelList default to true, returns new bouquet or -1/-2 */ int CBouquetList::show(bool bShowChannelList) { neutrino_msg_t msg; neutrino_msg_data_t data; int res = -1; + int icol_w, icol_h; + int w_max_text = 0; + int w_max_icon = 0; - //if(Bouquets.size()==0) - // return res; + for(unsigned int count = 0; count < sizeof(CBouquetListButtons)/sizeof(CBouquetListButtons[0]);count++){ + int w_text = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getRenderWidth(g_Locale->getText (CBouquetListButtons[count].locale),true); + w_max_text = std::max(w_max_icon, w_text); + frameBuffer->getIconSize(CBouquetListButtons[count].button, &icol_w, &icol_h); + w_max_icon = std::max(w_max_icon, icol_w); + } + int need_width = sizeof(CBouquetListButtons)/sizeof(CBouquetListButtons[0])*(w_max_icon + w_max_text + 20); CVFD::getInstance()->setMode(CVFD::MODE_MENU_UTF8, ""); fheight = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->getHeight(); - width = w_max (g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getWidth()*52, 20);//500 + width = w_max (need_width, 20);//500 height = h_max (16 * fheight, 40); /* assuming all color icons must have same size */ - int icol_w, icol_h; frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_RED, &icol_w, &icol_h); footerHeight = std::max(icol_h+8, g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight()+8); //TODO get footerHeight from buttons @@ -353,7 +384,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()) { @@ -387,84 +418,54 @@ int CBouquetList::show(bool bShowChannelList) return -3; } } - else if(Bouquets.empty()) - continue; //FIXME msgs not forwarded to neutrino !! else if ( msg == CRCInput::RC_setup) { - int ret = doMenu(); - if(ret > 0) { - CNeutrinoApp::getInstance ()->g_channel_list_changed = true; - res = -4; - loop = false; - } else if(ret < 0) - paint(); + if (!Bouquets.empty()) { + int ret = doMenu(); + if(ret > 0) { + CNeutrinoApp::getInstance ()->g_channel_list_changed = true; + res = -4; + loop = false; + } else if(ret < 0) + paint(); + } } else if ( msg == (neutrino_msg_t) g_settings.key_list_start ) { - selected=0; - liststart = (selected/listmaxshow)*listmaxshow; - paint(); + if (!Bouquets.empty()) + updateSelection(0); } else if ( msg == (neutrino_msg_t) g_settings.key_list_end ) { - selected=Bouquets.size()-1; - liststart = (selected/listmaxshow)*listmaxshow; - paint(); + if (!Bouquets.empty()) + updateSelection(Bouquets.size()-1); } else if (msg == CRCInput::RC_up || (int) msg == g_settings.key_channelList_pageup) { - int step = 0; - int prev_selected = selected; - - step = ((int) msg == g_settings.key_channelList_pageup) ? listmaxshow : 1; // browse or step 1 - selected -= step; -#if 0 - if((prev_selected-step) < 0) // because of uint - selected = Bouquets.size()-1; -#endif - if((prev_selected-step) < 0) { - if(prev_selected != 0 && step != 1) - selected = 0; - else - selected = Bouquets.size() - 1; + if (!Bouquets.empty()) { + int step = ((int) msg == g_settings.key_channelList_pageup) ? listmaxshow : 1; // browse or step 1 + int new_selected = selected - step; + if (new_selected < 0) { + if (selected != 0 && step != 1) + new_selected = 0; + else + new_selected = Bouquets.size() - 1; + } + updateSelection(new_selected); } - - paintItem(prev_selected - liststart); - unsigned int oldliststart = liststart; - liststart = (selected/listmaxshow)*listmaxshow; - if(oldliststart!=liststart) - paint(); - else - paintItem(selected - liststart); } else if (msg == CRCInput::RC_down || (int) msg == g_settings.key_channelList_pagedown) { - unsigned int step = 0; - unsigned int prev_selected = selected; - - step = ((int) msg == g_settings.key_channelList_pagedown) ? listmaxshow : 1; // browse or step 1 - selected += step; -#if 0 - if(selected >= Bouquets.size()) { - if (((Bouquets.size() / listmaxshow) + 1) * listmaxshow == Bouquets.size() + listmaxshow) // last page has full entries - selected = 0; - else - selected = ((step == listmaxshow) && (selected < (((Bouquets.size() / listmaxshow) + 1) * listmaxshow))) ? (Bouquets.size() - 1) : 0; + if (!Bouquets.empty()) { + int step = ((int) msg == g_settings.key_channelList_pagedown) ? listmaxshow : 1; // browse or step 1 + int new_selected = selected + step; + if (new_selected >= (int) Bouquets.size()) { + if ((Bouquets.size() - listmaxshow -1 < selected) && (selected != (Bouquets.size() - 1)) && (step != 1)) + new_selected = Bouquets.size() - 1; + else if (((Bouquets.size() / listmaxshow) + 1) * listmaxshow == Bouquets.size() + listmaxshow) // last page has full entries + new_selected = 0; + else + new_selected = ((step == (int) listmaxshow) && (new_selected < (int) (((Bouquets.size() / listmaxshow)+1) * listmaxshow))) ? (Bouquets.size() - 1) : 0; + } + updateSelection(new_selected); } -#endif - if(selected >= Bouquets.size()) { - if((Bouquets.size() - listmaxshow -1 < prev_selected) && (prev_selected != (Bouquets.size() - 1)) && (step != 1)) - selected = Bouquets.size() - 1; - else if (((Bouquets.size() / listmaxshow) + 1) * listmaxshow == Bouquets.size() + listmaxshow) // last page has full entries - selected = 0; - else - selected = ((step == listmaxshow) && (selected < (((Bouquets.size() / listmaxshow)+1) * listmaxshow))) ? (Bouquets.size() - 1) : 0; - } - - paintItem(prev_selected - liststart); - unsigned int oldliststart = liststart; - liststart = (selected/listmaxshow)*listmaxshow; - if(oldliststart!=liststart) - paint(); - else - paintItem(selected - liststart); } else if(msg == (neutrino_msg_t)g_settings.key_bouquet_up || msg == (neutrino_msg_t)g_settings.key_bouquet_down) { if(bShowChannelList) { @@ -478,45 +479,36 @@ int CBouquetList::show(bool bShowChannelList) hide(); return -3; } - } - else if ( msg == CRCInput::RC_ok ) { - if(!bShowChannelList || Bouquets[selected]->channelList->getSize() > 0) { + if(!Bouquets.empty() && (!bShowChannelList || !Bouquets[selected]->channelList->isEmpty())) { zapOnExit = true; loop=false; } } else if (CRCInput::isNumeric(msg)) { - if (pos == lmaxpos) { - if (msg == CRCInput::RC_0) { + if (!Bouquets.empty()) { + if (pos == lmaxpos) { + if (msg == CRCInput::RC_0) { + chn = firstselected; + pos = lmaxpos; + } else { + chn = CRCInput::getNumericValue(msg); + pos = 1; + } + } else { + chn = chn * 10 + CRCInput::getNumericValue(msg); + pos++; + } + + if (chn > Bouquets.size()) { chn = firstselected; pos = lmaxpos; - } else { - chn = CRCInput::getNumericValue(msg); - pos = 1; } - } else { - chn = chn * 10 + CRCInput::getNumericValue(msg); - pos++; - } - if (chn > Bouquets.size()) { - chn = firstselected; - pos = lmaxpos; + int new_selected = (chn - 1) % Bouquets.size(); // is % necessary (i.e. can firstselected be > Bouquets.size()) ? + updateSelection(new_selected); } - - int prevselected=selected; - selected = (chn - 1) % Bouquets.size(); // is % necessary (i.e. can firstselected be > Bouquets.size()) ? - paintItem(prevselected - liststart); - unsigned int oldliststart = liststart; - liststart = (selected/listmaxshow)*listmaxshow; - if(oldliststart!=liststart) { - paint(); - } else { - paintItem(selected - liststart); - } - } else { if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & messages_return::cancel_all ) { loop = false; @@ -561,9 +553,9 @@ void CBouquetList::paintItem(int pos) CVFD::getInstance()->showMenuText(0, lname, -1, true); } else { if(npos < (int) Bouquets.size()) - iscurrent = Bouquets[npos]->channelList->getSize() > 0; - color = iscurrent ? COL_MENUCONTENT : COL_MENUCONTENTINACTIVE; - bgcolor = iscurrent ? COL_MENUCONTENT_PLUS_0 : COL_MENUCONTENTINACTIVE_PLUS_0; + iscurrent = !Bouquets[npos]->channelList->isEmpty(); + color = iscurrent ? COL_MENUCONTENT : COL_MENUCONTENTINACTIVE; + bgcolor = iscurrent ? COL_MENUCONTENT_PLUS_0 : COL_MENUCONTENTINACTIVE_PLUS_0; frameBuffer->paintBoxRel(x, ypos, width- 15, fheight, bgcolor); } @@ -579,14 +571,6 @@ void CBouquetList::paintItem(int pos) } } -const struct button_label CBouquetListButtons[4] = -{ - { NEUTRINO_ICON_BUTTON_RED, LOCALE_CHANNELLIST_FAVS}, - { NEUTRINO_ICON_BUTTON_GREEN, LOCALE_CHANNELLIST_PROVS}, - { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_CHANNELLIST_SATS}, - { NEUTRINO_ICON_BUTTON_BLUE, LOCALE_CHANNELLIST_HEAD} -}; - void CBouquetList::paintHead() { frameBuffer->paintBoxRel(x,y, width,theight+0, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP); diff --git a/src/gui/bouquetlist.h b/src/gui/bouquetlist.h index 35dcb136f..41e76a07b 100644 --- a/src/gui/bouquetlist.h +++ b/src/gui/bouquetlist.h @@ -99,6 +99,7 @@ class CBouquetList void paintHead(); void hide(); int doMenu(); + void updateSelection(int newpos); public: CBouquetList(const char * const Name = NULL); diff --git a/src/gui/cam_menu.cpp b/src/gui/cam_menu.cpp index 6da597a76..34071faec 100644 --- a/src/gui/cam_menu.cpp +++ b/src/gui/cam_menu.cpp @@ -49,6 +49,8 @@ #include #include +#include +#include void CCAMMenuHandler::init(void) { @@ -269,6 +271,7 @@ int CCAMMenuHandler::handleCamMsg (const neutrino_msg_t msg, neutrino_msg_data_t snprintf(str, sizeof(str), "%s %d: %s", g_Locale->getText(SlotType == CA_SLOT_TYPE_CI ? LOCALE_CI_INIT_OK : LOCALE_SC_INIT_OK), (int)curslot+1, name); printf("CCAMMenuHandler::handleCamMsg: %s\n", str); + CCamManager::getInstance()->Start(CZapit::getInstance()->GetCurrentChannelID(), CCamManager::PLAY, true); ShowHintUTF(LOCALE_MESSAGEBOX_INFO, str); #if 0 showHintBox(LOCALE_MESSAGEBOX_INFO, str, CI_MSG_TIME); @@ -471,7 +474,9 @@ int CCAMMenuHandler::doMenu(int slot, CA_SLOT_TYPE slotType) res = menu_return::RETURN_EXIT_ALL; } } else if (ret == 1) { - timeoutEnd = CRCInput::calcTimeoutEnd(10); + /* workaround: dont cycle here on timers */ + if (msg != NeutrinoMessages::EVT_TIMER) + timeoutEnd = CRCInput::calcTimeoutEnd(10); continue; } else if (ret == 2) { doexit = true; 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 f7c8b1d57..92c7f50d3 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -622,13 +622,15 @@ int CChannelList::show() else if ((msg == CRCInput::RC_red) || (msg == CRCInput::RC_epg)) { hide(); + /* RETURN_EXIT_ALL on FAV/SAT buttons or messages_return::cancel_all from CNeutrinoApp::getInstance()->handleMsg() */ if ( g_EventList->exec(chanlist[selected]->channel_id, chanlist[selected]->getName()) == menu_return::RETURN_EXIT_ALL) { res = -2; loop = false; + } else { + paintHead(); + paint(); + timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_CHANLIST]); } - paintHead(); - paint(); - timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_CHANLIST]); } else if (msg == CRCInput::RC_yellow) { bShowBouquetList = true; @@ -689,11 +691,11 @@ int CChannelList::show() if (!bouquetList->Bouquets.empty()) { bool found = true; uint32_t nNext = (bouquetList->getActiveBouquetNumber()+1) % bouquetList->Bouquets.size(); - if(bouquetList->Bouquets[nNext]->channelList->getSize() <= 0) { + if(bouquetList->Bouquets[nNext]->channelList->isEmpty() ) { found = false; nNext = nNext < bouquetList->Bouquets.size()-1 ? nNext+1 : 0; for(uint32_t i = nNext; i < bouquetList->Bouquets.size(); i++) { - if(bouquetList->Bouquets[i]->channelList->getSize() > 0) { + if( !bouquetList->Bouquets[i]->channelList->isEmpty() ) { found = true; nNext = i; break; @@ -711,11 +713,11 @@ int CChannelList::show() if (!bouquetList->Bouquets.empty()) { bool found = true; int nNext = (bouquetList->getActiveBouquetNumber()+bouquetList->Bouquets.size()-1) % bouquetList->Bouquets.size(); - if(bouquetList->Bouquets[nNext]->channelList->getSize() <= 0) { + if(bouquetList->Bouquets[nNext]->channelList->isEmpty() ) { found = false; nNext = nNext > 0 ? nNext-1 : bouquetList->Bouquets.size()-1; for(int i = nNext; i > 0; i--) { - if(bouquetList->Bouquets[i]->channelList->getSize() > 0) { + if(!bouquetList->Bouquets[i]->channelList->isEmpty()) { found = true; nNext = i; break; @@ -736,9 +738,11 @@ int CChannelList::show() } } else if (( msg == CRCInput::RC_spkr ) && g_settings.channellist_new_zap_mode ) { - this->new_mode_active = (this->new_mode_active ? 0 : 1); - paintHead(); - showChannelLogo(); + if(CNeutrinoApp::getInstance()->getMode() != NeutrinoMessages::mode_ts) { + this->new_mode_active = (this->new_mode_active ? 0 : 1); + paintHead(); + showChannelLogo(); + } } else if (CRCInput::isNumeric(msg) && (this->historyMode || g_settings.sms_channel)) { if (this->historyMode) { //numeric zap @@ -802,20 +806,19 @@ int CChannelList::show() else if ( msg == CRCInput::RC_blue ) { displayNext = !displayNext; - paint(); paintHead(); // update button bar - showChannelLogo(); + paint(); } else if ( msg == CRCInput::RC_green ) { int mode = CNeutrinoApp::getInstance()->GetChannelMode(); - if(mode){ + if(mode != LIST_MODE_FAV) { g_settings.channellist_sort_mode++; if(g_settings.channellist_sort_mode > 2) g_settings.channellist_sort_mode = 0; CNeutrinoApp::getInstance()->SetChannelMode(mode); - paint(); paintHead(); // update button bar + paint(); } } @@ -1186,7 +1189,7 @@ int CChannelList::numericZap(int key) channelList->addChannel(orgList->chanlist[i]); } } - if (channelList->getSize() != 0) { + if ( !channelList->isEmpty()) { channelList->adjustToChannelID(orgList->getActiveChannel_ChannelID(), false); this->frameBuffer->paintBackground(); res = channelList->exec(); @@ -1206,7 +1209,7 @@ int CChannelList::numericZap(int key) if(channel) channelList->addChannel(channel); } } - if (channelList->getSize() != 0) { + if ( !channelList->isEmpty() ) { this->frameBuffer->paintBackground(); res = channelList->exec(); CVFD::getInstance()->setMode(CVFD::MODE_TVRADIO); @@ -1624,7 +1627,7 @@ void CChannelList::paintButtonBar(bool is_current) { //printf("[neutrino channellist] %s...%d, selected %d\n", __FUNCTION__, __LINE__, selected); unsigned int smode = CNeutrinoApp::getInstance()->GetChannelMode(); - int num_buttons = smode ? NUM_LIST_BUTTONS_SORT : NUM_LIST_BUTTONS; + int num_buttons = smode != LIST_MODE_FAV ? NUM_LIST_BUTTONS_SORT : NUM_LIST_BUTTONS; 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, @@ -1968,6 +1971,11 @@ void CChannelList::paint() showChannelLogo(); } +bool CChannelList::isEmpty() const +{ + return this->chanlist.empty(); +} + int CChannelList::getSize() const { return this->chanlist.size(); diff --git a/src/gui/channellist.h b/src/gui/channellist.h index e3b360156..bf1b78319 100644 --- a/src/gui/channellist.h +++ b/src/gui/channellist.h @@ -146,6 +146,7 @@ public: int handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data); int getSize() const; + bool isEmpty() const; int getSelectedChannelIndex() const; void setSize(int newsize); int doChannelMenu(void); diff --git a/src/gui/epgplus.cpp b/src/gui/epgplus.cpp index 386285bcf..84e4d42df 100644 --- a/src/gui/epgplus.cpp +++ b/src/gui/epgplus.cpp @@ -883,11 +883,11 @@ int EpgPlus::exec (CChannelList * pchannelList, int selectedChannelIndex, CBouqu bool found = true; uint32_t nNext = (bouquetList->getActiveBouquetNumber()+1) % bouquetList->Bouquets.size(); //printf("**************************** EpgPlus::exec current bouquet %d new %d\n", bouquetList->getActiveBouquetNumber(), nNext); - if(bouquetList->Bouquets[nNext]->channelList->getSize() <= 0) { + if(bouquetList->Bouquets[nNext]->channelList->isEmpty() ) { found = false; nNext = nNext < bouquetList->Bouquets.size()-1 ? nNext+1 : 0; for(uint32_t i = nNext; i < bouquetList->Bouquets.size(); i++) { - if(bouquetList->Bouquets[i]->channelList->getSize() > 0) { + if(!bouquetList->Bouquets[i]->channelList->isEmpty() ) { found = true; nNext = i; break; @@ -909,11 +909,11 @@ int EpgPlus::exec (CChannelList * pchannelList, int selectedChannelIndex, CBouqu if (!bouquetList->Bouquets.empty()) { bool found = true; int nNext = (bouquetList->getActiveBouquetNumber()+bouquetList->Bouquets.size()-1) % bouquetList->Bouquets.size(); - if(bouquetList->Bouquets[nNext]->channelList->getSize() <= 0) { + if(bouquetList->Bouquets[nNext]->channelList->isEmpty()) { found = false; nNext = nNext > 0 ? nNext-1 : bouquetList->Bouquets.size()-1; for(int i = nNext; i > 0; i--) { - if(bouquetList->Bouquets[i]->channelList->getSize() > 0) { + if(!bouquetList->Bouquets[i]->channelList->isEmpty()) { found = true; nNext = i; break; @@ -1261,7 +1261,7 @@ int CEPGplusHandler::exec (CMenuTarget * parent, const std::string & /*actionKey //channelList = CNeutrinoApp::getInstance()->channelList; int bnum = bouquetList->getActiveBouquetNumber(); current_bouquet = bnum; - if(!bouquetList->Bouquets.empty() && bouquetList->Bouquets[bnum]->channelList->getSize() > 0) + if(!bouquetList->Bouquets.empty() && !bouquetList->Bouquets[bnum]->channelList->isEmpty() ) channelList = bouquetList->Bouquets[bnum]->channelList; else channelList = CNeutrinoApp::getInstance()->channelList; diff --git a/src/gui/epgview.cpp b/src/gui/epgview.cpp index 919a869d1..c0d7750f8 100644 --- a/src/gui/epgview.cpp +++ b/src/gui/epgview.cpp @@ -152,7 +152,7 @@ void CEpgData::start() toph = topboxheight; } -void CEpgData::addTextToArray(const std::string & text, bool screening) // UTF-8 +void CEpgData::addTextToArray(const std::string & text, int screening) // UTF-8 { //printf("line: >%s<\n", text.c_str() ); if (text==" ") @@ -170,7 +170,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 = ""; @@ -249,7 +249,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: @@ -262,7 +261,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); @@ -270,8 +269,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; @@ -446,12 +446,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; @@ -544,7 +544,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start } } // Compare strings normally if not positively found to be equal before - if (false == bHide && false == (std::string::npos == epgData.info2.find(epgData.info1))) { + if (false == bHide && 0 == epgData.info2.find(epgData.info1)) { bHide = true; } } @@ -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); @@ -674,10 +674,10 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start 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; @@ -694,7 +694,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start switch ( msg ) { case NeutrinoMessages::EVT_TIMER: - if (data == g_InfoViewer->lcdUpdateTimer) { + if (data == g_InfoViewer->getUpdateTimer()) { GetEPGData(channel_id, id, &startzeit, false); if ( epg_done!= -1 ) { CProgressBar pb(true, -1, -1, 30, 100, 70, true); @@ -717,7 +717,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); @@ -728,7 +728,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); @@ -847,19 +847,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; } @@ -895,8 +900,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: @@ -1025,10 +1032,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; @@ -1045,6 +1053,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 = ""; @@ -1064,9 +1073,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; @@ -1108,9 +1122,9 @@ void CEpgData::showTimerEventBar (bool pshow) frameBuffer->paintBoxRel(sx,y,ox,h, COL_INFOBAR_SHADOW_PLUS_1, RADIUS_LARGE, CORNER_BOTTOM);//round if (g_settings.recording_type != CNeutrinoApp::RECORDING_OFF) - ::paintButtons(x, y, 0, has_follow_screenings ? 3:2, EpgButtons, h); + ::paintButtons(x, y, 0, (has_follow_screenings && !call_fromfollowlist) ? 3:2, EpgButtons, h); else - ::paintButtons(x, y, 0, has_follow_screenings ? 2:1, &EpgButtons[1], h); + ::paintButtons(x, y, 0, (has_follow_screenings && !call_fromfollowlist) ? 2:1, &EpgButtons[1], h); #if 0 // Button: Timer Record & Channelswitch 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 f0f2f5d21..936606b12 100644 --- a/src/gui/eventlist.cpp +++ b/src/gui/eventlist.cpp @@ -606,7 +606,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; @@ -973,16 +973,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; @@ -1241,6 +1236,7 @@ int CEventFinderMenu::showMenu(void) /************************************************************************************************/ { int res = menu_return::RETURN_REPAINT; + m_search_channelname_mf = NULL; *m_event = false; if(*m_search_list == CNeutrinoEventList::SEARCH_LIST_CHANNEL) @@ -1264,24 +1260,51 @@ int CEventFinderMenu::showMenu(void) CStringInputSMS stringInput(LOCALE_EVENTFINDER_KEYWORD,m_search_keyword, 20, NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, "abcdefghijklmnopqrstuvwxyz0123456789 -_/()<>=+.,:!?\\'"); - CMenuForwarder* mf2 = new CMenuForwarder(LOCALE_EVENTFINDER_KEYWORD ,true, *m_search_keyword, &stringInput, NULL, CRCInput::RC_1 ); - CMenuOptionChooser* mo0 = new CMenuOptionChooser(LOCALE_EVENTFINDER_SEARCH_WITHIN_LIST , m_search_list, SEARCH_LIST_OPTIONS, SEARCH_LIST_OPTION_COUNT, true, NULL, CRCInput::RC_2); - CMenuForwarderNonLocalized* mf1 = new CMenuForwarderNonLocalized("", *m_search_list != CNeutrinoEventList::SEARCH_LIST_ALL, m_search_channelname, this, "3", CRCInput::RC_3 ); + CMenuForwarder* mf0 = new CMenuForwarder(LOCALE_EVENTFINDER_KEYWORD, true, *m_search_keyword, &stringInput, NULL, CRCInput::RC_1, NEUTRINO_ICON_BUTTON_1); + CMenuOptionChooser* mo0 = new CMenuOptionChooser(LOCALE_EVENTFINDER_SEARCH_WITHIN_LIST, m_search_list, SEARCH_LIST_OPTIONS, SEARCH_LIST_OPTION_COUNT, true, this, CRCInput::RC_2, NEUTRINO_ICON_BUTTON_2); + m_search_channelname_mf = new CMenuForwarderNonLocalized("", *m_search_list != CNeutrinoEventList::SEARCH_LIST_ALL, m_search_channelname, this, "3", CRCInput::RC_3, NEUTRINO_ICON_BUTTON_3); CMenuOptionChooser* mo1 = new CMenuOptionChooser(LOCALE_EVENTFINDER_SEARCH_WITHIN_EPG, m_search_epg_item, SEARCH_EPG_OPTIONS, SEARCH_EPG_OPTION_COUNT, true, NULL, CRCInput::RC_4); - CMenuForwarder* mf0 = new CMenuForwarder(LOCALE_EVENTFINDER_START_SEARCH, true, NULL, this, "1", CRCInput::RC_5 ); + CMenuForwarder* mf1 = new CMenuForwarder(LOCALE_EVENTFINDER_START_SEARCH, true, NULL, this, "1", CRCInput::RC_5, NEUTRINO_ICON_BUTTON_5); CMenuWidget searchMenu(LOCALE_EVENTFINDER_HEAD, NEUTRINO_ICON_FEATURES); searchMenu.addItem(GenericMenuSeparator); - searchMenu.addItem(mf2, false); + searchMenu.addItem(mf0); searchMenu.addItem(GenericMenuSeparatorLine); - searchMenu.addItem(mo0, false); - searchMenu.addItem(mf1, false); - searchMenu.addItem(mo1, false); + searchMenu.addItem(mo0); + searchMenu.addItem(m_search_channelname_mf); + searchMenu.addItem(mo1); searchMenu.addItem(GenericMenuSeparatorLine); - searchMenu.addItem(mf0, false); + searchMenu.addItem(mf1); res = searchMenu.exec(NULL,""); return(res); } + + +/************************************************************************************************/ +bool CEventFinderMenu::changeNotify(const neutrino_locale_t OptionName, void *) +/************************************************************************************************/ +{ + if (ARE_LOCALES_EQUAL(OptionName, LOCALE_EVENTFINDER_SEARCH_WITHIN_LIST)) + { + if (*m_search_list == CNeutrinoEventList::SEARCH_LIST_CHANNEL) + { + m_search_channelname = g_Zapit->getChannelName(*m_search_channel_id); + m_search_channelname_mf->setActive(true); + } + else if (*m_search_list == CNeutrinoEventList::SEARCH_LIST_BOUQUET) + { + m_search_channelname = bouquetList->Bouquets[*m_search_bouquet_id]->channelList->getName(); + m_search_channelname_mf->setActive(true); + } + else if (*m_search_list == CNeutrinoEventList::SEARCH_LIST_ALL) + { + m_search_channelname = ""; + m_search_channelname_mf->setActive(false); + } + } + return false; +} + diff --git a/src/gui/eventlist.h b/src/gui/eventlist.h index c1ef8b81b..41a128cfa 100644 --- a/src/gui/eventlist.h +++ b/src/gui/eventlist.h @@ -134,9 +134,10 @@ class CEventListHandler : public CMenuTarget }; -class CEventFinderMenu : public CMenuTarget +class CEventFinderMenu : public CMenuTarget, CChangeObserver { private: + CMenuForwarderNonLocalized* m_search_channelname_mf; int* m_event; int* m_search_epg_item; std::string* m_search_keyword; @@ -153,6 +154,7 @@ class CEventFinderMenu : public CMenuTarget t_channel_id* search_channel_id, t_bouquet_id* search_bouquet_id); int exec( CMenuTarget* parent, const std::string &actionkey); + bool changeNotify(const neutrino_locale_t OptionName, void *); }; #endif diff --git a/src/gui/ext_update.cpp b/src/gui/ext_update.cpp new file mode 100644 index 000000000..c8763de72 --- /dev/null +++ b/src/gui/ext_update.cpp @@ -0,0 +1,533 @@ +/* + update with settings - Neutrino-GUI + + Copyright (C) 2001 Steffen Hehn 'McClean' + and some other guys + Homepage: http://dbox.cyberphoria.org/ + + Copyright (C) 2012 M. Liebmann (micha-bbg) + + License: GPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#define UPDATE_DEBUG_TIMER +#define UPDATE_DEBUG + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CHintBox * hintBox = 0; + +CExtUpdate::CExtUpdate() +{ + imgFilename = ""; + mtdRamError = ""; + mtdNumber = -1; + MTDBufSize = 0xFFFF; + MTDBuf = new char[MTDBufSize]; + backupList = CONFIGDIR "/settingsupdate.conf"; + defaultBackup = CONFIGDIR; + + fUpdate = NULL; + updateLogBuf[0] = '\0'; + fLogEnabled = 1; + fLogfile = "/tmp/update.log"; + mountPkt = "/tmp/image_mount"; + FileHelpers = NULL; +} + +CExtUpdate::~CExtUpdate() +{ + if (MTDBuf != NULL) + delete[] MTDBuf; + if(FileHelpers) + delete[] FileHelpers; +} + +CExtUpdate* CExtUpdate::getInstance() +{ + static CExtUpdate* ExtUpdate = NULL; + if(!ExtUpdate) + ExtUpdate = new CExtUpdate(); + return ExtUpdate; +} + +bool CExtUpdate::ErrorReset(bool modus, const std::string & msg1, const std::string & msg2) +{ + char buf[1024]; + + if (modus & RESET_UNLOAD) { + umount(mountPkt.c_str()); + my_system("rmmod", mtdramDriver.c_str()); + } + if (modus & RESET_FD1) + close(fd1); + if (modus & RESET_FD2) + close(fd2); + if (modus & RESET_F1) + fclose(f1); + + if (msg2 == "") + snprintf(buf, sizeof(buf), "%s\n", msg1.c_str()); + else + snprintf(buf, sizeof(buf), "%s %s\n", msg1.c_str(), msg2.c_str()); + + if ((msg1 != "") || (msg2 != "")) { + mtdRamError = buf; + WRITE_UPDATE_LOG("ERROR: %s", buf); + printf(mtdRamError.c_str()); + } + if(hintBox) + hintBox->hide(); + return false; +} + +bool CExtUpdate::applySettings(const std::string & filename, int mode) +{ + if(!FileHelpers) + FileHelpers = new CFileHelpers(); + + 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 = applySettings(); + DBG_TIMER_STOP("Image editing") + if (!ret) { + if (mtdRamError != "") + DisplayErrorMessage(mtdRamError.c_str()); + } + else { + 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"); + if (mode == MODE_EXPERT) + CFlashExpert::getInstance()->writemtd(filename, mtdNumber); + } + return ret; +} + +bool CExtUpdate::isMtdramLoad() +{ + char buf[256] = ""; + bool ret = false; + FILE* f = fopen("/proc/modules", "r"); + if (f) { + while(fgets(buf, sizeof(buf), f) != NULL) { + if (strstr(buf, "mtdram") != NULL) { + ret = true; + break; + } + } + fclose(f); + } + return ret; +} + +bool CExtUpdate::applySettings() +{ + if(!hintBox) + hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_PROCESSED)); + hintBox->paint(); + mtdRamError = ""; + std::string osrelease = ""; + mtdramDriver = ""; // driver path + char buf1[256] = ""; + char buf2[256] = ""; + + CMTDInfo * mtdInfo = CMTDInfo::getInstance(); + std::string mtdFilename = mtdInfo->findMTDsystem(); // /dev/mtdX + int mtdSize = mtdInfo->getMTDSize(mtdFilename); + int mtdEraseSize = mtdInfo->getMTDEraseSize(mtdFilename); + mtdNumber = mtdInfo->findMTDNumber(mtdFilename); + + // get osrelease + struct utsname uts_info; + 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"); + + // check if mtdram driver is already loaded + if (!isMtdramLoad()) { + // check if exist mtdram driver + snprintf(buf1, sizeof(buf1), "/lib/modules/%s/mtdram.ko", osrelease.c_str()); + mtdramDriver = buf1; + if ( !file_exists(mtdramDriver.c_str()) ) + return ErrorReset(0, "no mtdram driver available"); + // load mtdram driver + snprintf(buf1, sizeof(buf1), "total_size=%d", mtdSize/1024); + snprintf(buf2, sizeof(buf2), "erase_size=%d", mtdEraseSize/1024); + my_system("insmod", mtdramDriver.c_str(), buf1, buf2); + // check if mtdram driver is now loaded + if (!isMtdramLoad()) + return ErrorReset(0, "error load mtdram driver"); + } + else { + DBG_MSG("mtdram driver is already loaded"); + } + + // find mtdram device + std::string mtdRamFilename = "", mtdBlockFileName = ""; + int mtdRamSize, mtdRamEraseSize, mtdRamNr = 0; + f1 = fopen("/proc/mtd", "r"); + if(!f1) + return ErrorReset(RESET_UNLOAD, "cannot read /proc/mtd"); + fgets(buf1, sizeof(buf1), f1); + while(!feof(f1)) { + if(fgets(buf1, sizeof(buf1), f1)!=NULL) { + char dummy[50] = ""; + sscanf(buf1, "mtd%1d: %8x %8x \"%48s\"\n", &mtdRamNr, &mtdRamSize, &mtdRamEraseSize, dummy); + if (strstr(buf1, "mtdram test device") != NULL) { + sprintf(buf1, "/dev/mtd%d", mtdRamNr); + mtdRamFilename = buf1; + sprintf(buf1, "/dev/mtdblock%d", mtdRamNr); + mtdBlockFileName = buf1; + break; + } + } + } + fclose(f1); + + if (mtdRamFilename == "") + return ErrorReset(RESET_UNLOAD, "no mtdram test device found"); + else { + // check mtdRamSize / mtdRamEraseSize + if ((mtdRamSize != mtdSize) || (mtdRamEraseSize != mtdEraseSize)) { + snprintf(buf2, sizeof(buf2), "error MTDSize(%08x/%08x) or MTDEraseSize(%08x/%08x)\n", mtdSize, mtdRamSize, mtdEraseSize, mtdRamEraseSize); + return ErrorReset(RESET_UNLOAD, buf2); + } + } + + // copy image to mtdblock + if (MTDBuf == NULL) + return ErrorReset(RESET_UNLOAD, "malloc error"); + fd1 = open(imgFilename.c_str(), O_RDONLY); + if (fd1 < 0) + return ErrorReset(RESET_UNLOAD, "cannot read image file: " + imgFilename); + long filesize = lseek(fd1, 0, SEEK_END); + lseek(fd1, 0, SEEK_SET); + if(filesize == 0) + return ErrorReset(RESET_UNLOAD | RESET_FD1, "image filesize is 0"); + if(filesize > mtdSize) + return ErrorReset(RESET_UNLOAD | RESET_FD1, "image filesize too large"); + fd2 = -1; + int tmpCount = 0; + while (fd2 < 0) { + fd2 = open(mtdBlockFileName.c_str(), O_WRONLY); + tmpCount++; + if (tmpCount > 3) + break; + sleep(1); + } + if (fd2 < 0) + return ErrorReset(RESET_UNLOAD | RESET_FD1, "cannot open mtdBlock"); + long fsize = filesize; + long block; + while(fsize > 0) { + block = fsize; + if(block > (long)MTDBufSize) + block = MTDBufSize; + read(fd1, MTDBuf, block); + write(fd2, MTDBuf, block); + fsize -= block; + } + close(fd1); + close(fd2); + + FileHelpers->createDir(mountPkt.c_str(), 0755); + int res = mount(mtdBlockFileName.c_str(), mountPkt.c_str(), "jffs2", 0, NULL); + if (res) + return ErrorReset(RESET_UNLOAD, "mount error"); + + readBackupList(mountPkt); + + res = umount(mountPkt.c_str()); + if (res) + return ErrorReset(RESET_UNLOAD, "unmount error"); + + unlink(imgFilename.c_str()); + + // copy mtdblock to image + if (MTDBuf == NULL) + return ErrorReset(RESET_UNLOAD, "malloc error"); + fd1 = open(mtdBlockFileName.c_str(), O_RDONLY); + if (fd1 < 0) + return ErrorReset(RESET_UNLOAD, "cannot read mtdBlock"); + fsize = mtdRamSize; + fd2 = open(imgFilename.c_str(), O_WRONLY | O_CREAT); + if (fd2 < 0) + return ErrorReset(RESET_UNLOAD | RESET_FD1, "cannot open image file: ", imgFilename); + while(fsize > 0) { + block = fsize; + if(block > (long)MTDBufSize) + block = MTDBufSize; + read(fd1, MTDBuf, block); + write(fd2, MTDBuf, block); + fsize -= block; + } + lseek(fd2, 0, SEEK_SET); + long fsizeDst = lseek(fd2, 0, SEEK_END); + close(fd1); + close(fd2); + // check image file size + if (mtdRamSize != fsizeDst) { + unlink(imgFilename.c_str()); + return ErrorReset(0, "error file size: ", imgFilename); + } + + // unload mtdramDriver only + ErrorReset(RESET_UNLOAD); + + if(hintBox) + hintBox->hide(); + + return true; +} + +std::string Wildcard = ""; + +int fileSelect(const struct dirent *entry) +{ + if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) + return 0; + else + if ((Wildcard != "") && (fnmatch(Wildcard.c_str(), entry->d_name, FNM_FILE_NAME))) + return 0; + else + return 1; + +} + +bool CExtUpdate::copyFileList(const std::string & fileList, const std::string & dstPath) +{ + Wildcard = ""; + struct dirent **namelist; + std::string fList = fileList, dst; + static struct stat FileInfo; + char buf[PATH_MAX]; + + size_t pos = fileList.find_last_of("/"); + fList = fileList.substr(0, pos); + Wildcard = fileList.substr(pos+1); + + int n = scandir(fList.c_str(), &namelist, fileSelect, 0); + if (n > 0) { + dst = dstPath + fList; + FileHelpers->createDir(dst.c_str(), 0755); + while (n--) { + std::string dName = namelist[n]->d_name; + if (lstat((fList+"/"+dName).c_str(), &FileInfo) != -1) { + if (S_ISLNK(FileInfo.st_mode)) { + int len = readlink((fList+"/"+dName).c_str(), buf, sizeof(buf)-1); + if (len != -1) { + buf[len] = '\0'; + WRITE_UPDATE_LOG("symlink: %s => %s\n", (dst+"/"+dName).c_str(), buf); + symlink(buf, (dst+"/"+dName).c_str()); + } + } + else + if (S_ISREG(FileInfo.st_mode)) { + WRITE_UPDATE_LOG("copy %s => %s\n", (fList+"/"+dName).c_str(), (dst+"/"+dName).c_str()); + if (!FileHelpers->copyFile((fList+"/"+dName).c_str(), (dst+"/"+dName).c_str(), FileInfo.st_mode & 0x0FFF)) + return ErrorReset(0, "copyFile error"); + } + } + free(namelist[n]); + } + free(namelist); + } + + return true; +} + +bool CExtUpdate::findConfigEntry(std::string & line, std::string find) +{ + if (line.find("#:" + find + "=") == 0) { + size_t pos = line.find_first_of('='); + line = line.substr(pos+1); + line = trim(line); + return true; + } + return false; +} + +bool CExtUpdate::readConfig(const std::string & line) +{ + std::string tmp1 = line; + if (findConfigEntry(tmp1, "Log")) { + if (tmp1 != "") + fLogEnabled = atoi(tmp1.c_str()); + return true; + } + tmp1 = line; + if (findConfigEntry(tmp1, "LogFile")) { + if (tmp1 != "") + fLogfile = tmp1; + return true; + } + + return true; +} + +bool CExtUpdate::readBackupList(const std::string & dstPath) +{ + char buf[PATH_MAX]; + static struct stat FileInfo; + + f1 = fopen(backupList.c_str(), "r"); + if (f1 == NULL) { + f1 = fopen(backupList.c_str(), "w"); + if (f1 != NULL) { + char tmp1[1024]; + snprintf(tmp1, sizeof(tmp1), "Log=%d\nLogFile=%s\n\n%s\n\n", fLogEnabled, fLogfile.c_str(), defaultBackup.c_str()); + fwrite(tmp1, 1, strlen(tmp1), f1); + fclose(f1); + } + else + return ErrorReset(0, "cannot create missing backuplist file: " + backupList); + } + + f1 = fopen(backupList.c_str(), "r"); + if (f1 == NULL) + return ErrorReset(0, "cannot read backuplist file: " + backupList); + fpos_t fz; + fseek(f1, 0, SEEK_END); + fgetpos(f1, &fz); + fseek(f1, 0, SEEK_SET); + if (fz.__pos == 0) + return ErrorReset(RESET_F1, "backuplist filesize is 0"); + size_t pos; + while(fgets(buf, sizeof(buf), f1) != NULL) { + std::string line = buf; + line = trim(line); + // 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); + } + // 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)) { + snprintf(buf, sizeof(buf), g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_SKIPPED), line.c_str()); + WRITE_UPDATE_LOG("%s%s", buf, "\n"); + ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, buf, CMessageBox::mbrOk, CMessageBox::mbOk, NEUTRINO_ICON_INFO); + continue; + } + // remove '/' from line end + size_t len = line.length(); + pos = line.find_last_of("/"); + if (len == pos+1) + line = line.substr(0, pos); + std::string dst = dstPath + line; + if ((line.find("*") != std::string::npos) || (line.find("?") != std::string::npos)) { + // Wildcards + DBG_MSG("Wildcards: %s\n", dst.c_str()); + WRITE_UPDATE_LOG("\n"); + WRITE_UPDATE_LOG("--------------------\n"); + WRITE_UPDATE_LOG("Wildcards: %s\n", dst.c_str()); + copyFileList(line, dstPath); + } + else { + if (lstat(line.c_str(), &FileInfo) != -1) { + if (S_ISREG(FileInfo.st_mode)) { + // one file only + pos = dst.find_last_of("/"); + std::string dir = dst.substr(0, pos); + FileHelpers->createDir(dir.c_str(), 0755); + DBG_MSG("file: %s => %s\n", line.c_str(), dst.c_str()); + WRITE_UPDATE_LOG("\n"); + WRITE_UPDATE_LOG("file: %s => %s\n", line.c_str(), dst.c_str()); + WRITE_UPDATE_LOG("--------------------\n"); + if (!FileHelpers->copyFile(line.c_str(), dst.c_str(), FileInfo.st_mode & 0x0FFF)) + return ErrorReset(0, "copyFile error"); + } + else if (S_ISDIR(FileInfo.st_mode)) { + // directory + DBG_MSG("directory: %s => %s\n", line.c_str(), dst.c_str()); + WRITE_UPDATE_LOG("\n"); + WRITE_UPDATE_LOG("directory: %s => %s\n", line.c_str(), dst.c_str()); + WRITE_UPDATE_LOG("--------------------\n"); + FileHelpers->copyDir(line.c_str(), dst.c_str()); + } + } + + } + } + fclose(f1); + + return true; +} + +void CExtUpdate::updateLog(const char *buf) +{ + if ((!fUpdate) && (fLogEnabled)) + fUpdate = fopen(fLogfile.c_str(), "a"); + if (fUpdate) { + fwrite(buf, 1, strlen(buf), fUpdate); + fclose(fUpdate); + fUpdate = NULL; + } +} diff --git a/src/gui/ext_update.h b/src/gui/ext_update.h new file mode 100644 index 000000000..9f0ee6744 --- /dev/null +++ b/src/gui/ext_update.h @@ -0,0 +1,109 @@ +/* + update with settings - Neutrino-GUI + + Copyright (C) 2001 Steffen Hehn 'McClean' + and some other guys + Homepage: http://dbox.cyberphoria.org/ + + Copyright (C) 2012 M. Liebmann (micha-bbg) + + License: GPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __CEXTUPDATE__ +#define __CEXTUPDATE__ + +#include +#include + +#include + +class CExtUpdate +{ + private: + enum + { + RESET_UNLOAD = 1, + RESET_FD1 = 2, + RESET_FD2 = 4, + RESET_F1 = 8 + }; + std::string imgFilename; + std::string mtdRamError; + int mtdNumber; + int MTDBufSize; + char *MTDBuf; + int fd1, fd2; + FILE *f1; + std::string mtdramDriver; + std::string backupList, defaultBackup; + std::string mountPkt; + CFileHelpers* FileHelpers; + + 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); + bool findConfigEntry(std::string & line, std::string find); + bool isMtdramLoad(); + + FILE * fUpdate; + char updateLogBuf[1024]; + std::string fLogfile; + int fLogEnabled; + void updateLog(const char *buf); + + public: + enum + { + MODE_EXPERT = 0, + MODE_SOFTUPDATE = 1 + }; + CExtUpdate(); + ~CExtUpdate(); + static CExtUpdate* getInstance(); + + bool applySettings(const std::string & filename, int mode); + bool ErrorReset(bool modus, const std::string & msg1="", const std::string & msg2=""); + +}; + +#ifdef UPDATE_DEBUG_TIMER +static struct timeval timer_tv, timer_tv2; +static unsigned int timer_msec; +#define DBG_TIMER_START() gettimeofday(&timer_tv, NULL); +#define DBG_TIMER_STOP(label) \ + gettimeofday(&timer_tv2, NULL); \ + timer_msec = ((timer_tv2.tv_sec - timer_tv.tv_sec) * 1000) + ((timer_tv2.tv_usec - timer_tv.tv_usec) / 1000); \ + printf("##### [ext_update.cpp] %s: %u msec\n", label, timer_msec); +#else +#define DBG_TIMER_START() +#define DBG_TIMER_STOP(label) +#endif // UPDATE_DEBUG_TIMER + +#ifdef UPDATE_DEBUG +#define DBG_MSG(fmt, args...) printf("#### [ext_update.cpp:%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args); +#else +#define DBG_MSG(fmt, args...) +#endif // UPDATE_DEBUG + +#define WRITE_UPDATE_LOG(fmt, args...) \ + snprintf(updateLogBuf, sizeof(updateLogBuf), "[update:%d] " fmt, __LINE__ , ## args); \ + updateLog(updateLogBuf); + +#endif // __CEXTUPDATE__ diff --git a/src/gui/filebrowser.cpp b/src/gui/filebrowser.cpp index 4e7f07f1f..18d431de1 100644 --- a/src/gui/filebrowser.cpp +++ b/src/gui/filebrowser.cpp @@ -232,7 +232,7 @@ unsigned char SMSKeyInput::getOldKey() const { return m_oldKey; } - +#if 0 const timeval* SMSKeyInput::getOldKeyTime() const { return &m_oldKeyTime; @@ -248,7 +248,7 @@ int SMSKeyInput::getTimeout() const { return m_timeout; } - +#endif void SMSKeyInput::setTimeout(int timeout) { m_timeout = timeout; diff --git a/src/gui/filebrowser.h b/src/gui/filebrowser.h index 3a20ab783..b1e92dabf 100644 --- a/src/gui/filebrowser.h +++ b/src/gui/filebrowser.h @@ -92,7 +92,7 @@ public: * @return the last key calculated by #handleMsg(neutrino_msg_t) */ unsigned char getOldKey() const; - +#if 0 /** * Returns time of last key push. * resolution: usecs @@ -106,7 +106,7 @@ public: time_t getOldKeyTimeSec() const; int getTimeout() const; - +#endif /** * Sets the timeout. * @param timeout keypresses within this period are taken as a diff --git a/src/gui/imageinfo.cpp b/src/gui/imageinfo.cpp index ac5ecfa27..9748d3f57 100644 --- a/src/gui/imageinfo.cpp +++ b/src/gui/imageinfo.cpp @@ -39,8 +39,8 @@ #include #include -#include "svn_version.h" -#define SVN_REV "SVN Rev.:" +#include "git_version.h" +#define GIT_DESC "GIT Desc.:" #define GIT_REV "GIT Build:" extern cVideo * videoDecoder; @@ -92,8 +92,8 @@ void CImageInfo::Init(void) offset = tmpoffset; } } -#ifdef SVNVERSION - int off_tmp = g_Font[font_info]->getRenderWidth(SVN_REV); +#ifdef GITVERSION + int off_tmp = g_Font[font_info]->getRenderWidth(GIT_DESC); #else int off_tmp = g_Font[font_info]->getRenderWidth(GIT_REV); #endif @@ -206,8 +206,8 @@ void CImageInfo::paint() const char * version = config.getString("version", "no version").c_str(); const char * docs = config.getString("docs", "http://wiki.neutrino-hd.de").c_str(); const char * forum = config.getString("forum", "http://forum.tuxbox.org").c_str(); -#ifdef SVNVERSION - const char * builddate = config.getString("builddate", SVNVERSION).c_str(); +#ifdef GITVERSION + const char * builddate = GITVERSION; #else const char * builddate = config.getString("builddate", BUILT_DATE).c_str(); #endif @@ -244,8 +244,8 @@ void CImageInfo::paint() paintLine(xpos+offset, font_info, Version_Kernel.c_str()); ypos += iheight; -#ifdef SVNVERSION - paintLine(xpos , font_info, SVN_REV); +#ifdef GITVERSION + paintLine(xpos , font_info, GIT_DESC); #else paintLine(xpos , font_info, GIT_REV); #endif diff --git a/src/gui/info_menue.cpp b/src/gui/info_menue.cpp index bb8470a48..c90c17b7d 100644 --- a/src/gui/info_menue.cpp +++ b/src/gui/info_menue.cpp @@ -79,7 +79,7 @@ int CInfoMenu::showMenu() mf->setHint(NEUTRINO_ICON_HINT_DBOXINFO, LOCALE_MENU_HINT_DBOXINFO); info->addItem(mf); - mf = new CMenuForwarder(LOCALE_STREAMINFO_HEAD, true, NULL, &streaminfo, NULL, CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW); + mf = new CMenuForwarder(LOCALE_STREAMINFO_HEAD, !CNeutrinoApp::getInstance()->channelList->isEmpty(), NULL, &streaminfo, NULL, CRCInput::RC_yellow, NEUTRINO_ICON_BUTTON_YELLOW); mf->setHint(NEUTRINO_ICON_HINT_STREAMINFO, LOCALE_MENU_HINT_STREAMINFO); info->addItem(mf); diff --git a/src/gui/infoviewer.cpp b/src/gui/infoviewer.cpp index 0b6883847..e1292fd5d 100644 --- a/src/gui/infoviewer.cpp +++ b/src/gui/infoviewer.cpp @@ -90,7 +90,24 @@ CInfoViewer::CInfoViewer () timescale = NULL; 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(); } @@ -129,6 +146,7 @@ void CInfoViewer::Init() channel_id = CZapit::getInstance()->GetCurrentChannelID();; lcdUpdateTimer = 0; + rt_x = rt_y = rt_h = rt_w = 0; } /* @@ -192,10 +210,6 @@ void CInfoViewer::start () time_left_width = 2 * g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->getWidth(); /* still a kludge */ time_dot_width = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]->getRenderWidth(":"); time_width = time_left_width* 2+ time_dot_width; - - const int lcd_update_time_tv_mode = (60 * 1000 * 1000); - if (lcdUpdateTimer == 0) - lcdUpdateTimer = g_RCInput->addTimer (lcd_update_time_tv_mode, false, true); } void CInfoViewer::changePB() @@ -997,7 +1011,9 @@ void CInfoViewer::showMotorMoving (int duration) void CInfoViewer::killRadiotext() { - frameBuffer->paintBackgroundBox(rt_x, rt_y, rt_w, rt_h); + if (g_Radiotext->S_RtOsd) + frameBuffer->paintBackgroundBox(rt_x, rt_y, rt_w, rt_h); + rt_x = rt_y = rt_h = rt_w = 0; } void CInfoViewer::showRadiotext() @@ -1133,7 +1149,6 @@ void CInfoViewer::showRadiotext() } - int CInfoViewer::handleMsg (const neutrino_msg_t msg, neutrino_msg_data_t data) { if ((msg == NeutrinoMessages::EVT_CURRENTNEXT_EPG) || (msg == NeutrinoMessages::EVT_NEXTPROGRAM)) { @@ -1273,16 +1288,16 @@ CSectionsdClient::CurrentNextInfo CInfoViewer::getEPG (const t_channel_id for_ch /* of there is no EPG, send an event so that parental lock can work */ if (info.current_uniqueKey == 0 && info.next_uniqueKey == 0) { oldinfo = info; - t_channel_id *p = new t_channel_id; - *p = for_channel_id; + char *p = new char[sizeof(t_channel_id)]; + memcpy(p, &for_channel_id, sizeof(t_channel_id)); g_RCInput->postMsg (NeutrinoMessages::EVT_NOEPG_YET, (const neutrino_msg_data_t) p, false); return info; } if (info.current_uniqueKey != oldinfo.current_uniqueKey || info.next_uniqueKey != oldinfo.next_uniqueKey) { if (info.flags & (CSectionsdClient::epgflags::has_current | CSectionsdClient::epgflags::has_next)) { - CSectionsdClient::CurrentNextInfo * _info = new CSectionsdClient::CurrentNextInfo; - *_info = info; + char *_info = new char[sizeof(CSectionsdClient::CurrentNextInfo)]; + memcpy(_info, &info, sizeof(CSectionsdClient::CurrentNextInfo)); neutrino_msg_t msg; if (info.flags & CSectionsdClient::epgflags::has_current) msg = NeutrinoMessages::EVT_CURRENTEPG; @@ -1290,8 +1305,8 @@ CSectionsdClient::CurrentNextInfo CInfoViewer::getEPG (const t_channel_id for_ch msg = NeutrinoMessages::EVT_NEXTEPG; g_RCInput->postMsg(msg, (unsigned) _info, false ); } else { - t_channel_id *p = new t_channel_id; - *p = for_channel_id; + char *p = new char[sizeof(t_channel_id)]; + memcpy(p, &for_channel_id, sizeof(t_channel_id)); g_RCInput->postMsg (NeutrinoMessages::EVT_NOEPG_YET, (const neutrino_msg_data_t) p, false); // data is pointer to allocated memory } oldinfo = info; @@ -1891,6 +1906,13 @@ void CInfoViewer::showEpgInfo() //message on event change } } +void CInfoViewer::setUpdateTimer(uint64_t interval) +{ + g_RCInput->killTimer(lcdUpdateTimer); + if (interval) + lcdUpdateTimer = g_RCInput->addTimer(interval, false); +} + #if 0 int CInfoViewerHandler::exec (CMenuTarget * parent, const std::string & /*actionkey*/) { diff --git a/src/gui/infoviewer.h b/src/gui/infoviewer.h index acecd909a..e2d5a9b95 100644 --- a/src/gui/infoviewer.h +++ b/src/gui/infoviewer.h @@ -107,6 +107,8 @@ class CInfoViewer CProgressBar *snrscale, *sigscale, *timescale; bool casysChange; bool channellogoChange; + uint32_t lcdUpdateTimer; + void paintBackground(int col_Numbox); void show_Data( bool calledFromEvent = false ); void display_Info(const char *current, const char *next, bool UTF8 = true, @@ -136,7 +138,6 @@ class CInfoViewer bool chanready; bool is_visible; bool virtual_zap_mode; - uint32_t lcdUpdateTimer; char aspectRatio; uint32_t sec_timer_id; @@ -170,6 +171,8 @@ class CInfoViewer void showSNR(); void Init(void); bool SDT_freq_update; + void setUpdateTimer(uint64_t interval); + uint32_t getUpdateTimer(void) { return lcdUpdateTimer; } }; #if 0 class CInfoViewerHandler : public CMenuTarget diff --git a/src/gui/infoviewer_bb.cpp b/src/gui/infoviewer_bb.cpp index 7502bad65..cf033a766 100644 --- a/src/gui/infoviewer_bb.cpp +++ b/src/gui/infoviewer_bb.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -86,8 +87,14 @@ CInfoViewerBB::CInfoViewerBB() pthread_detach(scrambledT); } #endif + hddpercent = 0; hddperT = 0; hddperTflag = false; + bbIconInfo[0].x = 0; + bbIconInfo[0].h = 0; + BBarY = 0; + BBarFontY = 0; + Init(); } @@ -233,10 +240,13 @@ void CInfoViewerBB::getBBButtonInfo() text = g_settings.usermenu_text[SNeutrinoSettings::BUTTON_GREEN]; if (text == g_Locale->getText(LOCALE_AUDIOSELECTMENUE_HEAD)) text = ""; - if (!g_RemoteControl->current_PIDs.APIDs.empty()) { + if(NeutrinoMessages::mode_ts == CNeutrinoApp::getInstance()->getMode() && !CMoviePlayerGui::getInstance().timeshift){ + text = CMoviePlayerGui::getInstance().CurrentAudioName(); + }else if (!g_RemoteControl->current_PIDs.APIDs.empty()) { int selected = g_RemoteControl->current_PIDs.PIDs.selected_apid; - if (text.empty()) + if (text.empty()){ text = g_RemoteControl->current_PIDs.APIDs[selected].desc; + } } break; case CInfoViewerBB::BUTTON_SUBS: @@ -603,20 +613,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); } } @@ -624,11 +631,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); @@ -642,8 +648,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) @@ -711,14 +723,21 @@ void CInfoViewerBB::paint_ca_icons(int caid, char * icon, int &icon_space_offset void CInfoViewerBB::showIcon_CA_Status(int notfirst) { + if (g_settings.casystem_display == 3) + return; + if(NeutrinoMessages::mode_ts == CNeutrinoApp::getInstance()->getMode() && !CMoviePlayerGui::getInstance().timeshift){ + if (g_settings.casystem_display == 2) { + fta = true; + showOne_CAIcon(); + } + return; + } + int caids[] = { 0x900, 0xD00, 0xB00, 0x1800, 0x0500, 0x0100, 0x600, 0x2600, 0x4a00, 0x0E00 }; const char * white = (char *) "white"; const char * yellow = (char *) "yellow"; int icon_space_offset = 0; - if (g_settings.casystem_display == 3) - return; - if(!g_InfoViewer->chanready) { if (g_settings.casystem_display == 2) { fta = true; 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 409d0ddd4..af9c630ed 100644 --- a/src/gui/miscsettings_menu.cpp +++ b/src/gui/miscsettings_menu.cpp @@ -227,7 +227,8 @@ int CMiscMenue::showMiscSettingsMenu() int res = misc_menue.exec(NULL, ""); delete fanNotifier; delete sectionsdConfigNotifier; - delete miscNotifier; + if(cs_get_revision() > 7) + delete miscNotifier; return res; } @@ -251,7 +252,6 @@ void CMiscMenue::showMiscSettingsMenuGeneral(CMenuWidget *ms_general) CMenuOptionNumberChooser * mn = new CMenuOptionNumberChooser(LOCALE_FAN_SPEED, &g_settings.fan_speed, true, 1, 14, fanNotifier, 0, 0, LOCALE_OPTIONS_OFF); mn->setHint("", LOCALE_MENU_HINT_FAN_SPEED); ms_general->addItem(mn); - fanNotifier->changeNotify(NONEXISTANT_LOCALE, (void*) &g_settings.fan_speed); } //rotor diff --git a/src/gui/motorcontrol.cpp b/src/gui/motorcontrol.cpp index 8b43f99f5..627535772 100644 --- a/src/gui/motorcontrol.cpp +++ b/src/gui/motorcontrol.cpp @@ -308,7 +308,7 @@ int CMotorControl::exec(CMenuTarget* parent, const std::string &) default: //printf("[motorcontrol] message received...\n"); if ((msg >= CRCInput::RC_WithData) && (msg < CRCInput::RC_WithData + 0x10000000)) - delete (unsigned char*) data; + delete[] (unsigned char*) data; break; } } @@ -424,7 +424,7 @@ int CMotorControl::exec(CMenuTarget* parent, const std::string &) default: //printf("[motorcontrol] message received...\n"); if ((msg >= CRCInput::RC_WithData) && (msg < CRCInput::RC_WithData + 0x10000000)) - delete (unsigned char*) data; + delete[] (unsigned char*) data; break; } } diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index b651122ee..1fd5de186 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -1120,7 +1120,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 || @@ -1631,7 +1631,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 @@ -2059,7 +2059,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/movieplayer.cpp b/src/gui/movieplayer.cpp index 9839f1f0d..14df92259 100644 --- a/src/gui/movieplayer.cpp +++ b/src/gui/movieplayer.cpp @@ -697,6 +697,9 @@ void CMoviePlayerGui::callInfoViewer(const int duration, const int curr_pos) CNeutrinoApp::getInstance()->channelList->getActiveChannel_ChannelID()); return; } + currentaudioname = "Unk"; + getCurrentAudioName( is_file_player, currentaudioname); + if (isMovieBrowser && p_movie_info) { g_InfoViewer->showMovieTitle(playstate, p_movie_info->epgChannel, p_movie_info->epgTitle, p_movie_info->epgInfo1, duration, curr_pos); @@ -721,6 +724,76 @@ bool CMoviePlayerGui::getAudioName(int apid, std::string &apidtitle) return false; } +void CMoviePlayerGui::addAudioFormat(int count, std::string &apidtitle, bool file_player, bool& enabled) +{ + enabled = true; + switch(ac3flags[count]) + { + case 1: /*AC3,EAC3*/ + if (apidtitle.find("AC3") == std::string::npos || file_player) + apidtitle.append(" (AC3)"); + break; + case 2: /*teletext*/ + apidtitle.append(" (Teletext)"); + enabled = false; + break; + case 3: /*MP2*/ + apidtitle.append("( MP2)"); + break; + case 4: /*MP3*/ + apidtitle.append(" (MP3)"); + break; + case 5: /*AAC*/ + apidtitle.append(" (AAC)"); + break; + case 6: /*DTS*/ + apidtitle.append(" (DTS)"); + enabled = false; + break; + case 7: /*MLP*/ + apidtitle.append(" (MLP)"); + break; + default: + break; + } +} + +void CMoviePlayerGui::getCurrentAudioName( bool file_player, std::string &audioname) +{ + if(file_player && !numpida){ + playback->FindAllPids(apids, ac3flags, &numpida, language); + if(numpida) + currentapid = apids[0]; + } + bool dumm = true; + for (unsigned int count = 0; count < numpida; count++) { + + if(currentapid == apids[count]){ + if(!file_player){ + getAudioName(apids[count], audioname); + return ; + }else if (!language[count].empty()){ + audioname = language[count]; + addAudioFormat(count, audioname, file_player, dumm); + if(!dumm && (count < numpida)){ + currentapid = apids[count+1]; + continue; + } + return ; + } + char apidnumber[20]; + sprintf(apidnumber, "Stream %d %X", count + 1, apids[count]); + audioname = apidnumber; + addAudioFormat(count, audioname, file_player, dumm); + if(!dumm && (count < numpida)){ + currentapid = apids[count+1]; + continue; + } + return ; + } + } +} + void CMoviePlayerGui::selectAudioPid(bool file_player) { CMenuWidget APIDSelector(LOCALE_APIDSELECTOR_HEAD, NEUTRINO_ICON_AUDIO); @@ -731,7 +804,6 @@ void CMoviePlayerGui::selectAudioPid(bool file_player) if(file_player && !numpida){ playback->FindAllPids(apids, ac3flags, &numpida, language); - /* fix current pid in case of file play */ if(numpida) currentapid = apids[0]; } @@ -753,36 +825,12 @@ void CMoviePlayerGui::selectAudioPid(bool file_player) sprintf(apidnumber, "Stream %d %X", count + 1, apids[count]); apidtitle = apidnumber; } - - switch(ac3flags[count]) - { - case 1: /*AC3,EAC3*/ - if (apidtitle.find("AC3") == std::string::npos || file_player) - apidtitle.append(" (AC3)"); - break; - case 2: /*teletext*/ - apidtitle.append(" (Teletext)"); - enabled = false; - break; - case 3: /*MP2*/ - apidtitle.append("( MP2)"); - break; - case 4: /*MP3*/ - apidtitle.append(" (MP3)"); - break; - case 5: /*AAC*/ - apidtitle.append(" (AAC)"); - break; - case 6: /*DTS*/ - apidtitle.append(" (DTS)"); - enabled = false; - break; - case 7: /*MLP*/ - apidtitle.append(" (MLP)"); - break; - default: - break; + addAudioFormat(count, apidtitle, file_player, enabled); + if(defpid && !enabled && (count < numpida)){ + currentapid = apids[count+1]; + defpid = false; } + char cnt[5]; sprintf(cnt, "%d", count); CMenuForwarderNonLocalized * item = new CMenuForwarderNonLocalized(apidtitle.c_str(), enabled, NULL, selector, cnt, CRCInput::convertDigitToKey(count + 1)); @@ -800,7 +848,7 @@ void CMoviePlayerGui::selectAudioPid(bool file_player) APIDSelector.addItem(new CMenuOptionNumberChooser(NONEXISTANT_LOCALE, &percent[i], currentapid == apids[i], 0, 999, CVolume::getInstance(), 0, 0, NONEXISTANT_LOCALE, - g_RemoteControl->current_PIDs.APIDs[i].desc)); + p_movie_info->audioPids[i].epgAudioPidName.c_str())); } } diff --git a/src/gui/movieplayer.h b/src/gui/movieplayer.h index 1ede8b215..31125f1a1 100644 --- a/src/gui/movieplayer.h +++ b/src/gui/movieplayer.h @@ -69,7 +69,7 @@ class CMoviePlayerGui : public CMenuTarget std::string full_name; std::string file_name; - + std::string currentaudioname; bool playing; CMoviePlayerGui::state playstate; int speed; @@ -112,6 +112,8 @@ class CMoviePlayerGui : public CMenuTarget void fillPids(); bool getAudioName(int pid, std::string &apidtitle); void selectAudioPid(bool file_player); + void getCurrentAudioName( bool file_player, std::string &audioname); + void addAudioFormat(int count, std::string &apidtitle, bool file_player, bool& enabled ); void handleMovieBrowser(neutrino_msg_t msg, int position = 0); bool SelectFile(); @@ -127,6 +129,7 @@ class CMoviePlayerGui : public CMenuTarget int exec(CMenuTarget* parent, const std::string & actionKey); bool Playing() { return playing; }; + std::string CurrentAudioName() { return currentaudioname; }; int timeshift; int file_prozent; }; diff --git a/src/gui/network_service.cpp b/src/gui/network_service.cpp index 23ca4bc48..b2971471e 100644 --- a/src/gui/network_service.cpp +++ b/src/gui/network_service.cpp @@ -56,7 +56,7 @@ static struct network_service services[SERVICE_COUNT] = { "FTP", "vsftpd", "", LOCALE_MENU_HINT_NET_FTPD, "", 0 }, { "Telnet", "telnetd", "-l/bin/login", LOCALE_MENU_HINT_NET_TELNET, "", 0 }, { "DjMount", "djmount", "-o iocharset=utf8 /media/00upnp/", LOCALE_MENU_HINT_NET_DJMOUNT, "", 0 }, - { "uShare", "ushare", "-D", LOCALE_MENU_HINT_NET_USHARE, "", 0 } + { "uShare", "ushare", "-D -n `cat /etc/hostname`", LOCALE_MENU_HINT_NET_USHARE, "", 0 } }; CNetworkService::CNetworkService(std::string cmd, std::string opts) @@ -72,8 +72,9 @@ CNetworkService::CNetworkService(std::string cmd, std::string opts) void CNetworkService::Start() { + std::string cmd = command + " " + options; printf("CNetworkService::Start: %s %s\n", command.c_str(), options.c_str()); - my_system( command.c_str(), options.c_str()); + my_system("/bin/sh", "-c", cmd.c_str()); enabled = true; TouchFile(); } 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/osd_setup.cpp b/src/gui/osd_setup.cpp index 82a6df825..5df9e9a6b 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -65,8 +65,6 @@ extern std::string ttx_font_file; COsdSetup::COsdSetup(bool wizard_mode) { colorSetupNotifier = new CColorSetupNotifier(); - colorSetupNotifier->changeNotify(NONEXISTANT_LOCALE, NULL); - fontsizenotifier = new CFontSizeNotifier; osd_menu = NULL; @@ -890,19 +888,30 @@ int COsdSetup::showContextChanlistMenu() menu_chanlist->enableFade(false); menu_chanlist->setSelected(cselected); - menu_chanlist->addIntroItems(LOCALE_MISCSETTINGS_CHANNELLIST, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL); + menu_chanlist->addIntroItems(LOCALE_MISCSETTINGS_CHANNELLIST);//, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL); - menu_chanlist->addItem(new CMenuOptionChooser(LOCALE_MISCSETTINGS_CHANNELLIST_EPGTEXT_ALIGN, &g_settings.channellist_epgtext_align_right, CHANNELLIST_EPGTEXT_ALIGN_RIGHT_OPTIONS, CHANNELLIST_EPGTEXT_ALIGN_RIGHT_OPTIONS_COUNT, true)); - menu_chanlist->addItem(new CMenuOptionChooser(LOCALE_CHANNELLIST_EXTENDED, &g_settings.channellist_extended, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true)); - menu_chanlist->addItem(new CMenuOptionChooser(LOCALE_CHANNELLIST_FOOT, &g_settings.channellist_foot, CHANNELLIST_FOOT_OPTIONS, CHANNELLIST_FOOT_OPTIONS_COUNT, true)); - menu_chanlist->addItem(new CMenuOptionChooser(LOCALE_MISCSETTINGS_CHANNELLIST_COLORED_EVENTS, &g_settings.colored_events_channellist, OPTIONS_COLORED_EVENTS_OPTIONS, OPTIONS_COLORED_EVENTS_OPTION_COUNT, true)); + CMenuOptionChooser * mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_CHANNELLIST_EPGTEXT_ALIGN, &g_settings.channellist_epgtext_align_right, CHANNELLIST_EPGTEXT_ALIGN_RIGHT_OPTIONS, CHANNELLIST_EPGTEXT_ALIGN_RIGHT_OPTIONS_COUNT, true); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_EPG_ALIGN); + menu_chanlist->addItem(mc); + + mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_EXTENDED, &g_settings.channellist_extended, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_EXTENDED); + menu_chanlist->addItem(mc); + + mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_FOOT, &g_settings.channellist_foot, CHANNELLIST_FOOT_OPTIONS, CHANNELLIST_FOOT_OPTIONS_COUNT, true); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_FOOT); + menu_chanlist->addItem(mc); + + mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_CHANNELLIST_COLORED_EVENTS, &g_settings.colored_events_channellist, OPTIONS_COLORED_EVENTS_OPTIONS, OPTIONS_COLORED_EVENTS_OPTION_COUNT, true); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_COLORED); + menu_chanlist->addItem(mc); CMenuWidget *fontSettingsSubMenu = new CMenuWidget(LOCALE_FONTMENU_HEAD, NEUTRINO_ICON_KEYBINDING); fontSettingsSubMenu->enableSaveScreen(true); fontSettingsSubMenu->enableFade(false); int i = 1; - fontSettingsSubMenu->addIntroItems(font_sizes_groups[i].groupname, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL); + fontSettingsSubMenu->addIntroItems(font_sizes_groups[i].groupname);//, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL); for (unsigned int j = 0; j < font_sizes_groups[i].count; j++) { @@ -910,7 +919,10 @@ int COsdSetup::showContextChanlistMenu() } fontSettingsSubMenu->addItem(GenericMenuSeparatorLine); fontSettingsSubMenu->addItem(new CMenuForwarder(LOCALE_OPTIONS_DEFAULT, true, NULL, this, font_sizes_groups[i].actionkey)); - menu_chanlist->addItem(new CMenuDForwarder(LOCALE_FONTMENU_HEAD, true, NULL, fontSettingsSubMenu, "", CRCInput::convertDigitToKey(0))); + + CMenuForwarder * mf = new CMenuDForwarder(LOCALE_FONTMENU_HEAD, true, NULL, fontSettingsSubMenu, NULL, CRCInput::RC_green, NEUTRINO_ICON_BUTTON_GREEN); + mf->setHint("", LOCALE_MENU_HINT_FONTS); + menu_chanlist->addItem(mf); int res = menu_chanlist->exec(NULL, ""); cselected = menu_chanlist->getSelected(); 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 4d2d1586c..3165df49b 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) { @@ -226,6 +234,9 @@ int CPictureViewerGui::show() paint(); } + 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/rc_lock.cpp b/src/gui/rc_lock.cpp index 51e12a12d..2b7177692 100644 --- a/src/gui/rc_lock.cpp +++ b/src/gui/rc_lock.cpp @@ -38,6 +38,7 @@ #include const std::string CRCLock::NO_USER_INPUT = "noUserInput"; +bool CRCLock::locked = false; // -- Menue Handler Interface // -- Infinite Loop to lock remote control (until release lock key pressed) @@ -45,6 +46,9 @@ const std::string CRCLock::NO_USER_INPUT = "noUserInput"; int CRCLock::exec(CMenuTarget* parent, const std::string &actionKey) { + if(locked) + return menu_return::RETURN_EXIT_ALL; + if (parent) parent->hide(); @@ -55,7 +59,9 @@ int CRCLock::exec(CMenuTarget* parent, const std::string &actionKey) return menu_return::RETURN_EXIT_ALL; // -- Lockup Box + locked = true; lockBox(); + locked = false; ShowLocalizedMessage(LOCALE_RCLOCK_TITLE, LOCALE_RCLOCK_UNLOCKMSG, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO,450, no_input ? 5 : -1); return menu_return::RETURN_EXIT_ALL; diff --git a/src/gui/rc_lock.h b/src/gui/rc_lock.h index 4e6ea758c..bd32757d0 100644 --- a/src/gui/rc_lock.h +++ b/src/gui/rc_lock.h @@ -36,12 +36,13 @@ // class CRCLock: public CMenuTarget { +private: + void lockBox(); public: static const std::string NO_USER_INPUT; int exec(CMenuTarget* parent, const std::string & actionKey); - void lockBox(); + static bool locked; }; - #endif diff --git a/src/gui/record_setup.cpp b/src/gui/record_setup.cpp index aced80cda..599754ece 100644 --- a/src/gui/record_setup.cpp +++ b/src/gui/record_setup.cpp @@ -199,6 +199,10 @@ int CRecordSetup::showRecordSetup() end_of_recording->setHint("", LOCALE_MENU_HINT_RECORD_END); recordingSettings->addItem(end_of_recording); + CMenuOptionChooser* slow_warn = new CMenuOptionChooser(LOCALE_RECORDINGMENU_SLOW_WARN, &g_settings.recording_slow_warning, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); + slow_warn->setHint("", LOCALE_MENU_HINT_RECORD_SLOW_WARN); + recordingSettings->addItem(slow_warn); + //template //CStringInput recordingSettings_filenameTemplate(LOCALE_RECORDINGMENU_FILENAME_TEMPLATE, &g_settings.recording_filename_template[0], 21, LOCALE_RECORDINGMENU_FILENAME_TEMPLATE_HINT, LOCALE_IPSETUP_HINT_2, "%/-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "); //CMenuForwarder* mf11 = new CMenuForwarder(LOCALE_RECORDINGMENU_FILENAME_TEMPLATE, true, g_settings.recording_filename_template[0], &recordingSettings_filenameTemplate); diff --git a/src/gui/scan.cpp b/src/gui/scan.cpp index e11f0c099..e3b50c908 100644 --- a/src/gui/scan.cpp +++ b/src/gui/scan.cpp @@ -431,7 +431,7 @@ int CScanTs::handleMsg(neutrino_msg_t msg, neutrino_msg_data_t data) break; default: if ((msg >= CRCInput::RC_WithData) && (msg < CRCInput::RC_WithData + 0x10000000)) - delete (unsigned char*) data; + delete[] (unsigned char*) data; break; } return msg; diff --git a/src/gui/start_wizard.cpp b/src/gui/start_wizard.cpp index 29a4ef9fe..991835987 100644 --- a/src/gui/start_wizard.cpp +++ b/src/gui/start_wizard.cpp @@ -99,13 +99,10 @@ 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 = file_exists("/var/tuxbox/config/initial/"); + bool init_settings = false; + if (g_info.delivery_system == DVB_S) + init_settings = file_exists("/var/tuxbox/config/initial/"); + if(init_settings && (res != menu_return::RETURN_EXIT_ALL)) { if (ShowMsgUTF(LOCALE_WIZARD_INITIAL_SETTINGS, g_Locale->getText(LOCALE_WIZARD_INSTALL_SETTINGS), @@ -116,9 +113,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/streaminfo2.cpp b/src/gui/streaminfo2.cpp index d5e969656..94357d8b6 100644 --- a/src/gui/streaminfo2.cpp +++ b/src/gui/streaminfo2.cpp @@ -447,6 +447,8 @@ void CStreamInfo2::paint_techinfo(int xpos, int ypos) int spaceoffset = 0,i = 0; int ypos1 = ypos; int box_width = width*2/3 - 10; + + yypos = ypos; if(box_h > 0) frameBuffer->paintBoxRel (0, ypos, box_width, box_h, COL_MENUHEAD_PLUS_0); diff --git a/src/gui/timerlist.cpp b/src/gui/timerlist.cpp index f5835073f..406e10ef5 100644 --- a/src/gui/timerlist.cpp +++ b/src/gui/timerlist.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -571,9 +572,32 @@ int CTimerList::show() } else if ((msg == CRCInput::RC_red) && !(timerlist.empty())) { - Timer->removeTimerEvent(timerlist[selected].eventID); - skipEventID=timerlist[selected].eventID; - update=true; + bool killTimer = true; + if (CRecordManager::getInstance()->RecordingStatus(timerlist[selected].channel_id)) { + CTimerd::RecordingStopInfo recinfo; + recinfo.channel_id = timerlist[selected].channel_id; + recinfo.eventID = timerlist[selected].eventID; + if (CRecordManager::getInstance()->IsRecording(&recinfo)) { + std::string title = ""; + char buf1[1024]; + CEPGData epgdata; + CEitManager::getInstance()->getEPGid(timerlist[selected].epgID, timerlist[selected].epg_starttime, &epgdata); + memset(buf1, '\0', sizeof(buf1)); + if (epgdata.title != "") + title = "(" + epgdata.title + ")\n"; + snprintf(buf1, sizeof(buf1)-1, g_Locale->getText(LOCALE_TIMERLIST_ASK_TO_DELETE), title.c_str()); + if(ShowMsgUTF(LOCALE_RECORDINGMENU_RECORD_IS_RUNNING, buf1, + CMessageBox::mbrYes, CMessageBox::mbYes | CMessageBox::mbNo, NULL, 450, 30, false) == CMessageBox::mbrNo) { + killTimer = false; + update = false; + } + } + } + if (killTimer) { + Timer->removeTimerEvent(timerlist[selected].eventID); + skipEventID=timerlist[selected].eventID; + update = true; + } } else if (msg==CRCInput::RC_green) { diff --git a/src/gui/update.cpp b/src/gui/update.cpp index d61b0f542..591dcaba9 100644 --- a/src/gui/update.cpp +++ b/src/gui/update.cpp @@ -35,6 +35,7 @@ #endif #include +#include #include #include @@ -450,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); @@ -518,6 +523,14 @@ CFlashExpert::CFlashExpert() width = w_max (40, 10); } +CFlashExpert* CFlashExpert::getInstance() +{ + static CFlashExpert* FlashExpert = NULL; + if(!FlashExpert) + FlashExpert = new CFlashExpert(); + return FlashExpert; +} + void CFlashExpert::readmtd(int preadmtd) { char tmpStr[256]; @@ -525,11 +538,11 @@ void CFlashExpert::readmtd(int preadmtd) gettimeofday(&tv, NULL); strftime(tmpStr, sizeof(tmpStr), "_%Y%m%d_%H%M.img", localtime(&tv.tv_sec)); CMTDInfo* mtdInfo = CMTDInfo::getInstance(); - std::string filename = "/tmp/" + mtdInfo->getMTDName(preadmtd); + std::string filename = (std::string)g_settings.update_dir + "/" + mtdInfo->getMTDName(preadmtd); filename += tmpStr; if (preadmtd == -1) { - filename = "/tmp/flashimage.img"; // US-ASCII (subset of UTF-8 and ISO8859-1) + filename = (std::string)g_settings.update_dir + "/flashimage.img"; // US-ASCII (subset of UTF-8 and ISO8859-1) preadmtd = MTD_OF_WHOLE_IMAGE; } setTitle(LOCALE_FLASHUPDATE_TITLEREADFLASH); @@ -558,7 +571,7 @@ void CFlashExpert::writemtd(const std::string & filename, int mtdNumber) { char message[500]; - sprintf(message, + snprintf(message, sizeof(message), g_Locale->getText(LOCALE_FLASHUPDATE_REALLYFLASHMTD), FILESYSTEM_ENCODING_TO_UTF8_STRING(filename).c_str(), CMTDInfo::getInstance()->getMTDName(mtdNumber).c_str()); @@ -576,7 +589,7 @@ void CFlashExpert::writemtd(const std::string & filename, int mtdNumber) CFlashTool ft; ft.setStatusViewer( this ); ft.setMTDDevice( CMTDInfo::getInstance()->getMTDFileName(mtdNumber) ); - if(!ft.program( "/tmp/" + filename, 50, 100)) { + if(!ft.program( (std::string)g_settings.update_dir + "/" + filename, 50, 100)) { showStatusMessageUTF(ft.getErrorMessage()); // UTF-8 sleep(10); } else { @@ -613,6 +626,8 @@ void CFlashExpert::showMTDSelector(const std::string & actionkey) sprintf(sActionKey, "%s%d", actionkey.c_str(), lx); mtdselector->addItem(new CMenuForwarderNonLocalized(mtdInfo->getMTDName(lx).c_str(), enabled, NULL, this, sActionKey, CRCInput::convertDigitToKey(shortcut++))); } + if (actionkey == "writemtd") + mtdselector->addItem(new CMenuForwarderNonLocalized("systemFS with settings", true, NULL, this, "writemtd10", CRCInput::convertDigitToKey(shortcut++))); mtdselector->exec(NULL,""); delete mtdselector; } @@ -623,7 +638,7 @@ void CFlashExpert::showFileSelector(const std::string & actionkey) fileselector->addIntroItems(LOCALE_FLASHUPDATE_FILESELECTOR, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL); struct dirent **namelist; - int n = scandir("/tmp", &namelist, 0, alphasort); + int n = scandir(g_settings.update_dir, &namelist, 0, alphasort); if (n < 0) { perror("no flashimages available"); @@ -678,7 +693,10 @@ int CFlashExpert::exec(CMenuTarget* parent, const std::string & actionKey) selectedMTD = iWritemtd; showFileSelector(""); } else { - if(selectedMTD==-1) { + if(selectedMTD == 10) { + CExtUpdate::getInstance()->applySettings(actionKey, CExtUpdate::MODE_EXPERT); + } + else if(selectedMTD==-1) { writemtd(actionKey, MTD_OF_WHOLE_IMAGE); } else { writemtd(actionKey, selectedMTD); diff --git a/src/gui/update.h b/src/gui/update.h index 6f85b9342..98122db86 100644 --- a/src/gui/update.h +++ b/src/gui/update.h @@ -74,11 +74,12 @@ class CFlashExpert : public CProgressWindow void showFileSelector(const std::string & actionkey); void readmtd(int readmtd); - void writemtd(const std::string & filename, int mtdNumber); public: CFlashExpert(); + static CFlashExpert* getInstance(); int exec(CMenuTarget* parent, const std::string & actionKey); + void writemtd(const std::string & filename, int mtdNumber); }; diff --git a/src/gui/user_menue.cpp b/src/gui/user_menue.cpp index 2aa65eed7..1318fe662 100644 --- a/src/gui/user_menue.cpp +++ b/src/gui/user_menue.cpp @@ -288,7 +288,7 @@ bool CUserMenu::showUserMenu(int button) menu_prev = SNeutrinoSettings::ITEM_TECHINFO; streamInfo = new CStreamInfo2(); keyhelper.get(&key,&icon,CRCInput::RC_blue); - menu_item = new CMenuForwarder(LOCALE_EPGMENU_STREAMINFO, true, NULL, streamInfo, "-1", key, icon ); + menu_item = new CMenuForwarder(LOCALE_EPGMENU_STREAMINFO, !CNeutrinoApp::getInstance()->channelList->isEmpty(), NULL, streamInfo, "-1", key, icon ); menu->addItem(menu_item, false); break; case SNeutrinoSettings::ITEM_GAMES: diff --git a/src/gui/widget/buttons.cpp b/src/gui/widget/buttons.cpp index bffb99a66..a97a5a3bc 100644 --- a/src/gui/widget/buttons.cpp +++ b/src/gui/widget/buttons.cpp @@ -132,7 +132,7 @@ int paintButtons( const int &x, //workaround for to small screen (1) int skip_last_button_txt = false; - if( (w_footer > 0) && ( (w_button*cnt) > (uint) w_footer) ){ + if( (w_footer > 0) && ( ((w_button*cnt) + ((cnt -1) * w_space)) > (uint) w_footer) ){ w_button= ((w_footer+w_max_icon)/(cnt)); skip_last_button_txt = true; } diff --git a/src/gui/widget/components.cpp b/src/gui/widget/components.cpp index 52f64db69..be43e39b5 100644 --- a/src/gui/widget/components.cpp +++ b/src/gui/widget/components.cpp @@ -275,7 +275,7 @@ void CComponentsInfoBox::hide() col_body = col_frame = col_shadow = COL_BACKGROUND; //paint with background and restore, set last used colors - paint(false); + paint(false, true); col_body = c_tmp1; col_shadow = c_tmp2; col_frame = c_tmp3; diff --git a/src/gui/widget/components.h b/src/gui/widget/components.h index 78f2bed53..c7ec2586a 100644 --- a/src/gui/widget/components.h +++ b/src/gui/widget/components.h @@ -80,7 +80,7 @@ class CComponentsDetailLine : public CComponents fb_pixel_t color_line = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); ~CComponentsDetailLine(); - void paint(bool do_save_bg = true); + void paint(bool do_save_bg = false); void hide(); void setColor(fb_pixel_t color_line, fb_pixel_t color_shadow){col_line = color_line; col_shadow = color_shadow;}; void setYPosDown(const int& y_pos_down){y_down = y_pos_down;}; @@ -101,7 +101,7 @@ class CComponentsInfoBox : public CComponents CComponentsInfoBox( const int x_pos, const int y_pos, const int w, const int h, bool has_shadow = true, fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, fb_pixel_t color_body = COL_MENUCONTENTDARK_PLUS_0,fb_pixel_t color_shadow = COL_MENUCONTENTDARK_PLUS_0); - void paint(bool do_save_bg = true, bool fullPaint = false); + void paint(bool do_save_bg = false, bool fullPaint = false); void hide(); void restore(bool clear_ = true); void setColor(fb_pixel_t color_frame, fb_pixel_t color_body, fb_pixel_t color_shadow){col_frame = color_frame; col_body = color_body; col_shadow = color_shadow;}; 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/menue.cpp b/src/gui/widget/menue.cpp index 23af427ce..3b6389265 100644 --- a/src/gui/widget/menue.cpp +++ b/src/gui/widget/menue.cpp @@ -491,10 +491,14 @@ int CMenuWidget::exec(CMenuTarget* parent, const std::string &) } } } +#if 0 GenericMenuBack->setHint("", NONEXISTANT_LOCALE); +#endif checkHints(); +#if 0 if (has_hints) GenericMenuBack->setHint(NEUTRINO_ICON_HINT_BACK, LOCALE_MENU_HINT_BACK); +#endif if(savescreen) { calcSize(); @@ -758,8 +762,9 @@ void CMenuWidget::hide() restoreScreen();//FIXME else { frameBuffer->paintBackgroundBoxRel(x, y, full_width, full_height); - paintHint(-1); + //paintHint(-1); } + paintHint(-1); /* setActive() paints item for hidden parent menu, if called from child menu */ for (unsigned int count = 0; count < items.size(); count++) @@ -878,8 +883,8 @@ void CMenuWidget::calcSize() if(total_pages > 1) sb_width=15; - full_width = ConnectLineBox_Width+width+sb_width+SHADOW_OFFSET; - full_height = height+RADIUS_LARGE+SHADOW_OFFSET*2+hint_height+INFO_BOX_Y_OFFSET; + full_width = /*ConnectLineBox_Width+*/width+sb_width+SHADOW_OFFSET; + full_height = height+RADIUS_LARGE+SHADOW_OFFSET*2 /*+hint_height+INFO_BOX_Y_OFFSET*/; setMenuPos(width - sb_width); } @@ -1039,14 +1044,14 @@ void CMenuWidget::saveScreen() background = new fb_pixel_t [full_width * full_height]; if(background) - frameBuffer->SaveScreen(x-ConnectLineBox_Width, y, full_width, full_height, background); + frameBuffer->SaveScreen(x /*-ConnectLineBox_Width*/, y, full_width, full_height, background); } void CMenuWidget::restoreScreen() { if(background) { if(savescreen) - frameBuffer->RestoreScreen(x-ConnectLineBox_Width, y, full_width, full_height, background); + frameBuffer->RestoreScreen(x /*-ConnectLineBox_Width*/, y, full_width, full_height, background); } } @@ -1075,12 +1080,22 @@ void CMenuWidget::paintHint(int pos) if (hint_painted) { /* clear detailsline line */ - if (details_line != NULL) - details_line->restore(); + // TODO CComponents::hide with param restore ? or auto (if it have saved screens) ? + if (details_line != NULL) { + if (savescreen) + details_line->restore(); + else + details_line->hide(); + } /* clear info box */ - if (info_box != NULL) - if (pos == -1) - info_box->restore(); + if (info_box != NULL) { + if (pos == -1) { + if (savescreen) + info_box->restore(); + else + info_box->hide(); + } + } hint_painted = false; } if (pos < 0) @@ -1090,8 +1105,12 @@ void CMenuWidget::paintHint(int pos) //printf("paintHint: icon %s text %s\n", item->hintIcon.c_str(), g_Locale->getText(item->hint)); if (item->hintIcon.empty() && item->hint == NONEXISTANT_LOCALE) { - if (info_box != NULL) - info_box->restore(); + if (info_box != NULL) { + if (savescreen) + info_box->restore(); + else + info_box->hide(); + } return; } @@ -1114,7 +1133,7 @@ void CMenuWidget::paintHint(int pos) details_line->setYPosDown(ypos2a); details_line->setHMarkDown(markh); } - details_line->paint(); + details_line->paint(savescreen); if (info_box == NULL) info_box = new CComponentsInfoBox(x, ypos2, iwidth, hint_height); @@ -1123,7 +1142,8 @@ void CMenuWidget::paintHint(int pos) info_box->setYPos(ypos2); info_box->setWidth(iwidth); } - info_box->paint(); + /* force full paint - menu-over i.e. option chooser with pulldown can overwrite */ + info_box->paint(savescreen, true); int offset = 10; if (!item->hintIcon.empty()) { diff --git a/src/gui/widget/msgbox.cpp b/src/gui/widget/msgbox.cpp index 032b4877e..6d797df8d 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 c5267ae64..fa8dff4e4 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 064461be3..276cc131c 100644 --- a/src/gui/widget/stringinput.cpp +++ b/src/gui/widget/stringinput.cpp @@ -169,7 +169,7 @@ void CStringInput::init() } mheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(); iheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_INFO]->getHeight(); - footerHeight = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight()+8; //initial height value for buttonbar + //footerHeight = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight()+8; //initial height value for buttonbar height = hheight+ mheight + 50; if (hint_1 != NONEXISTANT_LOCALE) { @@ -525,7 +525,7 @@ int CStringInput::handleOthers(const neutrino_msg_t /*msg*/, const neutrino_msg_ void CStringInput::hide() { - frameBuffer->paintBackgroundBoxRel(x, y, width, height + footerHeight); + frameBuffer->paintBackgroundBoxRel(x, y, width, height + hheight); } const char * CStringInput::getHint1(void) @@ -755,7 +755,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); diff --git a/src/gui/widget/stringinput.h b/src/gui/widget/stringinput.h index 0a5a5aea9..8834f3914 100644 --- a/src/gui/widget/stringinput.h +++ b/src/gui/widget/stringinput.h @@ -51,7 +51,6 @@ class CStringInput : public CMenuTarget int hheight; // head font height int mheight; // menu font height int iheight; - int footerHeight; int lower_bound; int upper_bound; diff --git a/src/gui/widget/stringinput_ext.cpp b/src/gui/widget/stringinput_ext.cpp index 2f80729bc..44f29523f 100644 --- a/src/gui/widget/stringinput_ext.cpp +++ b/src/gui/widget/stringinput_ext.cpp @@ -516,7 +516,6 @@ void CDateInput::onBeforeExec() sprintf( value, "%02d.%02d.%04d %02d:%02d", tmTime->tm_mday, tmTime->tm_mon+1, tmTime->tm_year+1900, tmTime->tm_hour, tmTime->tm_min); - dst = tmTime->tm_isdst; } void CDateInput::onAfterExec() @@ -529,7 +528,6 @@ void CDateInput::onAfterExec() tmTime.tm_year -= 1900; tmTime.tm_sec = 0; - //tmTime.tm_isdst = dst; tmTime.tm_isdst = -1; if(tmTime.tm_year>129) diff --git a/src/gui/widget/stringinput_ext.h b/src/gui/widget/stringinput_ext.h index 42b632391..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;}; @@ -167,7 +167,6 @@ class CDateInput : public CExtendedInput { private: time_t* time; - int dst; protected: virtual void onBeforeExec(); diff --git a/src/gui/widget/textbox.cpp b/src/gui/widget/textbox.cpp index 3bab0f7ce..fb19beddb 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,54 @@ 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 = NULL; + 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 +196,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 +241,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 +309,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 +325,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_nMaxWidth) +// lineBreakWidth = m_nMaxWidth; + + //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 +367,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 +389,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 +415,9 @@ void CTextBox::refreshTextLineArray(void) aktLine = ""; aktWidth = 0; m_nNrOfNewLine++; - if(pos_prev >= TextChars) loop = false; + + if(pos_prev >= TextChars) + loop = false; } } } @@ -375,7 +426,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 +443,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 +458,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) { @@ -438,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; @@ -468,10 +540,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) { @@ -487,10 +561,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) { @@ -506,25 +582,30 @@ 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; + if (max_width>0) + 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; @@ -534,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 = NULL; } diff --git a/src/gui/widget/textbox.h b/src/gui/widget/textbox.h index a308d05f9..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); @@ -147,11 +168,16 @@ class CTextBox void scrollPageDown(const int pages); void scrollPageUp(const int pages); void enableBackgroundPaint(bool mode = true){m_nPaintBackground = mode;}; - bool setText(const std::string* newText, int _max_width = 0); + 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 f8e18168c..6a68b0704 100644 --- a/src/gui/zapit_setup.cpp +++ b/src/gui/zapit_setup.cpp @@ -39,6 +39,8 @@ CZapitSetup::CZapitSetup() { + zapit1 = NULL; + zapit2 = NULL; width = w_max (40, 10); //% } diff --git a/src/neutrino.cpp b/src/neutrino.cpp index c4a143e2c..83c0bd580 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include "gui/audioplayer.h" #include "gui/bouquetlist.h" @@ -133,10 +134,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 ; @@ -188,27 +185,6 @@ extern const char * locale_real_names[]; /* #include */ // USERMENU const char* usermenu_button_def[SNeutrinoSettings::BUTTON_MAX]={"red","green","yellow","blue"}; -static void initGlobals(void) -{ - g_fontRenderer = NULL; - - g_RCInput = NULL; - g_Timerd = NULL; - g_RemoteControl = NULL; - - g_EpgData = NULL; - g_InfoViewer = NULL; - g_EventList = NULL; - g_videoSettings = NULL; - - g_Locale = new CLocaleManager; - g_PluginList = NULL; - InfoClock = NULL; - g_CamHandler = NULL; - g_Radiotext = NULL; - g_volume = NULL; -} - /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + CNeutrinoApp - Constructor, initialize g_fontRenderer + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ @@ -227,6 +203,7 @@ CNeutrinoApp::CNeutrinoApp() TVchannelList = NULL; RADIOchannelList = NULL; skipShutdownTimer = false; + skipSleepTimer = false; current_muted = 0; recordingstatus = 0; g_channel_list_changed = 0; @@ -567,7 +544,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); @@ -582,14 +561,15 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.recording_stopsectionsd = configfile.getBool("recording_stopsectionsd" , false ); g_settings.recording_audio_pids_default = configfile.getInt32("recording_audio_pids_default", TIMERD_APIDS_STD | TIMERD_APIDS_AC3); g_settings.recording_zap_on_announce = configfile.getBool("recording_zap_on_announce" , false); - g_settings.shutdown_timer_record_type = configfile.getBool("shutdown_timer_record_type" , false); + g_settings.shutdown_timer_record_type = configfile.getBool("shutdown_timer_record_type" , false); g_settings.recording_stream_vtxt_pid = configfile.getBool("recordingmenu.stream_vtxt_pid" , false); g_settings.recording_stream_pmt_pid = configfile.getBool("recordingmenu.stream_pmt_pid" , false); g_settings.recording_choose_direct_rec_dir = configfile.getInt32( "recording_choose_direct_rec_dir", 0 ); g_settings.recording_epg_for_filename = configfile.getBool("recording_epg_for_filename" , true); g_settings.recording_epg_for_end = configfile.getBool("recording_epg_for_end" , false); - g_settings.recording_save_in_channeldir = configfile.getBool("recording_save_in_channeldir" , false); + g_settings.recording_save_in_channeldir = configfile.getBool("recording_save_in_channeldir" , false); + g_settings.recording_slow_warning = configfile.getBool("recording_slow_warning" , true); // default plugin for movieplayer g_settings.movieplayer_plugin = configfile.getString( "movieplayer_plugin", "Teletext" ); @@ -1004,6 +984,7 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setBool ("recording_epg_for_filename" , g_settings.recording_epg_for_filename ); configfile.setBool ("recording_epg_for_end" , g_settings.recording_epg_for_end ); configfile.setBool ("recording_save_in_channeldir" , g_settings.recording_save_in_channeldir ); + configfile.setBool ("recording_slow_warning" , g_settings.recording_slow_warning ); // default plugin for movieplayer configfile.setString ( "movieplayer_plugin", g_settings.movieplayer_plugin ); @@ -1261,16 +1242,6 @@ void CNeutrinoApp::channelsInit(bool bOnly) } } printf("[neutrino] created %s bouquet with %d TV and %d RADIO channels\n", sit->second.name.c_str(), tvi, ri); -#if 0 - if(tvi) - tmp1->channelList->SortAlpha(); - else - TVsatList->deleteBouquet(tmp1); - if(ri) - tmp2->channelList->SortAlpha(); - else - RADIOsatList->deleteBouquet(tmp2); -#endif if(!tvi) TVsatList->deleteBouquet(tmp1); if(!ri) @@ -1618,13 +1589,10 @@ void CNeutrinoApp::InitZapper() channelsInit(); if(tvmode) - { tvMode(true); - } else { - g_RCInput->killTimer(g_InfoViewer->lcdUpdateTimer); - g_InfoViewer->lcdUpdateTimer = g_RCInput->addTimer( LCD_UPDATE_TIME_RADIO_MODE, false ); + else radioMode(true); - } + if(g_settings.cacheTXT) tuxtxt_init(); @@ -1677,11 +1645,6 @@ void CNeutrinoApp::InitZapitClient() CZapitClient::EVT_ZAP_SUB_COMPLETE, CZapitClient::EVT_ZAP_SUB_FAILED, CZapitClient::EVT_ZAP_MOTOR, -#if 0 - CZapitClient::EVT_ZAP_CA_CLEAR, - CZapitClient::EVT_ZAP_CA_LOCK, - CZapitClient::EVT_ZAP_CA_FTA, -#endif CZapitClient::EVT_ZAP_CA_ID, CZapitClient::EVT_RECORDMODE_ACTIVATED, CZapitClient::EVT_RECORDMODE_DEACTIVATED, @@ -1697,9 +1660,6 @@ void CNeutrinoApp::InitZapitClient() CZapitClient::EVT_BOUQUETS_CHANGED, CZapitClient::EVT_SERVICES_CHANGED, CZapitClient::EVT_SCAN_SERVICENAME, -#if 0 - CZapitClient::EVT_SCAN_FOUND_A_CHAN, -#endif CZapitClient::EVT_SCAN_FOUND_TV_CHAN, CZapitClient::EVT_SCAN_FOUND_RADIO_CHAN, CZapitClient::EVT_SCAN_FOUND_DATA_CHAN, @@ -1747,10 +1707,9 @@ void wake_up( bool &wakeup) } printf("[timerd] wakeup from standby: %s\n", wakeup ? "yes" : "no"); if(!wakeup){ - const char *neutrino_leave_deepstandby_script = CONFIGDIR "/deepstandby.off"; - printf("[%s] executing %s\n",__FILE__ ,neutrino_leave_deepstandby_script); - if (my_system(neutrino_leave_deepstandby_script) != 0) - perror( neutrino_leave_deepstandby_script ); + puts("[neutrino.cpp] executing " NEUTRINO_LEAVE_DEEPSTANDBY_SCRIPT "."); + if (my_system(NEUTRINO_LEAVE_DEEPSTANDBY_SCRIPT) != 0) + perror(NEUTRINO_LEAVE_DEEPSTANDBY_SCRIPT " failed"); } #endif @@ -1764,6 +1723,8 @@ TIMER_START(); cs_api_init(); cs_register_messenger(CSSendMessage); + g_Locale = new CLocaleManager; + int loadSettingsErg = loadSetup(NEUTRINO_SETTINGS_FILE); initialize_iso639_map(); @@ -1780,8 +1741,7 @@ TIMER_START(); SetupFonts(); SetupTiming(); g_PicViewer = new CPictureViewer(); - colorSetupNotifier = new CColorSetupNotifier; - colorSetupNotifier->changeNotify(NONEXISTANT_LOCALE, NULL); + CColorSetupNotifier::setPalette(); CHintBox * hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_NEUTRINO_STARTING)); hintBox->paint(); @@ -1853,17 +1813,14 @@ TIMER_START(); #endif dprintf(DEBUG_NORMAL, "g_info.has_fan: %d\n", g_info.has_fan); //fan speed - if (g_info.has_fan) { - CFanControlNotifier * funNotifier= new CFanControlNotifier(); - funNotifier->changeNotify(NONEXISTANT_LOCALE, (void*) &g_settings.fan_speed); - delete funNotifier; - } + if (g_info.has_fan) + CFanControlNotifier::setSpeed(g_settings.fan_speed); dvbsub_init(); 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; @@ -1884,9 +1841,6 @@ TIMER_START(); g_InfoViewer = new CInfoViewer; g_EventList = new CNeutrinoEventList; - int dx, dy; - frameBuffer->getIconSize(NEUTRINO_ICON_VOLUME, &dx, &dy); - g_CamHandler = new CCAMMenuHandler(); g_CamHandler->init(); @@ -1965,14 +1919,8 @@ void CNeutrinoApp::quickZap(int msg) int res; StopSubtitles(); -#if 0 - CRecordManager::getInstance()->StopAutoRecord(); - if(CRecordManager::getInstance()->RecordingStatus()) -#else - //if(recordingstatus && !autoshift) printf("CNeutrinoApp::quickZap haveFreeFrontend %d\n", CFEManager::getInstance()->haveFreeFrontend()); if(!CFEManager::getInstance()->haveFreeFrontend()) -#endif { res = channelList->numericZap(g_settings.key_zaphistory); StartSubtitles(res < 0); @@ -2166,6 +2114,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(); @@ -2255,13 +2230,6 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) if(g_settings.audio_AnalogMode < 0 || g_settings.audio_AnalogMode > 2) g_settings.audio_AnalogMode = 0; -#if 0 // per-channel auto volume save/restore - unsigned int volume; - g_Zapit->getVolume(&volume, &volume); - current_volume = 100 - volume*100/63; - printf("zapit volume %d new current %d mode %d\n", volume, current_volume, g_settings.audio_AnalogMode); - g_volume->setvol(current_volume); -#endif g_RCInput->killTimer(scrambled_timer); scrambled_timer = g_RCInput->addTimer(10*1000*1000, true); @@ -2289,7 +2257,7 @@ int CNeutrinoApp::handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data) if( res != messages_return::unhandled ) { if( ( msg>= CRCInput::RC_WithData ) && ( msg< CRCInput::RC_WithData+ 0x10000000 ) ) - delete (unsigned char*) data; + delete[] (unsigned char*) data; return( res & ( 0xFFFFFFFF - messages_return::unhandled ) ); } @@ -2345,7 +2313,7 @@ _repeat: SetChannelMode(old_mode); bouquetList->activateBouquet(old_b, false); if(!bouquetList->Bouquets.empty()) - bouquetList->Bouquets[old_b]->channelList->setSelected(old_num); + bouquetList->Bouquets[bouquetList->getActiveBouquetNumber()]->channelList->setSelected(old_num); StartSubtitles(mode == mode_tv); } else if(nNewChannel == -3) { // list mode changed @@ -2537,12 +2505,7 @@ _repeat: } #endif else if( msg == NeutrinoMessages::EVT_MUTECHANGED ) { -#if 0 - CControldMsg::commandMute* cmd = (CControldMsg::commandMute*) data; - if(cmd->type == (CControld::volume_type)g_settings.audio_avs_Control) - g_volume->AudioMute(cmd->mute, true ); - delete[] (unsigned char*) data; -#endif + //FIXME unused ? return messages_return::handled; } else if( msg == NeutrinoMessages::EVT_SERVICESCHANGED ) { @@ -2605,11 +2568,8 @@ _repeat: CTimerd::RecordingStopInfo* recinfo = (CTimerd::RecordingStopInfo*)data; printf("NeutrinoMessages::RECORD_STOP: eventID %d channel_id %llx\n", recinfo->eventID, recinfo->channel_id); CRecordManager::getInstance()->Stop(recinfo); -#if 0 // done when EVT_RECORDMODE received ? - if((mode == mode_standby) && !CRecordManager::getInstance()->RecordingStatus()) - cpuFreq->SetCpuFreq(g_settings.standby_cpufreq * 1000 * 1000); -#endif autoshift = CRecordManager::getInstance()->TimeshiftOnly(); + delete[] (unsigned char*) data; return messages_return::handled; } @@ -2617,29 +2577,26 @@ _repeat: res = messages_return::handled; t_channel_id channel_id = *(t_channel_id*) data; CRecordManager::getInstance()->Update(channel_id); -#if 0 //TODO ? - /* if new vpid */ - if(CMoviePlayerGui::getInstance().timeshift) - res |= messages_return::cancel_all; - } -#endif return res; } + else if( msg == NeutrinoMessages::ZAPTO) { - CTimerd::EventInfo * eventinfo; - eventinfo = (CTimerd::EventInfo *) data; - if(recordingstatus==0) { - bool isTVMode = CServiceManager::getInstance()->IsChannelTVChannel(eventinfo->channel_id); + CTimerd::EventInfo * eventinfo = (CTimerd::EventInfo *) data; + if (eventinfo->channel_id != CZapit::getInstance()->GetCurrentChannelID()){ + if( (recordingstatus == 0) || (recordingstatus && CRecordManager::getInstance()->TimeshiftOnly()) || (recordingstatus && CFEManager::getInstance()->haveFreeFrontend()) || + (recordingstatus && channelList->SameTP(eventinfo->channel_id)) ) { + bool isTVMode = CServiceManager::getInstance()->IsChannelTVChannel(eventinfo->channel_id); - dvbsub_stop(); + dvbsub_stop(); - if ((!isTVMode) && (mode != mode_radio)) { - radioMode(false); + if ((!isTVMode) && (mode != mode_radio)) { + radioMode(false); + } + else if (isTVMode && (mode != mode_tv)) { + tvMode(false); + } + channelList->zapTo_ChannelID(eventinfo->channel_id); } - else if (isTVMode && (mode != mode_tv)) { - tvMode(false); - } - channelList->zapTo_ChannelID(eventinfo->channel_id); } delete[] (unsigned char*) data; return messages_return::handled; @@ -2649,52 +2606,19 @@ _repeat: standbyMode( false ); } if( mode != mode_scart ) { + CTimerd::RecordingInfo * eventinfo = (CTimerd::RecordingInfo *) data; std::string name = g_Locale->getText(LOCALE_ZAPTOTIMER_ANNOUNCE); - - CTimerd::TimerList tmpTimerList; - CTimerdClient tmpTimerdClient; - - tmpTimerList.clear(); - tmpTimerdClient.getTimerList( tmpTimerList ); - - if( !tmpTimerList.empty() ) { - sort( tmpTimerList.begin(), tmpTimerList.end() ); - - CTimerd::responseGetTimer &timer = tmpTimerList[0]; - - name += "\n"; - - std::string zAddData = CServiceManager::getInstance()->GetServiceName(timer.channel_id); - if( zAddData.empty()) { - zAddData = g_Locale->getText(LOCALE_TIMERLIST_PROGRAM_UNKNOWN); - } - - if(timer.epgID!=0) { - CEPGData epgdata; - zAddData += " :\n"; - if (CEitManager::getInstance()->getEPGid(timer.epgID, timer.epg_starttime, &epgdata)) { - zAddData += epgdata.title; - } - else if(strlen(timer.epgTitle)!=0) { - zAddData += timer.epgTitle; - } - } - else if(strlen(timer.epgTitle)!=0) { - zAddData += timer.epgTitle; - } - - name += zAddData; - } + getAnnounceEpgName( eventinfo, name); ShowHintUTF( LOCALE_MESSAGEBOX_INFO, name.c_str() ); } - + delete [] (unsigned char*) data; return messages_return::handled; } else if( msg == NeutrinoMessages::ANNOUNCE_RECORD) { my_system(NEUTRINO_RECORDING_TIMER_SCRIPT); - + CTimerd::RecordingInfo * eventinfo = (CTimerd::RecordingInfo *) data; if (g_settings.recording_type == RECORDING_FILE) { - char * recordingDir = ((CTimerd::RecordingInfo*)data)->recordingDir; + char * recordingDir = eventinfo->recordingDir; for(int i=0 ; i < NETWORK_NFS_NR_OF_ENTRIES ; i++) { if (strcmp(g_settings.network_nfs_local_dir[i],recordingDir) == 0) { printf("[neutrino] waking up %s (%s)\n",g_settings.network_nfs_ip[i].c_str(),recordingDir); @@ -2707,43 +2631,39 @@ _repeat: wakeup_hdd(g_settings.network_nfs_recordingdir); } } - if( g_settings.recording_zap_on_announce ) { - //TODO check transponder ? + + if( g_settings.recording_zap_on_announce && (mode != mode_standby) && (eventinfo->channel_id != CZapit::getInstance()->GetCurrentChannelID())) { CRecordManager::getInstance()->StopAutoRecord(); - if(!CRecordManager::getInstance()->RecordingStatus()) { - dvbsub_stop(); //FIXME if same channel ? - t_channel_id channel_id=((CTimerd::RecordingInfo*)data)->channel_id; + bool recordingStatus = CRecordManager::getInstance()->RecordingStatus(); + if ( !recordingStatus || (recordingStatus && CRecordManager::getInstance()->TimeshiftOnly()) || (recordingStatus && CFEManager::getInstance()->haveFreeFrontend()) || + (recordingStatus && channelList->SameTP(eventinfo->channel_id)) ){ + dvbsub_stop(); + t_channel_id channel_id=eventinfo->channel_id; g_Zapit->zapTo_serviceID_NOWAIT(channel_id); } } + if(( mode != mode_scart ) && ( mode != mode_standby )){ + std::string name = g_Locale->getText(LOCALE_RECORDTIMER_ANNOUNCE); + getAnnounceEpgName(eventinfo, name); + ShowHintUTF(LOCALE_MESSAGEBOX_INFO, name.c_str()); + } delete[] (unsigned char*) data; - if( mode != mode_scart ) - ShowHintUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_RECORDTIMER_ANNOUNCE)); return messages_return::handled; } else if( msg == NeutrinoMessages::ANNOUNCE_SLEEPTIMER) { - if( mode != mode_scart ) - ShowHintUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_SLEEPTIMERBOX_ANNOUNCE)); + 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); return messages_return::handled; } else if( msg == NeutrinoMessages::SLEEPTIMER) { - if(data) { - skipShutdownTimer = - (ShowLocalizedMessage(LOCALE_MESSAGEBOX_INFO, LOCALE_SHUTDOWNTIMER_ANNOUNCE, - CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo, NULL, 450, 30, true) == CMessageBox::mbrYes);//FIXME - if(skipShutdownTimer) { - printf("NeutrinoMessages::SLEEPTIMER: skiping\n"); - skipShutdownTimer = false; - return messages_return::handled; - } - else { - printf("NeutrinoMessages::SLEEPTIMER: shutdown\n"); - ExitRun(true, (cs_get_revision() > 7)); - } + if(skipSleepTimer) { + printf("NeutrinoMessages::SLEEPTIMER: skiping\n"); + skipSleepTimer = false; + return messages_return::handled; } if(g_settings.shutdown_real) ExitRun(true, (cs_get_revision() > 7)); - else + else if(mode != mode_standby) standbyMode( true ); return messages_return::handled; } @@ -2810,7 +2730,7 @@ _repeat: ShowMsgUTF(LOCALE_MESSAGEBOX_INFO, text, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO, 0, atoi(timeout.c_str())); } - delete (unsigned char*) data; + delete[] (unsigned char*) data; return messages_return::handled; } else if (msg == NeutrinoMessages::EVT_RECORDING_ENDED) { @@ -2948,10 +2868,9 @@ void CNeutrinoApp::ExitRun(const bool /*write_si*/, int retcode) saveSetup(NEUTRINO_SETTINGS_FILE); if(retcode) { - const char *neutrino_enter_deepstandby_script = CONFIGDIR "/deepstandby.on"; - printf("[%s] executing %s\n",__FILE__ ,neutrino_enter_deepstandby_script); - if (my_system(neutrino_enter_deepstandby_script) != 0) - perror(neutrino_enter_deepstandby_script ); + puts("[neutrino.cpp] executing " NEUTRINO_ENTER_DEEPSTANDBY_SCRIPT "."); + if (my_system(NEUTRINO_ENTER_DEEPSTANDBY_SCRIPT) != 0) + perror(NEUTRINO_ENTER_DEEPSTANDBY_SCRIPT " failed"); printf("entering off state\n"); mode = mode_off; @@ -3016,51 +2935,11 @@ void CNeutrinoApp::ExitRun(const bool /*write_si*/, int retcode) } } } -#if 0 - neutrino_msg_t msg; - neutrino_msg_data_t data; - - cpuFreq->SetCpuFreq(g_settings.standby_cpufreq * 1000 * 1000); - powerManager->SetStandby(true, true); - if (g_info.delivery_system == DVB_S && (cs_get_revision() < 8)) { - int fspeed = 0; - CFanControlNotifier * funNotifier= new CFanControlNotifier(); - funNotifier->changeNotify(NONEXISTANT_LOCALE, (void *) &fspeed); - delete funNotifier; - } - if (powerManager) { - powerManager->Close(); - delete powerManager; - } - - delete &CMoviePlayerGui::getInstance(); - shutdown_cs_api(); - - my_system("/etc/init.d/rcK"); - CVFD::getInstance()->ShowIcon(FP_ICON_CAM1, true); - InfoClock->StopClock(); - - g_RCInput->clearRCMsg(); - while( true ) { - g_RCInput->getMsg(&msg, &data, 10000); - if( msg == CRCInput::RC_standby ) { - printf("Power key, going to reboot...\n"); - sleep(2); - reboot(LINUX_REBOOT_CMD_RESTART); - } else if( ( msg == NeutrinoMessages::ANNOUNCE_RECORD) || ( msg == NeutrinoMessages::ANNOUNCE_ZAPTO) ) { - printf("Zap/record timer, going to reboot...\n"); - sleep(2); - reboot(LINUX_REBOOT_CMD_RESTART); - } - } -#endif } else { delete g_RCInput; //fan speed if (g_info.has_fan) { - int fspeed = 0; - CFanControlNotifier funNotifier; - funNotifier.changeNotify(NONEXISTANT_LOCALE, (void *) &fspeed); + CFanControlNotifier::setSpeed(0); } //CVFD::getInstance()->ShowText(g_Locale->getText(LOCALE_MAINMENU_REBOOT)); stop_video(); @@ -3075,6 +2954,16 @@ void CNeutrinoApp::saveEpg(bool cvfd_mode) { struct stat my_stat; if(stat(g_settings.epg_dir.c_str(), &my_stat) == 0){ + if(!cvfd_mode){//skip saveepg in standby mode, if last saveepg time < 15 Min. + std::string index_xml = g_settings.epg_dir.c_str(); + index_xml += "/index.xml"; + time_t t=0; + if(stat(index_xml.c_str(), &my_stat) == 0){ + if(difftime(time(&t), my_stat.st_ctime) < 900){ + return; + } + } + } printf("[neutrino] Saving EPG to %s...\n", g_settings.epg_dir.c_str()); CVFD::getInstance()->Clear(); @@ -3092,8 +2981,10 @@ void CNeutrinoApp::saveEpg(bool cvfd_mode) CVFD::getInstance()->Clear(); CVFD::getInstance()->setMode(cvfd_mode ? CVFD::MODE_SHUTDOWN : CVFD::MODE_STANDBY);// true CVFD::MODE_SHUTDOWN , false CVFD::MODE_STANDBY break; - } else if (!cvfd_mode) + } else if (!cvfd_mode){ + printf("wait for epg saving, Msg %x \n", (int) msg); handleMsg(msg, data); + } } } } @@ -3101,18 +2992,17 @@ void CNeutrinoApp::saveEpg(bool cvfd_mode) void CNeutrinoApp::tvMode( bool rezap ) { INFO("rezap %d current mode %d", rezap, mode); - if(mode==mode_radio ) { + if (mode == mode_radio) { if (g_settings.radiotext_enable && g_Radiotext) { delete g_Radiotext; g_Radiotext = NULL; } videoDecoder->StopPicture(); - g_RCInput->killTimer(g_InfoViewer->lcdUpdateTimer); - g_InfoViewer->lcdUpdateTimer = g_RCInput->addTimer( LCD_UPDATE_TIME_TV_MODE, false ); CVFD::getInstance()->ShowIcon(FP_ICON_RADIO, false); StartSubtitles(!rezap); } + g_InfoViewer->setUpdateTimer(LCD_UPDATE_TIME_TV_MODE); g_volume->Init(); @@ -3185,11 +3075,12 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) { //static bool wasshift = false; INFO("%s", bOnOff ? "ON" : "OFF" ); - + if( bOnOff ) { if( mode == mode_scart ) { //g_Controld->setScartMode( 0 ); } + g_InfoViewer->setUpdateTimer(0); // delete timer StopSubtitles(); if(SDTreloadChannels && !CRecordManager::getInstance()->RecordingStatus()){ SDT_ReloadChannels(); @@ -3200,7 +3091,12 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) /* wasshift = */ CRecordManager::getInstance()->StopAutoRecord(); - if(!CRecordManager::getInstance()->RecordingStatus()) { + if(mode == mode_radio && g_Radiotext) + g_Radiotext->radiotext_stop(); + + + bool stream_status = CStreamManager::getInstance()->StreamStatus(); + if(!fromDeepStandby && !CRecordManager::getInstance()->RecordingStatus() && !stream_status) { g_Zapit->setStandby(true); } else { g_Zapit->stopPlayBack(); @@ -3208,9 +3104,12 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) videoDecoder->Standby(true); - g_Sectionsd->setPauseScanning(true); + g_Sectionsd->setPauseScanning(!fromDeepStandby); g_Sectionsd->setServiceChanged(0, false); + lastMode = mode; + mode = mode_standby; + if(!CRecordManager::getInstance()->RecordingStatus() ) { //only save epg when not recording if(g_settings.epg_save && !fromDeepStandby) { @@ -3218,8 +3117,10 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) } } - CVFD::getInstance()->Clear(); - CVFD::getInstance()->setMode(CVFD::MODE_STANDBY); + if(CVFD::getInstance()->getMode() != CVFD::MODE_STANDBY){ + CVFD::getInstance()->Clear(); + CVFD::getInstance()->setMode(CVFD::MODE_STANDBY); + } if(g_settings.mode_clock) { InfoClock->StopClock(); @@ -3235,15 +3136,10 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) if(!CRecordManager::getInstance()->RecordingStatus()) cpuFreq->SetCpuFreq(g_settings.standby_cpufreq * 1000 * 1000); - lastMode = mode; - mode = mode_standby; //fan speed - if (g_info.has_fan) { - int fspeed = 1; - CFanControlNotifier * funNotifier= new CFanControlNotifier(); - funNotifier->changeNotify(NONEXISTANT_LOCALE, (void *) &fspeed); - delete funNotifier; - } + if (g_info.has_fan) + CFanControlNotifier::setSpeed(1); + frameBuffer->setActive(false); // Active standby on powerManager->SetStandby(true, false); @@ -3266,11 +3162,8 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) } frameBuffer->setActive(true); //fan speed - if (g_info.has_fan) { - CFanControlNotifier * funNotifier= new CFanControlNotifier(); - funNotifier->changeNotify(NONEXISTANT_LOCALE, (void*) &g_settings.fan_speed); - delete funNotifier; - } + if (g_info.has_fan) + CFanControlNotifier::setSpeed(g_settings.fan_speed); puts("[neutrino.cpp] executing " NEUTRINO_LEAVE_STANDBY_SCRIPT "."); if (my_system(NEUTRINO_LEAVE_STANDBY_SCRIPT) != 0) @@ -3310,15 +3203,6 @@ void CNeutrinoApp::standbyMode( bool bOnOff, bool fromDeepStandby ) InfoClock->StartClock(); g_volume->AudioMute(current_muted, true); -#if 0 - /* auto-record will be started when zap is complete - * FIXME is it needed to restart manual timeshift here ? */ - if((mode == mode_tv) && wasshift) { - //startAutoRecord(); - CRecordManager::getInstance()->StartAutoRecord(); - } - wasshift = false; -#endif StartSubtitles(); } } @@ -3327,12 +3211,11 @@ void CNeutrinoApp::radioMode( bool rezap) { //printf("radioMode: rezap %s\n", rezap ? "yes" : "no"); INFO("rezap %d current mode %d", rezap, mode); - if(mode==mode_tv ) { - g_RCInput->killTimer(g_InfoViewer->lcdUpdateTimer); - g_InfoViewer->lcdUpdateTimer = g_RCInput->addTimer( LCD_UPDATE_TIME_RADIO_MODE, false ); + if (mode == mode_tv) { CVFD::getInstance()->ShowIcon(FP_ICON_TV, false); StopSubtitles(); } + g_InfoViewer->setUpdateTimer(LCD_UPDATE_TIME_RADIO_MODE); CVFD::getInstance()->setMode(CVFD::MODE_TVRADIO); CVFD::getInstance()->ShowIcon(FP_ICON_RADIO, true); @@ -3346,6 +3229,10 @@ void CNeutrinoApp::radioMode( bool rezap) g_RemoteControl->radioMode(); SetChannelMode(g_settings.channel_mode_radio); + + if (g_settings.radiotext_enable && !g_Radiotext) + g_Radiotext = new CRadioText; + if( rezap ) { t_channel_id last_chid = CZapit::getInstance()->GetLastRADIOChannel(); channelList->setSelected(0xfffffff); /* make sure that zapTo_ChannelID will zap */ @@ -3355,10 +3242,6 @@ void CNeutrinoApp::radioMode( bool rezap) channelList->zapTo(0); } videoDecoder->ShowPicture(DATADIR "/neutrino/icons/radiomode.jpg"); - - if (g_settings.radiotext_enable) { - g_Radiotext = new CRadioText; - } } //switching from current mode to tv or radio mode or to optional parameter prev_mode @@ -3523,12 +3406,6 @@ int CNeutrinoApp::exec(CMenuTarget* parent, const std::string & actionKey) MoviePluginSelector.exec(NULL, ""); return menu_return::RETURN_REPAINT; } -#if 0 // commented in menu, needed ? - else if(actionKey == "autolink") { - CRecordManager::getInstance()->LinkTimeshift(); - returnval = menu_return::RETURN_EXIT_ALL; - } -#endif else if(actionKey == "clearSectionsd") { g_Sectionsd->freeMemory(); @@ -3555,16 +3432,19 @@ bool CNeutrinoApp::changeNotify(const neutrino_locale_t OptionName, void * /*dat **************************************************************************************/ void stop_daemons(bool stopall) { - streamts_stop = 1; dvbsub_close(); tuxtxt_stop(); tuxtxt_close(); + if (g_Radiotext) { + delete g_Radiotext; + g_Radiotext = NULL; + } printf("httpd shutdown\n"); 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(); @@ -3638,12 +3518,8 @@ int main(int argc, char **argv) signal(SIGHUP, SIG_IGN); // process are unspecified (signal(2)) /* don't die in streamts.cpp from a SIGPIPE if client disconnects */ signal(SIGPIPE, SIG_IGN); -#if 0 - for(int i = 3; i < 256; i++) - close(i); -#endif + tzset(); - initGlobals(); return CNeutrinoApp::getInstance()->run(argc, argv); } @@ -3799,10 +3675,6 @@ void CNeutrinoApp::StartSubtitles(bool show) void CNeutrinoApp::SelectSubtitles() { -#if 0 - int curnum = channelList->getActiveChannelNumber(); - CZapitChannel * cc = channelList->getChannel(curnum); -#endif /* called on NeutrinoMessages::EVT_ZAP_COMPLETE, should be safe to use zapit current channel */ CZapitChannel * cc = CZapit::getInstance()->GetCurrentChannel(); @@ -3863,6 +3735,34 @@ void CNeutrinoApp::SDT_ReloadChannels() } } +void CNeutrinoApp::getAnnounceEpgName(CTimerd::RecordingInfo * eventinfo, std::string &name) +{ + + name += "\n"; + + std::string zAddData = CServiceManager::getInstance()->GetServiceName(eventinfo->channel_id); + if( zAddData.empty()) { + zAddData = g_Locale->getText(LOCALE_TIMERLIST_PROGRAM_UNKNOWN); + } + + if(eventinfo->epgID!=0) { + CEPGData epgdata; + zAddData += " :\n"; + if (CEitManager::getInstance()->getEPGid(eventinfo->epgID, eventinfo->epg_starttime, &epgdata)) { + zAddData += epgdata.title; + } + else if(strlen(eventinfo->epgTitle)!=0) { + zAddData += eventinfo->epgTitle; + } + } + else if(strlen(eventinfo->epgTitle)!=0) { + zAddData += " :\n"; + zAddData += eventinfo->epgTitle; + } + + name += zAddData; +} + void CNeutrinoApp::Cleanup() { #ifdef EXIT_CLEANUP @@ -3895,7 +3795,6 @@ void CNeutrinoApp::Cleanup() delete g_Radiotext; g_Radiotext = NULL; printf("cleanup 13\n");fflush(stdout); - delete colorSetupNotifier; colorSetupNotifier = NULL; delete audioSetupNotifier; audioSetupNotifier = NULL; delete MoviePluginChanger; MoviePluginChanger = NULL; printf("cleanup 14\n");fflush(stdout); diff --git a/src/neutrino.h b/src/neutrino.h index 3ff32bf3e..b129adfe6 100644 --- a/src/neutrino.h +++ b/src/neutrino.h @@ -118,12 +118,11 @@ private: int current_muted; bool skipShutdownTimer; + bool skipSleepTimer; bool pbBlinkChange; - int tvsort[LIST_MODE_LAST]; int radiosort[LIST_MODE_LAST]; - CColorSetupNotifier *colorSetupNotifier; CMoviePluginChangeExec *MoviePluginChanger; void SDT_ReloadChannels(); @@ -135,6 +134,7 @@ private: void scartMode( bool bOnOff ); void standbyMode( bool bOnOff, bool fromDeepStandby = false ); void saveEpg(bool cvfd_mode); + void getAnnounceEpgName(CTimerd::RecordingInfo * eventinfo, std::string &name); void ExitRun(const bool write_si = true, int retcode = 0); void RealRun(CMenuWidget &mainSettings); diff --git a/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp b/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp index d737dbf0a..dfc1c5118 100644 --- a/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp +++ b/src/nhttpd/tuxboxapi/coolstream/controlapi.cpp @@ -37,6 +37,8 @@ #include "gui/plugins.h"//for relodplugins #include #include +#include "gui/rc_lock.h" + // yhttpd #include "yhttpd.h" #include "ytypes_globals.h" @@ -425,12 +427,14 @@ void CControlAPI::StandbyCGI(CyhookHandler *hh) { if (hh->ParamList["1"] == "on") // standby mode on { - NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::STANDBY_ON, CEventServer::INITID_HTTPD); + if(CNeutrinoApp::getInstance()->getMode() != 4) + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::STANDBY_ON, CEventServer::INITID_HTTPD); hh->SendOk(); } else if (hh->ParamList["1"] == "off")// standby mode off { - NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::STANDBY_OFF, CEventServer::INITID_HTTPD); + if(CNeutrinoApp::getInstance()->getMode() == 4) + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::STANDBY_OFF, CEventServer::INITID_HTTPD); hh->SendOk(); } else @@ -448,12 +452,18 @@ void CControlAPI::RCCGI(CyhookHandler *hh) { if (!(hh->ParamList.empty())) { - if (hh->ParamList["1"] == "lock") // lock remote control - NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::LOCK_RC, CEventServer::INITID_HTTPD); - else if (hh->ParamList["1"] == "unlock")// unlock remote control - NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::UNLOCK_RC, CEventServer::INITID_HTTPD); - else + if (hh->ParamList["1"] == "lock"){ // lock remote control + if(!CRCLock::locked) + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::LOCK_RC, CEventServer::INITID_HTTPD); + } + else if (hh->ParamList["1"] == "unlock"){// unlock remote control + if(CRCLock::locked) + NeutrinoAPI->EventServer->sendEvent(NeutrinoMessages::UNLOCK_RC, CEventServer::INITID_HTTPD); + + } + else{ hh->SendError(); + } } hh->SendOk(); } @@ -1472,15 +1482,19 @@ void CControlAPI::ZaptoCGI(CyhookHandler *hh) SendAllCurrentVAPid(hh); else if (hh->ParamList["1"] == "stopplayback") { - NeutrinoAPI->Zapit->stopPlayBack(); - NeutrinoAPI->Sectionsd->setPauseScanning(true); + if(NeutrinoAPI->Zapit->isPlayBackActive()){ + NeutrinoAPI->Zapit->stopPlayBack(); + NeutrinoAPI->Sectionsd->setPauseScanning(true); + } hh->SendOk(); } else if (hh->ParamList["1"] == "startplayback") { - NeutrinoAPI->Zapit->startPlayBack(); - NeutrinoAPI->Sectionsd->setPauseScanning(false); - dprintf("start playback requested..\n"); + if(!NeutrinoAPI->Zapit->isPlayBackActive()){ + NeutrinoAPI->Zapit->startPlayBack(); + NeutrinoAPI->Sectionsd->setPauseScanning(false); + dprintf("start playback requested..\n"); + } hh->SendOk(); } else if (hh->ParamList["1"] == "statusplayback") diff --git a/src/nhttpd/web/Y_Tools_Rcsim.yhtm b/src/nhttpd/web/Y_Tools_Rcsim.yhtm index 5418f02c1..ff2157ed7 100644 --- a/src/nhttpd/web/Y_Tools_Rcsim.yhtm +++ b/src/nhttpd/web/Y_Tools_Rcsim.yhtm @@ -5,9 +5,13 @@ // diff --git a/src/nhttpd/yhttpd_core/helper.cpp b/src/nhttpd/yhttpd_core/helper.cpp index 68d7b55e3..38b188ba2 100644 --- a/src/nhttpd/yhttpd_core/helper.cpp +++ b/src/nhttpd/yhttpd_core/helper.cpp @@ -44,6 +44,7 @@ void correctTime(struct tm *zt) { zt->tm_hour = minmax(zt->tm_hour, 0, 23); zt->tm_min = minmax(zt->tm_min, 0, 59); zt->tm_sec = minmax(zt->tm_sec, 0, 59); + zt->tm_isdst = -1; } //============================================================================= // Strings 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/helpers.cpp b/src/system/helpers.cpp index a564982e6..c993bbf41 100644 --- a/src/system/helpers.cpp +++ b/src/system/helpers.cpp @@ -33,6 +33,7 @@ #include /* or */ #include #include +#include #include #include @@ -81,7 +82,7 @@ int my_system(const char * cmd, const char * arg1, const char * arg2, const char case 0: /* child process */ for(i = 3; i < maxfd; i++) close(i); - if(execlp(cmd, cmd, arg1, arg2, arg3, arg4, arg5, arg6, NULL)) + if(execlp(cmd, cmd, arg1, arg2, arg3, arg4, arg5, arg6, (char*)NULL)) { std::string txt = "ERROR: my_system \"" + (std::string) cmd + "\""; perror(txt.c_str()); @@ -235,3 +236,237 @@ bool get_mem_usage(unsigned long &kbtotal, unsigned long &kbfree) printf("mem: total %ld cached %ld free %ld\n", kbtotal, cached, kbfree); return true; } + +std::string trim(std::string &str, const std::string &trimChars /*= " \n\r\t"*/) +{ + std::string result = str.erase(str.find_last_not_of(trimChars) + 1); + return result.erase(0, result.find_first_not_of(trimChars)); +} + +CFileHelpers::CFileHelpers() +{ + FileBufSize = 0xFFFF; + FileBuf = new char[FileBufSize]; + doCopyFlag = true; +} + +CFileHelpers::~CFileHelpers() +{ + if (FileBuf != NULL) + delete [] FileBuf; +} + +CFileHelpers* CFileHelpers::getInstance() +{ + static CFileHelpers* FileHelpers = NULL; + if(!FileHelpers) + FileHelpers = new CFileHelpers(); + return FileHelpers; +} + +bool CFileHelpers::copyFile(const char *Src, const char *Dst, mode_t mode) +{ + doCopyFlag = true; + unlink(Dst); + if ((fd1 = open(Src, O_RDONLY)) < 0) + return false; + if ((fd2 = open(Dst, O_WRONLY | O_CREAT)) < 0) { + close(fd1); + return false; + } + + long block; + off64_t fsizeSrc64 = lseek64(fd1, 0, SEEK_END); + lseek64(fd1, 0, SEEK_SET); + if (fsizeSrc64 > 0x7FFFFFF0) { // > 2GB + off64_t fsize64 = fsizeSrc64; + block = FileBufSize; + //printf("#####[%s] fsizeSrc64: %lld 0x%010llX - large file\n", __FUNCTION__, fsizeSrc64, fsizeSrc64); + while(fsize64 > 0) { + if(fsize64 < (off64_t)FileBufSize) + block = (long)fsize64; + read(fd1, FileBuf, block); + write(fd2, FileBuf, block); + fsize64 -= block; + if (!doCopyFlag) + break; + } + if (doCopyFlag) { + lseek64(fd2, 0, SEEK_SET); + off64_t fsizeDst64 = lseek64(fd2, 0, SEEK_END); + if (fsizeSrc64 != fsizeDst64){ + close(fd1); + close(fd2); + return false; + } + } + } + else { // < 2GB + long fsizeSrc = lseek(fd1, 0, SEEK_END); + lseek(fd1, 0, SEEK_SET); + long fsize = fsizeSrc; + block = FileBufSize; + //printf("#####[%s] fsizeSrc: %ld 0x%08lX - normal file\n", __FUNCTION__, fsizeSrc, fsizeSrc); + while(fsize > 0) { + if(fsize < (long)FileBufSize) + block = fsize; + read(fd1, FileBuf, block); + write(fd2, FileBuf, block); + fsize -= block; + if (!doCopyFlag) + break; + } + if (doCopyFlag) { + lseek(fd2, 0, SEEK_SET); + long fsizeDst = lseek(fd2, 0, SEEK_END); + if (fsizeSrc != fsizeDst){ + close(fd1); + close(fd2); + return false; + } + } + } + close(fd1); + close(fd2); + + if (!doCopyFlag) { + sync(); + unlink(Dst); + return false; + } + + chmod(Dst, mode); + return true; +} + +bool CFileHelpers::copyDir(const char *Src, const char *Dst) +{ + DIR *Directory; + struct dirent *CurrentFile; + static struct stat FileInfo; + char srcPath[PATH_MAX]; + char dstPath[PATH_MAX]; + char buf[PATH_MAX]; + + //open directory + if ((Directory = opendir(Src)) == NULL) + return false; + if (lstat(Src, &FileInfo) == -1) { + closedir(Directory); + return false; + } + // create directory + // is symlink + if (S_ISLNK(FileInfo.st_mode)) { + int len = readlink(Src, buf, sizeof(buf)-1); + if (len != -1) { + buf[len] = '\0'; + symlink(buf, Dst); + } + } + else { + // directory + if (createDir(Dst, FileInfo.st_mode & 0x0FFF) == false) { + if (errno != EEXIST) { + closedir(Directory); + return false; + } + } + } + + // read directory + while ((CurrentFile = readdir(Directory)) != NULL) { + // ignore '.' and '..' + if (strcmp(CurrentFile->d_name, ".") && strcmp(CurrentFile->d_name, "..")) { + strcpy(srcPath, Src); + strcat(srcPath, "/"); + strcat(srcPath, CurrentFile->d_name); + if (lstat(srcPath, &FileInfo) == -1) { + closedir(Directory); + return false; + } + strcpy(dstPath, Dst); + strcat(dstPath, "/"); + strcat(dstPath, CurrentFile->d_name); + // is symlink + if (S_ISLNK(FileInfo.st_mode)) { + int len = readlink(srcPath, buf, sizeof(buf)-1); + if (len != -1) { + buf[len] = '\0'; + symlink(buf, dstPath); + } + } + // is directory + else if (S_ISDIR(FileInfo.st_mode)) { + copyDir(srcPath, dstPath); + } + // is file + else if (S_ISREG(FileInfo.st_mode)) { + copyFile(srcPath, dstPath, FileInfo.st_mode & 0x0FFF); + } + } + } + closedir(Directory); + return true; +} + +bool CFileHelpers::createDir(const char *Dir, mode_t mode) +{ + char dirPath[PATH_MAX]; + DIR *dir; + if ((dir = opendir(Dir)) != NULL) { + closedir(dir); + errno = EEXIST; + return false; + } + + int ret = -1; + while (ret == -1) { + strcpy(dirPath, Dir); + ret = mkdir(dirPath, mode); + if ((errno == ENOENT) && (ret == -1)) { + char * pos = strrchr(dirPath,'/'); + if (pos != NULL) { + pos[0] = '\0'; + createDir(dirPath, mode); + } + } + else { + if (ret == 0) + return true; + if (errno == EEXIST) + return true; + else + return false; + } + } + errno = 0; + return true; +} + +bool CFileHelpers::removeDir(const char *Dir) +{ + DIR *dir; + struct dirent *entry; + char path[PATH_MAX]; + + dir = opendir(Dir); + if (dir == NULL) { + printf("Error opendir()\n"); + return false; + } + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) { + snprintf(path, (size_t) PATH_MAX, "%s/%s", Dir, entry->d_name); + if (entry->d_type == DT_DIR) + removeDir(path); + else + unlink(path); + } + } + closedir(dir); + rmdir(Dir); + + errno = 0; + return true; +} diff --git a/src/system/helpers.h b/src/system/helpers.h index c14938527..b3393a0d3 100644 --- a/src/system/helpers.h +++ b/src/system/helpers.h @@ -34,4 +34,26 @@ int check_dir(const char * dir); bool get_fs_usage(const char * dir, long &total, long &used); bool get_mem_usage(unsigned long &total, unsigned long &free); +std::string trim(std::string &str, const std::string &trimChars = " \n\r\t"); + +class CFileHelpers +{ + private: + int FileBufSize; + char *FileBuf; + int fd1, fd2; + + public: + CFileHelpers(); + ~CFileHelpers(); + static CFileHelpers* getInstance(); + bool doCopyFlag; + + bool copyFile(const char *Src, const char *Dst, mode_t mode); + bool copyDir(const char *Src, const char *Dst); + bool createDir(const char *Dir, mode_t mode); + bool removeDir(const char *Dir); + +}; + #endif diff --git a/src/system/locals.h b/src/system/locals.h index 857ffefc8..73aeb3603 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -463,6 +463,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, @@ -511,6 +512,9 @@ typedef enum LOCALE_FLASHUPDATE_SQUASHFS_NOVERSION, LOCALE_FLASHUPDATE_TITLEREADFLASH, LOCALE_FLASHUPDATE_TITLEWRITEFLASH, + LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_PROCESSED, + LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_SKIPPED, + LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_SUCCESSFULLY, LOCALE_FLASHUPDATE_UPDATEMODE, LOCALE_FLASHUPDATE_UPDATEMODE_INTERNET, LOCALE_FLASHUPDATE_UPDATEMODE_MANUAL, @@ -952,6 +956,7 @@ typedef enum LOCALE_MENU_HINT_RECORD_CHANDIR, LOCALE_MENU_HINT_RECORD_DIR, LOCALE_MENU_HINT_RECORD_END, + LOCALE_MENU_HINT_RECORD_SLOW_WARN, LOCALE_MENU_HINT_RECORD_TDIR, LOCALE_MENU_HINT_RECORD_TIME, LOCALE_MENU_HINT_RECORD_TIMEAFTER, @@ -1341,6 +1346,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, @@ -1518,6 +1525,7 @@ typedef enum LOCALE_RECORDINGMENU_SERVER, LOCALE_RECORDINGMENU_SERVER_MAC, LOCALE_RECORDINGMENU_SETUPNOW, + LOCALE_RECORDINGMENU_SLOW_WARN, LOCALE_RECORDINGMENU_TIMESHIFT, LOCALE_RECORDINGMENU_TSDIR, LOCALE_RECORDINGMENU_VCR, @@ -1691,6 +1699,7 @@ typedef enum LOCALE_TIMERLIST_ALARMTIME, LOCALE_TIMERLIST_APIDS, LOCALE_TIMERLIST_APIDS_DFLT, + LOCALE_TIMERLIST_ASK_TO_DELETE, LOCALE_TIMERLIST_BOUQUETSELECT, LOCALE_TIMERLIST_CHANNEL, LOCALE_TIMERLIST_CHANNELSELECT, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 7f13792bb..ede893246 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -463,6 +463,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", @@ -511,6 +512,9 @@ const char * locale_real_names[] = "flashupdate.squashfs.noversion", "flashupdate.titlereadflash", "flashupdate.titlewriteflash", + "flashupdate.update_with_settings_processed", + "flashupdate.update_with_settings_skipped", + "flashupdate.update_with_settings_successfully", "flashupdate.updatemode", "flashupdate.updatemode_internet", "flashupdate.updatemode_manual", @@ -952,6 +956,7 @@ const char * locale_real_names[] = "menu.hint_record_chandir", "menu.hint_record_dir", "menu.hint_record_end", + "menu.hint_record_slow_warn", "menu.hint_record_tdir", "menu.hint_record_time", "menu.hint_record_timeafter", @@ -1341,6 +1346,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", @@ -1518,6 +1525,7 @@ const char * locale_real_names[] = "recordingmenu.server", "recordingmenu.server_mac", "recordingmenu.setupnow", + "recordingmenu.slow_warn", "recordingmenu.timeshift", "recordingmenu.tsdir", "recordingmenu.vcr", @@ -1691,6 +1699,7 @@ const char * locale_real_names[] = "timerlist.alarmtime", "timerlist.apids", "timerlist.apids_dflt", + "timerlist.ask_to_delete", "timerlist.bouquetselect", "timerlist.channel", "timerlist.channelselect", diff --git a/src/system/setting_helpers.cpp b/src/system/setting_helpers.cpp index b93cbb0d1..eeb013c9f 100644 --- a/src/system/setting_helpers.cpp +++ b/src/system/setting_helpers.cpp @@ -129,10 +129,9 @@ bool CTouchFileNotifier::changeNotify(const neutrino_locale_t, void * data) return true; } -bool CColorSetupNotifier::changeNotify(const neutrino_locale_t, void *) +void CColorSetupNotifier::setPalette() { CFrameBuffer *frameBuffer = CFrameBuffer::getInstance(); -// unsigned char r,g,b; //setting colors-.. frameBuffer->paletteGenFade(COL_MENUHEAD, convertSetupColor2RGB(g_settings.menu_Head_red, g_settings.menu_Head_green, g_settings.menu_Head_blue), @@ -165,13 +164,6 @@ bool CColorSetupNotifier::changeNotify(const neutrino_locale_t, void *) convertSetupColor2RGB(g_settings.infobar_Text_red, g_settings.infobar_Text_green, g_settings.infobar_Text_blue), 8, convertSetupAlpha2Alpha(g_settings.infobar_alpha) ); -/* frameBuffer->paletteSetColor( COL_INFOBAR_SHADOW, - convertSetupColor2RGB( - int(g_settings.infobar_red*0.4), - int(g_settings.infobar_green*0.4), - int(g_settings.infobar_blue*0.4)), - g_settings.infobar_alpha); -*/ frameBuffer->paletteGenFade(COL_INFOBAR_SHADOW, convertSetupColor2RGB(int(g_settings.infobar_red*0.4), int(g_settings.infobar_green*0.4), int(g_settings.infobar_blue*0.4)), convertSetupColor2RGB(g_settings.infobar_Text_red, g_settings.infobar_Text_green, g_settings.infobar_Text_blue), @@ -189,10 +181,17 @@ bool CColorSetupNotifier::changeNotify(const neutrino_locale_t, void *) 8, convertSetupAlpha2Alpha(g_settings.infobar_alpha) ); frameBuffer->paletteSet(); +} + +bool CColorSetupNotifier::changeNotify(const neutrino_locale_t, void *) +{ + setPalette(); +#if 0 /* recalculate volumebar */ CVolume::getInstance()->Init(); /* recalculate infoclock */ CInfoClock::getInstance()->Init(); +#endif return false; } @@ -484,8 +483,7 @@ int CDataResetNotifier::exec(CMenuTarget* /*parent*/, const std::string& actionK //CNeutrinoApp::getInstance()->loadColors(NEUTRINO_SETTINGS_FILE); CNeutrinoApp::getInstance()->SetupFonts(); CNeutrinoApp::getInstance()->SetupTiming(); - CColorSetupNotifier colorSetupNotifier; - colorSetupNotifier.changeNotify(NONEXISTANT_LOCALE, NULL); + CColorSetupNotifier::setPalette(); CVFD::getInstance()->setlcdparameter(); CFrameBuffer::getInstance()->Clear(); } @@ -496,24 +494,26 @@ int CDataResetNotifier::exec(CMenuTarget* /*parent*/, const std::string& actionK return ret; } -bool CFanControlNotifier::changeNotify(const neutrino_locale_t, void * data) +void CFanControlNotifier::setSpeed(unsigned int speed) { - int cfd, ret; - //unsigned char speed = (unsigned char) g_settings.fan_speed; - unsigned int speed = * (int *) data; + int cfd; printf("FAN Speed %d\n", speed); cfd = open("/dev/cs_control", O_RDONLY); if(cfd < 0) { perror("Cannot open /dev/cs_control"); - return false; + return; } - ret = ioctl(cfd, IOC_CONTROL_PWM_SPEED, speed); - close(cfd); - if(ret < 0) { + if (ioctl(cfd, IOC_CONTROL_PWM_SPEED, speed) < 0) perror("IOC_CONTROL_PWM_SPEED"); - return false; - } + + close(cfd); +} + +bool CFanControlNotifier::changeNotify(const neutrino_locale_t, void * data) +{ + unsigned int speed = * (int *) data; + setSpeed(speed); return false; } diff --git a/src/system/setting_helpers.h b/src/system/setting_helpers.h index 22d0b27c9..88207dc36 100644 --- a/src/system/setting_helpers.h +++ b/src/system/setting_helpers.h @@ -88,6 +88,7 @@ class CColorSetupNotifier : public CChangeObserver { public: bool changeNotify(const neutrino_locale_t, void *); + static void setPalette(); }; class CAudioSetupNotifier : public CChangeObserver @@ -154,6 +155,7 @@ class CFanControlNotifier : public CChangeObserver { public: bool changeNotify(const neutrino_locale_t, void * data); + static void setSpeed(unsigned int speed); }; class CCpuFreqNotifier : public CChangeObserver 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 d3f04a3e5..cbb7b0c25 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -142,9 +142,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, @@ -326,6 +328,7 @@ struct SNeutrinoSettings int recording_epg_for_end; int recording_save_in_channeldir; int recording_zap_on_announce; + int recording_slow_warning; int shutdown_timer_record_type; int filesystem_is_utf8; diff --git a/src/timerd/timermanager.cpp b/src/timerd/timermanager.cpp index e03d6d306..7ea3e5ab6 100644 --- a/src/timerd/timermanager.cpp +++ b/src/timerd/timermanager.cpp @@ -1254,8 +1254,15 @@ void CTimerEvent_Record::Refresh() //============================================================= void CTimerEvent_Zapto::announceEvent() { + Refresh(); + CTimerd::RecordingInfo ri=eventInfo; + ri.eventID=eventID; + ri.recordingDir[0] = 0; + strcpy(ri.epgTitle, epgTitle.substr(0,sizeof(ri.epgTitle)-1).c_str()); + CTimerManager::getInstance()->getEventServer()->sendEvent(CTimerdClient::EVT_ANNOUNCE_ZAPTO, - CEventServer::INITID_TIMERD); + CEventServer::INITID_TIMERD, + &ri,sizeof(CTimerd::RecordingInfo)); } //------------------------------------------------------------ void CTimerEvent_Zapto::fireEvent() diff --git a/src/zapit/include/zapit/capmt.h b/src/zapit/include/zapit/capmt.h index c24267c58..674429940 100644 --- a/src/zapit/include/zapit/capmt.h +++ b/src/zapit/include/zapit/capmt.h @@ -65,7 +65,7 @@ class CCam : public CBasicClient CCam(); virtual ~CCam() {}; bool sendMessage(const char * const data, const size_t length, bool update = false); - bool makeCaPmt(CZapitChannel * channel, uint8_t list = CAPMT_ONLY, const CaIdVector &caids = CaIdVector()); + bool makeCaPmt(CZapitChannel * channel, bool add_private, uint8_t list = CAPMT_ONLY, const CaIdVector &caids = CaIdVector()); bool setCaPmt(bool update = false); bool sendCaPmt(uint64_t tpid, uint8_t *rawpmt, int rawlen); int makeMask(int demux, bool add); diff --git a/src/zapit/include/zapit/zapit.h b/src/zapit/include/zapit/zapit.h index 2c77eb030..aa32ae0b9 100644 --- a/src/zapit/include/zapit/zapit.h +++ b/src/zapit/include/zapit/zapit.h @@ -17,6 +17,7 @@ #include #include #include +#include #define PAL 0 #define NTSC 1 @@ -34,7 +35,7 @@ typedef volume_map_t::iterator volume_map_iterator_t; typedef std::pair volume_map_range_t; #define VOLUME_PERCENT_AC3 100 -#define VOLUME_PERCENT_PCM 75 +#define VOLUME_PERCENT_PCM 100 /* complete zapit start thread-parameters in a struct */ typedef struct ZAPIT_start_arg @@ -130,7 +131,9 @@ class CZapit : public OpenThreads::Thread CZapitChannel * current_channel; t_channel_id live_channel_id; + /* scan params */ TP_params TP; + fast_scan_type_t scant; CFrontend * live_fe; diff --git a/src/zapit/src/capmt.cpp b/src/zapit/src/capmt.cpp index 47a680e65..1514cd184 100644 --- a/src/zapit/src/capmt.cpp +++ b/src/zapit/src/capmt.cpp @@ -76,12 +76,12 @@ bool CCam::sendMessage(const char * const data, const size_t length, bool update return send_data(data, length); } -bool CCam::makeCaPmt(CZapitChannel * channel, uint8_t list, const CaIdVector &caids) +bool CCam::makeCaPmt(CZapitChannel * channel, bool add_private, uint8_t list, const CaIdVector &caids) { int len; unsigned char * buffer = channel->getRawPmt(len); - DBG("cam %x source %d camask %d list %02x buffer", (int) this, source_demux, camask, list); + INFO("cam %x source %d camask %d list %02x buffer", (int) this, source_demux, camask, list); if(!buffer) return false; @@ -89,32 +89,34 @@ bool CCam::makeCaPmt(CZapitChannel * channel, uint8_t list, const CaIdVector &ca ProgramMapSection pmt(buffer); CaProgramMapSection capmt(&pmt, list, 0x01, caids); - uint8_t tmp[10]; - tmp[0] = 0x84; - tmp[1] = 0x02; - tmp[2] = channel->getPmtPid() >> 8; - tmp[3] = channel->getPmtPid() & 0xFF; - capmt.injectDescriptor(tmp, false); + if (add_private) { + uint8_t tmp[10]; + tmp[0] = 0x84; + tmp[1] = 0x02; + tmp[2] = channel->getPmtPid() >> 8; + tmp[3] = channel->getPmtPid() & 0xFF; + capmt.injectDescriptor(tmp, false); - tmp[0] = 0x82; - tmp[1] = 0x02; - tmp[2] = camask; - tmp[3] = source_demux; - capmt.injectDescriptor(tmp, false); + tmp[0] = 0x82; + tmp[1] = 0x02; + tmp[2] = camask; + tmp[3] = source_demux; + capmt.injectDescriptor(tmp, false); - memset(tmp, 0, sizeof(tmp)); - tmp[0] = 0x81; - tmp[1] = 0x08; - tmp[2] = channel->getSatellitePosition() >> 8; - tmp[3] = channel->getSatellitePosition() & 0xFF; - tmp[4] = channel->getFreqId() >> 8; - tmp[5] = channel->getFreqId() & 0xFF; - tmp[6] = channel->getTransportStreamId() >> 8; - tmp[7] = channel->getTransportStreamId() & 0xFF; - tmp[8] = channel->getOriginalNetworkId() >> 8; - tmp[9] = channel->getOriginalNetworkId() & 0xFF; + memset(tmp, 0, sizeof(tmp)); + tmp[0] = 0x81; + tmp[1] = 0x08; + tmp[2] = channel->getSatellitePosition() >> 8; + tmp[3] = channel->getSatellitePosition() & 0xFF; + tmp[4] = channel->getFreqId() >> 8; + tmp[5] = channel->getFreqId() & 0xFF; + tmp[6] = channel->getTransportStreamId() >> 8; + tmp[7] = channel->getTransportStreamId() & 0xFF; + tmp[8] = channel->getOriginalNetworkId() >> 8; + tmp[9] = channel->getOriginalNetworkId() & 0xFF; - capmt.injectDescriptor(tmp, false); + capmt.injectDescriptor(tmp, false); + } calen = capmt.writeToBuffer(cabuf); #ifdef DEBUG_CAPMT @@ -235,7 +237,7 @@ bool CCamManager::SetMode(t_channel_id channel_id, enum runmode mode, bool start if(newmask == 0) { cam->sendMessage(NULL, 0, false); } else { - cam->makeCaPmt(channel); + cam->makeCaPmt(channel, true); cam->setCaPmt(true); } } @@ -249,7 +251,10 @@ bool CCamManager::SetMode(t_channel_id channel_id, enum runmode mode, bool start } CaIdVector caids; cCA::GetInstance()->GetCAIDS(caids); - uint8_t list = CCam::CAPMT_FIRST; + //uint8_t list = CCam::CAPMT_FIRST; + uint8_t list = CCam::CAPMT_ONLY; + if (channel_map.size() > 1) + list = CCam::CAPMT_ADD; for (it = channel_map.begin(); it != channel_map.end(); /*++it*/) { cam = it->second; @@ -258,14 +263,16 @@ bool CCamManager::SetMode(t_channel_id channel_id, enum runmode mode, bool start if(!channel) continue; +#if 0 if (it == channel_map.end()) list |= CCam::CAPMT_LAST; // FIRST->ONLY or MORE->LAST +#endif - cam->makeCaPmt(channel, list, caids); + cam->makeCaPmt(channel, false, list, caids); int len; unsigned char * buffer = channel->getRawPmt(len); cam->sendCaPmt(channel->getTransponderId(), buffer, len); - list = CCam::CAPMT_MORE; + //list = CCam::CAPMT_MORE; } mutex.unlock(); diff --git a/src/zapit/src/fastscan.cpp b/src/zapit/src/fastscan.cpp index 0e9e8c7b4..8fb2b8324 100644 --- a/src/zapit/src/fastscan.cpp +++ b/src/zapit/src/fastscan.cpp @@ -63,13 +63,13 @@ void CServiceScan::InitFastscanLnb(int id) switch(id) { default: case CD_OPERATOR_ID: - case OPERATOR_TVV: + case TVV_OPERATOR_ID: satmap[192].diseqc = 0; satmap[235].diseqc = 1; satmap[282].diseqc = 2; satmap[130].diseqc = 3; break; - case OPERATOR_TELESAT: + case TELESAT_OPERATOR_ID: satmap[130].diseqc = 0; satmap[192].diseqc = 1; satmap[235].diseqc = 2; @@ -216,10 +216,10 @@ bool CServiceScan::ParseFst(unsigned short pid, fast_scan_operator_t * op) delete dmx; return false; } - +#if 0 g_bouquetManager->clearAll(); CServiceManager::getInstance()->RemoveAllChannels(); - +#endif do { if (dmx->Read(buffer, SEC_SIZE) < 0) { delete dmx; diff --git a/src/zapit/src/frontend.cpp b/src/zapit/src/frontend.cpp index 6b9088957..4ffd3be48 100644 --- a/src/zapit/src/frontend.cpp +++ b/src/zapit/src/frontend.cpp @@ -870,7 +870,7 @@ void CFrontend::setDiseqcType(const diseqc_t newDiseqcType, bool force) return; } - if (force || ((config.diseqcType <= MINI_DISEQC) + if ((force && (newDiseqcType != NO_DISEQC)) || ((config.diseqcType <= MINI_DISEQC) && (newDiseqcType > MINI_DISEQC))) { secSetTone(SEC_TONE_OFF, 15); sendDiseqcPowerOn(); @@ -1033,7 +1033,7 @@ bool CFrontend::tuneChannel(CZapitChannel * /*channel*/, bool /*nvod*/) return false; return tuneFrequency(&transponder->second.feparams, transponder->second.polarization, false); } - +#if 0 bool CFrontend::retuneChannel(void) { mutex.lock(); @@ -1044,7 +1044,7 @@ bool CFrontend::retuneChannel(void) mutex.unlock(); return tuneFrequency(&transponder->second.feparams, transponder->second.polarization, true); } - +#endif int CFrontend::tuneFrequency(FrontendParameters * feparams, uint8_t polarization, bool nowait) { TP_params TP; diff --git a/src/zapit/src/zapit.cpp b/src/zapit/src/zapit.cpp index 8c7f49a22..83571b176 100644 --- a/src/zapit/src/zapit.cpp +++ b/src/zapit/src/zapit.cpp @@ -807,8 +807,6 @@ bool CZapit::StartScanTP(TP_params * TPparams) bool CZapit::StartFastScan(int scan_mode, int opid) { - fast_scan_type_t scant; - scant.type = scan_mode; scant.op = (fs_operator_t) opid;