diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index fc567f46f..cb914b55b 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -108,6 +108,14 @@ GENRE.TRAVEL_HOBBIES.6 Einkauf GENRE.TRAVEL_HOBBIES.7 Garten GENRE.UNKNOWN Unbekannt adzap Werbezapper +adzap.announce In 15 Sekunden wird umgeschaltet auf +adzap.cancel Deaktiviert +adzap.disable Deaktivieren +adzap.enable Einmalig aktivieren +adzap.minute Minute +adzap.minutes Minuten +adzap.monitor Daueraktiv bei aktueller Sendung +adzap.switchback Zurückschalten nach apidselector.head Sprachauswahl audio.srs_algo Art audio.srs_algo_heavy stark @@ -939,6 +947,7 @@ mbkey.truncate Film kürzen menu.back Zurück menu.cancel Abbrechen menu.hint_a_pic Konfigurieren Sie den Audioplayer und den Bildbetrachter +menu.hint_adzap Der Werbe-Zapper schaltet nach der eingestellten Zeit wieder auf den ursprünglichen Kanal zurück menu.hint_aplay Audioplayer menu.hint_aplay_setup Ändern Sie Audioplayer-Einstellungen wie Titel-Anzeige, Startverzeichnis oder Bildschirmschoner. menu.hint_audio Audio-Ausgang, Dolby Digital und SRS TruVolume Optionen und mehr @@ -2359,6 +2368,7 @@ usermenu.button_green Benutzermenü 'grün' usermenu.button_red Benutzermenü 'rot' usermenu.button_yellow Benutzermenü 'gelb' usermenu.head Benutzermenü +usermenu.item_adzap Werbezapper usermenu.item_bar ---- Trennung ---- usermenu.item_epg_misc EPG Funktionen usermenu.item_none (frei) diff --git a/data/locale/english.locale b/data/locale/english.locale index fe9592abf..a9877339a 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -108,6 +108,14 @@ GENRE.TRAVEL_HOBBIES.6 advertisement/shopping GENRE.TRAVEL_HOBBIES.7 gardening GENRE.UNKNOWN unknown adzap AdZap +adzap.announce In 15 seconds, the channel will be switched to +adzap.cancel Timer was cancelled +adzap.disable Deactivate +adzap.enable Activate once +adzap.minute minute +adzap.minutes minutes +adzap.monitor Stay active during current broadcast +adzap.switchback Switch back after apidselector.head Select language audio.srs_algo Type audio.srs_algo_heavy Heavy @@ -939,6 +947,7 @@ mbkey.truncate Truncate movie menu.back Back menu.cancel Cancel menu.hint_a_pic Configure audio player and picture viewer +menu.hint_adzap AdZap will switch back to the current channel when the selected time is up menu.hint_aplay Audio player menu.hint_aplay_setup Change title display, start directory, screen saver and more menu.hint_audio Audio output, DD\nSRS True volume options @@ -2359,6 +2368,7 @@ usermenu.button_green User menu green usermenu.button_red User menu red usermenu.button_yellow User menu yellow usermenu.head User menu +usermenu.item_adzap Adzap usermenu.item_bar ---- Boarder ---- usermenu.item_epg_misc EPG functions usermenu.item_none (empty) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 509a67b5a..8a275ac33 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -42,6 +42,7 @@ AM_CPPFLAGS += \ noinst_LIBRARIES = libtimerlist.a libneutrino_gui.a libneutrino_gui2.a libneutrino_gui_a_SOURCES = \ + adzap.cpp \ audio_select.cpp \ audio_setup.cpp \ audiomute.cpp \ diff --git a/src/gui/adzap.cpp b/src/gui/adzap.cpp new file mode 100644 index 000000000..424f0120d --- /dev/null +++ b/src/gui/adzap.cpp @@ -0,0 +1,291 @@ +/* + * adzap.cpp + * + * (C)2012-2013 by martii + * + * License: GPL + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is 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. + */ + +/* + * AS SOME FOLKS DON'T SEEM TO UNDERSTAND THE GPL: YOU ARE FREE TO USE + * THIS CODE FOR YOUR OWN LITTLE STB IMAGE. BUT IF YOU ARE DISTRIBUTING + * THAT IMAGE, YOU ARE BOUND TO THE GPL, AND YOU HAVE TO DISTRIBUTE THE + * SOURCE CODE, TOO. IF YOU DON'T: A) YOU ACKNOWLEDGE THAT YOU'RE AN + * ABSOLUTE JERK, AND B) YOU'RE NOT PERMITTED TO USE THIS CODE. AT ALL. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ZAPBACK_ALERT_PERIOD 15 // seconds. Keep this in sync with the locales. + +static CAdZapMenu *azm = NULL; + +CAdZapMenu *CAdZapMenu::getInstance() +{ + if (!azm) + azm = new CAdZapMenu(); + return azm; +} + +CAdZapMenu::CAdZapMenu() +{ + frameBuffer = CFrameBuffer::getInstance(); + width = w_max(40, 10); + hheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); + mheight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getHeight(); + height = hheight + 13 * mheight + 10; + + x = (((g_settings.screen_EndX - g_settings.screen_StartX) - width) / 2) + g_settings.screen_StartX; + y = (((g_settings.screen_EndY - g_settings.screen_StartY) - height) / 2) + g_settings.screen_StartY; + + sem_init(&sem, 0, 0); + + pthread_t thr; + if (pthread_create(&thr, 0, CAdZapMenu::Run, this)) + fprintf(stderr, "ERROR: pthread_create(CAdZapMenu::CAdZapMenu)\n"); + else + pthread_detach(thr); + channelId = -1; + armed = false; + monitor = false; + alerted = false; +} + +static bool sortByDateTime(const CChannelEvent & a, const CChannelEvent & b) +{ + return a.startTime < b.startTime; +} + +void CAdZapMenu::Update() +{ + clock_gettime(CLOCK_REALTIME, &zapBackTime); + zapBackTime.tv_sec += g_settings.adzap_zapBackPeriod - ZAPBACK_ALERT_PERIOD; + sem_post(&sem); +} + +void *CAdZapMenu::Run(void *arg) +{ + CAdZapMenu *me = (CAdZapMenu *) arg; + me->Run(); + pthread_exit(NULL); +} + +void CAdZapMenu::Run() +{ + set_threadname("CAdZapMenu::Run"); + while (true) { + CChannelList *channelList = NULL; + t_channel_id curChannelId = -1; + + if (monitor) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += 1; + + sem_timedwait(&sem, &ts); + + if (monitor && (monitorLifeTime.tv_sec > ts.tv_sec)) { + channelList = CNeutrinoApp::getInstance()->channelList; + curChannelId = + channelList ? channelList->getActiveChannel_ChannelID() + : -1; + if (!armed && (channelId != curChannelId)) { + armed = true; + clock_gettime(CLOCK_REALTIME, &zapBackTime); + zapBackTime.tv_sec += + g_settings.adzap_zapBackPeriod - + ZAPBACK_ALERT_PERIOD; + alerted = false; + } else if (channelId == curChannelId) { + armed = false; + alerted = false; + } + } else { + monitor = false; + armed = false; + alerted = false; + } + } else if (armed) + sem_timedwait(&sem, &zapBackTime); + else + sem_wait(&sem); + + if (armed) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + if (ts.tv_sec >= zapBackTime.tv_sec) { + if (!channelList) { + channelList = CNeutrinoApp::getInstance()->channelList; + curChannelId = + channelList ? + channelList->getActiveChannel_ChannelID() : -1; + } + if (!alerted) { + if (channelId != curChannelId) { + std::string name = + g_Locale->getText(LOCALE_ADZAP_ANNOUNCE); + name += "\n" + channelName; + ShowHint(LOCALE_ADZAP, name.c_str()); + } + alerted = true; + zapBackTime.tv_sec += ZAPBACK_ALERT_PERIOD; + } else { + alerted = false; + if (channelList) + channelList->zapTo_ChannelID(channelId); + armed = false; + } + } + } + } +} + +int CAdZapMenu::exec(CMenuTarget *parent, const std::string & actionKey) +{ + int res = menu_return::RETURN_EXIT_ALL; + + if (actionKey == "enable") { + if (!monitor) + armed = true; + alerted = false; + Update(); + return res; + } + if (actionKey == "disable") { + armed = false; + monitor = false; + alerted = false; + Update(); + return res; + } + if (actionKey == "monitor") { + armed = false; + monitor = true; + alerted = false; + Update(); + return res; + } + + if (actionKey == "adzap") { + if (armed || monitor) { + armed = false; + monitor = false; + alerted = false; + Update(); + ShowHint(LOCALE_ADZAP, LOCALE_ADZAP_CANCEL, 450, 1); + return res; + } + } + if (actionKey.length() == 1) { + g_settings.adzap_zapBackPeriod = actionKey[0] - '0'; + for (int shortcut = 1; shortcut < 10; shortcut++) + forwarders[shortcut - 1]->setMarked(shortcut == g_settings.adzap_zapBackPeriod); + g_settings.adzap_zapBackPeriod *= 60; + return menu_return::RETURN_REPAINT; + } + + if (parent) + parent->hide(); + + Settings(); + + return res; +} + +void CAdZapMenu::Settings() +{ + CChannelList *channelList = CNeutrinoApp::getInstance()->channelList; + channelId = + channelList ? channelList->getActiveChannel_ChannelID() : -1; + channelName = channelList->getActiveChannelName(); + + CMenuWidget *menu = new CMenuWidget(LOCALE_ADZAP, "settings", width); + menu->addItem(new + CMenuSeparator(CMenuSeparator::LINE | + CMenuSeparator::STRING, + LOCALE_ADZAP_SWITCHBACK)); + neutrino_locale_t minute = LOCALE_ADZAP_MINUTE; + for (int shortcut = 1; shortcut < 10; shortcut++) { + char actionKey[2]; + actionKey[0] = '0' + shortcut; + actionKey[1] = 0; + bool selected = g_settings.adzap_zapBackPeriod == 60 * shortcut; + forwarders[shortcut - 1] = + new CMenuForwarder(minute, true, NULL, this, actionKey, + CRCInput::convertDigitToKey(shortcut)); + forwarders[shortcut - 1]->setMarked(selected); + menu->addItem(forwarders[shortcut - 1], selected); + minute = LOCALE_ADZAP_MINUTES; + } + + menu->addItem(GenericMenuSeparatorLine); + + menu->addItem(new + CMenuForwarder(LOCALE_ADZAP_DISABLE, true, NULL, this, + "disable", CRCInput::RC_red, + NEUTRINO_ICON_BUTTON_RED)); + menu->addItem(new + CMenuForwarder(LOCALE_ADZAP_ENABLE, true, NULL, this, + "enable", CRCInput::RC_green, + NEUTRINO_ICON_BUTTON_GREEN)); + + CChannelEventList evtlist; + CEitManager::getInstance()->getEventsServiceKey(channelId & + 0xFFFFFFFFFFFFULL, + evtlist); + monitorLifeTime.tv_sec = 0; + if (!evtlist.empty()) { + sort(evtlist.begin(), evtlist.end(), sortByDateTime); + CChannelEventList::iterator eli; + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + for (eli = evtlist.begin(); eli != evtlist.end(); ++eli) { + if ((u_int) eli->startTime + (u_int) eli->duration > + (u_int) ts.tv_sec) { + monitorLifeTime.tv_sec = (uint) eli->startTime + eli->duration; + Update(); + break; + } + } + } + + menu->addItem(new + CMenuForwarder(LOCALE_ADZAP_MONITOR, + monitorLifeTime.tv_sec, NULL, this, + "monitor", CRCInput::RC_blue, + NEUTRINO_ICON_BUTTON_BLUE)); + + monitor = false; + menu->exec(NULL, ""); + menu->hide(); + delete menu; + Update(); +} diff --git a/src/gui/adzap.h b/src/gui/adzap.h new file mode 100644 index 000000000..6be3dd433 --- /dev/null +++ b/src/gui/adzap.h @@ -0,0 +1,61 @@ +/* + * adzap.h + * + * (C)2012 by martii + * + * License: GPL + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is 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 __adzap__ +#define __adzap__ + +#include "widget/menue.h" +#include +#include +#include +#include + +class CAdZapMenu: public CMenuTarget +{ + private: + CFrameBuffer * frameBuffer; + int x; + int y; + int width; + int height; + int hheight, mheight; // head/menu font height + bool running; + bool armed; + bool alerted; + bool monitor; + struct timespec zapBackTime; + std::string channelName; + CMenuForwarder *forwarders[9]; + struct timespec monitorLifeTime; + t_channel_id channelId; + sem_t sem; + CAdZapMenu(); + void Settings(); + void Update(); + void Run(void); + static void *Run(void *arg); + public: + static CAdZapMenu *getInstance(); + int exec(CMenuTarget * parent, const std::string & actionKey); +}; +#endif // __adzap__ diff --git a/src/gui/user_menue.cpp b/src/gui/user_menue.cpp index 60e5f6b37..f4e643dc1 100644 --- a/src/gui/user_menue.cpp +++ b/src/gui/user_menue.cpp @@ -372,12 +372,12 @@ bool CUserMenu::showUserMenu(neutrino_msg_t msg) menu_item = new CMenuForwarder(!g_settings.mode_clock ? LOCALE_CLOCK_SWITCH_ON:LOCALE_CLOCK_SWITCH_OFF, true, NULL, neutrino, "clock_switch", key, icon); menu_item->setHint("", LOCALE_MENU_HINT_CLOCK_MODE); break; -#if 0 case SNeutrinoSettings::ITEM_ADZAP: keyhelper.get(&key,&icon,CRCInput::RC_blue); menu_item = new CMenuForwarder(LOCALE_USERMENU_ITEM_ADZAP, true, NULL, neutrino, "adzap", key, icon); menu_item->setHint("", LOCALE_MENU_HINT_ADZAP); break; +#if 0 case SNeutrinoSettings::ITEM_TUNER_RESTART: keyhelper.get(&key,&icon); menu_item = new CMenuForwarder(LOCALE_SERVICEMENU_RESTART_TUNER, true, NULL, neutrino, "restarttuner", key, icon); diff --git a/src/gui/user_menue_setup.cpp b/src/gui/user_menue_setup.cpp index 643e0a2db..1e3527344 100644 --- a/src/gui/user_menue_setup.cpp +++ b/src/gui/user_menue_setup.cpp @@ -100,7 +100,6 @@ static keyvals usermenu_items[] = { SNeutrinoSettings::ITEM_SCRIPTS, LOCALE_MAINMENU_SCRIPTS, usermenu_show }, { SNeutrinoSettings::ITEM_LUA, LOCALE_MAINMENU_LUA, usermenu_show }, #if 0 - { SNeutrinoSettings::ITEM_ADZAP, LOCALE_USERMENU_ITEM_ADZAP, usermenu_show }, { SNeutrinoSettings::ITEM_TUNER_RESTART, LOCALE_SERVICEMENU_RESTART_TUNER, usermenu_show }, { SNeutrinoSettings::ITEM_THREE_D_MODE, LOCALE_THREE_D_SETTINGS, usermenu_show_three_d_mode }, { SNeutrinoSettings::ITEM_RASS, LOCALE_RASS_HEAD, usermenu_show }, @@ -112,6 +111,7 @@ static keyvals usermenu_items[] = { SNeutrinoSettings::ITEM_NETSETTINGS, LOCALE_MAINSETTINGS_NETWORK, usermenu_show }, { SNeutrinoSettings::ITEM_SWUPDATE, LOCALE_SERVICEMENU_UPDATE, usermenu_show }, { SNeutrinoSettings::ITEM_LIVESTREAM_RESOLUTION,LOCALE_LIVESTREAM_RESOLUTION, usermenu_show }, + { SNeutrinoSettings::ITEM_ADZAP, LOCALE_USERMENU_ITEM_ADZAP, usermenu_show }, { SNeutrinoSettings::ITEM_MAX, NONEXISTANT_LOCALE, usermenu_show } }; diff --git a/src/neutrino.cpp b/src/neutrino.cpp index a31dcdb47..c8cc9041b 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -65,6 +65,7 @@ #include #include +#include "gui/adzap.h" #include "gui/audiomute.h" #include "gui/audioplayer.h" #include "gui/bouquetlist.h" @@ -828,6 +829,7 @@ int CNeutrinoApp::loadSetup(const char * fname) } g_settings.epg_search_history_size = g_settings.epg_search_history.size(); + g_settings.adzap_zapBackPeriod = configfile.getInt32("adzap_zapBackPeriod", 180); // USERMENU -> in system/settings.h //------------------------------------------- @@ -1314,6 +1316,7 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt64("startchanneltv_id", g_settings.startchanneltv_id); configfile.setInt64("startchannelradio_id", g_settings.startchannelradio_id); configfile.setInt32("uselastchannel", g_settings.uselastchannel); + configfile.setInt32("adzap_zapBackPeriod", g_settings.adzap_zapBackPeriod); //epg search g_settings.epg_search_history_size = g_settings.epg_search_history.size(); if (g_settings.epg_search_history_size > g_settings.epg_search_history_max) @@ -4000,6 +4003,10 @@ int CNeutrinoApp::exec(CMenuTarget* parent, const std::string & actionKey) exit(1); } } + else if(actionKey == "adzap") { + CAdZapMenu::getInstance()->exec(parent, "adzap"); + return menu_return::RETURN_EXIT_ALL; + } else if(actionKey == "moviedir") { parent->hide(); diff --git a/src/system/locals.h b/src/system/locals.h index 7ed5c56ee..965d6cd84 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -135,6 +135,14 @@ typedef enum LOCALE_GENRE_TRAVEL_HOBBIES_7, LOCALE_GENRE_UNKNOWN, LOCALE_ADZAP, + LOCALE_ADZAP_ANNOUNCE, + LOCALE_ADZAP_CANCEL, + LOCALE_ADZAP_DISABLE, + LOCALE_ADZAP_ENABLE, + LOCALE_ADZAP_MINUTE, + LOCALE_ADZAP_MINUTES, + LOCALE_ADZAP_MONITOR, + LOCALE_ADZAP_SWITCHBACK, LOCALE_APIDSELECTOR_HEAD, LOCALE_AUDIO_SRS_ALGO, LOCALE_AUDIO_SRS_ALGO_HEAVY, @@ -966,6 +974,7 @@ typedef enum LOCALE_MENU_BACK, LOCALE_MENU_CANCEL, LOCALE_MENU_HINT_A_PIC, + LOCALE_MENU_HINT_ADZAP, LOCALE_MENU_HINT_APLAY, LOCALE_MENU_HINT_APLAY_SETUP, LOCALE_MENU_HINT_AUDIO, @@ -2386,6 +2395,7 @@ typedef enum LOCALE_USERMENU_BUTTON_RED, LOCALE_USERMENU_BUTTON_YELLOW, LOCALE_USERMENU_HEAD, + LOCALE_USERMENU_ITEM_ADZAP, LOCALE_USERMENU_ITEM_BAR, LOCALE_USERMENU_ITEM_EPG_MISC, LOCALE_USERMENU_ITEM_NONE, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index d2fc1f5e2..2eb1f2b95 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -135,6 +135,14 @@ const char * locale_real_names[] = "GENRE.TRAVEL_HOBBIES.7", "GENRE.UNKNOWN", "adzap", + "adzap.announce", + "adzap.cancel", + "adzap.disable", + "adzap.enable", + "adzap.minute", + "adzap.minutes", + "adzap.monitor", + "adzap.switchback", "apidselector.head", "audio.srs_algo", "audio.srs_algo_heavy", @@ -966,6 +974,7 @@ const char * locale_real_names[] = "menu.back", "menu.cancel", "menu.hint_a_pic", + "menu.hint_adzap", "menu.hint_aplay", "menu.hint_aplay_setup", "menu.hint_audio", @@ -2386,6 +2395,7 @@ const char * locale_real_names[] = "usermenu.button_red", "usermenu.button_yellow", "usermenu.head", + "usermenu.item_adzap", "usermenu.item_bar", "usermenu.item_epg_misc", "usermenu.item_none", diff --git a/src/system/settings.h b/src/system/settings.h index 1dede46a9..c254c7184 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -729,6 +729,9 @@ struct SNeutrinoSettings t_channel_id startchannelradio_id; int uselastchannel; + //adzap + int adzap_zapBackPeriod; + int power_standby; int hdd_sleep; int hdd_noise; @@ -789,6 +792,7 @@ struct SNeutrinoSettings ITEM_SWUPDATE = 30, ITEM_LIVESTREAM_RESOLUTION = 31, + ITEM_ADZAP = 32, ITEM_MAX // MUST be always the last in the list } USER_ITEM; @@ -817,8 +821,6 @@ struct SNeutrinoSettings }; }; -/* some default Values */ - extern const struct personalize_settings_t personalize_settings[SNeutrinoSettings::P_SETTINGS_MAX]; typedef struct time_settings_t @@ -865,9 +867,6 @@ const time_settings_struct_t timing_setting[SNeutrinoSettings::TIMING_SETTING_CO // shadow #define SHADOW_OFFSET 6 -/* end default values */ - - struct SglobalInfo { unsigned char box_Type;