]> git.vomp.tv Git - vompclient-marten.git/blob - remote.cc
MoComp nearly bug free
[vompclient-marten.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
31 const ULONG Remote::NOLEARNMODE;
32 // Not buttons
33 const  UCHAR Remote::NA_LEARN;
34 const  UCHAR Remote::NA_NONE;
35 const  UCHAR Remote::NA_UNKNOWN;
36 const  UCHAR Remote::NA_SIGNAL;
37 const  UCHAR Remote::DF_UP;
38 const  UCHAR Remote::DF_DOWN;
39 const  UCHAR Remote::DF_LEFT;
40 const  UCHAR Remote::DF_RIGHT;
41
42 // Problem common buttons
43 const  UCHAR Remote::VOLUMEUP;
44 const  UCHAR Remote::VOLUMEDOWN;
45 const  UCHAR Remote::CHANNELUP;
46 const  UCHAR Remote::CHANNELDOWN;
47
48 // Common buttons
49 const  UCHAR Remote::ZERO;
50 const  UCHAR Remote::ONE;
51 const  UCHAR Remote::TWO;
52 const  UCHAR Remote::THREE;
53 const  UCHAR Remote::FOUR;
54 const  UCHAR Remote::FIVE;
55 const  UCHAR Remote::SIX;
56 const  UCHAR Remote::SEVEN;
57 const  UCHAR Remote::EIGHT;
58 const  UCHAR Remote::NINE;
59 const  UCHAR Remote::POWER;
60 const  UCHAR Remote::GO;
61 const  UCHAR Remote::BACK;
62 const  UCHAR Remote::MENU;
63 const  UCHAR Remote::RED;
64 const  UCHAR Remote::GREEN;
65 const  UCHAR Remote::YELLOW;
66 const  UCHAR Remote::BLUE;
67 const  UCHAR Remote::MUTE;
68 const  UCHAR Remote::RADIO;
69 const  UCHAR Remote::REVERSE;
70 const  UCHAR Remote::PLAY;
71 const  UCHAR Remote::FORWARD;
72 const  UCHAR Remote::RECORD;
73 const  UCHAR Remote::STOP;
74 const  UCHAR Remote::PAUSE;
75 const  UCHAR Remote::SKIPBACK;
76 const  UCHAR Remote::SKIPFORWARD;
77 const  UCHAR Remote::OK;
78
79 // Old remote only
80 const  UCHAR Remote::FULL;
81
82 // New remote only
83 const  UCHAR Remote::TV;
84 const  UCHAR Remote::VIDEOS;
85 const  UCHAR Remote::MUSIC;
86 const  UCHAR Remote::PICTURES;
87 const  UCHAR Remote::GUIDE;
88 const  UCHAR Remote::UP;
89 const  UCHAR Remote::DOWN;
90 const  UCHAR Remote::LEFT;
91 const  UCHAR Remote::RIGHT;
92 const  UCHAR Remote::PREVCHANNEL;
93 const  UCHAR Remote::STAR;
94 const  UCHAR Remote::HASH;
95
96 // Android only
97 const  UCHAR Remote::PLAYPAUSE;
98
99
100 // Remote types
101 const  UCHAR Remote::OLDREMOTE;
102 const  UCHAR Remote::NEWREMOTE;
103
104 Remote::Remote()
105 {
106   if (instance) return;
107   instance = this;
108   remoteType = OLDREMOTE;
109   learnmode = NOLEARNMODE;
110 }
111
112 Remote::~Remote()
113 {
114   instance = NULL;
115 }
116
117 Remote* Remote::getInstance()
118 {
119   return instance;
120 }
121
122 void Remote::setRemoteType(UCHAR newType)
123 {
124   if ((newType != OLDREMOTE) && (newType != NEWREMOTE)) return;
125   remoteType = newType;
126 }
127
128 void Remote::EnterLearningMode(UCHAR command)
129 {
130   learnmode = command; //Armed
131 }
132
133 void Remote::ResetToDefault()
134 {
135   translist.clear();
136   InitHWCListwithDefaults();
137 }
138
139
140 UCHAR Remote::TranslateHWCFixed(ULLONG code)
141 {
142   switch (code)
143   {
144     case DOWN:
145       return DOWN;
146     case UP:
147       return UP;
148     case LEFT:
149       return LEFT;
150     case RIGHT:
151       return RIGHT;
152     case DF_DOWN:
153       return DOWN;
154     case DF_UP:
155       return UP;
156     case DF_LEFT:
157       return LEFT;
158     case DF_RIGHT:
159       return RIGHT;
160     case MENU:
161       return MENU;
162     case BACK:
163       return BACK;
164     case OK:
165       return OK;
166     default:
167       return NA_UNKNOWN;
168   }
169 }
170
171 const char*Remote::HardcodedTranslateStr(UCHAR command)
172 {
173   switch (command)
174   {
175     case DOWN:
176       return tr("Down");
177     case UP:
178       return tr("Up");
179     case LEFT:
180       return tr("Left");
181     case RIGHT:
182       return tr("Right");
183     case MENU:
184       return tr("Menu");
185     case BACK:
186       return tr("Back");
187     case OK:
188       return tr("Ok");
189     default:
190       return NULL;
191   }
192 }
193
194 UCHAR Remote::TranslateHWCList(ULLONG code)
195 {
196   if (learnmode != NOLEARNMODE)
197   {
198     setHWCtoCommand(code, learnmode);
199     learnmode = NOLEARNMODE;
200     return NA_LEARN;
201   }
202   RemoteTranslationList::iterator it = translist.find(code);
203   if (it == translist.end())
204   {
205     return NA_UNKNOWN;
206   }
207   else
208   {
209     return it->second;
210   }
211 }
212
213 UCHAR Remote::TranslateHWC(ULLONG code)
214 {
215   UCHAR ret = TranslateHWCFixed(code);
216   if (ret == NA_UNKNOWN)
217   {
218     ret = TranslateHWCList(code);
219   }
220   else
221   {
222     learnmode = NOLEARNMODE;
223   }
224
225   if (ret == NA_UNKNOWN)
226   {
227     return NA_UNKNOWN;
228   }
229   return ret;
230 }
231
232 void Remote::setHWCtoCommand(ULLONG hcw, UCHAR command)
233 {
234   translist[hcw] = command;
235 }
236
237 void Remote::unsetHWC(ULLONG hcw)
238 {
239   translist.erase(hcw);
240 }
241
242 void Remote::LoadKeysConfig(char *cfg)
243 {
244   char *start = cfg;
245   start = strchr(cfg,'H')+1;
246   while ((start-1) != NULL)
247   {
248     ULONG ul1, ul2;
249     ULONG uc;
250     if (sscanf(start,"%lXI%lXK%lX",&ul1,&ul2,&uc) == 3)
251     {
252       translist[((ULLONG) ul1) | ((ULLONG)ul2) << 32]=(UCHAR)uc;
253     }
254     start = strchr(start, 'H')+1;
255   }
256 }
257
258 char *Remote::SaveKeysConfig()
259 {
260   int length=21*translist.size() +1;
261   char *output=new char[length];
262   char *current=output;
263   RemoteTranslationList::const_iterator it;
264   for (it = translist.begin(); it != translist.end(); it++)
265   {
266           current+=snprintf(current,21,"H%08lXI%08lXK%02X",
267                           (ULONG)it->first ,(ULONG) (it->first >> 32), it->second);
268   }
269   return output;
270 }
271
272
273 void Remote::InitHWCListwithDefaults()
274 {
275   translist[VOLUMEUP] = VOLUMEUP;
276   translist[VOLUMEDOWN] = VOLUMEDOWN;
277   translist[CHANNELUP] = CHANNELUP;
278   translist[CHANNELDOWN] = CHANNELDOWN;
279
280   // Common buttons
281   translist[ZERO] = ZERO;
282   translist[ONE] = ONE;
283   translist[TWO] = TWO;
284   translist[THREE] = THREE;
285   translist[FOUR] = FOUR;
286   translist[FIVE] = FIVE;
287   translist[SIX] = SIX;
288   translist[SEVEN] = SEVEN;
289   translist[EIGHT] = EIGHT;
290   translist[NINE] = NINE;
291   translist[POWER] = POWER;
292   translist[GO] = GO;
293   translist[RED] = RED;
294   translist[GREEN] = GREEN;
295   translist[YELLOW] = YELLOW;
296   translist[BLUE] = BLUE;
297
298   translist[MUTE] = MUTE;
299   translist[RADIO] = RADIO;
300   translist[REVERSE] = REVERSE;
301   translist[FORWARD] = FORWARD;
302   translist[RECORD] = RECORD;
303   translist[STOP] = STOP;
304   translist[PAUSE] = PAUSE;
305   translist[PLAY] = PLAY;
306   translist[SKIPBACK] = SKIPBACK;
307   translist[SKIPFORWARD] = SKIPFORWARD;
308
309   // Old remote only
310   translist[FULL] = FULL;
311
312   // New remote only
313   translist[TV] = TV;
314   translist[VIDEOS] = VIDEOS;
315   translist[MUSIC] = MUSIC;
316   translist[PICTURES] = PICTURES;
317   translist[GUIDE] = GUIDE;
318   translist[PREVCHANNEL] = PREVCHANNEL;
319   translist[STAR] = STAR;
320   translist[HASH] = HASH;
321 }
322
323 const char *Remote::CommandDesc(UCHAR number)
324 {
325   switch (number)
326   {
327     case VOLUMEUP:
328       return tr("Volume Up");
329
330     case VOLUMEDOWN:
331       return tr("Volume Down");
332     case CHANNELUP:
333       return tr("Channel up");
334     case CHANNELDOWN:
335       return tr("Channel down");
336     case ZERO:
337       return "0";
338     case ONE:
339       return "1";
340     case TWO:
341       return "2";
342     case THREE:
343       return "3";
344     case FOUR:
345       return "4";
346     case FIVE:
347       return "5";
348     case SIX:
349       return "6";
350     case SEVEN:
351       return "7";
352     case EIGHT:
353       return "8";
354     case NINE:
355       return "9";
356     case POWER:
357       return tr("Power");
358     case GO:
359       return tr("Go");
360     case BACK:
361       return tr("Back");
362     case MENU:
363       return tr("Menu");
364     case RED:
365       return tr("Red");
366     case GREEN:
367       return tr("Green");
368     case YELLOW:
369       return tr("Yellow");
370     case BLUE:
371       return tr("Blue");
372     case MUTE:
373       return tr("Mute");
374     case RADIO:
375       return tr("Radio");
376     case REVERSE:
377       return tr("Reverse");
378     case PLAY:
379       return tr("Play");
380     case FORWARD:
381       return tr("Forward");
382     case RECORD:
383       return tr("Record");
384     case STOP:
385       return tr("Stop");
386     case PAUSE:
387       return tr("Pause");
388     case SKIPBACK:
389       return tr("Skip back");
390     case SKIPFORWARD:
391       return tr("Skip forward");
392     case OK:
393       return tr("Ok");
394     case FULL:
395       return tr("Fullscreen");
396     case TV:
397       return tr("TV");
398     case VIDEOS:
399       return tr("Videos");
400     case MUSIC:
401       return tr("Music");
402     case PICTURES:
403       return tr("Pictures");
404     case GUIDE:
405       return tr("Guide");
406     case UP:
407       return tr("Up");
408     case DOWN:
409       return tr("Down");
410     case LEFT:
411       return tr("Left");
412     case RIGHT:
413       return tr("Right");
414     case PREVCHANNEL:
415       return tr("Previous Channel");
416     case STAR:
417       return tr("Star");
418     case HASH:
419       return tr("Hash");
420     case PLAYPAUSE:
421        return tr("Play/Pause");
422
423     default:
424       return NULL;
425   }
426 }
427
428 char* Remote::HCWDesc(ULLONG hcw)
429 {
430   char *dest,*temp;
431   temp=(char*)CommandDesc((UCHAR)hcw);
432   if (temp != NULL)
433   {
434     dest=new char[strlen(temp)+1];
435     strcpy(dest,temp);
436   }
437   else
438   {
439     dest=new char[20];
440     sprintf(dest,"C:%lX",(ULONG)hcw);
441   }
442   return dest;
443 }
444
445 char *Remote::CommandTranslateStr(UCHAR command)
446 {
447   char *desc;
448   int length=5;//:+\t+0
449   int keys=0; //max 10;
450   char *commanddesc=(char*)CommandDesc(command);
451   if (commanddesc != NULL)
452   {
453     length+=strlen(commanddesc);
454   }
455   char *preassigneddesc=(char*)HardcodedTranslateStr(command);
456   if (preassigneddesc != NULL)
457   {
458     length+=strlen(preassigneddesc);
459   }
460
461   char *keydesc[10];
462   RemoteTranslationList::const_iterator it;
463   for (it = translist.begin(); it != translist.end(); it++)
464   {
465     if (it->second == command)
466     {
467       keydesc[keys] = HCWDesc(it->first);
468       length += strlen(keydesc[keys])+2;
469       keys ++;
470       if (keys == 10) break;
471     }
472   }
473
474   desc=new char [length];
475   char *current=desc;
476   if (commanddesc != NULL)
477   {
478     current+=sprintf(current,"%s:\t ",commanddesc);
479   }
480   else
481   {
482     current+=sprintf(current,":\t ");
483   }
484   if (preassigneddesc != NULL)
485   {
486     current+=sprintf(current,"%s\t",preassigneddesc);
487   }
488   else
489   {
490     current+=sprintf(current,"\t");
491   }
492   for (int i = 0;i < keys; i++)
493   {
494     current += sprintf(current,"%s, ",keydesc[i]);
495     delete [] keydesc[i];
496   }
497   return desc;
498 }
499
500 bool Remote::addOptionPagesToWTB(WTabBar *wtb)
501 {
502     WRemoteConfig* wrc = new WRemoteConfig();
503     wtb->addTab(tr("Remote Control"), wrc);
504     return true;
505 }
506
507 bool Remote::loadOptionsfromServer(VDR* vdr)
508 {
509    // Set remote keys
510   char * config;
511   config = vdr->configLoad("General", "Remote keys");
512
513   if (config)
514   {
515       Log::getInstance()->log("Remote", Log::INFO, "Config General/Remote keys load");
516     LoadKeysConfig(config);
517     delete[] config;
518   }
519   else
520   {
521     Log::getInstance()->log("Remote", Log::INFO, "Config General/Remote keys not found");
522     InitHWCListwithDefaults();
523   }
524   return true;
525 }
526
527 bool Remote::saveOptionstoServer()
528 {
529     char *keyscon=SaveKeysConfig();
530     VDR::getInstance()->configSave("General","Remote keys",keyscon);
531     delete [] keyscon;
532     return true;
533 }