vdr 2.6.8
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
char * plugin
Definition keys.h:126
int numKeys
Definition keys.h:125
cKeyMacro(void)
Definition keys.c:201
eKeys macro[MAXKEYSINMACRO]
Definition keys.h:124
~cKeyMacro()
Definition keys.c:209
const cKeyMacro * Get(eKeys Key)
Definition keys.c:269
Definition keys.h:92
char * remote
Definition keys.h:94
const char * Remote(void)
Definition keys.h:101
static const char * ToString(eKeys Key, bool Translate=false)
Definition keys.c:138
cKey(void)
Definition keys.c:77
static eKeys FromString(const char *Name)
Definition keys.c:123
eKeys key
Definition keys.h:96
eKeys Key(void)
Definition keys.h:103
char * code
Definition keys.h:95
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)
Definition keys.h:102
Definition keys.h:110
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:2219
const T * First(void) const
Returns the first element in this list, or NULL if the list is empty.
Definition tools.h:656
const T * Next(const T *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
Definition tools.h:663
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
cKeyMacros KeyMacros
Definition keys.c:267
static tKey keyTable[]
Definition keys.c:13
cKeys Keys
Definition keys.c:156
#define MAXKEYSINMACRO
Definition keys.h:120
eKeys
Definition keys.h:16
@ kPower
Definition keys.h:39
@ kRecord
Definition keys.h:34
@ kUser5
Definition keys.h:54
@ kSchedule
Definition keys.h:48
@ kUser9
Definition keys.h:54
@ kPlayPause
Definition keys.h:30
@ kCommands
Definition keys.h:53
@ k5
Definition keys.h:28
@ kRight
Definition keys.h:23
@ k8
Definition keys.h:28
@ kUser2
Definition keys.h:54
@ kRecordings
Definition keys.h:51
@ kUser4
Definition keys.h:54
@ kPause
Definition keys.h:32
@ k9
Definition keys.h:28
@ kUser3
Definition keys.h:54
@ kSetup
Definition keys.h:52
@ k3
Definition keys.h:28
@ kRed
Definition keys.h:24
@ kUp
Definition keys.h:17
@ kChanUp
Definition keys.h:40
@ kNone
Definition keys.h:55
@ k7
Definition keys.h:28
@ kPlay
Definition keys.h:31
@ kFastFwd
Definition keys.h:35
@ kChanPrev
Definition keys.h:42
@ kDown
Definition keys.h:18
@ kGreen
Definition keys.h:25
@ k1
Definition keys.h:28
@ kUser6
Definition keys.h:54
@ kStop
Definition keys.h:33
@ kSubtitles
Definition keys.h:47
@ kUser7
Definition keys.h:54
@ kLeft
Definition keys.h:22
@ k_Plugin
Definition keys.h:58
@ kBlue
Definition keys.h:27
@ kAudio
Definition keys.h:46
@ k2
Definition keys.h:28
@ kMute
Definition keys.h:45
@ kPrev
Definition keys.h:38
@ k0
Definition keys.h:28
@ kChannels
Definition keys.h:49
@ k_Setup
Definition keys.h:59
@ kYellow
Definition keys.h:26
@ k4
Definition keys.h:28
@ kTimers
Definition keys.h:50
@ kBack
Definition keys.h:21
@ kMenu
Definition keys.h:19
@ kUser8
Definition keys.h:54
@ k6
Definition keys.h:28
@ kFastRew
Definition keys.h:36
@ kChanDn
Definition keys.h:41
@ kVolDn
Definition keys.h:44
@ kNext
Definition keys.h:37
@ kOk
Definition keys.h:20
@ kUser1
Definition keys.h:54
@ kVolUp
Definition keys.h:43
@ kInfo
Definition keys.h:29
@ kUser0
Definition keys.h:54
Definition keys.h:87
const char * name
Definition keys.h:89
char * skipspace(const char *s)
Definition tools.h:244
#define esyslog(a...)
Definition tools.h:35