]> git.vomp.tv Git - vompclient.git/blob - remote.cc
Remove thread from videoomx, Code cleanup, Fix remote keys (could crash server!).
[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
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(VDR *vdr,const char *cfg)
243 {
244         ULONG number=0;
245         if (sscanf(cfg,"%ld",&number) != 1) return;
246         Log::getInstance()->log("Remote", Log::INFO, "Config General/Remote keys num keys %d",number);
247         char buffer[1024];
248         char keybuf[1024];
249         for (int i = 0; i < number; i++) {
250                 sprintf(keybuf, "RemoteKey%d", i);
251                 const char *keytrans = vdr->configLoad("General", keybuf);
252                 if (keytrans) {
253                         ULONG ul1, ul2;
254                         ULONG uc;
255                         if (sscanf(keytrans, "%lXI%lXK%lX", &ul1, &ul2, &uc) == 3) {
256                                 translist[((ULLONG) ul1) | ((ULLONG) ul2) << 32] = (UCHAR) uc;
257                         }
258                 }
259
260         }
261 }
262
263 void Remote::SaveKeysConfig()
264 {
265   int number=0;
266   char buffer[1024];
267   char keybuf[1024];
268   RemoteTranslationList::const_iterator it;
269   for (it = translist.begin(); it != translist.end(); it++)
270   {
271           sprintf(buffer,"%08lXI%08lXK%02X",
272                           (ULONG)it->first ,(ULONG) (it->first >> 32), it->second);
273           sprintf(keybuf,"RemoteKey%d",number);
274           VDR::getInstance()->configSave("General",keybuf,buffer);
275           number++;
276   }
277   sprintf(buffer,"%d",number);
278   VDR::getInstance()->configSave("General","RemoteKeyNum",buffer);
279 }
280
281
282 void Remote::InitHWCListwithDefaults()
283 {
284   translist[VOLUMEUP] = VOLUMEUP;
285   translist[VOLUMEDOWN] = VOLUMEDOWN;
286   translist[CHANNELUP] = CHANNELUP;
287   translist[CHANNELDOWN] = CHANNELDOWN;
288
289   // Common buttons
290   translist[ZERO] = ZERO;
291   translist[ONE] = ONE;
292   translist[TWO] = TWO;
293   translist[THREE] = THREE;
294   translist[FOUR] = FOUR;
295   translist[FIVE] = FIVE;
296   translist[SIX] = SIX;
297   translist[SEVEN] = SEVEN;
298   translist[EIGHT] = EIGHT;
299   translist[NINE] = NINE;
300   translist[POWER] = POWER;
301   translist[GO] = GO;
302   translist[RED] = RED;
303   translist[GREEN] = GREEN;
304   translist[YELLOW] = YELLOW;
305   translist[BLUE] = BLUE;
306
307   translist[MUTE] = MUTE;
308   translist[RADIO] = RADIO;
309   translist[REVERSE] = REVERSE;
310   translist[FORWARD] = FORWARD;
311   translist[RECORD] = RECORD;
312   translist[STOP] = STOP;
313   translist[PAUSE] = PAUSE;
314   translist[PLAY] = PLAY;
315   translist[SKIPBACK] = SKIPBACK;
316   translist[SKIPFORWARD] = SKIPFORWARD;
317
318   // Old remote only
319   translist[FULL] = FULL;
320
321   // New remote only
322   translist[TV] = TV;
323   translist[VIDEOS] = VIDEOS;
324   translist[MUSIC] = MUSIC;
325   translist[PICTURES] = PICTURES;
326   translist[GUIDE] = GUIDE;
327   translist[PREVCHANNEL] = PREVCHANNEL;
328   translist[STAR] = STAR;
329   translist[HASH] = HASH;
330 }
331
332 const char *Remote::CommandDesc(UCHAR number)
333 {
334   switch (number)
335   {
336     case VOLUMEUP:
337       return tr("Volume Up");
338
339     case VOLUMEDOWN:
340       return tr("Volume Down");
341     case CHANNELUP:
342       return tr("Channel up");
343     case CHANNELDOWN:
344       return tr("Channel down");
345     case ZERO:
346       return "0";
347     case ONE:
348       return "1";
349     case TWO:
350       return "2";
351     case THREE:
352       return "3";
353     case FOUR:
354       return "4";
355     case FIVE:
356       return "5";
357     case SIX:
358       return "6";
359     case SEVEN:
360       return "7";
361     case EIGHT:
362       return "8";
363     case NINE:
364       return "9";
365     case POWER:
366       return tr("Power");
367     case GO:
368       return tr("Go");
369     case BACK:
370       return tr("Back");
371     case MENU:
372       return tr("Menu");
373     case RED:
374       return tr("Red");
375     case GREEN:
376       return tr("Green");
377     case YELLOW:
378       return tr("Yellow");
379     case BLUE:
380       return tr("Blue");
381     case MUTE:
382       return tr("Mute");
383     case RADIO:
384       return tr("Radio");
385     case REVERSE:
386       return tr("Reverse");
387     case PLAY:
388       return tr("Play");
389     case FORWARD:
390       return tr("Forward");
391     case RECORD:
392       return tr("Record");
393     case STOP:
394       return tr("Stop");
395     case PAUSE:
396       return tr("Pause");
397     case SKIPBACK:
398       return tr("Skip back");
399     case SKIPFORWARD:
400       return tr("Skip forward");
401     case OK:
402       return tr("Ok");
403     case FULL:
404       return tr("Fullscreen");
405     case TV:
406       return tr("TV");
407     case VIDEOS:
408       return tr("Videos");
409     case MUSIC:
410       return tr("Music");
411     case PICTURES:
412       return tr("Pictures");
413     case GUIDE:
414       return tr("Guide");
415     case UP:
416       return tr("Up");
417     case DOWN:
418       return tr("Down");
419     case LEFT:
420       return tr("Left");
421     case RIGHT:
422       return tr("Right");
423     case PREVCHANNEL:
424       return tr("Previous Channel");
425     case STAR:
426       return tr("Star");
427     case HASH:
428       return tr("Hash");
429     case PLAYPAUSE:
430        return tr("Play/Pause");
431
432     default:
433       return NULL;
434   }
435 }
436
437 char* Remote::HCWDesc(ULLONG hcw)
438 {
439   char *dest,*temp;
440   temp=(char*)CommandDesc((UCHAR)hcw);
441   if (temp != NULL)
442   {
443     dest=new char[strlen(temp)+1];
444     strcpy(dest,temp);
445   }
446   else
447   {
448     dest=new char[20];
449     sprintf(dest,"C:%lX",(ULONG)hcw);
450   }
451   return dest;
452 }
453
454 char *Remote::CommandTranslateStr(UCHAR command)
455 {
456   char *desc;
457   int length=5;//:+\t+0
458   int keys=0; //max 10;
459   char *commanddesc=(char*)CommandDesc(command);
460   if (commanddesc != NULL)
461   {
462     length+=strlen(commanddesc);
463   }
464   char *preassigneddesc=(char*)HardcodedTranslateStr(command);
465   if (preassigneddesc != NULL)
466   {
467     length+=strlen(preassigneddesc);
468   }
469
470   char *keydesc[10];
471   RemoteTranslationList::const_iterator it;
472   for (it = translist.begin(); it != translist.end(); it++)
473   {
474     if (it->second == command)
475     {
476       keydesc[keys] = HCWDesc(it->first);
477       length += strlen(keydesc[keys])+2;
478       keys ++;
479       if (keys == 10) break;
480     }
481   }
482
483   desc=new char [length];
484   char *current=desc;
485   if (commanddesc != NULL)
486   {
487     current+=sprintf(current,"%s:\t ",commanddesc);
488   }
489   else
490   {
491     current+=sprintf(current,":\t ");
492   }
493   if (preassigneddesc != NULL)
494   {
495     current+=sprintf(current,"%s\t",preassigneddesc);
496   }
497   else
498   {
499     current+=sprintf(current,"\t");
500   }
501   for (int i = 0;i < keys; i++)
502   {
503     current += sprintf(current,"%s, ",keydesc[i]);
504     delete [] keydesc[i];
505   }
506   return desc;
507 }
508
509 bool Remote::addOptionPagesToWTB(WTabBar *wtb)
510 {
511     WRemoteConfig* wrc = new WRemoteConfig();
512     wtb->addTab(tr("Remote Control"), wrc);
513     return true;
514 }
515
516 bool Remote::loadOptionsfromServer(VDR* vdr)
517 {
518    // Set remote keys
519   char * config;
520   config = vdr->configLoad("General", "RemoteKeyNum");
521
522   if (config)
523   {
524     Log::getInstance()->log("Remote", Log::INFO, "Config General/Remote keys load");
525     LoadKeysConfig(vdr,config);
526     delete[] config;
527   }
528   else
529   {
530     Log::getInstance()->log("Remote", Log::INFO, "Config General/Remote keys not found");
531     InitHWCListwithDefaults();
532   }
533   return true;
534 }
535
536 bool Remote::saveOptionstoServer()
537 {
538     SaveKeysConfig();
539     return true;
540 }