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