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