diff --git a/src/driver/rcinput.cpp b/src/driver/rcinput.cpp index de67c0f60..d1eb5417c 100644 --- a/src/driver/rcinput.cpp +++ b/src/driver/rcinput.cpp @@ -4,7 +4,7 @@ Copyright (C) 2001 Steffen Hehn 'McClean' 2003 thegoodguy - Copyright (C) 2008-2014,2016 Stefan Seyfried + Copyright (C) 2008-2012 Stefan Seyfried Copyright (C) 2013-2014 martii License: GPL @@ -529,6 +529,7 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6 //static __u16 rc_last_key = KEY_MAX; static __u16 rc_last_repeat_key = KEY_MAX; + struct timeval tv; struct timeval tvselect; uint64_t InitialTimeout = Timeout; int64_t targetTimeout; @@ -1210,7 +1211,6 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6 for (int i = 0; i < NUMBER_OF_EVENT_DEVICES; i++) { if ((fd_rc[i] != -1) && (FD_ISSET(fd_rc[i], &rfds))) { - uint64_t now_pressed = 0; t_input_event ev; memset(&ev, 0, sizeof(ev)); /* we later check for ev.type = EV_SYN = 0x00, so set something invalid here... */ @@ -1226,22 +1226,6 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6 } if (ev.type == EV_SYN) continue; /* ignore... */ - if (ev.value) { - /* try to compensate for possible changes in wall clock - * kernel ev.time default uses CLOCK_REALTIME, as does gettimeofday(). - * so subtract gettimeofday() from ev.time and then add - * CLOCK_MONOTONIC, which is supposed to not change with settimeofday. - * Everything would be much easier if we could use the post-kernel 3.4 - * EVIOCSCLOCKID ioctl :-) */ - struct timespec t1; - now_pressed = ev.time.tv_usec + ev.time.tv_sec * 1000000ULL; - if (!clock_gettime(CLOCK_MONOTONIC, &t1)) { - struct timeval t2; - gettimeofday(&t2, NULL); - now_pressed += t1.tv_sec * 1000000ULL + t1.tv_nsec / 1000; - now_pressed -= (t2.tv_usec + t2.tv_sec * 1000000ULL); - } - } SHTDCNT::getInstance()->resetSleepTimer(); if (ev.value && firstKey) { firstKey = false; @@ -1288,12 +1272,11 @@ void CRCInput::getMsg_us(neutrino_msg_t * msg, neutrino_msg_data_t * data, uint6 #ifdef RCDEBUG printf("rc_last_key %04x rc_last_repeat_key %04x\n\n", rc_last_key, rc_last_repeat_key); #endif - bool keyok = true; -#if 0 uint64_t now_pressed; + bool keyok = true; + tv = ev.time; now_pressed = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); -#endif if (trkey == rc_last_key) { /* only allow selected keys to be repeated */ if (mayRepeat(trkey, bAllowRepeatLR) || diff --git a/src/gui/bedit/bouqueteditor_bouquets.cpp b/src/gui/bedit/bouqueteditor_bouquets.cpp index c588464f0..3f829e2b8 100644 --- a/src/gui/bedit/bouqueteditor_bouquets.cpp +++ b/src/gui/bedit/bouqueteditor_bouquets.cpp @@ -2,15 +2,7 @@ Neutrino-GUI - DBoxII-Project Copyright (C) 2001 Steffen Hehn 'McClean' - Homepage: http://dbox.cyberphoria.org/ - - Kommentar: - - Diese GUI wurde von Grund auf neu programmiert und sollte nun vom - Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert - auf der Client-Server Idee, diese GUI ist also von der direkten DBox- - Steuerung getrennt. Diese wird dann von Daemons uebernommen. - + Copyright (C) 2009,2011,2013,2016 Stefan Seyfried License: GPL @@ -166,7 +158,7 @@ void CBEBouquetWidget::hide() void CBEBouquetWidget::updateSelection(unsigned int newpos) { - if(newpos == selected) + if (newpos == selected || newpos == (unsigned int)-1) return; unsigned int prev_selected = selected; @@ -272,34 +264,11 @@ int CBEBouquetWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* cancelMoveBouquet(); } } - else if (msg==CRCInput::RC_up || msg==(neutrino_msg_t)g_settings.key_pageup) + else if (msg == CRCInput::RC_up || msg == (neutrino_msg_t)g_settings.key_pageup || + msg == CRCInput::RC_down || msg == (neutrino_msg_t)g_settings.key_pagedown) { - if (!(Bouquets->empty())) { - int step = (msg == (neutrino_msg_t)g_settings.key_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); - } - } - else if (msg==CRCInput::RC_down || msg==(neutrino_msg_t)g_settings.key_pagedown) - { - if (!(Bouquets->empty())) { - int step = ((int) msg == g_settings.key_pagedown) ? listmaxshow : 1; // browse or step 1 - int new_selected = selected + step; - if (new_selected > (int) Bouquets->size() - 1) { - if ((selected != Bouquets->size() - 1)) - new_selected = Bouquets->size() - 1; - else - new_selected = 0; - } - updateSelection(new_selected); - } + int new_selected = UpDownKey(*Bouquets, msg, listmaxshow, selected); + updateSelection(new_selected); } else if (msg == (neutrino_msg_t) g_settings.key_list_start || msg == (neutrino_msg_t) g_settings.key_list_end) { if (!(Bouquets->empty())) { diff --git a/src/gui/bedit/bouqueteditor_bouquets.h b/src/gui/bedit/bouqueteditor_bouquets.h index 1c935b587..256bd25bb 100644 --- a/src/gui/bedit/bouqueteditor_bouquets.h +++ b/src/gui/bedit/bouqueteditor_bouquets.h @@ -39,6 +39,7 @@ #include #include #include +#include #include /* class for handling when bouquets changed. */ @@ -51,7 +52,7 @@ public: virtual void onBouquetsChanged() {}; }; -class CBEBouquetWidget : public CMenuTarget +class CBEBouquetWidget : public CMenuTarget, public CListHelpers { private: diff --git a/src/gui/bedit/bouqueteditor_channels.cpp b/src/gui/bedit/bouqueteditor_channels.cpp index 3a6a14ba5..8a9ef7157 100644 --- a/src/gui/bedit/bouqueteditor_channels.cpp +++ b/src/gui/bedit/bouqueteditor_channels.cpp @@ -5,14 +5,7 @@ Homepage: http://dbox.cyberphoria.org/ Copyright (C) 2011 CoolStream International Ltd - - Kommentar: - - Diese GUI wurde von Grund auf neu programmiert und sollte nun vom - Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert - auf der Client-Server Idee, diese GUI ist also von der direkten DBox- - Steuerung getrennt. Diese wird dann von Daemons uebernommen. - + Copyright (C) 2009,2011,2013,2016 Stefan Seyfried License: GPL @@ -283,7 +276,7 @@ void CBEChannelWidget::hide() void CBEChannelWidget::updateSelection(unsigned int newpos) { - if(newpos == selected) + if (newpos == selected || newpos == (unsigned int)-1) return; unsigned int prev_selected = selected; @@ -360,34 +353,11 @@ int CBEChannelWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* cancelMoveChannel(); } } - else if (msg==CRCInput::RC_up || msg==(neutrino_msg_t)g_settings.key_pageup) + else if (msg == CRCInput::RC_up || msg == (neutrino_msg_t)g_settings.key_pageup || + msg == CRCInput::RC_down || msg == (neutrino_msg_t)g_settings.key_pagedown) { - if (!(Channels->empty())) { - int step = (msg == (neutrino_msg_t)g_settings.key_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 = Channels->size() - 1; - } - updateSelection(new_selected); - } - } - else if (msg==CRCInput::RC_down || msg==(neutrino_msg_t)g_settings.key_pagedown) - { - if (!(Channels->empty())) { - int step = ((int) msg == g_settings.key_pagedown) ? listmaxshow : 1; // browse or step 1 - int new_selected = selected + step; - if (new_selected > (int) Channels->size() - 1) { - if ((selected != Channels->size() - 1)) - new_selected = Channels->size() - 1; - else - new_selected = 0; - } - updateSelection(new_selected); - } + int new_selected = UpDownKey(*Channels, msg, listmaxshow, selected); + updateSelection(new_selected); } else if (msg == (neutrino_msg_t) g_settings.key_list_start || msg == (neutrino_msg_t) g_settings.key_list_end) { if (!(Channels->empty())) { diff --git a/src/gui/bedit/bouqueteditor_channels.h b/src/gui/bedit/bouqueteditor_channels.h index fd17636fb..d13b9aa74 100644 --- a/src/gui/bedit/bouqueteditor_channels.h +++ b/src/gui/bedit/bouqueteditor_channels.h @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -42,7 +43,7 @@ #include #include -class CBEChannelWidget : public CMenuTarget +class CBEChannelWidget : public CMenuTarget, public CListHelpers { private: diff --git a/src/gui/bouquetlist.cpp b/src/gui/bouquetlist.cpp index 59d357aa9..567438610 100644 --- a/src/gui/bouquetlist.cpp +++ b/src/gui/bouquetlist.cpp @@ -2,15 +2,7 @@ Neutrino-GUI - DBoxII-Project Copyright (C) 2001 Steffen Hehn 'McClean' - Homepage: http://dbox.cyberphoria.org/ - - Kommentar: - - Diese GUI wurde von Grund auf neu programmiert und sollte nun vom - Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert - auf der Client-Server Idee, diese GUI ist also von der direkten DBox- - Steuerung getrennt. Diese wird dann von Daemons uebernommen. - + Copyright (C) 2009,2011,2013,2015-2016 Stefan Seyfried License: GPL @@ -391,6 +383,8 @@ const struct button_label CBouquetListButtons[4] = void CBouquetList::updateSelection(int newpos) { + if (newpos < 0) /* to avoid all callers having to check */ + return; if((int) selected != newpos) { int prev_selected = selected; unsigned int oldliststart = liststart; @@ -528,33 +522,11 @@ int CBouquetList::show(bool bShowChannelList) if (!Bouquets.empty()) updateSelection(Bouquets.size()-1); } - else if (msg == CRCInput::RC_up || (int) msg == g_settings.key_pageup) + else if (msg == CRCInput::RC_up || (int) msg == g_settings.key_pageup || + msg == CRCInput::RC_down || (int) msg == g_settings.key_pagedown) { - if (!Bouquets.empty()) { - int step = ((int) msg == g_settings.key_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); - } - } - else if (msg == CRCInput::RC_down || (int) msg == g_settings.key_pagedown) - { - if (!Bouquets.empty()) { - int step = ((int) msg == g_settings.key_pagedown) ? listmaxshow : 1; // browse or step 1 - int new_selected = selected + step; - if (new_selected > (int) Bouquets.size() - 1) { - if ((selected != Bouquets.size() - 1)) - new_selected = Bouquets.size() - 1; - else - new_selected = 0; - } - updateSelection(new_selected); - } + int new_selected = UpDownKey(Bouquets, msg, listmaxshow, selected); + updateSelection(new_selected); } else if(msg == (neutrino_msg_t)g_settings.key_bouquet_up || msg == (neutrino_msg_t)g_settings.key_bouquet_down) { if(bShowChannelList) { diff --git a/src/gui/bouquetlist.h b/src/gui/bouquetlist.h index e767a6c47..1ba8a199e 100644 --- a/src/gui/bouquetlist.h +++ b/src/gui/bouquetlist.h @@ -34,6 +34,7 @@ #define __bouquetlist__ #include +#include #include #include @@ -77,7 +78,7 @@ class CBouquet }; -class CBouquetList +class CBouquetList : public CListHelpers { private: CFrameBuffer *frameBuffer; diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index 55420818f..9980d88f7 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -2,7 +2,7 @@ Neutrino-GUI - DBoxII-Project Copyright (C) 2001 Steffen Hehn 'McClean' - Copyright (C) 2007-2015 Stefan Seyfried + Copyright (C) 2007-2016 Stefan Seyfried Kommentar: @@ -728,31 +728,13 @@ int CChannelList::show() else if (!empty && msg == (neutrino_msg_t) g_settings.key_list_end) { actzap = updateSelection((*chanlist).size()-1); } - else if (!empty && (msg == CRCInput::RC_up || (int) msg == g_settings.key_pageup)) + else if (!empty && (msg == CRCInput::RC_up || (int)msg == g_settings.key_pageup || + msg == CRCInput::RC_down || (int)msg == g_settings.key_pagedown)) { displayList = 1; - int step = ((int) msg == g_settings.key_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 = (*chanlist).size() - 1; - } - actzap = updateSelection(new_selected); - } - else if (!empty && (msg == CRCInput::RC_down || (int) msg == g_settings.key_pagedown)) - { - displayList = 1; - int step = ((int) msg == g_settings.key_pagedown) ? listmaxshow : 1; // browse or step 1 - int new_selected = selected + step; - if (new_selected > (int) (*chanlist).size() - 1) { - if ((selected != (*chanlist).size() - 1)) - new_selected = (*chanlist).size() - 1; - else - new_selected = 0; - } - actzap = updateSelection(new_selected); + int new_selected = UpDownKey((*chanlist), msg, listmaxshow, selected); + if (new_selected >= 0) + actzap = updateSelection(new_selected); } else if (!edit_state && (msg == (neutrino_msg_t)g_settings.key_bouquet_up || msg == (neutrino_msg_t)g_settings.key_bouquet_down)) { diff --git a/src/gui/channellist.h b/src/gui/channellist.h index 96014b6b4..21d2babda 100644 --- a/src/gui/channellist.h +++ b/src/gui/channellist.h @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -63,7 +64,7 @@ enum { class CBouquet; -class CChannelList +class CChannelList : public CListHelpers { private: enum state_ diff --git a/src/gui/eventlist.cpp b/src/gui/eventlist.cpp index 49f76757d..7f6560d49 100644 --- a/src/gui/eventlist.cpp +++ b/src/gui/eventlist.cpp @@ -4,7 +4,7 @@ Copyright (C) 2001 Steffen Hehn 'McClean' Homepage: http://dbox.cyberphoria.org/ - Copyright (C) 2009-2014 Stefan Seyfried + Copyright (C) 2009-2016 Stefan Seyfried License: GPL @@ -359,7 +359,6 @@ int CEventList::exec(const t_channel_id channel_id, const std::string& channelna msg == CRCInput::RC_down || (int) msg == g_settings.key_pagedown) { bool paint_buttonbar = false; //function bar - int step = 0; int prev_selected = selected; // TODO: do we need this at all? Search button is always painted IIUC... if ((g_settings.key_channelList_addremind != (int)CRCInput::RC_nokey) || @@ -367,27 +366,9 @@ int CEventList::exec(const t_channel_id channel_id, const std::string& channelna ((g_settings.recording_type != CNeutrinoApp::RECORDING_OFF) && (g_settings.key_channelList_addrecord != (int)CRCInput::RC_nokey))) paint_buttonbar = true; - - if (msg == CRCInput::RC_up || (int) msg == g_settings.key_pageup) - { - step = ((int) msg == g_settings.key_pageup) ? listmaxshow : 1; // browse or step 1 - selected -= step; - if((prev_selected-step) < 0) // because of uint - selected = evtlist.size() - 1; - paintDescription(selected); - } - else if (msg == CRCInput::RC_down || (int) msg == g_settings.key_pagedown) - { - step = ((int) msg == g_settings.key_pagedown) ? listmaxshow : 1; // browse or step 1 - selected += step; - - if(selected >= evtlist.size()) - { - if (((evtlist.size() / listmaxshow) + 1) * listmaxshow == evtlist.size() + listmaxshow) // last page has full entries - selected = 0; - else - selected = ((step == (int)listmaxshow) && (selected < (((evtlist.size() / listmaxshow) + 1) * listmaxshow))) ? (evtlist.size() - 1) : 0; - } + int new_sel = UpDownKey(evtlist, msg, listmaxshow, selected); + if (new_sel >= 0) { + selected = new_sel; paintDescription(selected); } paintItem(prev_selected - liststart, channel_id); diff --git a/src/gui/eventlist.h b/src/gui/eventlist.h index 9bda01658..a5d9b9737 100644 --- a/src/gui/eventlist.h +++ b/src/gui/eventlist.h @@ -40,11 +40,12 @@ #include "infoviewer.h" #include "widget/menue.h" +#include "widget/listhelpers.h" #include -class CEventList +class CEventList : public CListHelpers { // Eventfinder start public: diff --git a/src/gui/timerlist.cpp b/src/gui/timerlist.cpp index 906424103..a0a5faac4 100644 --- a/src/gui/timerlist.cpp +++ b/src/gui/timerlist.cpp @@ -458,7 +458,7 @@ void CTimerList::updateEvents(void) height = theight+listmaxshow*fheight*2+footerHeight; // recalc height } - if (selected==timerlist.size() && !(timerlist.empty())) + if (!timerlist.empty() && selected == (int)timerlist.size()) { selected=timerlist.size()-1; liststart = (selected/listmaxshow)*listmaxshow; @@ -519,58 +519,22 @@ int CTimerList::show() loop=false; } - else if ((msg == CRCInput::RC_up || msg == (unsigned int)g_settings.key_pageup) && !(timerlist.empty())) + else if (!timerlist.empty() && + (msg == CRCInput::RC_up || (int)msg == g_settings.key_pageup || + msg == CRCInput::RC_down || (int)msg == g_settings.key_pagedown)) { - int step = 0; int prev_selected = selected; - - step = (msg == (unsigned int)g_settings.key_pageup) ? listmaxshow : 1; // browse or step 1 - selected -= step; - if((prev_selected-step) < 0) // because of uint - selected = timerlist.size() - 1; - - paintItem(prev_selected - liststart); - unsigned int oldliststart = liststart; - liststart = (selected/listmaxshow)*listmaxshow; - if (oldliststart!=liststart) - { + int oldliststart = liststart; + selected = UpDownKey(timerlist, msg, listmaxshow, selected); + if (selected < 0) /* UpDownKey error */ + selected = prev_selected; + liststart = (selected / listmaxshow) * listmaxshow; + if (oldliststart != liststart) paint(); - } - else - { + else { + paintItem(prev_selected - liststart); paintItem(selected - liststart); } - - paintFoot(); - } - else if ((msg == CRCInput::RC_down || msg == (unsigned int)g_settings.key_pagedown) && !(timerlist.empty())) - { - unsigned int step = 0; - int prev_selected = selected; - - step = (msg == (unsigned int)g_settings.key_pagedown) ? listmaxshow : 1; // browse or step 1 - selected += step; - - if(selected >= timerlist.size()) - { - if (((timerlist.size() / listmaxshow) + 1) * listmaxshow == timerlist.size() + listmaxshow) // last page has full entries - selected = 0; - else - selected = ((step == listmaxshow) && (selected < (((timerlist.size() / listmaxshow) + 1) * listmaxshow))) ? (timerlist.size() - 1) : 0; - } - paintItem(prev_selected - liststart); - - unsigned int oldliststart = liststart; - liststart = (selected/listmaxshow)*listmaxshow; - if (oldliststart!=liststart) - { - paint(); - } - else - { - paintItem(selected - liststart); - } - paintFoot(); } else if ((msg == CRCInput::RC_right || msg == CRCInput::RC_ok || msg==CRCInput::RC_blue) && !(timerlist.empty())) @@ -719,7 +683,7 @@ void CTimerList::paintItem(int pos) //selected item frameBuffer->paintBoxRel(x,ypos, real_width, 2*fheight, bgcolor, RADIUS_MID); - if (liststart+pos #include +#include #include @@ -43,7 +44,7 @@ class CTimerdClient; -class CTimerList : public CMenuTarget +class CTimerList : public CMenuTarget, public CListHelpers { private: CFrameBuffer *frameBuffer; @@ -54,8 +55,8 @@ class CTimerList : public CMenuTarget int fheight; // fontheight content int theight; // fontheight titel int footerHeight; - unsigned int selected; - unsigned int liststart; + int selected; + int liststart; unsigned int listmaxshow; bool visible; diff --git a/src/gui/upnpbrowser.cpp b/src/gui/upnpbrowser.cpp index 509300bb0..dd18cee43 100644 --- a/src/gui/upnpbrowser.cpp +++ b/src/gui/upnpbrowser.cpp @@ -2,16 +2,7 @@ Neutrino-GUI - DBoxII-Project UPnP Browser (c) 2007 by Jochen Friedrich - - Homepage: http://dbox.cyberphoria.org/ - - Kommentar: - - Diese GUI wurde von Grund auf neu programmiert und sollte nun vom - Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert - auf der Client-Server Idee, diese GUI ist also von der direkten DBox- - Steuerung getrennt. Diese wird dann von Daemons uebernommen. - + (c) 2009-2011,2016 Stefan Seyfried License: GPL @@ -436,6 +427,8 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) void CUpnpBrowserGui::updateDeviceSelection(int newpos) { + if (newpos < 0) /* do not explode if called with -1 arg... */ + return; if((int) m_selecteddevice != newpos) { int prev_selected = m_selecteddevice; unsigned int oldliststart = m_deviceliststart; @@ -488,28 +481,10 @@ void CUpnpBrowserGui::selectDevice() else if (msg_repeatok == (neutrino_msg_t) g_settings.key_list_end) { updateDeviceSelection(m_devices.size()-1); } - else if (msg_repeatok == CRCInput::RC_up || (int) msg == g_settings.key_pageup) + else if (msg_repeatok == CRCInput::RC_up || (int)msg == g_settings.key_pageup || + msg_repeatok == CRCInput::RC_down || (int)msg == g_settings.key_pagedown) { - int step = ((int) msg == g_settings.key_pageup) ? m_listmaxshow : 1; // browse or step 1 - int new_selected = m_selecteddevice - step; - if (new_selected < 0) { - if (m_selecteddevice != 0 && step != 1) - new_selected = 0; - else - new_selected = m_devices.size() - 1; - } - updateDeviceSelection(new_selected); - } - else if (msg_repeatok == CRCInput::RC_down || (int) msg == g_settings.key_pagedown) - { - int step = ((int) msg == g_settings.key_pagedown) ? m_listmaxshow : 1; // browse or step 1 - int new_selected = m_selecteddevice + step; - if (new_selected > (int) m_devices.size() - 1) { - if ((m_selecteddevice != m_devices.size() - 1)) - new_selected = m_devices.size() - 1; - else - new_selected = 0; - } + int new_selected = UpDownKey(m_devices, msg_repeatok, m_listmaxshow, m_selecteddevice); updateDeviceSelection(new_selected); } else if (msg == CRCInput::RC_right || msg == CRCInput::RC_ok) diff --git a/src/gui/upnpbrowser.h b/src/gui/upnpbrowser.h index 1e7f78051..940122d6a 100644 --- a/src/gui/upnpbrowser.h +++ b/src/gui/upnpbrowser.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -66,7 +67,7 @@ struct UPnPEntry int type; }; -class CUpnpBrowserGui : public CMenuTarget +class CUpnpBrowserGui : public CMenuTarget, public CListHelpers { public: CUpnpBrowserGui(); diff --git a/src/gui/widget/Makefile.am b/src/gui/widget/Makefile.am index ea77f8b29..0788d0319 100644 --- a/src/gui/widget/Makefile.am +++ b/src/gui/widget/Makefile.am @@ -25,6 +25,7 @@ libneutrino_gui_widget_a_SOURCES = \ keyboard_input.cpp \ listbox.cpp \ listframe.cpp \ + listhelpers.cpp \ menue.cpp \ messagebox.cpp \ mountchooser.cpp \ diff --git a/src/gui/widget/listbox.cpp b/src/gui/widget/listbox.cpp index 836ff5d7f..683fbac03 100644 --- a/src/gui/widget/listbox.cpp +++ b/src/gui/widget/listbox.cpp @@ -186,33 +186,13 @@ int CListBox::exec(CMenuTarget* parent, const std::string & /*actionKey*/) { loop = false; } - else if (msg == CRCInput::RC_up || (int) msg == g_settings.key_pageup) + else if (msg == CRCInput::RC_up || (int) msg == g_settings.key_pageup || + msg == CRCInput::RC_down || (int) msg == g_settings.key_pagedown) { - if(getItemCount()!=0) { - int step = (msg == (neutrino_msg_t)g_settings.key_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 = getItemCount() - 1; - } - updateSelection(new_selected); - } - } - else if (msg == CRCInput::RC_down || (int) msg == g_settings.key_pagedown) - { - if(getItemCount()!=0) { - int step = ((int) msg == g_settings.key_pagedown) ? listmaxshow : 1; // browse or step 1 - int new_selected = selected + step; - if (new_selected > (int) getItemCount() - 1) { - if ((selected != getItemCount() - 1)) - new_selected = getItemCount() - 1; - else - new_selected = 0; - } - updateSelection(new_selected); + if (getItemCount() != 0) { + int new_selected = UpDownKey((int)getItemCount(), msg, listmaxshow, selected); + if (new_selected >= 0) + updateSelection(new_selected); } } else if (msg == (neutrino_msg_t) g_settings.key_list_start || msg == (neutrino_msg_t) g_settings.key_list_end) { diff --git a/src/gui/widget/listbox.h b/src/gui/widget/listbox.h index ce52081e0..26a27f8e6 100644 --- a/src/gui/widget/listbox.h +++ b/src/gui/widget/listbox.h @@ -26,12 +26,13 @@ #define __listbox__ #include "menue.h" +#include "listhelpers.h" #include #include -class CListBox : public CMenuTarget +class CListBox : public CMenuTarget, public CListHelpers { protected: CFrameBuffer* frameBuffer; diff --git a/src/gui/widget/listhelpers.cpp b/src/gui/widget/listhelpers.cpp new file mode 100644 index 000000000..9d3adf3ab --- /dev/null +++ b/src/gui/widget/listhelpers.cpp @@ -0,0 +1,87 @@ +/* + Helper functions for various list implementations in neutrino + Copyright (C) 2016 Stefan Seyfried + + 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, see http://www.gnu.org/licenses/ +*/ + +#include +#include "listhelpers.h" + +#include +#include +#include +#include + +static int upDownKey(int size, neutrino_msg_t msg, int lines, int sel) +{ + int step; + if (size <= 0) /* list.empty() or similar... */ + return -1; + + if (msg >= CRCInput::RC_MaxRC) { + printf("CListHelpers:%s: invalid key? 0x%lx\n", __func__, msg); + return -1; + } + int key = (int)msg; + if (key == g_settings.key_pageup) + step = -lines; + else if (key == g_settings.key_pagedown) + step = lines; + else if (msg == CRCInput::RC_up) + step = -1; + else if (msg == CRCInput::RC_down) + step = 1; + else { + printf("CListHelpers:%s: invalid key? 0x%lx\n", __func__, msg); + return -1; + } + // printf("CListHelpers:%s: key 0x%04lx lines %d size %d sel %d\n", __func__, msg, lines, size, sel); + int new_sel = sel + step; + if (new_sel < 0) { + if (sel != 0 && step != 1) + new_sel = 0; + else + new_sel = size - 1; + } + else if (new_sel > size - 1) { + if (sel != size - 1) + new_sel = size - 1; + else + new_sel = 0; + } + return new_sel; +} + +int CListHelpers::_UpDownKey(int size, neutrino_msg_t msg, int lines, int sel, _id) +{ + return upDownKey(size, msg, lines, sel); +} + +template int CListHelpers::_UpDownKey(T list, neutrino_msg_t msg, int lines, int sel, _id) +{ + return upDownKey(list.size(), msg, lines, sel); +} + +/* all used versions need to be prototyped here, to avoid linker errors */ +/* helper macro for the prototypes */ +#define updown_t(x) template int CListHelpers::_UpDownKey(x, neutrino_msg_t, int, int, _id) +updown_t(std::vector); +updown_t(std::vector); +updown_t(std::vector); +updown_t(std::vector); +updown_t(std::vector); +updown_t(std::vector); diff --git a/src/gui/widget/listhelpers.h b/src/gui/widget/listhelpers.h new file mode 100644 index 000000000..228bd88d7 --- /dev/null +++ b/src/gui/widget/listhelpers.h @@ -0,0 +1,38 @@ +/* + Helper functions for various list implementations in neutrino + Copyright (C) 2016 Stefan Seyfried + + 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, see http://www.gnu.org/licenses/ +*/ + + +#ifndef __LISTHELPERS__ +#define __LISTHELPERS__ +/* allow to trick the compiler into overriding template definitions */ +template struct _id { typedef T type; }; + +class CListHelpers +{ + public: + template int UpDownKey(T list, neutrino_msg_t k, int lines, int sel) { + return _UpDownKey(list, k, lines, sel, _id()); + } + private: + /* stackoverflow.com/questions/3052579 */ + template int _UpDownKey(T list, neutrino_msg_t k, int lines, int sel, _id); + int _UpDownKey(int list, neutrino_msg_t k, int lines, int sel, _id); +}; +#endif diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 4635f4085..f9b2899a1 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -4,7 +4,7 @@ Copyright (C) 2001 Steffen Hehn 'McClean' and some other guys - Copyright (C) 2006-2016 Stefan Seyfried + Copyright (C) 2006-2014 Stefan Seyfried Copyright (C) 2011 CoolStream International Ltd @@ -1880,11 +1880,7 @@ void CNeutrinoApp::InitSectiondClient() dprintf(DEBUG_NORMAL, "had to wait %ld ms for sectionsd to start up\n", time_monotonic_ms() - t); #endif g_Sectionsd = new CSectionsdClient; - struct timespec t; - if (clock_gettime(CLOCK_MONOTONIC, &t)) { - dprintf(DEBUG_NORMAL, "CLOCK_MONOTONIC not supported? (%m), falling back to EVT_TIMESET\n"); - g_Sectionsd->registerEvent(CSectionsdClient::EVT_TIMESET, 222, NEUTRINO_UDS_NAME); - } + g_Sectionsd->registerEvent(CSectionsdClient::EVT_TIMESET, 222, NEUTRINO_UDS_NAME); g_Sectionsd->registerEvent(CSectionsdClient::EVT_GOT_CN_EPG, 222, NEUTRINO_UDS_NAME); g_Sectionsd->registerEvent(CSectionsdClient::EVT_EIT_COMPLETE, 222, NEUTRINO_UDS_NAME); g_Sectionsd->registerEvent(CSectionsdClient::EVT_WRITE_SI_FINISHED, 222, NEUTRINO_UDS_NAME);