/** * GraphTFT plugin for the Video Disk Recorder * * display.h - A plugin for the Video Disk Recorder * * (c) 2004 Lars Tegeler, Sascha Volkenandt * (c) 2006-2008 Jörg Wendel * * This code is distributed under the terms and conditions of the * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details. * * $Id: display.h,v 1.12 2012/09/27 13:07:09 wendel Exp $ * **/ #ifndef __GTFT_DISPLAY_H #define __GTFT_DISPLAY_H //*************************************************************************** // Includes //*************************************************************************** #include #include #include #include #include #include #include #include #include #include #include #include using std::map; using std::string; using std::vector; //*************************************************************************** // Class cGraphTFTService //*************************************************************************** class cGraphTFTService : public cThemeService { public: enum ChannelType { ctRadio = 0, ctTv }; enum { MaxTabs = 6 }; enum CalibrationStart { csUnknown = na, csUpperLeft, csUpperRight, csLowerLeft, csLowerRight, csDone, csTest }; enum DisplayMode { ModeUnknown = 0x00, ModeMask = 0xF0, DisplayMask = 0x0F, ModeNormal = 0x10, ModeReplay = 0x20, ModeMenu = 0x30, NormalView = 0x11, ReplayNormal = 0x21, ReplayMP3 = 0x22, ReplayDVD = 0x23, ReplayImage = 0x24, MenuDefault = 0x31, MenuMain = 0x32, MenuSchedule = 0x33, MenuChannels = 0x34, MenuTimers = 0x35, MenuRecordings = 0x36, MenuSetup = 0x37, MenuCommands = 0x38, MenuWhatsOnElse = 0x39, MenuWhatsOnNow = 0x3a, MenuWhatsOnNext = 0x3b, MenuSetupPage = 0x3c, ModeCalibration = 0x41, ModeCalibrationTest = 0x42 }; static int isModeNormal(DisplayMode mode) { return (mode & ModeMask) == ModeNormal; } static int isModeReplay(DisplayMode mode) { return (mode & ModeMask) == ModeReplay; } static int isModeMenu(DisplayMode mode) { return (mode & ModeMask) == ModeMenu; } }; //*************************************************************************** // Class GraphTFT Display //*************************************************************************** class cGraphTFTDisplay : public cStatus, cThread, public cGraphTFTService { public: // object cGraphTFTDisplay(const char* aSyntaxVersion); ~cGraphTFTDisplay(); // interface int Init(const char* dev, const char* cfgDir, int port); void setupChanged(); void setCalibrate(int active, int state = csUnknown); void switchCalibrate(int state = csUnknown); int calibrateTouch(int x, int y); int setMode(DisplayMode mode, const char* menuName = 0, int force = false); int isMode(DisplayMode mode) { return mode == _mode; } void setCoverPath(const char* path) { _coverPath = Str::notNull(path); } void musicAddPlaylistItem(const char* item, int index = na); void setMusicPlayerState(cTftCS::MusicServicePlayerInfo* state); void setMusicPlayerHelpButtons(cTftCS::MusicServiceHelpButtons* buttons); cTouchThread* getTouchThread() { return touchThread; } // thread stuff bool Start() { return cThread::Start(); } void Stop(); bool Active() const { return _active; } cMutex* getMutex() { return &_mutex; } void themesReloaded() { lastSection = 0; currentSection = 0; } // due to comThread destructor is called // by vdr, trick to inherited by cRemote void clearComThread() { comThread = 0; } void clearTouchThread() { touchThread = 0; } // event void mouseEvent(int x, int y, int button, int flag = ComThread::efNone, int data = 0); cDisplayItem* getItemAt(int x, int y); int processAction(cDisplayItem* p, string action, int step = 1); // display stuff void broadcast(int force = no); void triggerDump(const char* file, int width = na, int height = na); int display(string sectionName); void refresh(); void clear(); int updateGroup(int group); // Tabs const char* GetTabbedText(const char* s, int Tab); // some structures and types struct RdsInfo { string text; string title; string artist; }; class TimerList { public: TimerList() { runningCnt = 0; iter = 0; } struct TimerInfo { string title; string file; time_t start; time_t stop; int running; const char* nice() { enum { max = 200 }; static char buffer[max]; tm* tmp; *buffer = 0; tmp = localtime(&start); strftime(buffer, max-strlen(buffer), "%a %d.%m %H:%M", tmp); strcat(buffer, " - "); tmp = localtime(&stop); strftime(buffer+strlen(buffer), max-strlen(buffer), "%H:%M", tmp); snprintf(buffer+strlen(buffer), max-strlen(buffer), " %s", title.c_str()); return buffer; } }; typedef vector TimerInfos; void append(cTimer* timer) { TimerInfo info; info.running = timer->Recording(); info.title = timer->File(); // default info.file = timer->File(); info.start = timer->StartTime(); info.stop = timer->StopTime(); if (timer->Event()) info.title = timer->Event()->Title(); timers.push_back(info); if (info.running) runningCnt++; } const char* next() { if (!timers.size() || iter >= timers.size()) return ""; return timers[iter++].nice(); } const char* nextRunning() { if (!timers.size() || iter >= timers.size()) return ""; while (!timers[iter].running) { if (++iter >= timers.size()) return ""; } return timers[iter++].nice(); } const char* nextPending() { if (!timers.size() || iter >= timers.size()) return ""; while (timers[iter].running) { if (++iter >= timers.size()) return ""; } return timers[iter++].nice(); } TimerInfo* getTimer(int index) { return &timers[index]; } int count() { return timers.size(); } int countRunning() { return runningCnt; } void clear() { timers.clear(); runningCnt = 0; } unsigned int iter; protected: int runningCnt; TimerInfos timers; }; // actual replay struct ReplayInfo { DisplayMode lastMode; string name; string fileName; cControl* control; }; struct Calibration { string instruction; string info; int state; int cursorX; int cursorY; int lastX; int lastY; cTouchThread::CalibrationSetting settings; }; struct MenuItem { string text; string tabs[MaxTabs]; int tabCount; int nextX; Ts::MenuItemType type; const cEvent* event; const cChannel* channel; const cRecording* recording; }; struct MenuInfo { DisplayMode lastMode; int currentRow; int currentRowLast; int visibleRows; int topRow; int lineHeight; int lineHeightSelected; string title; string current; string buttons[4]; string text; int drawingRow; // current drawing index vector items; int charInTabs[MaxTabs+1]; }; struct MusicPlayerInfo { MusicPlayerInfo() : iter(0) {} string filename; string artist; string album; string genre; string comment; string year; double frequence; int bitrate; string smode; bool loop; bool shuffle; bool shutdown; bool recording; int rating; int index; // current index in tracklist int count; // items in tracklist bool lyrics; bool copy; bool timer; string status; // player status string currentTrack; vector tracks; // tracklist (only the unplayed part!) // help buttons string red; string green; string yellow; string blue; // internals unsigned int iter; const char* nextTrack() { if (iter >= tracks.size()) return ""; return tracks[iter++].c_str(); } }; // display contents cThemeSection* currentSection; cThemeSection* lastSection; ChannelType channelType; DisplayMode _mode; string _sectionName; int _eventsReady; bool _mute; int _volume; int _showRecording; int _channel; const cChannel* _presentChannel; const cEvent* _presentEvent; const cEvent* _followingEvent; string _channelText; const cEvent* _event; string _coverPath; string _recording; ReplayInfo _replay; string _message; TimerList _timers; // the timers MenuInfo _menu; MusicPlayerInfo _music; // special for Music Plugin RdsInfo _rds; // special for Radio Plugin Calibration calibration; int mouseX; int mouseY; int mouseKey; int touchMenu; uint64_t touchMenuHideAt; uint64_t touchMenuHideTime; // int displayActive; int snapshotPending; protected: // thread virtual void Action(); // helper functions int wait(uint64_t updateIn); int meanwhile(); void takeSnapshot(); bool StoppedTimer(const char *Name); void UpdateProgramme(); const cChannel* channelByName(const char* name); void updateTimers(); // status interface virtual void ChannelSwitch(const cDevice* Device, int ChannelNumber, bool LiveView); virtual void OsdSetEvent(const cEvent* event); virtual void OsdSetRecording(const cRecording* recording); virtual void OsdChannel(const char* Text); virtual void OsdProgramme(time_t PresentTime, const char* PresentTitle, const char *PresentSubtitle, time_t FollowingTime, const char *FollowingTitle, const char *FollowingSubtitle); virtual void SetVolume(int Volume, bool Absolute); virtual void Replaying(const cControl *Control, const char *Name, const char *FileName, bool On); virtual void Recording(const cDevice *Device, const char *Name, const char *FileName, bool On); virtual void TimerChange(const cTimer *Timer, eTimerChange Change); virtual void OsdStatusMessage(const char *Message); virtual void OsdTitle(const char* Title); virtual void OsdItem(const char* Text, int Index); virtual void OsdEventItem(const cEvent* Event, const char* Text, int Index, int Count); virtual void OsdCurrentItem(const char *Text); virtual void OsdClear(); virtual void OsdHelpKeys(const char* Red, const char* Green, const char* Yellow, const char* Blue); virtual void OsdTextItem(const char* Text, bool Scroll); virtual void OsdMenuDisplay(const char* kind); virtual void OsdMenuDestroy(); private: // renderer Renderer* renderer; int isDummyRender; ComThread* comThread; cTouchThread* touchThread; // thread control bool _active; cMutex _mutex; cCondVar _doUpdate; int wakeup; char* userDumpFile; int userDumpWidth; int userDumpHeight; // int forceNextDraw; uint64_t nextCyclicForce; int forceWriteThrough; const char* syntaxVersion; int versionReported; int startedAt; }; //*************************************************************************** #endif // __GTFT_DISPLAY_H