]> git.vomp.tv Git - vompclient.git/blob - remote.cc
Rewritten vomp discovery protocol
[vompclient.git] / remote.cc
1 /*
2     Copyright 2004-2005 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "remote.h"
22 #include "wremoteconfig.h"
23 #include "i18n.h"
24 #include "log.h"
25 #include "vdr.h"
26 #include "wtabbar.h"
27
28 Remote* Remote::instance = NULL;
29
30 Remote::Remote()
31 {
32   if (instance) return;
33   instance = this;
34   remoteType = OLDREMOTE;
35   learnmode = NOLEARNMODE;
36 }
37
38 Remote::~Remote()
39 {
40   instance = NULL;
41 }
42
43 Remote* Remote::getInstance()
44 {
45   return instance;
46 }
47
48 void Remote::setRemoteType(UCHAR newType)
49 {
50   if ((newType != OLDREMOTE) && (newType != NEWREMOTE)) return;
51   remoteType = newType;
52 }
53
54 void Remote::EnterLearningMode(UCHAR command)
55 {
56   learnmode = command; //Armed
57 }
58
59 void Remote::ResetToDefault()
60 {
61   translist.clear();
62   InitHWCListwithDefaults();
63 }
64
65
66 UCHAR Remote::TranslateHWCFixed(ULLONG code)
67 {
68   switch (code)
69   {
70     case DOWN:
71       return DOWN;
72     case UP:
73       return UP;
74     case LEFT:
75       return LEFT;
76     case RIGHT:
77       return RIGHT;
78     case DF_DOWN:
79       return DOWN;
80     case DF_UP:
81       return UP;
82     case DF_LEFT:
83       return LEFT;
84     case DF_RIGHT:
85       return RIGHT;
86     case MENU:
87       return MENU;
88     case BACK:
89       return BACK;
90     case OK:
91       return OK;
92     default:
93       return NA_UNKNOWN;
94   }
95 }
96
97 const char*Remote::HardcodedTranslateStr(UCHAR command)
98 {
99   switch (command)
100   {
101     case DOWN:
102       return tr("Down");
103     case UP:
104       return tr("Up");
105     case LEFT:
106       return tr("Left");
107     case RIGHT:
108       return tr("Right");
109     case MENU:
110       return tr("Menu");
111     case BACK:
112       return tr("Back");
113     case OK:
114       return tr("Ok");
115     default:
116       return NULL;
117   }
118 }
119
120 UCHAR Remote::TranslateHWCList(ULLONG code)
121 {
122   if (learnmode != NOLEARNMODE)
123   {
124     setHWCtoCommand(code, learnmode);
125     learnmode = NOLEARNMODE;
126     return NA_LEARN;
127   }
128   RemoteTranslationList::iterator it = translist.find(code);
129   if (it == translist.end())
130   {
131     return NA_UNKNOWN;
132   }
133   else
134   {
135     return it->second;
136   }
137 }
138
139 UCHAR Remote::TranslateHWC(ULLONG code)
140 {
141   UCHAR ret = TranslateHWCFixed(code);
142   if (ret == NA_UNKNOWN)
143   {
144     ret = TranslateHWCList(code);
145   }
146   else
147   {
148     learnmode = NOLEARNMODE;
149   }
150
151   if (ret == NA_UNKNOWN)
152   {
153     return NA_UNKNOWN;
154   }
155   return ret;
156 }
157
158 void Remote::setHWCtoCommand(ULLONG hcw, UCHAR command)
159 {
160   translist[hcw] = command;
161 }
162
163 void Remote::unsetHWC(ULLONG hcw)
164 {
165   translist.erase(hcw);
166 }
167
168 void Remote::LoadKeysConfig(char *cfg)
169 {
170   char *start = cfg;
171   start = strchr(cfg,'H')+1;
172   while ((start-1) != NULL)
173   {
174     ULONG ul1, ul2;
175     ULONG uc;
176     if (sscanf(start,"%lXI%lXK%lX",&ul1,&ul2,&uc) == 3)
177     {
178       translist[((ULLONG) ul1) | ((ULLONG)ul2) << 32]=(UCHAR)uc;
179     }
180     start = strchr(start, 'H')+1;
181   }
182 }
183
184 char *Remote::SaveKeysConfig()
185 {
186   int length=21*translist.size() +1;
187   char *output=new char[length];
188   char *current=output;
189   RemoteTranslationList::const_iterator it;
190   for (it = translist.begin(); it != translist.end(); it++)
191   {
192     current+=sprintf(current,"H%08lXI%08lXK%02X",
193       (ULONG)it->first ,(ULONG) (it->first >> 32), it->second);
194   }
195   return output;
196 }
197
198
199 void Remote::InitHWCListwithDefaults()
200 {
201   translist[VOLUMEUP] = VOLUMEUP;
202   translist[VOLUMEDOWN] = VOLUMEDOWN;
203   translist[CHANNELUP] = CHANNELUP;
204   translist[CHANNELDOWN] = CHANNELDOWN;
205
206   // Common buttons
207   translist[ZERO] = ZERO;
208   translist[ONE] = ONE;
209   translist[TWO] = TWO;
210   translist[THREE] = THREE;
211   translist[FOUR] = FOUR;
212   translist[FIVE] = FIVE;
213   translist[SIX] = SIX;
214   translist[SEVEN] = SEVEN;
215   translist[EIGHT] = EIGHT;
216   translist[NINE] = NINE;
217   translist[POWER] = POWER;
218   translist[GO] = GO;
219   translist[RED] = RED;
220   translist[GREEN] = GREEN;
221   translist[YELLOW] = YELLOW;
222   translist[BLUE] = BLUE;
223
224   translist[MUTE] = MUTE;
225   translist[RADIO] = RADIO;
226   translist[REVERSE] = REVERSE;
227   translist[FORWARD] = FORWARD;
228   translist[RECORD] = RECORD;
229   translist[STOP] = STOP;
230   translist[PAUSE] = PAUSE;
231   translist[PLAY] = PLAY;
232   translist[SKIPBACK] = SKIPBACK;
233   translist[SKIPFORWARD] = SKIPFORWARD;
234
235   // Old remote only
236   translist[FULL] = FULL;
237
238   // New remote only
239   translist[TV] = TV;
240   translist[VIDEOS] = VIDEOS;
241   translist[MUSIC] = MUSIC;
242   translist[PICTURES] = PICTURES;
243   translist[GUIDE] = GUIDE;
244   translist[PREVCHANNEL] = PREVCHANNEL;
245   translist[STAR] = STAR;
246   translist[HASH] = HASH;
247 }
248
249 const char *Remote::CommandDesc(UCHAR number)
250 {
251   switch (number)
252   {
253     case VOLUMEUP:
254       return tr("Volume Up");
255
256     case VOLUMEDOWN:
257       return tr("Volume Down");
258     case CHANNELUP:
259       return tr("Channel up");
260     case CHANNELDOWN:
261       return tr("Channel down");
262     case ZERO:
263       return "0";
264     case ONE:
265       return "1";
266     case TWO:
267       return "2";
268     case THREE:
269       return "3";
270     case FOUR:
271       return "4";
272     case FIVE:
273       return "5";
274     case SIX:
275       return "6";
276     case SEVEN:
277       return "7";
278     case EIGHT:
279       return "8";
280     case NINE:
281       return "9";
282     case POWER:
283       return tr("Power");
284     case GO:
285       return tr("Go");
286     case BACK:
287       return tr("Back");
288     case MENU:
289       return tr("Menu");
290     case RED:
291       return tr("Red");
292     case GREEN:
293       return tr("Green");
294     case YELLOW:
295       return tr("Yellow");
296     case BLUE:
297       return tr("Blue");
298     case MUTE:
299       return tr("Mute");
300     case RADIO:
301       return tr("Radio");
302     case REVERSE:
303       return tr("Reverse");
304     case PLAY:
305       return tr("Play");
306     case FORWARD:
307       return tr("Forward");
308     case RECORD:
309       return tr("Record");
310     case STOP:
311       return tr("Stop");
312     case PAUSE:
313       return tr("Pause");
314     case SKIPBACK:
315       return tr("Skip back");
316     case SKIPFORWARD:
317       return tr("Skip forward");
318     case OK:
319       return tr("Ok");
320     case FULL:
321       return tr("Fullscreen");
322     case TV:
323       return tr("TV");
324     case VIDEOS:
325       return tr("Videos");
326     case MUSIC:
327       return tr("Music");
328     case PICTURES:
329       return tr("Pictures");
330     case GUIDE:
331       return tr("Guide");
332     case UP:
333       return tr("Up");
334     case DOWN:
335       return tr("Down");
336     case LEFT:
337       return tr("Left");
338     case RIGHT:
339       return tr("Right");
340     case PREVCHANNEL:
341       return tr("Previous Channel");
342     case STAR:
343       return tr("Star");
344     case HASH:
345       return tr("Hash");
346
347     default:
348       return NULL;
349   }
350 }
351
352 char* Remote::HCWDesc(ULLONG hcw)
353 {
354   char *dest,*temp;
355   temp=(char*)CommandDesc((UCHAR)hcw);
356   if (temp != NULL)
357   {
358     dest=new char[strlen(temp)+1];
359     strcpy(dest,temp);
360   }
361   else
362   {
363     dest=new char[20];
364     sprintf(dest,"C:%lX",(ULONG)hcw);
365   }
366   return dest;
367 }
368
369 char *Remote::CommandTranslateStr(UCHAR command)
370 {
371   char *desc;
372   int length=5;//:+\t+0
373   int keys=0; //max 10;
374   char *commanddesc=(char*)CommandDesc(command);
375   if (commanddesc != NULL)
376   {
377     length+=strlen(commanddesc);
378   }
379   char *preassigneddesc=(char*)HardcodedTranslateStr(command);
380   if (preassigneddesc != NULL)
381   {
382     length+=strlen(preassigneddesc);
383   }
384
385   char *keydesc[10];
386   RemoteTranslationList::const_iterator it;
387   for (it = translist.begin(); it != translist.end(); it++)
388   {
389     if (it->second == command)
390     {
391       keydesc[keys] = HCWDesc(it->first);
392       length += strlen(keydesc[keys])+2;
393       keys ++;
394       if (keys == 10) break;
395     }
396   }
397
398   desc=new char [length];
399   char *current=desc;
400   if (commanddesc != NULL)
401   {
402     current+=sprintf(current,"%s:\t ",commanddesc);
403   }
404   else
405   {
406     current+=sprintf(current,":\t ");
407   }
408   if (preassigneddesc != NULL)
409   {
410     current+=sprintf(current,"%s\t",preassigneddesc);
411   }
412   else
413   {
414     current+=sprintf(current,"\t");
415   }
416   for (int i = 0;i < keys; i++)
417   {
418     current += sprintf(current,"%s, ",keydesc[i]);
419     delete [] keydesc[i];
420   }
421   return desc;
422 }
423
424 bool Remote::addOptionPagesToWTB(WTabBar *wtb)
425 {
426     WRemoteConfig* wrc = new WRemoteConfig();
427     wtb->addTab(tr("Remote Control"), wrc);
428     return true;
429 }
430
431 bool Remote::loadOptionsfromServer(VDR* vdr)
432 {
433    // Set remote keys
434   char * config;
435   config = vdr->configLoad("General", "Remote keys");
436
437   if (config)
438   {
439       Log::getInstance()->log("Remote", Log::INFO, "Config General/Remote keys load");
440     LoadKeysConfig(config);
441     delete[] config;
442   }
443   else
444   {
445     Log::getInstance()->log("Remote", Log::INFO, "Config General/Remote keys not found");
446     InitHWCListwithDefaults();
447   }
448   return true;
449 }
450
451 bool Remote::saveOptionstoServer()
452 {
453     char *keyscon=SaveKeysConfig();
454     VDR::getInstance()->configSave("General","Remote keys",keyscon);
455     delete [] keyscon;
456     return true;
457 }