/** * GraphLCD plugin for the Video Disk Recorder * * status.c - status monitor class * * (c) 2001-2004 Carsten Siebholz **/ #include #include #include "display.h" #include "state.h" #include "strfct.h" #include #include #include "compat.h" cGraphLCDState::cGraphLCDState(cGraphLCDDisplay * Display) : mDisplay(Display), first(true), tickUsed(false) { channel.number = 0; channel.str = ""; channel.strTmp = ""; event.presentTime = 0; event.presentTitle = ""; event.presentSubtitle = ""; event.followingTime = 0; event.followingTitle = ""; event.followingSubtitle = ""; replay.name = ""; replay.loopmode = ""; replay.control = NULL; replay.mode = eReplayNormal; replay.current = 0; replay.currentLast = FRAMESPERSEC; replay.total = 0; replay.totalLast = 1; for (int i = 0; i < MAXDEVICES; i++) { card[i].recordingCount = 0; card[i].recordingName = ""; } osd.currentItem = ""; osd.title = ""; for (int i = 0; i < 4; i++) osd.colorButton[i] = ""; osd.message = ""; osd.textItem = ""; osd.currentItemIndex = 0; volume.value = -1; volume.lastChange = 0; SetChannel(cDevice::CurrentChannel()); } cGraphLCDState::~cGraphLCDState() { } void cGraphLCDState::ChannelSwitch(const cDevice * Device, int ChannelNumber) { //printf("graphlcd plugin: cGraphLCDState::ChannelSwitch %d %d\n", Device->CardIndex(), ChannelNumber); if (GraphLCDSetup.PluginActive) { if (ChannelNumber > 0 && Device->IsPrimaryDevice() && !EITScanner.UsesDevice(Device)) { if (ChannelNumber == cDevice::CurrentChannel()) { SetChannel(ChannelNumber); } } } } #if VDRVERSNUM < 10338 void cGraphLCDState::Recording(const cDevice * Device, const char * Name) #else void cGraphLCDState::Recording(const cDevice * Device, const char * Name, const char *FileName, bool On) #endif { //printf("graphlcd plugin: cGraphLCDState::Recording %d %s\n", Device->CardIndex(), Name); if (GraphLCDSetup.PluginActive) { mutex.Lock(); #if VDRVERSNUM < 10338 if (Name) #else if (On) #endif { card[Device->DeviceNumber()].recordingCount++; #if VDRVERSNUM < 10338 card[Device->DeviceNumber()].recordingName = Name; #else card[Device->DeviceNumber()].recordingName = Name ? Name : ""; #endif } else { if (card[Device->DeviceNumber()].recordingCount > 0) card[Device->DeviceNumber()].recordingCount--; card[Device->DeviceNumber()].recordingName = ""; } mutex.Unlock(); mDisplay->Update(); } } #if VDRVERSNUM < 10338 void cGraphLCDState::Replaying(const cControl * Control, const char * Name) #else void cGraphLCDState::Replaying(const cControl * Control, const char * Name, const char *FileName, bool On) #endif { //printf("graphlcd plugin: cGraphLCDState::Replaying %s\n", Name); if (GraphLCDSetup.PluginActive) { #if VDRVERSNUM < 10338 if (Name) #else if (On) #endif { mutex.Lock(); replay.control = (cControl *) Control; replay.mode = eReplayNormal; replay.name = ""; replay.loopmode = ""; #if VDRVERSNUM < 10338 if (!isempty(Name)) #else if (Name && !isempty(Name)) #endif { if (GraphLCDSetup.IdentifyReplayType) { int slen = strlen(Name); bool bFound = false; /////////////////////////////////////////////////////////////////////// //Looking for mp3-Plugin Replay : [LS] (444/666) title // if (slen > 6 && *(Name+0)=='[' && *(Name+3)==']' && *(Name+5)=='(') { unsigned int i; for (i=6; *(Name + i) != '\0'; ++i) //search for [xx] (xxxx) title { if (*(Name+i)==' ' && *(Name+i-1)==')') { bFound = true; break; } } if (bFound) //found MP3-Plugin replaymessage { unsigned int j; // get loopmode replay.loopmode = Name; replay.loopmode = replay.loopmode.substr (0, 5); if (replay.loopmode[2] == '.') replay.loopmode.erase (2, 1); if (replay.loopmode[1] == '.') replay.loopmode.erase (1, 1); if (replay.loopmode[1] == ']') replay.loopmode = ""; //printf ("loopmode=<%s>\n", replay.loopmode.c_str ()); for (j=0;*(Name+i+j) != '\0';++j) //trim name { if (*(Name+i+j)!=' ') break; } if (strlen(Name+i+j) > 0) { //if name isn't empty, then copy replay.name = Name + i + j; } else { //if Name empty, set fallback title replay.name = tr("Unknown title"); } replay.mode = eReplayMusic; } } /////////////////////////////////////////////////////////////////////// //Looking for DVD-Plugin Replay : 1/8 4/28, de 2/5 ac3, no 0/7, 16:9, VOLUMENAME //cDvdPlayerControl::GerDisplayHeaderLine // titleinfo, audiolang, spulang, aspect, title if (!bFound) { if (slen>7) { unsigned int i,n; for (n=0,i=0;*(Name+i) != '\0';++i) { //search volumelabel after 4*", " => xxx, xxx, xxx, xxx, title if (*(Name+i)==' ' && *(Name+i-1)==',') { if (++n == 4) { bFound = true; break; } } } if (bFound) //found DVD replaymessage { unsigned int j;bool b; for (j=0;*(Name+i+j) != '\0';++j) //trim name { if (*(Name+i+j)!=' ') break; } if (strlen(Name+i+j) > 0) { // if name isn't empty, then copy replay.name = Name + i + j; // replace all '_' with ' ' replace(replay.name.begin(), replay.name.end(), '_', ' '); for (j = 0, b = true; j < replay.name.length(); ++j) { // KAPITALIZE -> Kaptialize if (replay.name[j] == ' ') b = true; else if (b) b = false; else replay.name[j] = tolower(replay.name[j]); } } else { //if Name empty, set fallback title replay.name = tr("Unknown title"); } replay.mode = eReplayDVD; } } } if (!bFound) { int i; for (i=slen-1;i>0;--i) { //Reversesearch last Subtitle // - filename contains '~' => subdirectory // or filename contains '/' => subdirectory switch (*(Name+i)) { case '/': { // look for file extentsion like .xxx or .xxxx if (slen>5 && ((*(Name+slen-4) == '.') || (*(Name+slen-5) == '.'))) { replay.mode = eReplayFile; } else { break; } } case '~': { replay.name = Name + i + 1; bFound = true; i = 0; } default: break; } } } if (0 == strncmp(Name,"[image] ",8)) { if (replay.mode != eReplayFile) //if'nt already Name stripped-down as filename replay.name = Name + 8; replay.mode = eReplayImage; bFound = true; } else if (0 == strncmp(Name,"[audiocd] ",10)) { replay.name = Name + 10; replay.mode = eReplayAudioCD; bFound = true; } if (!bFound || !GraphLCDSetup.ModifyReplayString) { replay.name = Name; } } else { replay.name = Name; } } replay.currentLast = FRAMESPERSEC; replay.totalLast = 1; mutex.Unlock(); } else { mutex.Lock(); replay.control = NULL; mutex.Unlock(); SetChannel(channel.number); } #if VDRVERSNUM < 10338 mDisplay->Replaying(Name ? true : false, replay.mode); #else mDisplay->Replaying(On, replay.mode); #endif } } void cGraphLCDState::SetVolume(int Volume, bool Absolute) { //printf("graphlcd plugin: cGraphLCDState::SetVolume %d %d\n", Volume, Absolute); if (GraphLCDSetup.PluginActive) { mutex.Lock(); #if VDRVERSNUM < 10402 volume.value = Volume; #else if (!Absolute) { volume.value += Volume; } else { volume.value = Volume; } #endif if (!first) { volume.lastChange = cTimeMs::Now(); mutex.Unlock(); mDisplay->Update(); } else { // first time first = false; mutex.Unlock(); } } } void cGraphLCDState::Tick() { //printf("graphlcd plugin: cGraphLCDState::Tick\n"); if (GraphLCDSetup.PluginActive) { mutex.Lock(); tickUsed = true; if (replay.control) { if (replay.control->GetIndex(replay.current, replay.total, false)) { replay.total = (replay.total == 0) ? 1 : replay.total; } else { replay.control = NULL; } } mutex.Unlock(); } } void cGraphLCDState::OsdClear() { //printf("graphlcd plugin: cGraphLCDState::OsdClear\n"); if (GraphLCDSetup.PluginActive) { mutex.Lock(); channel.strTmp = ""; osd.title = ""; osd.items.clear(); for (int i = 0; i < 4; i++) osd.colorButton[i] = ""; osd.message = ""; osd.textItem = ""; mutex.Unlock(); mDisplay->SetClear(); } } void cGraphLCDState::OsdTitle(const char * Title) { //printf("graphlcd plugin: cGraphLCDState::OsdTitle '%s'\n", Title); if (GraphLCDSetup.PluginActive) { mutex.Lock(); osd.message = ""; osd.title = ""; if (Title) { osd.title = Title; // remove the time std::string::size_type pos = osd.title.find('\t'); if (pos != std::string::npos) osd.title.resize(pos); osd.title = compactspace(osd.title); } mutex.Unlock(); mDisplay->SetOsdTitle(); } } void cGraphLCDState::OsdStatusMessage(const char * Message) { //printf("graphlcd plugin: cGraphLCDState::OsdStatusMessage '%s'\n", Message); if (GraphLCDSetup.PluginActive) { if (GraphLCDSetup.ShowMessages) { mutex.Lock(); if (Message) osd.message = compactspace(Message); else osd.message = ""; mutex.Unlock(); mDisplay->Update(); } } } void cGraphLCDState::OsdHelpKeys(const char * Red, const char * Green, const char * Yellow, const char * Blue) { //printf("graphlcd plugin: cGraphLCDState::OsdHelpKeys %s - %s - %s - %s\n", Red, Green, Yellow, Blue); if (GraphLCDSetup.PluginActive) { if (GraphLCDSetup.ShowColorButtons) { mutex.Lock(); for (int i = 0; i < 4; i++) osd.colorButton[i] = ""; if (Red) osd.colorButton[0] = compactspace(Red); if (Green) osd.colorButton[1] = compactspace(Green); if (Yellow) osd.colorButton[2] = compactspace(Yellow); if (Blue) osd.colorButton[3] = compactspace(Blue); mutex.Unlock(); } } } void cGraphLCDState::OsdItem(const char * Text, int Index) { //printf("graphlcd plugin: cGraphLCDState::OsdItem %s, %d\n", Text, Index); if (GraphLCDSetup.PluginActive) { if (GraphLCDSetup.ShowMenu) { mutex.Lock(); osd.message = ""; if (Text) osd.items.push_back(Text); mutex.Unlock(); if (Text) mDisplay->SetOsdItem(Text); } } } void cGraphLCDState::OsdCurrentItem(const char * Text) { //printf("graphlcd plugin: cGraphLCDState::OsdCurrentItem %s\n", Text); if (GraphLCDSetup.PluginActive) { if (GraphLCDSetup.ShowMenu) { int tabs; std::string::size_type pos; mutex.Lock(); osd.message = ""; osd.currentItem = ""; if (Text) { osd.currentItem = Text; // count nr of tabs in text tabs = 0; for (unsigned int i = 0; i < osd.currentItem.length(); i++) { if (osd.currentItem[i] == '\t') tabs++; } if (tabs == 1) { // only one tab => prob. Setup Menu pos = osd.currentItem.find('\t'); osd.currentItemIndex = 0; if (pos != std::string::npos) { for (unsigned int i = 0; i < osd.items.size(); i++) { if (osd.items[i].find(osd.currentItem.c_str(), 0, pos) == 0) { osd.currentItemIndex = i; osd.items[i] = osd.currentItem; break; } } } } else { osd.currentItemIndex = 0; for (unsigned int i = 0; i < osd.items.size(); i++) { if (osd.items[i].compare(osd.currentItem) == 0) { osd.currentItemIndex = i; break; } } } } mutex.Unlock(); if (Text) mDisplay->SetOsdCurrentItem(); } } } void cGraphLCDState::OsdTextItem(const char * Text, bool Scroll) { //printf("graphlcd plugin: cGraphLCDState::OsdTextItem %s %d\n", Text, Scroll); if (GraphLCDSetup.PluginActive) { mutex.Lock(); if (Text) { osd.textItem = trim(Text); #if 0 // replace '\n' with ' ' for (unsigned int i = 0; i < osd.textItem.length(); i++) if (osd.textItem[i] == '\n' && (i + 1) < osd.textItem.length() && osd.textItem[i + 1] != '\n') osd.textItem[i] = ' '; #endif } mutex.Unlock(); mDisplay->SetOsdTextItem(Text, Scroll); } } void cGraphLCDState::OsdChannel(const char * Text) { //printf("graphlcd plugin: cGraphLCDState::OsdChannel %s\n", Text); if (GraphLCDSetup.PluginActive) { mutex.Lock(); if (Text) { channel.strTmp = Text; channel.strTmp = compactspace(channel.strTmp); } else { channel.strTmp = ""; } mutex.Unlock(); if (Text) mDisplay->Update(); } } void cGraphLCDState::OsdProgramme(time_t PresentTime, const char * PresentTitle, const char * PresentSubtitle, time_t FollowingTime, const char * FollowingTitle, const char * FollowingSubtitle) { //printf("graphlcd plugin: cGraphLCDState::OsdProgramme PT : %s\n", PresentTitle); //printf("graphlcd plugin: cGraphLCDState::OsdProgramme PST: %s\n", PresentSubtitle); //printf("graphlcd plugin: cGraphLCDState::OsdProgramme FT : %s\n", FollowingTitle); //printf("graphlcd plugin: cGraphLCDState::OsdProgramme FST: %s\n", FollowingSubtitle); if (GraphLCDSetup.PluginActive) { mutex.Lock(); event.presentTime = PresentTime; event.presentTitle = ""; if (!isempty(PresentTitle)) event.presentTitle = PresentTitle; event.presentSubtitle = ""; if (!isempty(PresentSubtitle)) event.presentSubtitle = PresentSubtitle; event.followingTime = FollowingTime; event.followingTitle = ""; if (!isempty(FollowingTitle)) event.followingTitle = FollowingTitle; event.followingSubtitle = ""; if (!isempty(FollowingSubtitle)) event.followingSubtitle = FollowingSubtitle; mutex.Unlock(); mDisplay->Update(); } } void cGraphLCDState::SetChannel(int ChannelNumber) { char tmp[16]; if (ChannelNumber == 0) return; mutex.Lock(); channel.number = ChannelNumber; cChannel * ch = Channels.GetByNumber(channel.number); channel.id = ch->GetChannelID(); sprintf(tmp, "%d ", channel.number); channel.str = tmp; channel.str += ch->Name(); event.presentTime = 0; event.followingTime = 0; mutex.Unlock(); mDisplay->SetChannel(ChannelNumber); } void cGraphLCDState::GetProgramme() { mutex.Lock(); #if VDRVERSNUM < 10300 const cEventInfo * present = NULL, * following = NULL; cMutexLock mutexLock; const cSchedules * schedules = cSIProcessor::Schedules(mutexLock); if (channel.id.Valid()) { if (schedules) { const cSchedule * schedule = schedules->GetSchedule(channel.id); if (schedule) { if ((present = schedule->GetPresentEvent()) != NULL) { event.presentTime = present->GetTime(); event.presentTitle = ""; if (!isempty(present->GetTitle())) event.presentTitle = present->GetTitle(); event.presentSubtitle = ""; if (!isempty(present->GetSubtitle())) event.presentSubtitle = present->GetSubtitle(); } if ((following = schedule->GetFollowingEvent()) != NULL) { event.followingTime = following->GetTime(); event.followingTitle = ""; if (!isempty(following->GetTitle())) event.followingTitle = following->GetTitle(); event.followingSubtitle = ""; if (!isempty(following->GetSubtitle())) event.followingSubtitle = following->GetSubtitle(); } } } } #else const cEvent * present = NULL, * following = NULL; cSchedulesLock schedulesLock; const cSchedules * schedules = cSchedules::Schedules(schedulesLock); if (channel.id.Valid()) { if (schedules) { const cSchedule * schedule = schedules->GetSchedule(channel.id); if (schedule) { if ((present = schedule->GetPresentEvent()) != NULL) { event.presentTime = present->StartTime(); event.presentTitle = ""; if (!isempty(present->Title())) event.presentTitle = present->Title(); event.presentSubtitle = ""; if (!isempty(present->ShortText())) event.presentSubtitle = present->ShortText(); } if ((following = schedule->GetFollowingEvent()) != NULL) { event.followingTime = following->StartTime(); event.followingTitle = ""; if (!isempty(following->Title())) event.followingTitle = following->Title(); event.followingSubtitle = ""; if (!isempty(following->ShortText())) event.followingSubtitle = following->ShortText(); } } } } #endif mutex.Unlock(); } tChannelState cGraphLCDState::GetChannelState() { tChannelState ret; mutex.Lock(); ret = channel; mutex.Unlock(); return ret; } tEventState cGraphLCDState::GetEventState() { tEventState ret; GetProgramme(); mutex.Lock(); ret = event; mutex.Unlock(); return ret; } tReplayState cGraphLCDState::GetReplayState() { tReplayState ret; mutex.Lock(); if (tickUsed) { if (replay.control) { ret = replay; replay.currentLast = replay.current; replay.totalLast = replay.total; } else { ret = replay; } } else { if (replay.control) { if (replay.control->GetIndex(replay.current, replay.total, false)) { replay.total = (replay.total == 0) ? 1 : replay.total; ret = replay; replay.currentLast = replay.current; replay.totalLast = replay.total; } else { replay.control = NULL; ret = replay; } } else { ret = replay; } } mutex.Unlock(); return ret; } tCardState cGraphLCDState::GetCardState(int number) { tCardState ret; mutex.Lock(); ret = card[number]; mutex.Unlock(); return ret; } tOsdState cGraphLCDState::GetOsdState() { tOsdState ret; mutex.Lock(); ret = osd; mutex.Unlock(); return ret; } tVolumeState cGraphLCDState::GetVolumeState() { tVolumeState ret; mutex.Lock(); ret = volume; mutex.Unlock(); return ret; }