vdr
1.7.27
|
00001 /* 00002 * interface.c: Abstract user interface layer 00003 * 00004 * See the main source file 'vdr.c' for copyright information and 00005 * how to reach the author. 00006 * 00007 * $Id: interface.c 2.1 2011/12/04 14:52:38 kls Exp $ 00008 */ 00009 00010 #include "interface.h" 00011 #include <ctype.h> 00012 #include <stdlib.h> 00013 #include <unistd.h> 00014 #include "i18n.h" 00015 #include "status.h" 00016 00017 cInterface *Interface = NULL; 00018 00019 cInterface::cInterface(int SVDRPport) 00020 { 00021 interrupted = false; 00022 SVDRP = NULL; 00023 if (SVDRPport) 00024 SVDRP = new cSVDRP(SVDRPport); 00025 } 00026 00027 cInterface::~cInterface() 00028 { 00029 delete SVDRP; 00030 } 00031 00032 eKeys cInterface::GetKey(bool Wait) 00033 { 00034 if (!cRemote::HasKeys()) 00035 Skins.Flush(); 00036 if (SVDRP) { 00037 if (SVDRP->Process()) 00038 Wait = false; 00039 } 00040 if (!cRemote::IsLearning()) 00041 return cRemote::Get(Wait ? 1000 : 10); 00042 else 00043 return kNone; 00044 } 00045 00046 eKeys cInterface::Wait(int Seconds, bool KeepChar) 00047 { 00048 if (Seconds == 0) 00049 Seconds = Setup.OSDMessageTime; 00050 Skins.Flush(); 00051 eKeys Key = kNone; 00052 time_t timeout = time(NULL) + Seconds; 00053 for (;;) { 00054 Key = GetKey(); 00055 if (ISRAWKEY(Key) || time(NULL) > timeout || interrupted) 00056 break; 00057 } 00058 if (KeepChar && ISRAWKEY(Key) || Key == k_Plugin) 00059 cRemote::Put(Key); 00060 interrupted = false; 00061 return Key; 00062 } 00063 00064 bool cInterface::Confirm(const char *s, int Seconds, bool WaitForTimeout) 00065 { 00066 isyslog("confirm: %s", s); 00067 eKeys k = Skins.Message(mtWarning, s, Seconds); 00068 bool result = WaitForTimeout ? k == kNone : k == kOk; 00069 isyslog("%sconfirmed", result ? "" : "not "); 00070 return result; 00071 } 00072 00073 bool cInterface::QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu) 00074 { 00075 DisplayMenu->SetItem(tr("Phase 1: Detecting RC code type"), 2, false, false); 00076 DisplayMenu->SetItem(tr("Press any key on the RC unit"), 4, false, false); 00077 DisplayMenu->Flush(); 00078 if (Remote->Initialize()) { 00079 DisplayMenu->SetItem(tr("RC code detected!"), 4, false, false); 00080 DisplayMenu->SetItem(tr("Do not press any key..."), 5, false, false); 00081 DisplayMenu->Flush(); 00082 cCondWait::SleepMs(3000); 00083 DisplayMenu->SetItem("", 4, false, false); 00084 DisplayMenu->SetItem("", 5, false, false); 00085 00086 DisplayMenu->SetItem(tr("Phase 2: Learning specific key codes"), 2, false, false); 00087 eKeys NewKey = kUp; 00088 while (NewKey != kNone) { 00089 DisplayMenu->SetItem(cString::sprintf(tr("Press key for '%s'"), cKey::ToString(NewKey, true)), 4, false, false); 00090 cRemote::Clear(); 00091 DisplayMenu->Flush(); 00092 for (eKeys k = NewKey; k == NewKey; ) { 00093 char *NewCode = NULL; 00094 eKeys Key = cRemote::Get(100, &NewCode); 00095 switch (Key) { 00096 case kUp: if (NewKey > kUp) { 00097 NewKey = eKeys(NewKey - 1); 00098 cKey *last = Keys.Last(); 00099 if (last && last->Key() == NewKey) 00100 Keys.Del(last); 00101 } 00102 break; 00103 case kDown: DisplayMenu->SetItem(tr("Press 'Up' to confirm"), 4, false, false); 00104 DisplayMenu->SetItem(tr("Press 'Down' to continue"), 5, false, false); 00105 DisplayMenu->SetItem("", 6, false, false); 00106 DisplayMenu->SetItem("", 7, false, false); 00107 DisplayMenu->SetItem("", 8, false, false); 00108 DisplayMenu->Flush(); 00109 for (;;) { 00110 Key = cRemote::Get(100); 00111 if (Key == kUp) { 00112 DisplayMenu->Clear(); 00113 return true; 00114 } 00115 else if (Key == kDown) { 00116 DisplayMenu->SetItem("", 5, false, false); 00117 k = kNone; // breaks the outer for() loop 00118 break; 00119 } 00120 } 00121 break; 00122 case kMenu: NewKey = eKeys(NewKey + 1); 00123 break; 00124 case kNone: if (NewCode) { 00125 dsyslog("new %s code: %s = %s", Remote->Name(), NewCode, cKey::ToString(NewKey)); 00126 Keys.Add(new cKey(Remote->Name(), NewCode, NewKey)); 00127 NewKey = eKeys(NewKey + 1); 00128 free(NewCode); 00129 } 00130 break; 00131 default: break; 00132 } 00133 } 00134 if (NewKey > kUp) 00135 DisplayMenu->SetItem(tr("(press 'Up' to go back)"), 6, false, false); 00136 else 00137 DisplayMenu->SetItem("", 6, false, false); 00138 if (NewKey > kDown) 00139 DisplayMenu->SetItem(tr("(press 'Down' to end key definition)"), 7, false, false); 00140 else 00141 DisplayMenu->SetItem("", 7, false, false); 00142 if (NewKey > kMenu) 00143 DisplayMenu->SetItem(tr("(press 'Menu' to skip this key)"), 8, false, false); 00144 else 00145 DisplayMenu->SetItem("", 8, false, false); 00146 } 00147 return true; 00148 } 00149 return false; 00150 } 00151 00152 void cInterface::LearnKeys(void) 00153 { 00154 for (cRemote *Remote = Remotes.First(); Remote; Remote = Remotes.Next(Remote)) { 00155 if (!Remote->Ready()) { 00156 esyslog("ERROR: remote control %s not ready!", Remote->Name()); 00157 continue; 00158 } 00159 bool known = Keys.KnowsRemote(Remote->Name()); 00160 dsyslog("remote control %s - %s", Remote->Name(), known ? "keys known" : "learning keys"); 00161 if (!known) { 00162 cSkinDisplayMenu *DisplayMenu = Skins.Current()->DisplayMenu(); 00163 char Headline[256]; 00164 snprintf(Headline, sizeof(Headline), tr("Learning Remote Control Keys")); 00165 cRemote::Clear(); 00166 DisplayMenu->SetTitle(Headline); 00167 DisplayMenu->SetItem(Remote->Name(), 0, false, false); 00168 cRemote::SetLearning(Remote); 00169 bool rc = QueryKeys(Remote, DisplayMenu); 00170 cRemote::SetLearning(NULL); 00171 DisplayMenu->Clear(); 00172 if (!rc) { 00173 delete DisplayMenu; 00174 continue; 00175 } 00176 DisplayMenu->SetItem(Remote->Name(), 0, false, false); 00177 DisplayMenu->SetItem(tr("Phase 3: Saving key codes"), 2, false, false); 00178 DisplayMenu->SetItem(tr("Press 'Up' to save, 'Down' to cancel"), 4, false, false); 00179 for (;;) { 00180 eKeys key = GetKey(); 00181 if (key == kUp) { 00182 Keys.Save(); 00183 delete DisplayMenu; 00184 break; 00185 } 00186 else if (key == kDown) { 00187 Keys.Load(); 00188 delete DisplayMenu; 00189 break; 00190 } 00191 } 00192 } 00193 } 00194 }