diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/assembler.c | 114 | ||||
-rw-r--r-- | client/assembler.h | 32 | ||||
-rw-r--r-- | client/device.c | 7 | ||||
-rw-r--r-- | client/device.h | 4 | ||||
-rw-r--r-- | client/menu.c | 802 | ||||
-rw-r--r-- | client/menu.h | 132 | ||||
-rw-r--r-- | client/remote.c | 465 | ||||
-rw-r--r-- | client/remote.h | 123 | ||||
-rw-r--r-- | client/setup.c | 4 | ||||
-rw-r--r-- | client/socket.c | 230 | ||||
-rw-r--r-- | client/socket.h | 13 |
11 files changed, 6 insertions, 1920 deletions
diff --git a/client/assembler.c b/client/assembler.c deleted file mode 100644 index c6f8115..0000000 --- a/client/assembler.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * $Id: assembler.c,v 1.3 2008/04/07 14:27:28 schmirl Exp $ - */ - -#include "client/assembler.h" -#include "common.h" - -#include "tools/socket.h" -#include "tools/select.h" - -#include <vdr/tools.h> -#include <vdr/device.h> -#include <vdr/ringbuffer.h> - -#include <unistd.h> - -cStreamdevAssembler::cStreamdevAssembler(cTBSocket *Socket) - :cThread("Streamdev: UDP-TS Assembler") -{ - m_Socket = Socket; - if (pipe(m_Pipe) != 0) { - esyslog("streamdev-client: Couldn't open assembler pipe: %m"); - return; - } - fcntl(m_Pipe[0], F_SETFL, O_NONBLOCK); - fcntl(m_Pipe[1], F_SETFL, O_NONBLOCK); - m_Mutex.Lock(); - Start(); -} - -cStreamdevAssembler::~cStreamdevAssembler() { - if (m_Active) { - m_Active = false; -/* WakeUp();*/ - Cancel(3); - } - close(m_Pipe[0]); - close(m_Pipe[1]); -} - -void cStreamdevAssembler::Action(void) { - cTBSelect sel; - uchar buffer[2048]; - bool fillup = true; - - const int rbsize = TS_SIZE * 5600; - const int rbmargin = TS_SIZE * 2; - const int rbminfill = rbmargin * 50; - cRingBufferLinear ringbuf(rbsize, rbmargin, true); - - m_Mutex.Lock(); - - m_Active = true; - while (m_Active) { - sel.Clear(); - - if (ringbuf.Available() < rbsize * 80 / 100) - sel.Add(*m_Socket, false); - if (ringbuf.Available() > rbminfill) { - if (fillup) { - Dprintf("giving signal\n"); - m_WaitFill.Broadcast(); - m_Mutex.Unlock(); - fillup = false; - } - sel.Add(m_Pipe[1], true); - } - - if (sel.Select(1500) < 0) { - if (!m_Active) // Exit was requested - break; - esyslog("streamdev-client: Fatal error: %m"); - Dprintf("streamdev-client: select failed (%m)\n"); - m_Active = false; - break; - } - - if (sel.CanRead(*m_Socket)) { - int b; - if ((b = m_Socket->Read(buffer, sizeof(buffer))) < 0) { - esyslog("streamdev-client: Couldn't read from server: %m"); - Dprintf("streamdev-client: read failed (%m)\n"); - m_Active = false; - break; - } - if (b == 0) - m_Active = false; - else - ringbuf.Put(buffer, b); - } - - if (sel.CanWrite(m_Pipe[1])) { - int recvd; - const uchar *block = ringbuf.Get(recvd); - if (block && recvd > 0) { - int result; - if (recvd > ringbuf.Available() - rbminfill) - recvd = ringbuf.Available() - rbminfill; - if ((result = write(m_Pipe[1], block, recvd)) == -1) { - esyslog("streamdev-client: Couldn't write to VDR: %m"); // TODO - Dprintf("streamdev-client: write failed (%m)\n"); - m_Active = false; - break; - } - ringbuf.Del(result); - } - } - } -} - -void cStreamdevAssembler::WaitForFill(void) { - m_WaitFill.Wait(m_Mutex); - m_Mutex.Unlock(); -} diff --git a/client/assembler.h b/client/assembler.h deleted file mode 100644 index a4b0747..0000000 --- a/client/assembler.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * $Id: assembler.h,v 1.1 2004/12/30 22:44:04 lordjaxom Exp $ - */ - -#ifndef VDR_STREAMDEV_ASSEMBLER_H -#define VDR_STREAMDEV_ASSEMBLER_H - -#include <vdr/config.h> -#include <vdr/thread.h> - -class cTBSocket; - -class cStreamdevAssembler: public cThread { -private: - cTBSocket *m_Socket; - cMutex m_Mutex; - cCondVar m_WaitFill; - int m_Pipe[2]; - bool m_Active; -protected: - virtual void Action(void); - -public: - cStreamdevAssembler(cTBSocket *Socket); - virtual ~cStreamdevAssembler(); - - int ReadPipe(void) const { return m_Pipe[0]; } - void WaitForFill(void); -}; - -#endif // VDR_STREAMDEV_ASSEMBLER_H - diff --git a/client/device.c b/client/device.c index d8cbe70..708b1dc 100644 --- a/client/device.c +++ b/client/device.c @@ -1,10 +1,9 @@ /* - * $Id: device.c,v 1.16 2008/04/07 14:27:28 schmirl Exp $ + * $Id: device.c,v 1.17 2008/04/07 14:40:39 schmirl Exp $ */ #include "client/device.h" #include "client/setup.h" -#include "client/assembler.h" #include "client/filter.h" #include "tools/select.h" @@ -26,11 +25,9 @@ cStreamdevDevice *cStreamdevDevice::m_Device = NULL; cStreamdevDevice::cStreamdevDevice(void) { m_Channel = NULL; m_TSBuffer = NULL; - m_Assembler = NULL; m_Filters = new cStreamdevFilters; StartSectionHandler(); - cSchedules::Read(); m_Device = this; m_Pids = 0; @@ -54,7 +51,6 @@ cStreamdevDevice::~cStreamdevDevice() { DELETENULL(m_Filters); DELETENULL(m_TSBuffer); - delete m_Assembler; } bool cStreamdevDevice::ProvidesSource(int Source) const { @@ -283,7 +279,6 @@ bool cStreamdevDevice::ReInit(void) { ClientSocket.Reset(); if (m_Device != NULL) { //DELETENULL(m_Device->m_TSBuffer); - DELETENULL(m_Device->m_Assembler); m_Device->Unlock(); } return StreamdevClientSetup.StartClient ? Init() : true; diff --git a/client/device.h b/client/device.h index cbc9235..0c7e918 100644 --- a/client/device.h +++ b/client/device.h @@ -1,5 +1,5 @@ /* - * $Id: device.h,v 1.6 2008/04/07 14:27:28 schmirl Exp $ + * $Id: device.h,v 1.7 2008/04/07 14:40:39 schmirl Exp $ */ #ifndef VDR_STREAMDEV_DEVICE_H @@ -8,7 +8,6 @@ #include <vdr/device.h> #include "client/socket.h" -#include "client/assembler.h" #include "client/filter.h" class cTBString; @@ -21,7 +20,6 @@ class cStreamdevDevice: public cDevice { private: const cChannel *m_Channel; cTSBuffer *m_TSBuffer; - cStreamdevAssembler *m_Assembler; cStreamdevFilters *m_Filters; int m_Pids; bool m_DvrClosed; diff --git a/client/menu.c b/client/menu.c deleted file mode 100644 index 679ee73..0000000 --- a/client/menu.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * $Id: menu.c,v 1.5 2008/04/07 14:27:28 schmirl Exp $ - */ - -#include <vdr/menuitems.h> -#include <vdr/interface.h> - -#include "client/menu.h" -#include "client/socket.h" -#include "i18n.h" - -#define CHNUMWIDTH (numdigits(Channels.MaxNumber()) + 1) - -// --- cMenuText ------------------------------------------------------------- - -class cMenuText : public cOsdMenu { -public: - cMenuText(const char *Title, const char *Text, eDvbFont Font = fontOsd); - virtual eOSState ProcessKey(eKeys Key); - }; - -// --- cStreamdevMenu -------------------------------------------------------- - -cStreamdevMenu::cStreamdevMenu(void): - cOsdMenu(tr("Streaming Control")) { - SetHasHotkeys(); - Add(new cOsdItem(hk(tr("Remote Schedule")), (eOSState)subSchedule)); - Add(new cOsdItem(hk(tr("Remote Timers")), (eOSState)subTimers)); - Add(new cOsdItem(hk(tr("Remote Recordings")), (eOSState)subRecordings)); - Add(new cOsdItem(hk(tr("Suspend Server")), (eOSState)subSuspend)); - Add(new cOsdItem(hk(tr("Synchronize EPG")), (eOSState)subSyncEPG)); -} - -cStreamdevMenu::~cStreamdevMenu() { -} - -eOSState cStreamdevMenu::ProcessKey(eKeys Key) { - eOSState state = cOsdMenu::ProcessKey(Key); - switch (state) { - case subSchedule: return AddSubMenu(new cStreamdevMenuSchedule); - case subTimers: return AddSubMenu(new cStreamdevMenuTimers); - case subRecordings: return AddSubMenu(new cStreamdevMenuRecordings); - case subSuspend: SuspendServer(); return osEnd; - case subSyncEPG: ClientSocket.SynchronizeEPG(); return osEnd; - default: return state; - } -} - -void cStreamdevMenu::SuspendServer(void) { - if (ClientSocket.SuspendServer()) - INFO(tr("Server is suspended")); - else - ERROR(tr("Couldn't suspend Server!")); -} - -// --- cStreamdevMenuEditTimer ----------------------------------------------- - -class cStreamdevMenuEditTimer : public cOsdMenu { -private: - int m_Channel; - bool m_AddIfConfirmed; - cRemoteTimer *m_Timer; - cRemoteTimer m_Data; - cMenuEditDateItem *m_FirstDay; - -protected: - void SetFirstDayItem(void); - -public: - cStreamdevMenuEditTimer(cRemoteTimer *Timer, bool New = false); - virtual ~cStreamdevMenuEditTimer(); - - virtual eOSState ProcessKey(eKeys Key); -}; - -cStreamdevMenuEditTimer::cStreamdevMenuEditTimer(cRemoteTimer *Timer, bool New): - cOsdMenu(tr("Edit remote timer"), 12) { - m_FirstDay = NULL; - m_Timer = Timer; - m_AddIfConfirmed = New; - - if (m_Timer) { - m_Data = *m_Timer; - if (New) - m_Data.m_Active = 1; - m_Channel = m_Data.Channel()->Number(); - Add(new cMenuEditBitItem( tr("Active"), &m_Data.m_Active, tfActive)); - Add(new cMenuEditChanItem(tr("Channel"), &m_Channel)); - Add(new cMenuEditDayItem( tr("Day"), &m_Data.m_Day)); - Add(new cMenuEditTimeItem(tr("Start"), &m_Data.m_Start)); - Add(new cMenuEditTimeItem(tr("Stop"), &m_Data.m_Stop)); - Add(new cMenuEditBitItem( tr("VPS"), &m_Data.m_Active, tfVps)); - Add(new cMenuEditIntItem( tr("Priority"), &m_Data.m_Priority, 0, - MAXPRIORITY)); - Add(new cMenuEditIntItem( tr("Lifetime"), &m_Data.m_Lifetime, 0, - MAXLIFETIME)); - Add(new cMenuEditStrItem( tr("File"), m_Data.m_File, - sizeof(m_Data.m_File), tr(FileNameChars))); - SetFirstDayItem(); - } -} - -cStreamdevMenuEditTimer::~cStreamdevMenuEditTimer() { - if (m_Timer && m_AddIfConfirmed) { - Dprintf("SOMETHING GETS DELETED\n"); - delete m_Timer; // apparently it wasn't confirmed - } -} - -void cStreamdevMenuEditTimer::SetFirstDayItem(void) { - if (!m_FirstDay && !m_Data.IsSingleEvent()) { - Add(m_FirstDay = new cMenuEditDateItem(tr("First day"),&m_Data.m_FirstDay)); - Display(); - } else if (m_FirstDay && m_Data.IsSingleEvent()) { - Del(m_FirstDay->Index()); - m_FirstDay = NULL; - m_Data.m_FirstDay = 0; - Display(); - } -} - -eOSState cStreamdevMenuEditTimer::ProcessKey(eKeys Key) { - eOSState state = cOsdMenu::ProcessKey(Key); - - if (state == osUnknown) { - switch (Key) { - case kOk: - { - cChannel *ch = Channels.GetByNumber(m_Channel); - if (ch) - m_Data.m_Channel = ch; - else { - ERROR(tr("*** Invalid Channel ***")); - break; - } - if (!*m_Data.m_File) - strcpy(m_Data.m_File, m_Data.Channel()->Name()); - if (m_Timer) { - bool success = true; - if (m_Data != *m_Timer) { - // Timer has changed - if ((success = ClientSocket.SaveTimer(m_Timer, m_Data))) { - *m_Timer = m_Data; - if (m_Timer->m_Active) - m_Timer->m_Active = 1; - // allows external programs to mark active timers with - // values > 1 and recognize if the user has modified them - } - } - if (success) { - if (m_AddIfConfirmed) - RemoteTimers.Add(m_Timer); - isyslog("timer %d %s (%s)", m_Timer->Index() + 1, - m_AddIfConfirmed ? "added" : "modified", - m_Timer->m_Active ? "active" : "inactive"); - m_AddIfConfirmed = false; - } - } - } - return osBack; - - case kRed: - case kGreen: - case kYellow: - case kBlue: return osContinue; - default: break; - } - } - if (Key != kNone) - SetFirstDayItem(); - return state; -} - -// --- cMenuWhatsOnItem ------------------------------------------------------ - -class cMenuWhatsOnItem : public cOsdItem { -public: - const cEvent *event; - const cChannel *channel; - cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel); //, bool Now = false); -}; - -// --- cMenuEvent ------------------------------------------------------------ - -class cMenuEvent : public cOsdMenu { -private: - const cEvent *event; -public: - cMenuEvent(const cEvent *Event, bool CanSwitch = false); - virtual void Display(void); - virtual eOSState ProcessKey(eKeys Key); -}; - -// --- cStreamdevMenuWhatsOn ------------------------------------------------- - -int cStreamdevMenuWhatsOn::m_CurrentChannel = 0; -const cEvent *cStreamdevMenuWhatsOn::m_ScheduleEventInfo = NULL; - -cStreamdevMenuWhatsOn::cStreamdevMenuWhatsOn(const cSchedules *Schedules, - bool Now, int CurrentChannel): - cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, - 7, 6) { - for (cChannel *Channel = Channels.First(); Channel; - Channel = Channels.Next(Channel)) { - if (!Channel->GroupSep()) { - const cSchedule *Schedule - = Schedules->GetSchedule(Channel->GetChannelID()); - if (Schedule) { - const cEvent *Event = Now ? Schedule->GetPresentEvent() - : Schedule->GetFollowingEvent(); - if (Event) - Add(new cMenuWhatsOnItem(Event, Channel), - Channel->Number() == CurrentChannel); - } - } - } - m_CurrentChannel = CurrentChannel; - SetHelp(Count() ? tr("Record") : NULL, Now ? tr("Next") : tr("Now"), - tr("Schedule"), tr("Switch")); -} - -const cEvent *cStreamdevMenuWhatsOn::ScheduleEventInfo(void) { - const cEvent *ei = m_ScheduleEventInfo; - m_ScheduleEventInfo = NULL; - return ei; -} - -eOSState cStreamdevMenuWhatsOn::Switch(void) { - cMenuWhatsOnItem *item = (cMenuWhatsOnItem*)Get(Current()); - if (item) { - cChannel *channel - = Channels.GetByChannelID(item->event->ChannelID(), true); - if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true)) - return osEnd; - } - ERROR(tr("Can't switch channel!")); - return osContinue; -} - -eOSState cStreamdevMenuWhatsOn::Record(void) { - cMenuWhatsOnItem *item = (cMenuWhatsOnItem*)Get(Current()); - if (item) { - cRemoteTimer *timer - = new cRemoteTimer(item->event); - return AddSubMenu(new cStreamdevMenuEditTimer(timer)); - // Load remote timers and see if timer exists before editing - } - return osContinue; -} - -eOSState cStreamdevMenuWhatsOn::ProcessKey(eKeys Key) { - eOSState state = cOsdMenu::ProcessKey(Key); - if (state == osUnknown) { - switch (Key) { - case kRecord: - case kRed: - return Record(); - - case kYellow: - state = osBack; - case kGreen: - { - cMenuWhatsOnItem *mi = (cMenuWhatsOnItem*)Get(Current()); - if (mi) { - m_ScheduleEventInfo = mi->event; - m_CurrentChannel = mi->channel->Number(); - } - } - break; - - case kBlue: - return Switch(); - - case kOk: - if (Count()) - return AddSubMenu(new cMenuEvent( - ((cMenuWhatsOnItem*)Get(Current()))->event, true)); - break; - - default: - break; - } - } - return state; -} - -// --- cMenuScheduleItem ----------------------------------------------------- - -class cMenuScheduleItem : public cOsdItem { -public: - const cEvent *event; - cMenuScheduleItem(const cEvent *Event); -}; - -// --- cStreamdevMenuSchedule ------------------------------------------------ - -cStreamdevMenuSchedule::cStreamdevMenuSchedule(void): - cOsdMenu("", 7, 6, 4) -{ - m_Now = false; - m_Next = false; - m_OtherChannel = -1; - m_Schedules = NULL; - - cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); - if (channel) { - m_Schedules = cSchedules::Schedules(m_Lock); - PrepareSchedule(channel); - SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next")); - } -} - -cStreamdevMenuSchedule::~cStreamdevMenuSchedule() { -} - -void cStreamdevMenuSchedule::PrepareSchedule(cChannel *Channel) { - Clear(); - char *buffer = NULL; - asprintf(&buffer, tr("Schedule - %s"), Channel->Name()); - SetTitle(buffer); - free(buffer); - if (m_Schedules) { - const cSchedule *Schedule = m_Schedules->GetSchedule(Channel->GetChannelID()); - if (Schedule) { - const cEvent *PresentEvent = Schedule->GetPresentEvent(Channel->Number() == cDevice::CurrentChannel()); - time_t now = time(NULL) - Setup.EPGLinger * 60; - for (const cEvent *Event = Schedule->Events()->First(); Event; Event = Schedule->Events()->Next(Event)) { - if (Event->EndTime() > now || Event == PresentEvent) - Add(new cMenuScheduleItem(Event), Event == PresentEvent); - } - } - } -} - -eOSState cStreamdevMenuSchedule::Switch(void) { - if (m_OtherChannel) { - if (Channels.SwitchTo(m_OtherChannel)) - return osEnd; - } - ERROR(tr("Can't switch channel!")); - return osContinue; -} - -eOSState cStreamdevMenuSchedule::Record(void) { - cMenuScheduleItem *item = (cMenuScheduleItem*)Get(Current()); - if (item) { - cRemoteTimer *timer - = new cRemoteTimer(item->event); - return AddSubMenu(new cStreamdevMenuEditTimer(timer)); - // Load remote timers and see if timer exists before editing - } - return osContinue; -} - -eOSState cStreamdevMenuSchedule::ProcessKey(eKeys Key) { - eOSState state = cOsdMenu::ProcessKey(Key); - if (state == osUnknown) { - switch (Key) { - case kRecord: - case kRed: - return Record(); - - case kGreen: - if (m_Schedules) { - if (!m_Now && !m_Next) { - int channelnr = 0; - if (Count()) { - cChannel *channel - = Channels.GetByChannelID( - ((cMenuScheduleItem*)Get(Current()))->event->ChannelID(), true); - if (channel) - channelnr = channel->Number(); - } - m_Now = true; - return AddSubMenu(new cStreamdevMenuWhatsOn(m_Schedules, true, - channelnr)); - } - m_Now = !m_Now; - m_Next = !m_Next; - return AddSubMenu(new cStreamdevMenuWhatsOn(m_Schedules, m_Now, - cStreamdevMenuWhatsOn::CurrentChannel())); - } - - case kYellow: - if (m_Schedules) - return AddSubMenu(new cStreamdevMenuWhatsOn(m_Schedules, false, - cStreamdevMenuWhatsOn::CurrentChannel())); - break; - - case kBlue: - if (Count()) - return Switch(); - break; - - case kOk: - if (Count()) - return AddSubMenu(new cMenuEvent( - ((cMenuScheduleItem*)Get(Current()))->event, m_OtherChannel)); - break; - - default: - break; - } - } else if (!HasSubMenu()) { - m_Now = false; - m_Next = false; - const cEvent *ei - = cStreamdevMenuWhatsOn::ScheduleEventInfo(); - if (ei) { - cChannel *channel - = Channels.GetByChannelID(ei->ChannelID(), true); - if (channel) { - PrepareSchedule(channel); - if (channel->Number() != cDevice::CurrentChannel()) { - m_OtherChannel = channel->Number(); - SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next"), - tr("Switch")); - } - Display(); - } - } - } - return state; -} - -// --- cStreamdevMenuRecordingItem ------------------------------------------- - -class cStreamdevMenuRecordingItem: public cOsdItem { -private: - int m_Total; - int m_New; - char *m_FileName; - char *m_Name; - -public: - cStreamdevMenuRecordingItem(cRemoteRecording *Recording, int Level); - virtual ~cStreamdevMenuRecordingItem(); - - void IncrementCounter(bool New); - const char *Name(void) const { return m_Name; } - const char *FileName(void) const { return m_FileName; } - bool IsDirectory(void) const { return m_Name != NULL; } -}; - -cStreamdevMenuRecordingItem::cStreamdevMenuRecordingItem( - cRemoteRecording *Recording, int Level) { - m_FileName = strdup(Recording->Name()); - m_Name = NULL; - m_Total = m_New = 0; - SetText(Recording->Title('\t', true, Level)); - if (*Text() == '\t') - m_Name = strdup(Text() + 2); -} - -cStreamdevMenuRecordingItem::~cStreamdevMenuRecordingItem() { -} - -void cStreamdevMenuRecordingItem::IncrementCounter(bool New) { - ++m_Total; - if (New) ++m_New; - char *buffer = NULL; - asprintf(&buffer, "%d\t%d\t%s", m_Total, m_New, m_Name); - SetText(buffer, false); -} - -// --- cStreamdevMenuRecordings ---------------------------------------------- - -cRemoteRecordings cStreamdevMenuRecordings::Recordings; -int cStreamdevMenuRecordings::HelpKeys = -1; - -cStreamdevMenuRecordings::cStreamdevMenuRecordings(const char *Base, int Level, - bool OpenSubMenus): - cOsdMenu(Base ? Base : tr("Remote Recordings"), 6, 6) { - m_Base = Base ? strdup(Base) : NULL; - m_Level = Setup.RecordingDirs ? Level : -1; - - Display(); // this keeps the higher level menus from showing up briefly when - // pressing 'Back' during replay - - if (!Base) { - STATUS(tr("Fetching recordings...")); - FLUSH(); - } - - if (Base || Recordings.Load()) { - cStreamdevMenuRecordingItem *LastItem = NULL; - char *LastItemText = NULL; - for (cRemoteRecording *r = Recordings.First(); r; r = Recordings.Next(r)) { - if (!Base || (strstr(r->Name(), Base) == r->Name() - && r->Name()[strlen(Base)] == '~')) { - cStreamdevMenuRecordingItem *Item = new cStreamdevMenuRecordingItem(r, - m_Level); - if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) - != 0)) { - Add(Item); - LastItem = Item; - free(LastItemText); - LastItemText = strdup(LastItem->Text()); - } else - delete Item; - - if (LastItem) { - if (LastItem->IsDirectory()) - LastItem->IncrementCounter(r->IsNew()); - } - } - } - free(LastItemText); - if (Current() < 0) - SetCurrent(First()); - else if (OpenSubMenus && Open(true)) - return; - } - - STATUS(NULL); - FLUSH(); - - SetHelpKeys(); -} - -cStreamdevMenuRecordings::~cStreamdevMenuRecordings() { - if (m_Base != NULL) free(m_Base); - HelpKeys = -1; -} - -void cStreamdevMenuRecordings::SetHelpKeys(void) { - cStreamdevMenuRecordingItem *ri =(cStreamdevMenuRecordingItem*)Get(Current()); - int NewHelpKeys = HelpKeys; - if (ri) { - if (ri->IsDirectory()) - NewHelpKeys = 1; - else { - NewHelpKeys = 2; - cRemoteRecording *recording = GetRecording(ri); - if (recording && recording->Summary()) - NewHelpKeys = 3; - } - } - if (NewHelpKeys != HelpKeys) { - switch (NewHelpKeys) { - case 0: SetHelp(NULL); break; - case 1: SetHelp(tr("Open")); break; - case 2: - case 3: SetHelp(NULL, NULL, tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL); - //SetHelp(tr("Play"), tr("Rewind"), tr("Delete"), NewHelpKeys == 3 ? tr("Summary") : NULL); XXX - } - HelpKeys = NewHelpKeys; - } -} - -cRemoteRecording *cStreamdevMenuRecordings::GetRecording( - cStreamdevMenuRecordingItem *Item) { - Dprintf("looking for %s\n", Item->FileName()); - cRemoteRecording *recording = Recordings.GetByName(Item->FileName()); - if (!recording) - ERROR(tr("Error while accessing recording!")); - return recording; -} - -bool cStreamdevMenuRecordings::Open(bool OpenSubMenus) { - cStreamdevMenuRecordingItem *ri - = (cStreamdevMenuRecordingItem*)Get(Current()); - - if (ri && ri->IsDirectory()) { - const char *t = ri->Name(); - char *buffer = NULL; - if (m_Base) { - asprintf(&buffer, "%s~%s", m_Base, t); - t = buffer; - } - AddSubMenu(new cStreamdevMenuRecordings(t, m_Level + 1, OpenSubMenus)); - if (buffer != NULL) free(buffer); - return true; - } - return false; -} - -eOSState cStreamdevMenuRecordings::Select(void) { - cStreamdevMenuRecordingItem *ri - = (cStreamdevMenuRecordingItem*)Get(Current()); - - if (ri) { - if (ri->IsDirectory()) - Open(); - /*else { - cControl::Launch(new cStreamdevPlayerControl(ri->FileName())); - return osEnd; - } XXX */ - } - return osContinue; -} - -eOSState cStreamdevMenuRecordings::Delete(void) { - if (HasSubMenu() || Count() == 0) - return osContinue; - cStreamdevMenuRecordingItem *ri - = (cStreamdevMenuRecordingItem*)Get(Current()); - if (ri && !ri->IsDirectory()) { - if (Interface->Confirm(tr("Delete recording?"))) { - cRemoteRecording *recording = GetRecording(ri); - if (recording) { - if (ClientSocket.DeleteRecording(recording)) { - cOsdMenu::Del(Current()); - Recordings.Del(recording); - Display(); - if (!Count()) - return osBack; - } - } - } - } - return osContinue; -} - -eOSState cStreamdevMenuRecordings::Summary(void) { - if (HasSubMenu() || Count() == 0) - return osContinue; - cStreamdevMenuRecordingItem *ri=(cStreamdevMenuRecordingItem *)Get(Current()); - if (ri && !ri->IsDirectory()) { - cRemoteRecording *recording = GetRecording(ri); - if (recording && recording->Summary() && *recording->Summary()) - return AddSubMenu(new cMenuText(tr("Summary"), recording->Summary())); - } - return osContinue; -} - -eOSState cStreamdevMenuRecordings::ProcessKey(eKeys Key) { - bool HadSubMenu = HasSubMenu(); - eOSState state = cOsdMenu::ProcessKey(Key); - - if (state == osUnknown) { - switch (Key) { - case kOk: - case kRed: return Select(); - case kYellow: return Delete(); - case kBlue: return Summary(); - default: break; - } - } - - if (Key == kYellow && HadSubMenu && !HasSubMenu()) { - cOsdMenu::Del(Current()); - if (!Count()) - return osBack; - Display(); - } - - if (!HasSubMenu() && Key != kNone) - SetHelpKeys(); - return state; -} - -// --- cStreamdevMenuTimerItem ----------------------------------------------- - -class cStreamdevMenuTimerItem: public cOsdItem { -private: - cRemoteTimer *m_Timer; - -public: - cStreamdevMenuTimerItem(cRemoteTimer *Timer); - virtual ~cStreamdevMenuTimerItem(); - - virtual void Set(void); - - cRemoteTimer *Timer(void) const { return m_Timer; } -}; - -cStreamdevMenuTimerItem::cStreamdevMenuTimerItem(cRemoteTimer *Timer) { - m_Timer = Timer; - Set(); -} - -cStreamdevMenuTimerItem::~cStreamdevMenuTimerItem() { -} - -void cStreamdevMenuTimerItem::Set(void) { - char *buffer = NULL; - asprintf(&buffer, "%c\t%d\t%s\t%02d:%02d\t%02d:%02d\t%s", - !m_Timer->Active() ? ' ' : - m_Timer->FirstDay() ? '!' : - /*m_Timer->Recording() ? '#' :*/ '>', - m_Timer->Channel()->Number(), - m_Timer->PrintDay(m_Timer->Day()), - m_Timer->Start() / 100, - m_Timer->Start() % 100, - m_Timer->Stop() / 100, - m_Timer->Stop() % 100, - m_Timer->File()); - SetText(buffer, false); -} - -// --- cStreamdevMenuTimers -------------------------------------------------- - -cStreamdevMenuTimers::cStreamdevMenuTimers(void): - cOsdMenu(tr("Remote Timers"), 2, CHNUMWIDTH, 10, 6, 6) { - Refresh(); - SetHelp(tr("Edit"), tr("New"), tr("Delete"), tr("On/Off")); -} - -cStreamdevMenuTimers::~cStreamdevMenuTimers() { -} - -eOSState cStreamdevMenuTimers::ProcessKey(eKeys Key) { - int timerNum = HasSubMenu() ? Count() : -1; - eOSState state = cOsdMenu::ProcessKey(Key); - - if (state == osUnknown) { - switch (Key) { - case kOk: return Summary(); - case kRed: return Edit(); - case kGreen: return New(); - case kYellow: return Delete(); - case kBlue: OnOff(); break; - default: break; - } - } - - if (timerNum >= 0 && !HasSubMenu()) { - Refresh(); - Display(); - } - return state; -} - -eOSState cStreamdevMenuTimers::Edit(void) { - if (HasSubMenu() || Count() == 0) - return osContinue; - isyslog("Streamdev: Editing remote timer %d", CurrentTimer()->Index() + 1); - return AddSubMenu(new cStreamdevMenuEditTimer(CurrentTimer())); -} - -eOSState cStreamdevMenuTimers::New(void) { - if (HasSubMenu()) - return osContinue; - return AddSubMenu(new cStreamdevMenuEditTimer(new cRemoteTimer, true)); -} - -eOSState cStreamdevMenuTimers::Delete(void) { - cRemoteTimer *ti = CurrentTimer(); - if (ti) { - if (Interface->Confirm(tr("Delete timer?"))) { - int idx = ti->Index(); - if (ClientSocket.DeleteTimer(ti)) { - RemoteTimers.Del(ti); - cOsdMenu::Del(Current()); - isyslog("Streamdev: Remote timer %d deleted", idx + 1); - } - Refresh(); - Display(); - } - } - return osContinue; -} - -eOSState cStreamdevMenuTimers::OnOff(void) { - cRemoteTimer *timer = CurrentTimer(); - if (timer) { - cRemoteTimer data = *timer; - data.OnOff(); - if (data.FirstDay()) - isyslog("Streamdev: Remote timer %d first day set to %s", - data.Index() + 1, data.PrintFirstDay()); - else - isyslog("Streamdev: Remote timer %d %sactivated", data.Index() + 1, - data.Active() ? "" : "de"); - - if (ClientSocket.SaveTimer(timer, data)) { - *timer = data; - RefreshCurrent(); - DisplayCurrent(true); - } else { - Refresh(); - Display(); - } - } - return osContinue; -} - -eOSState cStreamdevMenuTimers::Summary(void) { - if (HasSubMenu() || Count() == 0) - return osContinue; - - cRemoteTimer *ti = CurrentTimer(); - if (ti && ti->Summary() != "") - return AddSubMenu(new cMenuText(tr("Summary"), ti->Summary().c_str())); - - return osContinue; -} - -cRemoteTimer *cStreamdevMenuTimers::CurrentTimer(void) { - cStreamdevMenuTimerItem *item = (cStreamdevMenuTimerItem*)Get(Current()); - return item ? item->Timer() : NULL; -} - -void cStreamdevMenuTimers::Refresh(void) { - Clear(); - if (RemoteTimers.Load()) { - for (cRemoteTimer *t = RemoteTimers.First(); t; t = RemoteTimers.Next(t)) { - Add(new cStreamdevMenuTimerItem(t)); - } - } -} diff --git a/client/menu.h b/client/menu.h deleted file mode 100644 index 1cf8fa3..0000000 --- a/client/menu.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * $Id: menu.h,v 1.2 2008/04/07 14:27:28 schmirl Exp $ - */ - -#ifndef VDR_STREAMDEV_MENU_H -#define VDR_STREAMDEV_MENU_H - -#include <vdr/osd.h> - -#include "client/remote.h" - -class cStreamdevMenuRecordingItem; - -// --- cStreamdevMenu -------------------------------------------------------- - -class cStreamdevMenu: public cOsdMenu { -private: - enum eSubmenus { - sub_Start = os_User, - subSchedule, - subTimers, - subRecordings, - subSuspend, - subSyncEPG - }; - -protected: - void SuspendServer(void); - -public: - cStreamdevMenu(void); - virtual ~cStreamdevMenu(void); - - virtual eOSState ProcessKey(eKeys Key); -}; - -// --- cStreamdevMenuSchedule ------------------------------------------------ - -class cStreamdevMenuSchedule: public cOsdMenu { -private: - bool m_Now; - bool m_Next; - int m_OtherChannel; - const cSchedules *m_Schedules; - cSchedulesLock m_Lock; - -protected: - void PrepareSchedule(cChannel *Channel); - - eOSState Switch(void); - eOSState Record(void); - -public: - cStreamdevMenuSchedule(void); - virtual ~cStreamdevMenuSchedule(void); - - virtual eOSState ProcessKey(eKeys Key); -}; - -// --- cStreamdevMenuWhatsOn ------------------------------------------------- - -class cStreamdevMenuWhatsOn: public cOsdMenu { -private: - static int m_CurrentChannel; - static const cEvent *m_ScheduleEventInfo; - -protected: - eOSState Switch(void); - eOSState Record(void); - -public: - cStreamdevMenuWhatsOn(const cSchedules *Schedules, bool Now, - int CurrentChannel); - - static int CurrentChannel(void) { return m_CurrentChannel; } - static void SetCurrentChannel(int Channel) { m_CurrentChannel = Channel; } - static const cEvent *ScheduleEventInfo(void); - - virtual eOSState ProcessKey(eKeys Key); -}; - -// --- cStreamdevMenuRecordings ---------------------------------------------- - -class cStreamdevMenuRecordings: public cOsdMenu { -private: - char *m_Base; - int m_Level; - - static int HelpKeys; - static cRemoteRecordings Recordings; - -protected: - bool Open(bool OpenSubMenus = false); - void SetHelpKeys(); - cRemoteRecording *cStreamdevMenuRecordings::GetRecording( - cStreamdevMenuRecordingItem *Item); - - eOSState Select(void); - eOSState Delete(void); - eOSState Summary(void); - -public: - cStreamdevMenuRecordings(const char *Base = NULL, int Level = 0, - bool OpenSubMenus = false); - virtual ~cStreamdevMenuRecordings(); - - virtual eOSState ProcessKey(eKeys Key); -}; - -// --- cStreamdevMenuTimers -------------------------------------------------- - -class cStreamdevMenuTimers: public cOsdMenu { -protected: - eOSState Edit(void); - eOSState New(void); - eOSState Delete(void); - eOSState OnOff(void); - eOSState Summary(void); - - cRemoteTimer *CurrentTimer(void); - - void Refresh(void); - -public: - cStreamdevMenuTimers(void); - virtual ~cStreamdevMenuTimers(); - - virtual eOSState ProcessKey(eKeys Key); -}; - -#endif // VDR_STREAMDEV_MENU_H - diff --git a/client/remote.c b/client/remote.c deleted file mode 100644 index 6f3bd3c..0000000 --- a/client/remote.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * $Id: remote.c,v 1.5 2008/04/07 14:27:28 schmirl Exp $ - */ - -#include <ctype.h> - -#include "client/remote.h" -#include "client/device.h" -#include "common.h" - -cRemoteTimers RemoteTimers; - -// --- cRemoteRecording ------------------------------------------------------ - -cRemoteRecording::cRemoteRecording(const char *Text) { - m_IsValid = false; - m_Index = -1; - m_IsNew = false; - m_TitleBuffer = NULL; - - char *ptr; - char *timestr; - int idx; - - Dprintf("text: %s\n", Text); - - m_Index = strtoul(Text, &ptr, 10); - Dprintf("index: %d\n", m_Index); - if (*ptr == '\0' || *++ptr == '\0' ) return; - timestr = ptr; - while (*ptr != '\0' && !isspace(*ptr)) ++ptr; - if (*ptr == '\0' || *++ptr == '\0') return; - while (*ptr != '\0' && *ptr != '*' && !isspace(*ptr)) ++ptr; - if (*ptr == '*') m_IsNew = true; - Dprintf("new: %d\n", m_IsNew); - *(ptr++) = '\0'; - m_StartTime = timestr; - idx = -1; - while ((idx = m_StartTime.find(' ', idx + 1)) != -1) m_StartTime[idx] = '\t'; - Dprintf("m_Start: %s\n", m_StartTime.c_str()); - if (*ptr == 0) return; - if (isspace(*ptr)) ++ptr; - if (*ptr == 0) return; - m_Name = ptr; - Dprintf("file: %s\n", m_Name.c_str()); - m_IsValid = true; -} - -cRemoteRecording::~cRemoteRecording(void) { -} - -bool cRemoteRecording::operator==(const cRemoteRecording &Recording) { - return m_IsValid == Recording.m_IsValid - && m_Index == Recording.m_Index - && m_StartTime == Recording.m_StartTime - && m_Name == Recording.m_Name; -} - -void cRemoteRecording::ParseInfo(const char *Text) { - m_Summary = strreplace(strdup(Text), '|', '\n'); -} - -const char *cRemoteRecording::Title(char Delimiter, bool NewIndicator, - int Level) { - char New = NewIndicator && IsNew() ? '*' : ' '; - - if (m_TitleBuffer != NULL) { - free(m_TitleBuffer); - m_TitleBuffer = NULL; - } - - if (Level < 0 || Level == HierarchyLevels()) { - char *s; - const char *t; - if (Level > 0 && (t = strrchr(m_Name.c_str(), '~')) != NULL) - t++; - else - t = m_Name.c_str(); - - asprintf(&m_TitleBuffer, "%s%c%c%s", m_StartTime.c_str(), New, Delimiter, t); - // let's not display a trailing '~': - stripspace(m_TitleBuffer); - s = &m_TitleBuffer[strlen(m_TitleBuffer) - 1]; - if (*s == '~') - *s = 0; - } else if (Level < HierarchyLevels()) { - const char *s = m_Name.c_str(); - const char *p = s; - while (*++s) { - if (*s == '~') { - if (Level--) - p = s + 1; - else - break; - } - } - m_TitleBuffer = MALLOC(char, s - p + 3); - *m_TitleBuffer = Delimiter; - *(m_TitleBuffer + 1) = Delimiter; - strn0cpy(m_TitleBuffer + 2, p, s - p + 1); - } else - return ""; - return m_TitleBuffer; -} - -int cRemoteRecording::HierarchyLevels(void) -{ - const char *s = m_Name.c_str(); - int level = 0; - while (*++s) { - if (*s == '~') ++level; - } - return level; -} - -// --- cRemoteRecordings ----------------------------------------------------- - -bool cRemoteRecordings::Load(void) { - Clear(); - return ClientSocket.LoadRecordings(*this); -} - -cRemoteRecording *cRemoteRecordings::GetByName(const char *Name) { - for (cRemoteRecording *r = First(); r; r = Next(r)) - if (strcmp(r->Name(), Name) == 0) - return r; - return NULL; -} - -// --- cRemoteTimer ---------------------------------------------------------- - -cRemoteTimer::cRemoteTimer(const char *Text) { - m_IsValid = false; - m_Index = -1; - m_Active = -1; - m_Day = -1; - m_Start = -1; - m_Stop = -1; - m_StartTime = 0; - m_StopTime = 0; - m_Priority = -1; - m_Lifetime = -1; - m_File[0] = '\0'; - m_FirstDay = 0; - m_Buffer = NULL; - m_Channel = NULL; - - char *tmpbuf; - char *ptr; - - Dprintf("text: %s\n", Text); - - m_Index = strtoul(Text, &ptr, 10); - Dprintf("index: %d\n", m_Index); - if (*ptr == '\0' || *++ptr == '\0') return; - m_Active = strtoul(ptr, &ptr, 10); - Dprintf("m_Active: %d\n", m_Active); - if (*ptr == '\0' || *++ptr == '\0') return; - - tmpbuf = ptr; - while (*ptr != '\0' && *ptr != ':') ++ptr; - if (*ptr == '\0') return; - *(ptr++)= '\0'; - if (isnumber(tmpbuf)) - m_Channel = Channels.GetByNumber(strtoul(tmpbuf, NULL, 10)); - else - m_Channel = Channels.GetByChannelID(tChannelID::FromString(tmpbuf)); - Dprintf("channel no.: %d\n", m_Channel->Number()); - - tmpbuf = ptr; - while (*ptr != '\0' && *ptr != ':') ++ptr; - if (*ptr == '\0') return; - *(ptr++) = '\0'; - m_Day = ParseDay(tmpbuf, &m_FirstDay); - Dprintf("Day: %d\n", m_Day); - m_Start = strtoul(ptr, &ptr, 10); - Dprintf("Start: %d\n", m_Start); - if (*ptr == '\0' || *++ptr == '\0') return; - m_Stop = strtoul(ptr, &ptr, 10); - Dprintf("Stop: %d\n", m_Stop); - if (*ptr == '\0' || *++ptr == '\0') return; - m_Priority = strtoul(ptr, &ptr, 10); - Dprintf("Prio: %d\n", m_Priority); - if (*ptr == '\0' || *++ptr == '\0') return; - m_Lifetime = strtoul(ptr, &ptr, 10); - Dprintf("Lifetime: %d\n", m_Lifetime); - if (*ptr == '\0' || *++ptr == '\0') return; - tmpbuf = ptr; - while (*ptr != '\0' && *ptr != ':') ++ptr; - if (*ptr == '\0') return; - *(ptr++) = '\0'; - strncpy(m_File, tmpbuf, MaxFileName); - Dprintf("file: %s\n", m_File); - if (*ptr != '\0') m_Summary = ptr; - Dprintf("summary: %s\n", m_Summary.c_str()); - m_IsValid = true; -} - -cRemoteTimer::cRemoteTimer(const cEvent *Event) { - time_t tstart = Event->StartTime(); - time_t tstop = tstart + Event->Duration() + Setup.MarginStop * 60; - tstart -= Setup.MarginStart * 60; - struct tm tm_r; - struct tm *time = localtime_r(&tstart, &tm_r); - const char *title = Event->Title(); - cChannel *channel = Channels.GetByChannelID(Event->ChannelID(), true); - - m_IsValid = true; - m_Index = -1; - m_Active = true; - m_Day = time->tm_mday; - m_Start = time->tm_hour * 100 + time->tm_min; - time = localtime_r(&tstop, &tm_r); - m_Stop = time->tm_hour * 100 + time->tm_min; - m_StartTime = 0; - m_StopTime = 0; - if (m_Stop >= 2400) m_Stop -= 2400; - m_Priority = Setup.DefaultPriority; - m_Lifetime = Setup.DefaultLifetime; - m_File[0] = '\0'; - if (!isempty(title)) - strn0cpy(m_File, title, sizeof(m_File)); - m_FirstDay = 0; - m_Channel = channel; -} - -cRemoteTimer::cRemoteTimer(void) { - time_t t = time(NULL); - struct tm tm_r; - struct tm *now = localtime_r(&t, &tm_r); - - m_IsValid = true; - m_Index = -1; - m_Active = -1; - m_Day = now->tm_mday; - m_Start = now->tm_hour * 100 + now->tm_min; - m_Stop = now->tm_hour * 60 + now->tm_min + Setup.InstantRecordTime; - m_Stop = (m_Stop / 60) * 100 + (m_Stop % 60); - if (m_Stop >= 2400) m_Stop -= 2400; - m_StartTime = 0; - m_StopTime = 0; - m_Priority = Setup.DefaultPriority; - m_Lifetime = Setup.DefaultLifetime; - m_File[0] = '\0'; - m_FirstDay = 0; - m_Buffer = NULL; - m_Channel = Channels.GetByNumber(cDevice::CurrentChannel()); -} - -cRemoteTimer::~cRemoteTimer() { - if (m_Buffer != NULL) free(m_Buffer); -} - -cRemoteTimer &cRemoteTimer::operator=(const cRemoteTimer &Timer) { - Dprintf("\n\n\n\nOPÜERATHVBDÖLJVG\n\n\n"); - m_IsValid = Timer.m_IsValid; - m_Index = Timer.m_Index; - m_Active = Timer.m_Active; - m_Day = Timer.m_Day; - m_Start = Timer.m_Start; - m_Stop = Timer.m_Stop; - m_Priority = Timer.m_Priority; - m_Lifetime = Timer.m_Lifetime; - m_FirstDay = Timer.m_FirstDay; - m_Channel = Timer.m_Channel; - m_Summary = Timer.m_Summary; - return *this; -} - -bool cRemoteTimer::operator==(const cRemoteTimer &Timer) { - return m_IsValid == Timer.m_IsValid - && m_Index == Timer.m_Index - && m_Active == Timer.m_Active - && m_Day == Timer.m_Day - && m_Start == Timer.m_Start - && m_Stop == Timer.m_Stop - && m_Priority == Timer.m_Priority - && m_Lifetime == Timer.m_Lifetime - && m_FirstDay == Timer.m_FirstDay - && m_Channel == Timer.m_Channel - && strcmp(m_File, Timer.m_File) == 0 - && m_Summary == Timer.m_Summary; -} - -int cRemoteTimer::ParseDay(const char *s, time_t *FirstDay) { - char *tail; - int d = strtol(s, &tail, 10); - if (FirstDay) - *FirstDay = 0; - if (tail && *tail) { - d = 0; - if (tail == s) { - const char *first = strchr(s, '@'); - int l = first ? first - s : strlen(s); - if (l == 7) { - for (const char *p = s + 6; p >= s; p--) { - d <<= 1; - d |= (*p != '-'); - } - d |= 0x80000000; - } - if (FirstDay && first) { - ++first; - if (strlen(first) == 10) { - struct tm tm_r; - if (3 == sscanf(first, "%d-%d-%d", &tm_r.tm_year, &tm_r.tm_mon, &tm_r.tm_mday)) { - tm_r.tm_year -= 1900; - tm_r.tm_mon--; - tm_r.tm_hour = tm_r.tm_min = tm_r.tm_sec = 0; - tm_r.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting - *FirstDay = mktime(&tm_r); - } - } - else - d = 0; - } - } - } - else if (d < 1 || d > 31) - d = 0; - return d; -} - -const char *cRemoteTimer::PrintDay(int d, time_t FirstDay) { -#define DAYBUFFERSIZE 32 - static char buffer[DAYBUFFERSIZE]; - if ((d & 0x80000000) != 0) { - char *b = buffer; - const char *w = tr("MTWTFSS"); - while (*w) { - *b++ = (d & 1) ? *w : '-'; - d >>= 1; - w++; - } - if (FirstDay) { - struct tm tm_r; - localtime_r(&FirstDay, &tm_r); - b += strftime(b, DAYBUFFERSIZE - (b - buffer), "@%Y-%m-%d", &tm_r); - } - *b = 0; - } - else - sprintf(buffer, "%d", d); - return buffer; -} - -const char *cRemoteTimer::PrintFirstDay(void) const { - if (m_FirstDay) { - const char *s = PrintDay(m_Day, m_FirstDay); - if (strlen(s) == 18) - return s + 8; - } - return ""; // not NULL, so the caller can always use the result -} - -void cRemoteTimer::OnOff(void) { - if (IsSingleEvent()) - m_Active = !m_Active; - else if (m_FirstDay) { - m_FirstDay = 0; - m_Active = false; - } - else if (m_Active) - Skip(); - else - m_Active = true; - Matches(); // refresh m_Start and end time -} - -time_t cRemoteTimer::SetTime(time_t t, int SecondsFromMidnight) { - struct tm tm_r; - tm tm = *localtime_r(&t, &tm_r); - tm.tm_hour = SecondsFromMidnight / 3600; - tm.tm_min = (SecondsFromMidnight % 3600) / 60; - tm.tm_sec = SecondsFromMidnight % 60; - tm.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting - return mktime(&tm); -} - -bool cRemoteTimer::Matches(time_t t) { - m_StartTime = m_StopTime = 0; - if (t == 0) - t = time(NULL); - - int begin = TimeToInt(m_Start); // seconds from midnight - int length = TimeToInt(m_Stop) - begin; - if (length < 0) - length += SECSINDAY; - - int DaysToCheck = IsSingleEvent() ? 61 : 7; // 61 to handle months with 31/30/31 - for (int i = -1; i <= DaysToCheck; i++) { - time_t t0 = IncDay(t, i); - if (DayMatches(t0)) { - time_t a = SetTime(t0, begin); - time_t b = a + length; - if ((!m_FirstDay || a >= m_FirstDay) && t <= b) { - m_StartTime = a; - m_StopTime = b; - break; - } - } - } - if (!m_StartTime) - m_StartTime = m_FirstDay; // just to have something that's more than a week in the future - else if (t > m_StartTime || t > m_FirstDay + SECSINDAY + 3600) // +3600 in case of DST change - m_FirstDay = 0; - return m_Active && m_StartTime <= t && t < m_StopTime; // must m_Stop *before* m_StopTime to allow adjacent timers -} - -bool cRemoteTimer::DayMatches(time_t t) { - return IsSingleEvent() - ? GetMDay(t) == m_Day - : (m_Day & (1 << GetWDay(t))) != 0; -} - -int cRemoteTimer::GetMDay(time_t t) -{ - struct tm tm_r; - return localtime_r(&t, &tm_r)->tm_mday; -} - -int cRemoteTimer::GetWDay(time_t t) -{ - struct tm tm_r; - int weekday = localtime_r(&t, &tm_r)->tm_wday; - return weekday == 0 ? 6 : weekday - 1; // we start with monday==0! -} - -time_t cRemoteTimer::IncDay(time_t t, int Days) { - struct tm tm_r; - tm tm = *localtime_r(&t, &tm_r); - tm.tm_mday += Days; // now tm_mday may be out of its valid range - int h = tm.tm_hour; // save original hour to compensate for DST change - tm.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting - t = mktime(&tm); // normalize all values - tm.tm_hour = h; // compensate for DST change - return mktime(&tm); // calculate final result -} - -const char *cRemoteTimer::ToText(void) { - char *summary = NULL; - - if (m_Buffer != NULL) free(m_Buffer); - - strreplace(m_File, ':', '|'); - if (m_Summary != "") - summary = strreplace(strdup(m_Summary.c_str()), ':', '|'); - - asprintf(&m_Buffer, "%d:%s:%s:%04d:%04d:%d:%d:%s:%s", m_Active, - (const char*)Channel()->GetChannelID().ToString(), PrintDay(m_Day, m_FirstDay), - m_Start, m_Stop, m_Priority, m_Lifetime, m_File, summary ? summary : ""); - - if (summary != NULL) - free(summary); - strreplace(m_File, '|', ':'); - return m_Buffer; -} - -// --- cRemoteTimers --------------------------------------------------------- - -bool cRemoteTimers::Load(void) { - Clear(); - return ClientSocket.LoadTimers(*this); -} - diff --git a/client/remote.h b/client/remote.h deleted file mode 100644 index 82b2dee..0000000 --- a/client/remote.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * $Id: remote.h,v 1.3 2008/04/07 14:27:28 schmirl Exp $ - */ - -#ifndef VDR_STREAMDEV_REMOTE_H -#define VDR_STREAMDEV_REMOTE_H - -#include <vdr/config.h> -#include <string> - -class cEvent; -class cChannel; - -class cRemoteRecording: public cListObject { -private: - bool m_IsValid; - int m_Index; - bool m_IsNew; - char *m_TitleBuffer; - std::string m_StartTime; - std::string m_Name; - std::string m_Summary; - -public: - cRemoteRecording(const char *Text); - ~cRemoteRecording(); - - bool operator==(const cRemoteRecording &Recording); - bool operator!=(const cRemoteRecording &Recording); - - void ParseInfo(const char *Text); - - bool IsValid(void) const { return m_IsValid; } - int Index(void) const { return m_Index; } - const char *StartTime(void) const { return m_StartTime.c_str(); } - bool IsNew(void) const { return m_IsNew; } - const char *Name(void) const { return m_Name.c_str(); } - const char *Summary(void) const { return m_Summary.c_str(); } - const char *Title(char Delimiter, bool NewIndicator, int Level); - int HierarchyLevels(void); -}; - -inline bool cRemoteRecording::operator!=(const cRemoteRecording &Recording) { - return !operator==(Recording); -} - -class cRemoteRecordings: public cList<cRemoteRecording> { -public: - bool Load(void); - cRemoteRecording *GetByName(const char *Name); -}; - -class cRemoteTimer: public cListObject { - friend class cStreamdevMenuEditTimer; - -private: - bool m_IsValid; - int m_Index; - int m_Active; - int m_Day; - int m_Start; - int m_Stop; - time_t m_StartTime; - time_t m_StopTime; - int m_Priority; - int m_Lifetime; - char m_File[MaxFileName]; - time_t m_FirstDay; - std::string m_Summary; - char *m_Buffer; - const cChannel *m_Channel; - -public: - cRemoteTimer(const char *Text); - cRemoteTimer(const cEvent *Event); - cRemoteTimer(void); - ~cRemoteTimer(); - - cRemoteTimer &operator=(const cRemoteTimer &Timer); - bool operator==(const cRemoteTimer &Timer); - bool operator!=(const cRemoteTimer &Timer) { return !operator==(Timer); } - - static int ParseDay(const char *s, time_t *FirstDay); - static const char *PrintDay(int d, time_t FirstDay = 0); - static time_t SetTime(time_t t, int SecondsFromMidnight); - static time_t IncDay(time_t t, int Days); - static int TimeToInt(int t) { return (t / 100 * 60 + t % 100) * 60; } - - const char *PrintFirstDay(void) const; - void OnOff(void); - bool IsSingleEvent(void) const { return (m_Day & 0x80000000) == 0; } - void Skip(void) { m_FirstDay = IncDay(SetTime(StartTime(), 0), 1); } - bool Matches(time_t t = 0); - bool DayMatches(time_t t = 0); - int GetMDay(time_t t); - int GetWDay(time_t t); - - bool IsValid(void) const { return m_IsValid; } - int Index(void) const { return m_Index; } - int Active(void) const { return m_Active; } - int Day(void) const { return m_Day; } - int Start(void) const { return m_Start; } - int Stop(void) const { return m_Stop; } - time_t StartTime(void) { if (!m_StartTime) Matches(); return m_StartTime; } - time_t StopTime(void) { if (!m_StopTime) Matches(); return m_StopTime; } - int Priority(void) const { return m_Priority; } - int Lifetime(void) const { return m_Lifetime; } - const char *File(void) const { return m_File; } - time_t FirstDay(void) const { return m_FirstDay; } - const std::string &Summary(void) const { return m_Summary; } - const cChannel *Channel(void) const { return m_Channel; } - - const char *ToText(void); -}; - -class cRemoteTimers: public cList<cRemoteTimer> { -public: - bool Load(void); -}; - -extern cRemoteTimers RemoteTimers; - -#endif // VDR_STREAMDEV_REMOTE_H diff --git a/client/setup.c b/client/setup.c index 7da9948..31e20ad 100644 --- a/client/setup.c +++ b/client/setup.c @@ -1,5 +1,5 @@ /* - * $Id: setup.c,v 1.3 2008/04/07 14:27:28 schmirl Exp $ + * $Id: setup.c,v 1.4 2008/04/07 14:40:40 schmirl Exp $ */ #include <vdr/menuitems.h> @@ -52,7 +52,7 @@ void cStreamdevClientMenuSetupPage::Store(void) { if (m_NewSetup.StartClient) cStreamdevDevice::Init(); else - INFO(tr("Please restart VDR to activate changes")); + Skins.Message(mtInfo, tr("Please restart VDR to activate changes")); } SetupStore("StartClient", m_NewSetup.StartClient); diff --git a/client/socket.c b/client/socket.c index 69eeae7..569fd43 100644 --- a/client/socket.c +++ b/client/socket.c @@ -1,5 +1,5 @@ /* - * $Id: socket.c,v 1.10 2008/04/07 14:27:28 schmirl Exp $ + * $Id: socket.c,v 1.11 2008/04/07 14:40:40 schmirl Exp $ */ #include <tools/select.h> @@ -13,7 +13,6 @@ #include "client/socket.h" #include "client/setup.h" -#include "client/remote.h" #include "common.h" #include "i18n.h" @@ -362,128 +361,6 @@ bool cClientSocket::Quit(void) { return res; } -bool cClientSocket::LoadRecordings(cRemoteRecordings &Recordings) { - bool res; - - if (!CheckConnection()) return false; - - CMD_LOCK; - - if (!Command("LSTR")) - return false; - - std::string buffer; - while ((res = Expect(250, &buffer))) { - cRemoteRecording *rec = new cRemoteRecording(buffer.c_str() + 4); - Dprintf("recording valid: %d\n", rec->IsValid()); - if (rec->IsValid()) - Recordings.Add(rec); - else - delete rec; - if (buffer[3] == ' ') break; - } - - if (!res && buffer.substr(0, 3) != "550") { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't fetch recordings from %s:%d", - RemoteIp().c_str(), RemotePort()); - return false; - } - - for (cRemoteRecording *r = Recordings.First(); r; r = Recordings.Next(r)) { - std::string command = (std::string)"LSTR " + (const char*)itoa(r->Index()); - if (!Command(command)) - return false; - - if (Expect(250, &buffer)) - r->ParseInfo(buffer.c_str() + 4); - else if (buffer.substr(0, 3) != "550") { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't fetch details for recording from %s:%d", - RemoteIp().c_str(), RemotePort()); - return false; - } - Dprintf("recording complete: %d\n", r->Index()); - } - return res; -} - -bool cClientSocket::StartReplay(const char *Filename) { - if (!CheckConnection()) return false; - - CMD_LOCK; - - std::string command = (std::string)"PLAY " + Filename; - if (!Command(command, 220)) { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't replay \"%s\" from %s:%d", - Filename, RemoteIp().c_str(), RemotePort()); - return false; - } - return true; -} - -bool cClientSocket::AbortReplay(void) { - if (!CheckConnection()) return false; - - CMD_LOCK; - - if (m_DataSockets[siReplay] != NULL) { - std::string command = (std::string)"ABRT " + (const char*)itoa(siReplay); - if (!Command(command, 220)) { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't cleanly close data connection"); - return false; - } - - DELETENULL(m_DataSockets[siReplay]); - } - return true; -} - -bool cClientSocket::DeleteRecording(cRemoteRecording *Recording) { - bool res; - cRemoteRecording *rec = NULL; - - if (!CheckConnection()) - return false; - - CMD_LOCK; - - if (!Command("LSTR")) - return false; - - std::string buffer; - while ((res = Expect(250, &buffer))) { - if (rec == NULL) { - rec = new cRemoteRecording(buffer.c_str() + 4); - if (!rec->IsValid() || rec->Index() != Recording->Index()) - DELETENULL(rec); - } - if (buffer[3] == ' ') break; - } - - if (!res && buffer.substr(0, 3) != "550") { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't fetch recordings from %s:%d", - RemoteIp().c_str(), RemotePort()); - if (rec != NULL) delete rec; - return false; - } - - if (rec == NULL || *rec != *Recording) { - ERROR(tr("Recordings not in sync! Try again...")); - return false; - } - - std::string command = (std::string)"DELR " + (const char*)itoa(Recording->Index()); - if (!Command(command, 250)) { - ERROR(tr("Couldn't delete recording! Try again...")); - return false; - } - return true; -} - bool cClientSocket::SuspendServer(void) { if (!CheckConnection()) return false; @@ -496,108 +373,3 @@ bool cClientSocket::SuspendServer(void) { } return true; } - -bool cClientSocket::LoadTimers(cRemoteTimers &Timers) { - if (!CheckConnection()) return false; - - CMD_LOCK; - - if (!Command("LSTT")) - return false; - - bool res; - std::string buffer; - while ((res = Expect(250, &buffer))) { - cRemoteTimer *timer = new cRemoteTimer(buffer.c_str() + 4); - Dprintf("timer valid: %d\n", timer->IsValid()); - if (timer->IsValid()) - Timers.Add(timer); - if (buffer[3] == ' ') break; - } - - if (!res && buffer.substr(0, 3) != "550") { - if (errno == 0) - esyslog("ERROR: Streamdev: Couldn't fetch recordings from %s:%d", - RemoteIp().c_str(), RemotePort()); - return false; - } - return res; -} - -bool cClientSocket::SaveTimer(cRemoteTimer *Old, cRemoteTimer &New) { - if (!CheckConnection()) return false; - - CMD_LOCK; - - if (New.Index() == -1) { // New timer - std::string command = (std::string)"NEWT " + (const char*)New.ToText(); - if (!Command(command, 250)) { - ERROR(tr("Couldn't save timer! Try again...")); - return false; - } - } else { // Modified timer - std::string command = (std::string)"LSTT " + (const char*)itoa(New.Index()); - if (!Command(command)) - return false; - - std::string buffer; - if (!Expect(250, &buffer)) { - if (errno == 0) - ERROR(tr("Timers not in sync! Try again...")); - else - ERROR(tr("Server error! Try again...")); - return false; - } - - cRemoteTimer oldstate(buffer.c_str() + 4); - if (oldstate != *Old) { - /*Dprintf("old timer: %d,%d,%d,%d,%d,%d,%s,%d,%s,%d\n", oldstate.m_Index, - oldstate.m_Active,oldstate.m_Day,oldstate.m_Start,oldstate.m_StartTime,oldstate.m_Priority,oldstate.m_File,oldstate.m_FirstDay,(const char*)oldstate.m_Summary,oldstate.m_Channel->Number()); - Dprintf("new timer: %d,%d,%d,%d,%d,%d,%s,%d,%s,%d\n", Old->m_Index, - Old->m_Active,Old->m_Day,Old->m_Start,Old->m_StartTime,Old->m_Priority,Old->m_File,Old->m_FirstDay,(const char*)Old->m_Summary,Old->m_Channel->Number());*/ - ERROR(tr("Timers not in sync! Try again...")); - return false; - } - - - command = (std::string)"MODT " + (const char*)itoa(New.Index()) + " " - + (const char*)New.ToText(); - if (!Command(command, 250)) { - ERROR(tr("Couldn't save timer! Try again...")); - return false; - } - } - return true; -} - -bool cClientSocket::DeleteTimer(cRemoteTimer *Timer) { - if (!CheckConnection()) return false; - - CMD_LOCK; - - std::string command = (std::string)"LSTT " + (const char*)itoa(Timer->Index()); - if (!Command(command)) - return false; - - std::string buffer; - if (!Expect(250, &buffer)) { - if (errno == 0) - ERROR(tr("Timers not in sync! Try again...")); - else - ERROR(tr("Server error! Try again...")); - return false; - } - - cRemoteTimer oldstate(buffer.c_str() + 4); - if (oldstate != *Timer) { - ERROR(tr("Timers not in sync! Try again...")); - return false; - } - - command = (std::string)"DELT " + (const char*)itoa(Timer->Index()); - if (!Command(command, 250)) { - ERROR(tr("Couldn't delete timer! Try again...")); - return false; - } - return true; -} diff --git a/client/socket.h b/client/socket.h index 742c064..a0400e6 100644 --- a/client/socket.h +++ b/client/socket.h @@ -1,5 +1,5 @@ /* - * $Id: socket.h,v 1.5 2008/04/07 14:27:28 schmirl Exp $ + * $Id: socket.h,v 1.6 2008/04/07 14:40:40 schmirl Exp $ */ #ifndef VDR_STREAMDEV_CLIENT_CONNECTION_H @@ -13,10 +13,6 @@ #define CMD_LOCK cMutexLock CmdLock((cMutex*)&m_Mutex) -class cRemoteRecordings; -class cRemoteRecording; -class cRemoteTimers; -class cRemoteTimer; class cPES2TSRemux; class cClientSocket: public cTBSocket { @@ -53,13 +49,6 @@ public: bool SetFilter(ushort Pid, uchar Tid, uchar Mask, bool On); bool CloseDvr(void); bool SynchronizeEPG(void); - bool LoadRecordings(cRemoteRecordings &Recordings); - bool StartReplay(const char *Filename); - bool AbortReplay(void); - bool DeleteRecording(cRemoteRecording *Recording); - bool LoadTimers(cRemoteTimers &Timers); - bool SaveTimer(cRemoteTimer *Old, cRemoteTimer &New); - bool DeleteTimer(cRemoteTimer *Timer); bool SuspendServer(void); bool Quit(void); |