vdr 2.7.7
interface.c
Go to the documentation of this file.
1/*
2 * interface.c: Abstract user interface layer
3 *
4 * See the main source file 'vdr.c' for copyright information and
5 * how to reach the author.
6 *
7 * $Id: interface.c 4.1 2015/04/28 11:16:06 kls Exp $
8 */
9
10#include "interface.h"
11#include <ctype.h>
12#include <stdlib.h>
13#ifdef SDNOTIFY
14#include <systemd/sd-daemon.h>
15#endif
16#include <unistd.h>
17#include "i18n.h"
18#include "status.h"
19
21
23{
24 interrupted = false;
25}
26
30
32{
33 if (!cRemote::HasKeys())
34 Skins.Flush();
36 return cRemote::Get(Wait ? 1000 : 10);
37 else
38 return kNone;
39}
40
41eKeys cInterface::Wait(int Seconds, bool KeepChar)
42{
43 if (Seconds == 0)
44 Seconds = Setup.OSDMessageTime;
45 Skins.Flush();
46 eKeys Key = kNone;
47 time_t timeout = time(NULL) + Seconds;
48 for (;;) {
49 Key = GetKey();
50 if (ISRAWKEY(Key) || time(NULL) > timeout || interrupted)
51 break;
52 }
53 if (KeepChar && ISRAWKEY(Key) || Key == k_Plugin)
54 cRemote::Put(Key);
55 interrupted = false;
56 return Key;
57}
58
59bool cInterface::Confirm(const char *s, int Seconds, bool WaitForTimeout)
60{
61 isyslog("confirm: %s", s);
62 eKeys k = Skins.Message(mtWarning, s, Seconds);
63 bool result = WaitForTimeout ? k == kNone : k == kOk;
64 isyslog("%sconfirmed", result ? "" : "not ");
65 return result;
66}
67
69{
70 DisplayMenu->SetItem(tr("Phase 1: Detecting RC code type"), 2, false, false);
71 DisplayMenu->SetItem(tr("Press any key on the RC unit"), 4, false, false);
72 DisplayMenu->Flush();
73 if (Remote->Initialize()) {
74 DisplayMenu->SetItem(tr("RC code detected!"), 4, false, false);
75 DisplayMenu->SetItem(tr("Do not press any key..."), 5, false, false);
76 DisplayMenu->Flush();
78 DisplayMenu->SetItem("", 4, false, false);
79 DisplayMenu->SetItem("", 5, false, false);
80
81 DisplayMenu->SetItem(tr("Phase 2: Learning specific key codes"), 2, false, false);
82 eKeys NewKey = kUp;
83 while (NewKey != kNone) {
84 DisplayMenu->SetItem(cString::sprintf(tr("Press key for '%s'"), cKey::ToString(NewKey, true)), 4, false, false);
86 DisplayMenu->Flush();
87 for (eKeys k = NewKey; k == NewKey; ) {
88 char *NewCode = NULL;
89 eKeys Key = cRemote::Get(100, &NewCode);
90 switch (Key) {
91 case kUp: if (NewKey > kUp) {
92 NewKey = eKeys(NewKey - 1);
93 cKey *last = Keys.Last();
94 if (last && last->Key() == NewKey)
95 Keys.Del(last);
96 }
97 break;
98 case kDown: DisplayMenu->SetItem(tr("Press 'Up' to confirm"), 4, false, false);
99 DisplayMenu->SetItem(tr("Press 'Down' to continue"), 5, false, false);
100 DisplayMenu->SetItem("", 6, false, false);
101 DisplayMenu->SetItem("", 7, false, false);
102 DisplayMenu->SetItem("", 8, false, false);
103 DisplayMenu->Flush();
104 for (;;) {
105 Key = cRemote::Get(100);
106 if (Key == kUp) {
107 DisplayMenu->Clear();
108 return true;
109 }
110 else if (Key == kDown) {
111 DisplayMenu->SetItem("", 5, false, false);
112 k = kNone; // breaks the outer for() loop
113 break;
114 }
115 }
116 break;
117 case kMenu: NewKey = eKeys(NewKey + 1);
118 break;
119 case kNone: if (NewCode) {
120 dsyslog("new %s code: %s = %s", Remote->Name(), NewCode, cKey::ToString(NewKey));
121 Keys.Add(new cKey(Remote->Name(), NewCode, NewKey));
122 NewKey = eKeys(NewKey + 1);
123 free(NewCode);
124 }
125 break;
126 default: break;
127 }
128 }
129 if (NewKey > kUp)
130 DisplayMenu->SetItem(tr("(press 'Up' to go back)"), 6, false, false);
131 else
132 DisplayMenu->SetItem("", 6, false, false);
133 if (NewKey > kDown)
134 DisplayMenu->SetItem(tr("(press 'Down' to end key definition)"), 7, false, false);
135 else
136 DisplayMenu->SetItem("", 7, false, false);
137 if (NewKey > kMenu)
138 DisplayMenu->SetItem(tr("(press 'Menu' to skip this key)"), 8, false, false);
139 else
140 DisplayMenu->SetItem("", 8, false, false);
141 }
142 return true;
143 }
144 return false;
145}
146
148{
149 for (cRemote *Remote = Remotes.First(); Remote; Remote = Remotes.Next(Remote)) {
150 if (!Remote->Ready()) {
151 esyslog("ERROR: remote control %s not ready!", Remote->Name());
152 continue;
153 }
154 bool known = Keys.KnowsRemote(Remote->Name());
155 dsyslog("remote control %s - %s", Remote->Name(), known ? "keys known" : "learning keys");
156 if (!known) {
157#ifdef SDNOTIFY
158 sd_notify(0, "READY=1\nSTATUS=Learning keys...");
159#endif
160 cSkinDisplayMenu *DisplayMenu = Skins.Current()->DisplayMenu();
161 DisplayMenu->SetMenuCategory(mcUnknown);
162 char Headline[256];
163 snprintf(Headline, sizeof(Headline), tr("Learning Remote Control Keys"));
165 DisplayMenu->SetTitle(Headline);
166 DisplayMenu->SetItem(Remote->Name(), 0, false, false);
167 cRemote::SetLearning(Remote);
168 bool rc = QueryKeys(Remote, DisplayMenu);
170 DisplayMenu->Clear();
171 if (!rc) {
172 delete DisplayMenu;
173 continue;
174 }
175 DisplayMenu->SetItem(Remote->Name(), 0, false, false);
176 DisplayMenu->SetItem(tr("Phase 3: Saving key codes"), 2, false, false);
177 DisplayMenu->SetItem(tr("Press 'Up' to save, 'Down' to cancel"), 4, false, false);
178 for (;;) {
179 eKeys key = GetKey();
180 if (key == kUp) {
181 Keys.Save();
182 delete DisplayMenu;
183 break;
184 }
185 else if (key == kDown) {
186 Keys.Load();
187 delete DisplayMenu;
188 break;
189 }
190 }
191 }
192 }
193}
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
Definition thread.c:73
bool Confirm(const char *s, int Seconds=10, bool WaitForTimeout=false)
Definition interface.c:59
bool QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu)
Definition interface.c:68
eKeys GetKey(bool Wait=true)
Definition interface.c:31
cInterface(void)
Definition interface.c:22
void LearnKeys(void)
Definition interface.c:147
bool interrupted
Definition interface.h:19
eKeys Wait(int Seconds=0, bool KeepChar=false)
Definition interface.c:41
Definition keys.h:92
static const char * ToString(eKeys Key, bool Translate=false)
Definition keys.c:138
eKeys Key(void)
Definition keys.h:103
const char * Name(void)
Definition remote.h:46
static bool IsLearning()
Definition remote.h:48
static void SetLearning(cRemote *Learning)
Definition remote.h:47
static eKeys Get(int WaitMs=1000, char **UnknownCode=NULL)
Definition remote.c:181
bool Put(uint64_t Code, bool Repeat=false, bool Release=false)
Definition remote.c:124
static void Clear(void)
Definition remote.c:72
static bool HasKeys(void)
Definition remote.c:175
virtual bool Initialize(void)
Definition remote.c:61
virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable)=0
Sets the item at the given Index to Text.
virtual void SetTitle(const char *Title)=0
Sets the title of this menu to Title.
virtual void Clear(void)=0
Clears the entire central area of the menu.
virtual void SetMenuCategory(eMenuCategory MenuCategory)
Sets the current menu category.
Definition skins.c:90
virtual void Flush(void)
Actually draws the OSD display to the output device.
Definition skins.h:59
static cString sprintf(const char *fmt,...) __attribute__((format(printf
Definition tools.c:1195
cSetup Setup
Definition config.c:372
#define tr(s)
Definition i18n.h:85
cInterface * Interface
Definition interface.c:20
cKeys Keys
Definition keys.c:156
#define ISRAWKEY(k)
Definition keys.h:78
eKeys
Definition keys.h:16
@ kUp
Definition keys.h:17
@ kNone
Definition keys.h:55
@ kDown
Definition keys.h:18
@ k_Plugin
Definition keys.h:58
@ kMenu
Definition keys.h:19
@ kOk
Definition keys.h:20
cRemotes Remotes
Definition remote.c:211
cSkins Skins
Definition skins.c:253
@ mcUnknown
Definition skins.h:106
@ mtWarning
Definition skins.h:37
#define dsyslog(a...)
Definition tools.h:37
#define esyslog(a...)
Definition tools.h:35
#define isyslog(a...)
Definition tools.h:36