vdr 2.6.1
keys.c
Go to the documentation of this file.
1/*
2 * keys.c: Remote control Key handling
3 *
4 * See the main source file 'vdr.c' for copyright information and
5 * how to reach the author.
6 *
7 * $Id: keys.c 2.2 2012/12/04 12:52:52 kls Exp $
8 */
9
10#include "keys.h"
11#include "plugin.h"
12
13static tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
14 { kUp, trNOOP("Key$Up") },
15 { kDown, trNOOP("Key$Down") },
16 { kMenu, trNOOP("Key$Menu") },
17 { kOk, trNOOP("Key$Ok") },
18 { kBack, trNOOP("Key$Back") },
19 { kLeft, trNOOP("Key$Left") },
20 { kRight, trNOOP("Key$Right") },
21 { kRed, trNOOP("Key$Red") },
22 { kGreen, trNOOP("Key$Green") },
23 { kYellow, trNOOP("Key$Yellow") },
24 { kBlue, trNOOP("Key$Blue") },
25 { k0, "0" },
26 { k1, "1" },
27 { k2, "2" },
28 { k3, "3" },
29 { k4, "4" },
30 { k5, "5" },
31 { k6, "6" },
32 { k7, "7" },
33 { k8, "8" },
34 { k9, "9" },
35 { kInfo, trNOOP("Key$Info") },
36 { kPlayPause, trNOOP("Key$Play/Pause") },
37 { kPlay, trNOOP("Key$Play") },
38 { kPause, trNOOP("Key$Pause") },
39 { kStop, trNOOP("Key$Stop") },
40 { kRecord, trNOOP("Key$Record") },
41 { kFastFwd, trNOOP("Key$FastFwd") },
42 { kFastRew, trNOOP("Key$FastRew") },
43 { kNext, trNOOP("Key$Next") },
44 { kPrev, trNOOP("Key$Prev") },
45 { kPower, trNOOP("Key$Power") },
46 { kChanUp, trNOOP("Key$Channel+") },
47 { kChanDn, trNOOP("Key$Channel-") },
48 { kChanPrev, trNOOP("Key$PrevChannel") },
49 { kVolUp, trNOOP("Key$Volume+") },
50 { kVolDn, trNOOP("Key$Volume-") },
51 { kMute, trNOOP("Key$Mute") },
52 { kAudio, trNOOP("Key$Audio") },
53 { kSubtitles, trNOOP("Key$Subtitles") },
54 { kSchedule, trNOOP("Key$Schedule") },
55 { kChannels, trNOOP("Key$Channels") },
56 { kTimers, trNOOP("Key$Timers") },
57 { kRecordings, trNOOP("Key$Recordings") },
58 { kSetup, trNOOP("Key$Setup") },
59 { kCommands, trNOOP("Key$Commands") },
60 { kUser0, trNOOP("Key$User0") },
61 { kUser1, trNOOP("Key$User1") },
62 { kUser2, trNOOP("Key$User2") },
63 { kUser3, trNOOP("Key$User3") },
64 { kUser4, trNOOP("Key$User4") },
65 { kUser5, trNOOP("Key$User5") },
66 { kUser6, trNOOP("Key$User6") },
67 { kUser7, trNOOP("Key$User7") },
68 { kUser8, trNOOP("Key$User8") },
69 { kUser9, trNOOP("Key$User9") },
70 { kNone, "" },
71 { k_Setup, "_Setup" },
72 { kNone, NULL },
73 };
74
75// --- cKey ------------------------------------------------------------------
76
78{
79 remote = code = NULL;
80 key = kNone;
81}
82
83cKey::cKey(const char *Remote, const char *Code, eKeys Key)
84{
85 remote = strdup(Remote);
86 code = strdup(Code);
87 key = Key;
88}
89
91{
92 free(remote);
93 free(code);
94}
95
96bool cKey::Parse(char *s)
97{
98 char *p = strchr(s, '.');
99 if (p) {
100 *p++ = 0;
101 remote = strdup(s);
102 char *q = strpbrk(p, " \t");
103 if (q) {
104 *q++ = 0;
105 key = FromString(p);
106 if (key != kNone) {
107 q = skipspace(q);
108 if (*q) {
109 code = strdup(q);
110 return true;
111 }
112 }
113 }
114 }
115 return false;
116}
117
118bool cKey::Save(FILE *f)
119{
120 return fprintf(f, "%s.%-10s %s\n", remote, ToString(key), code) > 0;
121}
122
123eKeys cKey::FromString(const char *Name)
124{
125 if (Name) {
126 for (tKey *k = keyTable; k->name; k++) {
127 const char *n = k->name;
128 const char *p = strchr(n, '$');
129 if (p)
130 n = p + 1;
131 if (strcasecmp(n, Name) == 0)
132 return k->type;
133 }
134 }
135 return kNone;
136}
137
138const char *cKey::ToString(eKeys Key, bool Translate)
139{
140 for (tKey *k = keyTable; k->name; k++) {
141 if (k->type == Key) {
142 const char *n = k->name;
143 if (Translate)
144 n = tr(n);
145 const char *p = strchr(n, '$');
146 if (p)
147 n = p + 1;
148 return n;
149 }
150 }
151 return NULL;
152}
153
154// --- cKeys -----------------------------------------------------------------
155
157
158bool cKeys::KnowsRemote(const char *Remote)
159{
160 if (Remote) {
161 for (cKey *k = First(); k; k = Next(k)) {
162 if (strcmp(Remote, k->Remote()) == 0)
163 return true;
164 }
165 }
166 return false;
167}
168
169eKeys cKeys::Get(const char *Remote, const char *Code)
170{
171 if (Remote && Code) {
172 for (cKey *k = First(); k; k = Next(k)) {
173 if (strcmp(Remote, k->Remote()) == 0 && strcmp(Code, k->Code()) == 0)
174 return k->Key();
175 }
176 }
177 return kNone;
178}
179
180const char *cKeys::GetSetup(const char *Remote)
181{
182 if (Remote) {
183 for (cKey *k = First(); k; k = Next(k)) {
184 if (strcmp(Remote, k->Remote()) == 0 && k->Key() == k_Setup)
185 return k->Code();
186 }
187 }
188 return NULL;
189}
190
191void cKeys::PutSetup(const char *Remote, const char *Setup)
192{
193 if (!GetSetup(Remote))
194 Add(new cKey(Remote, Setup, k_Setup));
195 else
196 esyslog("ERROR: called PutSetup() for %s, but setup has already been defined!", Remote);
197}
198
199// --- cKeyMacro -------------------------------------------------------------
200
202{
203 numKeys = 0;
204 for (int i = 0; i < MAXKEYSINMACRO; i++)
205 macro[i] = kNone; // for compatibility with old code that doesn't know about NumKeys()
206 plugin = NULL;
207}
208
210{
211 free(plugin);
212}
213
214bool cKeyMacro::Parse(char *s)
215{
216 int n = 0;
217 char *p;
218 char *strtok_next;
219 while ((p = strtok_r(s, " \t", &strtok_next)) != NULL) {
220 if (n < MAXKEYSINMACRO) {
221 if (*p == '@') {
222 if (plugin) {
223 esyslog("ERROR: only one @plugin allowed per macro");
224 return false;
225 }
226 if (!n) {
227 esyslog("ERROR: @plugin can't be first in macro");
228 return false;
229 }
230 macro[n] = k_Plugin;
231 if (n < MAXKEYSINMACRO) {
232 plugin = strdup(p + 1);
234 esyslog("ERROR: unknown plugin '%s'", plugin);
235 // this is not a fatal error - plugins may or may not be loaded
236 macro[--n] = kNone; // makes sure the key doesn't cause any side effects
237 }
238 }
239 else {
240 esyslog("ERROR: key macro too long");
241 return false;
242 }
243 }
244 else {
245 macro[n] = cKey::FromString(p);
246 if (macro[n] == kNone) {
247 esyslog("ERROR: unknown key '%s'", p);
248 return false;
249 }
250 }
251 n++;
252 s = NULL;
253 }
254 else {
255 esyslog("ERROR: key macro too long");
256 return false;
257 }
258 }
259 if (n < 2)
260 esyslog("ERROR: empty key macro"); // non fatal
261 numKeys = n;
262 return true;
263}
264
265// --- cKeyMacros ------------------------------------------------------------
266
268
270{
271 if (Key != kNone) {
272 for (cKeyMacro *k = First(); k; k = Next(k)) {
273 if (*k->Macro() == Key)
274 return k;
275 }
276 }
277 return NULL;
278}
bool Parse(char *s)
Definition: keys.c:214
cKeyMacro(void)
Definition: keys.c:201
eKeys macro[MAXKEYSINMACRO]
~cKeyMacro()
Definition: keys.c:209
const cKeyMacro * Get(eKeys Key)
Definition: keys.c:269
const char * Remote(void)
static const char * ToString(eKeys Key, bool Translate=false)
Definition: keys.c:138
char * code
cKey(void)
Definition: keys.c:77
static eKeys FromString(const char *Name)
Definition: keys.c:123
eKeys key
eKeys Key(void)
char * remote
bool Save(FILE *f)
Definition: keys.c:118
bool Parse(char *s)
Definition: keys.c:96
~cKey()
Definition: keys.c:90
const char * Code(void)
void PutSetup(const char *Remote, const char *Setup)
Definition: keys.c:191
eKeys Get(const char *Remote, const char *Code)
Definition: keys.c:169
const char * GetSetup(const char *Remote)
Definition: keys.c:180
bool KnowsRemote(const char *Remote)
Definition: keys.c:158
void Add(cListObject *Object, cListObject *After=NULL)
Definition: tools.c:2184
const cKey * First(void) const
Returns the first element in this list, or NULL if the list is empty.
const cKey * Next(const cKey *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
static cPlugin * GetPlugin(int Index)
Definition: plugin.c:469
cSetup Setup
Definition: config.c:372
#define tr(s)
Definition: i18n.h:85
#define trNOOP(s)
Definition: i18n.h:88
#define MAXKEYSINMACRO
@ kPower
@ kRecord
@ kUser5
@ kSchedule
@ kUser9
@ kPlayPause
@ kCommands
@ k5
@ kRight
@ k8
@ kUser2
@ kRecordings
@ kUser4
@ kPause
@ k9
@ kUser3
@ kSetup
@ k3
@ kRed
@ kUp
@ kChanUp
@ kNone
@ k7
@ kPlay
@ kFastFwd
@ kChanPrev
@ kDown
@ kGreen
@ k1
@ kUser6
@ kStop
@ kSubtitles
@ kUser7
@ kLeft
@ k_Plugin
@ kBlue
@ kAudio
@ k2
@ kMute
@ kPrev
@ k0
@ kChannels
@ k_Setup
@ kYellow
@ k4
@ kTimers
@ kBack
@ kMenu
@ kUser8
@ k6
@ kFastRew
@ kChanDn
@ kVolDn
@ kNext
@ kOk
@ kUser1
@ kVolUp
@ kInfo
@ kUser0
char * skipspace(const char *s)
#define esyslog(a...)
cKeyMacros KeyMacros
Definition: keys.c:267
static tKey keyTable[]
Definition: keys.c:13
cKeys Keys
Definition: keys.c:156
const char * name