]> git.vomp.tv Git - vompclient.git/blob - remotelinux.cc
More compiler warning fixes
[vompclient.git] / remotelinux.cc
1 /*
2     Copyright 2004-2005 Chris Tallon; 2012 Marten Richter
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 "remotelinux.h"
22 #include "i18n.h"
23 #include "vdr.h"
24 #include "woptionpane.h"
25
26 #include <linux/input.h>
27 #include <sys/types.h>
28
29
30 #include <errno.h>
31
32 #include <sys/stat.h>
33 #include <fcntl.h>
34
35 #include <cstdio>
36 #include <iostream>
37 #include <ostream>
38
39 #include <bcm_host.h>
40
41 using namespace std;
42 using namespace CEC;
43
44 #include <libcec/cecloader.h>
45
46
47
48
49 #define W_G_HCW(type,code) ( (((ULLONG)(type))<<32) | code)
50
51 #define W_HCW_KC 1 /* key code as defined by kernel for keyboard and remotes through /dev/input */
52 #define W_HCW_CEC 2 /* HDMI_CEC */
53 #define W_HCW_LIRC 3 /* remote control LIRC*/
54
55
56 RemoteLinux::RemoteLinux()
57 {
58   initted = 0;
59   curcec=0;
60   hascurcec=false;
61   haspower=false;
62   powerkey=0;
63   signal=false;
64   cec_adap=NULL;
65   num_loop=0;
66   cechandlesvolume=false;
67
68 }
69
70 RemoteLinux::~RemoteLinux()
71 {
72         for (unsigned int i=0; i<devices.size();i++) {
73                 close(devices[i]);
74         }
75 }
76
77 #define test_bit(input,b)  ((1 << ((b) % 8))&(input)[b / 8] )
78
79
80 int RemoteLinux::init(const char* devName)
81 {
82   if (initted) return 0;
83   initted = 1;
84
85   InitKeymap();
86
87   for (int eventid=0;eventid<100;eventid++){
88           char buffer[1024];
89           sprintf(buffer,"/dev/input/event%d",eventid);
90
91
92           struct stat test_buf;
93           if (stat(buffer,&test_buf)==0) {
94                   Log::getInstance()->log("Remote", Log::NOTICE, "Probe /dev/input/event%d",eventid);
95                   // file exists
96                   unsigned long ev_type=0;
97                   int new_fd=open(buffer,O_RDONLY);
98                   if (new_fd<0) {
99                           Log::getInstance()->log("Remote", Log::NOTICE, "Can not open /dev/input/event%d",eventid);
100                           continue;
101                   }
102                   if (ioctl(new_fd, EVIOCGBIT(0, EV_MAX), &ev_type) < 0) {
103                           Log::getInstance()->log("Remote", Log::NOTICE, "Ioctl failed /dev/input/event%d %d",eventid,errno);
104                       close(new_fd);
105                   }
106                   //Now test if it generates keyboard presses
107                   if (test_bit((char*)&ev_type , EV_KEY)) {
108                           Log::getInstance()->log("Remote", Log::NOTICE, "Add /dev/input/event%d to List",eventid);
109                           devices.push_back(new_fd);
110                   } else {
111                           close(new_fd);
112                   }
113
114
115
116
117           }
118
119
120
121
122
123   }
124   return initCec();
125 }
126
127 int RemoteLinux::initCec() {
128
129   // bcm_host_init(); //may be move to custom hardware init?
130 // now init cec
131         Log::getInstance()->log("Remote", Log::NOTICE, "Init LibCEC");
132         cec_config.Clear();
133         cec_callbacks.Clear();
134         cec_callbacks.CBCecLogMessage = cecLogMessage;
135         cec_callbacks.CBCecKeyPress = cecKeyPress;
136         cec_callbacks.CBCecCommand = cecCommand;
137         cec_callbacks.CBCecConfigurationChanged = cecConfigurationChanged;
138         cec_callbacks.CBCecSourceActivated = cecSourceActivated;
139         cec_config.clientVersion=LIBCEC_VERSION_CURRENT;
140         cec_config.bActivateSource=1;
141         cec_config.bUseTVMenuLanguage=1;
142         //cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
143         cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
144         //cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_TUNER);
145
146         strncpy(cec_config.strDeviceName,"vomp",sizeof(cec_config.strDeviceName));
147
148
149         cec_config.callbackParam = NULL; // I do not care
150         cec_config.callbacks = &cec_callbacks;
151
152         cec_adap = LibCecInitialise(&cec_config);
153         if (!cec_adap) {
154                 Log::getInstance()->log("Remote", Log::ERR, "Init LibCEC failed");
155                 return 1;
156         }
157         cec_adap->InitVideoStandalone();
158
159
160         cec_adapter  cec_devices[10];
161         int adap_num=cec_adap->FindAdapters(cec_devices,10,NULL);
162         if (adap_num<0) {
163                 Log::getInstance()->log("Remote", Log::ERR, "CEC:Failed to find adapter");
164                 return 1;
165
166         }
167         if (adap_num==0) {
168                 Log::getInstance()->log("Remote", Log::NOTICE, "CEC: No adapter found");
169                 return 1;
170
171         }
172         if (!cec_adap->Open(cec_devices[0].comm)) {
173                 Log::getInstance()->log("Remote", Log::ERR, "CEC:Failed to open adapter");
174                 return 1;
175         }
176
177         if (!cec_adap->SetActiveSource(cec_config.deviceTypes[0])) {
178                 Log::getInstance()->log("Remote", Log::ERR, "CEC:Failed set active source");
179                 return 1;
180         }
181
182
183
184
185   return 1;
186 }
187
188 int RemoteLinux::shutdown()
189 {
190   if (!initted) return 0;
191   deinitCec();
192   while (devices.size()) {
193           int cur_fd = devices.back();
194           devices.pop_back();
195           close(cur_fd);
196   }
197
198   initted = 0;
199   return 1;
200 }
201
202 void RemoteLinux::deinitCec()
203 {
204         if (cec_adap) {
205                 Log::getInstance()->log("Remote", Log::NOTICE, "Shutdown libcec begin");
206                 cec_adap->SetInactiveView();
207                 cec_adap->Close();
208                 vc_cec_register_callback(NULL, NULL);//deactivate callback!
209                 UnloadLibCec(cec_adap);
210                 cec_adap = NULL;
211                 Log::getInstance()->log("Remote", Log::NOTICE, "Shutdown libcec end");
212         }
213
214 }
215
216 UCHAR RemoteLinux::getButtonPress(int waitType) {
217         /* how = 0 - block
218          how = 1 - start new wait
219          how = 2 - continue wait
220          how = 3 - no wait
221          */
222
223          //in units of 40 ms
224
225         int retval;
226         fd_set readfds;
227         struct timeval tv;
228
229         tv.tv_sec = 0;
230         tv.tv_usec = 40000;
231         if (waitType == 0) {
232                 num_loop = -1;
233         } else if (waitType == 1) {
234
235                 num_loop = 25;
236         } else if (waitType == 2) {
237                 if (num_loop<=0) num_loop = 25;
238         } else if (waitType == 3) {
239                 tv.tv_sec = 0;
240                 tv.tv_usec = 0;
241                 num_loop = 0;
242         }
243
244
245         int ret = 0;
246         while (num_loop!=0) {
247                 ret = NA_UNKNOWN;
248                 FD_ZERO(&readfds);
249
250                 int maxfd = 0;
251                 for (unsigned int i = 0; i < devices.size(); i++) {
252                         int cur_fd = devices[i];
253                         maxfd = max(cur_fd, maxfd);
254                         FD_SET(cur_fd, &readfds);
255                 }
256
257                 retval = select(maxfd + 1, &readfds, NULL, NULL, &tv);
258                 tv.tv_sec = 0;
259                 tv.tv_usec = 40000;
260                 // 0 = nothing happened
261                 // 1 = data arrived (actually num of descriptors that changed)
262                 // other value = signal or error
263                 if (retval == 0) {
264                         if (hascurcec) {
265                                 hascurcec = false;
266                                 return (UCHAR) TranslateHWC(W_G_HCW(W_HCW_CEC,curcec));
267                         }
268                         if (haspower) {
269                                 haspower =false;
270                                 return powerkey;
271                         }
272                         ret = NA_NONE;
273                 } else {
274                         if (retval == -1) {
275                                 Log::getInstance()->log("Remote", Log::NOTICE, "na_signal");
276                                 return NA_SIGNAL;
277
278                         }
279                         for (unsigned int i = 0; i < devices.size(); i++) {
280                                 int cur_fd = devices[i];
281                                 if (FD_ISSET(cur_fd, &readfds)) {
282                                         struct input_event ev;
283                                         int count = read(cur_fd, &ev, sizeof(ev));
284                                         if (count == sizeof(ev)) {
285                                                 if (ev.type == EV_KEY && ev.value == 1) {
286                                                         UCHAR retty=(UCHAR) TranslateHWC(
287                                                                                         W_G_HCW(W_HCW_KC,ev.code));
288                                                         return retty;
289                                                 }
290                                         }
291
292                                 }
293
294                         }
295
296                 }
297                 //Log::getInstance()->log("Remote", Log::NOTICE, "numloop: %d %d",num_loop,retval);
298                 if (num_loop > 0)
299                 num_loop--;
300         }
301         if (ret != 0)
302                 return ret;
303
304         return NA_UNKNOWN;
305
306 }
307
308 void RemoteLinux::clearBuffer()
309 {
310         UCHAR buttonpress=getButtonPress(3);
311           while(buttonpress != NA_NONE && buttonpress!=NA_UNKNOWN){
312                   buttonpress=getButtonPress(3);
313           };
314 }
315
316 UCHAR RemoteLinux::TranslateHWCFixed(ULLONG code)
317 {
318     switch (code) 
319     {
320     case W_G_HCW(W_HCW_KC,KEY_DOWN):
321         return DOWN;
322     case W_G_HCW(W_HCW_KC,KEY_UP):
323         return UP;
324     case W_G_HCW(W_HCW_KC,KEY_LEFT):
325         return LEFT;
326     case W_G_HCW(W_HCW_KC,KEY_RIGHT):
327         return RIGHT;
328     case W_G_HCW(W_HCW_KC,KEY_M):
329     case W_G_HCW(W_HCW_KC,KEY_MEDIA):
330         return MENU;
331     case W_G_HCW(W_HCW_KC,KEY_BACKSPACE):
332     case W_G_HCW(W_HCW_KC,KEY_EXIT):
333         return BACK;
334     case W_G_HCW(W_HCW_KC,KEY_ENTER):
335     case W_G_HCW(W_HCW_KC,KEY_SPACE):
336     case W_G_HCW(W_HCW_KC,KEY_OK):
337         return OK;
338     //CEC
339     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_DOWN):
340         return DOWN;
341     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_UP):
342         return UP;
343     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_LEFT):
344         return LEFT;
345     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_RIGHT):
346         return RIGHT;
347     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_ROOT_MENU):
348     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_CONTENTS_MENU):
349     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_SETUP_MENU):
350         return MENU;
351     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_EXIT ):
352         return BACK;
353     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_ENTER):
354     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_SELECT):
355     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_AN_RETURN):
356         return OK;
357     case W_G_HCW(W_HCW_KC,KEY_SLEEP):
358     case W_G_HCW(W_HCW_KC,KEY_POWER):
359     case W_G_HCW(W_HCW_KC,KEY_ESC):
360     case W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_POWER):
361     case POWER:
362         return POWER;
363     default:
364         return NA_UNKNOWN;
365     };
366 }
367
368 const char*RemoteLinux::HardcodedTranslateStr(UCHAR command)
369 {
370     switch (command) 
371     {
372     case DOWN:
373         return tr("Down");
374     case UP:
375         return tr("Up");
376     case LEFT:
377         return tr("Left");
378     case RIGHT:
379         return tr("Right");
380     case MENU:
381         return tr("M");
382     case BACK:
383         return tr("Backspace, Back");
384     case OK:
385         return tr("Return, Space");
386     default:
387         return NULL;
388     };
389     
390 }
391
392
393 void RemoteLinux::InitHWCListwithDefaults()
394 {
395     //Processing VK_Messages
396     translist[W_G_HCW(W_HCW_KC,KEY_9)] = NINE;
397     translist[W_G_HCW(W_HCW_KC,KEY_8)] = EIGHT;
398     translist[W_G_HCW(W_HCW_KC,KEY_7)] = SEVEN;
399     translist[W_G_HCW(W_HCW_KC,KEY_6)] = SIX;
400     translist[W_G_HCW(W_HCW_KC,KEY_5)] = FIVE;
401     translist[W_G_HCW(W_HCW_KC,KEY_4)] = FOUR;
402     translist[W_G_HCW(W_HCW_KC,KEY_3)] = THREE;
403     translist[W_G_HCW(W_HCW_KC,KEY_2)] = TWO;
404     translist[W_G_HCW(W_HCW_KC,KEY_1)] = ONE;
405     translist[W_G_HCW(W_HCW_KC,KEY_0)] = ZERO;
406     translist[W_G_HCW(W_HCW_KC,KEY_KPDOT)] = STAR;
407    // translist[W_G_HCW(W_HCW_KC,KEY_#)] = HASH;
408
409     translist[W_G_HCW(W_HCW_KC,KEY_KP9)] = NINE;
410     translist[W_G_HCW(W_HCW_KC,KEY_KP8)] = EIGHT;
411     translist[W_G_HCW(W_HCW_KC,KEY_KP7)] = SEVEN;
412     translist[W_G_HCW(W_HCW_KC,KEY_KP6)] = SIX;
413     translist[W_G_HCW(W_HCW_KC,KEY_KP5)] = FIVE;
414     translist[W_G_HCW(W_HCW_KC,KEY_KP4)] = FOUR;
415     translist[W_G_HCW(W_HCW_KC,KEY_KP3)] = THREE;
416     translist[W_G_HCW(W_HCW_KC,KEY_KP2)] = TWO;
417     translist[W_G_HCW(W_HCW_KC,KEY_KP1)] = ONE;
418     translist[W_G_HCW(W_HCW_KC,KEY_KP0)] = ZERO;
419
420     translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_9)] = NINE;
421         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_8)] = EIGHT;
422         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_7)] = SEVEN;
423         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_6)] = SIX;
424         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_5)] = FIVE;
425         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_4)] = FOUR;
426         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_3)] = THREE;
427         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_2)] = TWO;
428         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_1)] = ONE;
429         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_0)] = ZERO;
430         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_STAR)] = STAR;
431         translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_POUND)] = HASH;
432
433
434     translist[W_G_HCW(W_HCW_KC,KEY_J)] = GO; //j for JUMP TO instead of go to
435     translist[W_G_HCW(W_HCW_KC,KEY_R)] = RED;
436     translist[W_G_HCW(W_HCW_KC,KEY_G)] = GREEN;
437     translist[W_G_HCW(W_HCW_KC,KEY_Y)] = YELLOW;
438     translist[W_G_HCW(W_HCW_KC,KEY_B)] = BLUE;
439     //Processing Remote Style Messages
440     translist[W_G_HCW(W_HCW_KC,KEY_GREEN)] = GREEN;
441     translist[W_G_HCW(W_HCW_KC,KEY_RED)] = RED;
442     translist[W_G_HCW(W_HCW_KC,KEY_YELLOW)] = YELLOW;
443     translist[W_G_HCW(W_HCW_KC,KEY_BLUE)] = BLUE;
444     translist[W_G_HCW(W_HCW_KC,KEY_MENU)] = MENU;
445
446     translist[W_G_HCW(W_HCW_KC,KEY_RECORD)] = RECORD;
447     translist[W_G_HCW(W_HCW_KC,KEY_PLAY)] = PLAY; //Playback Televison
448     translist[W_G_HCW(W_HCW_KC,KEY_PAUSE)] = PAUSE;
449     translist[W_G_HCW(W_HCW_KC,KEY_STOP)] = STOP;
450     translist[W_G_HCW(W_HCW_KC,KEY_PLAYPAUSE)] = PLAYPAUSE;
451     translist[W_G_HCW(W_HCW_KC,KEY_P)] = PLAYPAUSE;
452     translist[W_G_HCW(W_HCW_KC,KEY_NEXT)] = SKIPFORWARD;
453     translist[W_G_HCW(W_HCW_KC,KEY_F2)] = SKIPFORWARD;
454     translist[W_G_HCW(W_HCW_KC,KEY_PREVIOUS)] = SKIPBACK;
455     translist[W_G_HCW(W_HCW_KC,KEY_F1)] = SKIPBACK;
456     translist[W_G_HCW(W_HCW_KC,KEY_FORWARD)] = FORWARD;
457     translist[W_G_HCW(W_HCW_KC,KEY_FASTFORWARD)] = FORWARD;
458     translist[W_G_HCW(W_HCW_KC,KEY_F)] = FORWARD;
459     translist[W_G_HCW(W_HCW_KC,KEY_BACK)] = REVERSE;
460     translist[W_G_HCW(W_HCW_KC,KEY_REWIND)] = REVERSE;
461     translist[W_G_HCW(W_HCW_KC,KEY_T)] = REVERSE;
462     translist[W_G_HCW(W_HCW_KC,KEY_MUTE)] = MUTE;
463     translist[W_G_HCW(W_HCW_KC,KEY_F8)] = MUTE;
464     translist[W_G_HCW(W_HCW_KC,KEY_F10)] = VOLUMEUP;
465     translist[W_G_HCW(W_HCW_KC,KEY_F9)] = VOLUMEDOWN;
466     translist[W_G_HCW(W_HCW_KC,KEY_VOLUMEUP)] = VOLUMEUP;
467     translist[W_G_HCW(W_HCW_KC,KEY_VOLUMEDOWN)] = VOLUMEDOWN;
468     translist[W_G_HCW(W_HCW_KC,KEY_CHANNELUP)] = CHANNELUP;
469     translist[W_G_HCW(W_HCW_KC,KEY_CHANNELDOWN)] = CHANNELDOWN;
470     translist[W_G_HCW(W_HCW_KC,KEY_PAGEUP)] = CHANNELUP;
471     translist[W_G_HCW(W_HCW_KC,KEY_PAGEDOWN)] = CHANNELDOWN;
472
473
474     //Processing CEC_Messages
475     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER9)] = NINE;
476     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER8)] = EIGHT;
477     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER7)] = SEVEN;
478     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER6)] = SIX;
479     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER5)] = FIVE;
480     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER4)] = FOUR;
481     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER3)] = THREE;
482     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER2)] = TWO;
483     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER1)] = ONE;
484     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER0)] = ZERO;
485     //translist[W_G_HCW(W_HCW_CEC,KEY_KPDOT)] = STAR;
486
487
488
489     //translist[W_G_HCW(W_HCW_CEC,KEY_J)] = GO; //j for JUMP TO instead of go to
490     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F2_RED)] = RED;
491     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F3_GREEN)] = GREEN;
492     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F4_YELLOW)] = YELLOW;
493     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F1_BLUE)] = BLUE;
494     //Processing Remote Style Messages
495     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_FAVORITE_MENU)] = MENU;
496
497     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_RECORD)] = RECORD;
498     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_PLAY)] = PLAY; //Playback Televison
499     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_PAUSE)] = PAUSE;
500     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_STOP)] = STOP;
501     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_PAUSE_PLAY_FUNCTION)] = PLAYPAUSE;
502     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_FORWARD)] = SKIPFORWARD;
503     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_BACKWARD)] = SKIPBACK;
504     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_FAST_FORWARD )] = FORWARD;
505     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_REWIND)] = REVERSE;
506     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_MUTE)] = MUTE;
507     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_VOLUME_UP)] = VOLUMEUP;
508     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_VOLUME_DOWN)] = VOLUMEDOWN;
509     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_CHANNEL_UP )] = CHANNELUP;
510     translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_CHANNEL_DOWN)] = CHANNELDOWN;
511
512 }
513
514 #define NAMETRICK(pre, code) linux_keymap[pre ## code]=  #code
515 #define NAMETRICK2(pre, code) cec_keymap[pre ## code]=  #code
516 //extracte from linux/input.h
517
518 static const char * linux_keymap[KEY_MAX+1];
519 static const char * cec_keymap[CEC_USER_CONTROL_CODE_MAX+1];
520
521 void RemoteLinux::InitKeymap()
522 {
523         for (int i=0;i<KEY_MAX+1;i++) {
524                 linux_keymap[i]=NULL;
525         }
526         NAMETRICK(KEY_,RESERVED);
527         NAMETRICK(KEY_,ESC);
528         NAMETRICK(KEY_,1);
529         NAMETRICK(KEY_,2);
530         NAMETRICK(KEY_,3);
531         NAMETRICK(KEY_,4);
532         NAMETRICK(KEY_,5);
533         NAMETRICK(KEY_,6);
534         NAMETRICK(KEY_,7);
535         NAMETRICK(KEY_,8);
536         NAMETRICK(KEY_,9);
537         NAMETRICK(KEY_,0);
538         NAMETRICK(KEY_,MINUS);
539         NAMETRICK(KEY_,EQUAL);
540         NAMETRICK(KEY_,BACKSPACE);
541         NAMETRICK(KEY_,TAB);
542         NAMETRICK(KEY_,Q);
543         NAMETRICK(KEY_,W);
544         NAMETRICK(KEY_,E);
545         NAMETRICK(KEY_,R);
546         NAMETRICK(KEY_,T);
547         NAMETRICK(KEY_,Y);
548         NAMETRICK(KEY_,U);
549         NAMETRICK(KEY_,I);
550         NAMETRICK(KEY_,O);
551         NAMETRICK(KEY_,P);
552         NAMETRICK(KEY_,LEFTBRACE);
553         NAMETRICK(KEY_,RIGHTBRACE);
554         NAMETRICK(KEY_,ENTER);
555         NAMETRICK(KEY_,LEFTCTRL);
556         NAMETRICK(KEY_,A);
557         NAMETRICK(KEY_,S);
558         NAMETRICK(KEY_,D);
559         NAMETRICK(KEY_,F);
560         NAMETRICK(KEY_,G);
561         NAMETRICK(KEY_,H);
562         NAMETRICK(KEY_,J);
563         NAMETRICK(KEY_,K);
564         NAMETRICK(KEY_,L);
565         NAMETRICK(KEY_,SEMICOLON);
566         NAMETRICK(KEY_,APOSTROPHE);
567         NAMETRICK(KEY_,GRAVE);
568         NAMETRICK(KEY_,LEFTSHIFT);
569         NAMETRICK(KEY_,BACKSLASH);
570         NAMETRICK(KEY_,Z);
571         NAMETRICK(KEY_,X);
572         NAMETRICK(KEY_,C);
573         NAMETRICK(KEY_,V);
574         NAMETRICK(KEY_,B);
575         NAMETRICK(KEY_,N);
576         NAMETRICK(KEY_,M);
577         NAMETRICK(KEY_,COMMA);
578         NAMETRICK(KEY_,DOT);
579         NAMETRICK(KEY_,SLASH);
580         NAMETRICK(KEY_,RIGHTSHIFT);
581         NAMETRICK(KEY_,KPASTERISK);
582         NAMETRICK(KEY_,LEFTALT);
583         NAMETRICK(KEY_,SPACE);
584         NAMETRICK(KEY_,CAPSLOCK);
585         NAMETRICK(KEY_,F1);
586         NAMETRICK(KEY_,F2);
587         NAMETRICK(KEY_,F3);
588         NAMETRICK(KEY_,F4);
589         NAMETRICK(KEY_,F5);
590         NAMETRICK(KEY_,F6);
591         NAMETRICK(KEY_,F7);
592         NAMETRICK(KEY_,F8);
593         NAMETRICK(KEY_,F9);
594         NAMETRICK(KEY_,F10);
595         NAMETRICK(KEY_,NUMLOCK);
596         NAMETRICK(KEY_,SCROLLLOCK);
597         NAMETRICK(KEY_,KP7);
598         NAMETRICK(KEY_,KP8);
599         NAMETRICK(KEY_,KP9);
600         NAMETRICK(KEY_,KPMINUS);
601         NAMETRICK(KEY_,KP4);
602         NAMETRICK(KEY_,KP5);
603         NAMETRICK(KEY_,KP6);
604         NAMETRICK(KEY_,KPPLUS);
605         NAMETRICK(KEY_,KP1);
606         NAMETRICK(KEY_,KP2);
607         NAMETRICK(KEY_,KP3);
608         NAMETRICK(KEY_,KP0);
609         NAMETRICK(KEY_,KPDOT);
610         NAMETRICK(KEY_,F11);
611         NAMETRICK(KEY_,F12);
612         NAMETRICK(KEY_,KPENTER);
613         NAMETRICK(KEY_,RIGHTCTRL);
614         NAMETRICK(KEY_,KPSLASH);
615         NAMETRICK(KEY_,SYSRQ);
616         NAMETRICK(KEY_,RIGHTALT);
617         NAMETRICK(KEY_,LINEFEED);
618         NAMETRICK(KEY_,HOME);
619         NAMETRICK(KEY_,UP);
620         NAMETRICK(KEY_,PAGEUP);
621         NAMETRICK(KEY_,LEFT);
622         NAMETRICK(KEY_,RIGHT);
623         NAMETRICK(KEY_,END);
624         NAMETRICK(KEY_,DOWN);
625         NAMETRICK(KEY_,PAGEDOWN);
626         NAMETRICK(KEY_,INSERT);
627         NAMETRICK(KEY_,DELETE);
628         NAMETRICK(KEY_,MACRO);
629         NAMETRICK(KEY_,MUTE);
630         NAMETRICK(KEY_,VOLUMEDOWN);
631         NAMETRICK(KEY_,VOLUMEUP);
632         NAMETRICK(KEY_,POWER);
633         NAMETRICK(KEY_,KPEQUAL);
634         NAMETRICK(KEY_,KPPLUSMINUS);
635         NAMETRICK(KEY_,PLAY);
636         NAMETRICK(KEY_,PAUSE);
637         NAMETRICK(KEY_,SCALE);
638         NAMETRICK(KEY_,KPCOMMA);
639         NAMETRICK(KEY_,YEN);
640         NAMETRICK(KEY_,LEFTMETA);
641         NAMETRICK(KEY_,RIGHTMETA);
642         NAMETRICK(KEY_,COMPOSE);
643         NAMETRICK(KEY_,STOP);
644         NAMETRICK(KEY_,AGAIN);
645         NAMETRICK(KEY_,PROPS);
646         NAMETRICK(KEY_,UNDO);
647         NAMETRICK(KEY_,FRONT);
648         NAMETRICK(KEY_,COPY);
649         NAMETRICK(KEY_,OPEN);
650         NAMETRICK(KEY_,PASTE);
651         NAMETRICK(KEY_,FIND);
652         NAMETRICK(KEY_,CUT);
653         NAMETRICK(KEY_,HELP);
654         NAMETRICK(KEY_,MENU);
655         NAMETRICK(KEY_,CALC);
656         NAMETRICK(KEY_,SETUP);
657         NAMETRICK(KEY_,SLEEP);
658         NAMETRICK(KEY_,WAKEUP);
659         NAMETRICK(KEY_,FILE);
660         NAMETRICK(KEY_,SENDFILE);
661         NAMETRICK(KEY_,DELETEFILE);
662         NAMETRICK(KEY_,XFER);
663         NAMETRICK(KEY_,PROG1);
664         NAMETRICK(KEY_,PROG2);
665         NAMETRICK(KEY_,WWW);
666         NAMETRICK(KEY_,MSDOS);
667         NAMETRICK(KEY_,COFFEE);
668         NAMETRICK(KEY_,DIRECTION);
669         NAMETRICK(KEY_,CYCLEWINDOWS);
670         NAMETRICK(KEY_,MAIL);
671         NAMETRICK(KEY_,BOOKMARKS);
672         NAMETRICK(KEY_,COMPUTER);
673         NAMETRICK(KEY_,BACK);
674         NAMETRICK(KEY_,FORWARD);
675         NAMETRICK(KEY_,FASTFORWARD);
676         NAMETRICK(KEY_,CLOSECD);
677         NAMETRICK(KEY_,EJECTCD);
678         NAMETRICK(KEY_,EJECTCLOSECD);
679         NAMETRICK(KEY_,NEXTSONG);
680         NAMETRICK(KEY_,PLAYPAUSE);
681         NAMETRICK(KEY_,PREVIOUSSONG);
682         NAMETRICK(KEY_,STOPCD);
683         NAMETRICK(KEY_,RECORD);
684         NAMETRICK(KEY_,REWIND);
685         NAMETRICK(KEY_,PHONE);
686         NAMETRICK(KEY_,ISO);
687         NAMETRICK(KEY_,CONFIG);
688         NAMETRICK(KEY_,HOMEPAGE);
689         NAMETRICK(KEY_,REFRESH);
690         NAMETRICK(KEY_,EXIT);
691         NAMETRICK(KEY_,MOVE);
692         NAMETRICK(KEY_,EDIT);
693         NAMETRICK(KEY_,SCROLLUP);
694         NAMETRICK(KEY_,SCROLLDOWN);
695         NAMETRICK(KEY_,KPLEFTPAREN);
696         NAMETRICK(KEY_,KPRIGHTPAREN);
697         NAMETRICK(KEY_,NEW);
698         NAMETRICK(KEY_,REDO);
699         NAMETRICK(KEY_,OK);
700         NAMETRICK(KEY_,SELECT);
701         NAMETRICK(KEY_,GOTO);
702         NAMETRICK(KEY_,CLEAR);
703         NAMETRICK(KEY_,POWER2);
704         NAMETRICK(KEY_,OPTION);
705         NAMETRICK(KEY_,INFO);
706         NAMETRICK(KEY_,TIME);
707         NAMETRICK(KEY_,VENDOR);
708         NAMETRICK(KEY_,ARCHIVE);
709         NAMETRICK(KEY_,PROGRAM);
710         NAMETRICK(KEY_,CHANNEL);
711         NAMETRICK(KEY_,FAVORITES);
712         NAMETRICK(KEY_,EPG);
713         NAMETRICK(KEY_,PVR);
714         NAMETRICK(KEY_,MHP);
715         NAMETRICK(KEY_,LANGUAGE);
716         NAMETRICK(KEY_,TITLE);
717         NAMETRICK(KEY_,SUBTITLE);
718         NAMETRICK(KEY_,ANGLE);
719         NAMETRICK(KEY_,ZOOM);
720         NAMETRICK(KEY_,MODE);
721         NAMETRICK(KEY_,KEYBOARD);
722         NAMETRICK(KEY_,SCREEN);
723         NAMETRICK(KEY_,RED);
724         NAMETRICK(KEY_,GREEN);
725         NAMETRICK(KEY_,YELLOW);
726         NAMETRICK(KEY_,BLUE);
727         NAMETRICK(KEY_,CHANNELUP);
728         NAMETRICK(KEY_,CHANNELDOWN);
729         NAMETRICK(KEY_,FIRST);
730         NAMETRICK(KEY_,LAST);
731         NAMETRICK(KEY_,AB);
732         NAMETRICK(KEY_,NEXT);
733         NAMETRICK(KEY_,RESTART);
734         NAMETRICK(KEY_,SLOW);
735         NAMETRICK(KEY_,SHUFFLE);
736         NAMETRICK(KEY_,BREAK);
737         NAMETRICK(KEY_,PREVIOUS);
738         NAMETRICK(KEY_,DIGITS);
739         NAMETRICK(KEY_,TEEN);
740         NAMETRICK(KEY_,TWEN);
741         NAMETRICK(KEY_,VIDEOPHONE);
742         NAMETRICK(KEY_,GAMES);
743         NAMETRICK(KEY_,ZOOMIN);
744         NAMETRICK(KEY_,ZOOMOUT);
745         NAMETRICK(KEY_,ZOOMRESET);
746         NAMETRICK(KEY_,DOLLAR);
747         NAMETRICK(KEY_,EURO);
748         NAMETRICK(KEY_,MEDIA);
749         NAMETRICK(KEY_,FRAMEBACK);
750         NAMETRICK(KEY_,FRAMEFORWARD);
751         NAMETRICK(KEY_,CONTEXT_MENU);
752         NAMETRICK(KEY_,MEDIA_REPEAT);
753         NAMETRICK(KEY_,NUMERIC_0);
754         NAMETRICK(KEY_,NUMERIC_1);
755         NAMETRICK(KEY_,NUMERIC_2);
756         NAMETRICK(KEY_,NUMERIC_3);
757         NAMETRICK(KEY_,NUMERIC_4);
758         NAMETRICK(KEY_,NUMERIC_5);
759         NAMETRICK(KEY_,NUMERIC_6);
760         NAMETRICK(KEY_,NUMERIC_7);
761         NAMETRICK(KEY_,NUMERIC_8);
762         NAMETRICK(KEY_,NUMERIC_9);
763         NAMETRICK(KEY_,NUMERIC_STAR);
764         NAMETRICK(KEY_,NUMERIC_POUND);
765
766         for (int i=0;i<CEC_USER_CONTROL_CODE_MAX+1;i++) {
767                         cec_keymap[i]=NULL;
768         }
769         NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT);
770         NAMETRICK2(CEC_USER_CONTROL_CODE_,UP);
771         NAMETRICK2(CEC_USER_CONTROL_CODE_,DOWN);
772         NAMETRICK2(CEC_USER_CONTROL_CODE_,LEFT);
773         NAMETRICK2(CEC_USER_CONTROL_CODE_,RIGHT);
774         NAMETRICK2(CEC_USER_CONTROL_CODE_,RIGHT_UP);
775         NAMETRICK2(CEC_USER_CONTROL_CODE_,RIGHT_DOWN);
776         NAMETRICK2(CEC_USER_CONTROL_CODE_,LEFT_UP);
777         NAMETRICK2(CEC_USER_CONTROL_CODE_,LEFT_DOWN);
778         NAMETRICK2(CEC_USER_CONTROL_CODE_,ROOT_MENU);
779         NAMETRICK2(CEC_USER_CONTROL_CODE_,SETUP_MENU);
780         NAMETRICK2(CEC_USER_CONTROL_CODE_,CONTENTS_MENU);
781         NAMETRICK2(CEC_USER_CONTROL_CODE_,FAVORITE_MENU);
782         NAMETRICK2(CEC_USER_CONTROL_CODE_,EXIT);
783         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER0);
784         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER1);
785         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER2);
786         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER3);
787         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER4);
788         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER5);
789         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER6);
790         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER7);
791         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER8);
792         NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER9);
793         NAMETRICK2(CEC_USER_CONTROL_CODE_,DOT);
794         NAMETRICK2(CEC_USER_CONTROL_CODE_,ENTER);
795         NAMETRICK2(CEC_USER_CONTROL_CODE_,CLEAR);
796         NAMETRICK2(CEC_USER_CONTROL_CODE_,NEXT_FAVORITE);
797         NAMETRICK2(CEC_USER_CONTROL_CODE_,CHANNEL_UP);
798         NAMETRICK2(CEC_USER_CONTROL_CODE_,CHANNEL_DOWN);
799         NAMETRICK2(CEC_USER_CONTROL_CODE_,PREVIOUS_CHANNEL);
800         NAMETRICK2(CEC_USER_CONTROL_CODE_,SOUND_SELECT);
801         NAMETRICK2(CEC_USER_CONTROL_CODE_,INPUT_SELECT);
802         NAMETRICK2(CEC_USER_CONTROL_CODE_,DISPLAY_INFORMATION);
803         NAMETRICK2(CEC_USER_CONTROL_CODE_,HELP);
804         NAMETRICK2(CEC_USER_CONTROL_CODE_,PAGE_UP);
805         NAMETRICK2(CEC_USER_CONTROL_CODE_,PAGE_DOWN);
806         NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER );
807         NAMETRICK2(CEC_USER_CONTROL_CODE_,VOLUME_UP );
808         NAMETRICK2(CEC_USER_CONTROL_CODE_,VOLUME_DOWN );
809         NAMETRICK2(CEC_USER_CONTROL_CODE_,MUTE );
810         NAMETRICK2(CEC_USER_CONTROL_CODE_,PLAY );
811         NAMETRICK2(CEC_USER_CONTROL_CODE_,STOP );
812         NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE );
813         NAMETRICK2(CEC_USER_CONTROL_CODE_,RECORD );
814         NAMETRICK2(CEC_USER_CONTROL_CODE_,REWIND );
815         NAMETRICK2(CEC_USER_CONTROL_CODE_,FAST_FORWARD );
816         NAMETRICK2(CEC_USER_CONTROL_CODE_,EJECT );
817         NAMETRICK2(CEC_USER_CONTROL_CODE_,FORWARD );
818         NAMETRICK2(CEC_USER_CONTROL_CODE_,BACKWARD );
819         NAMETRICK2(CEC_USER_CONTROL_CODE_,STOP_RECORD );
820         NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE_RECORD );
821         NAMETRICK2(CEC_USER_CONTROL_CODE_,ANGLE );
822         NAMETRICK2(CEC_USER_CONTROL_CODE_,SUB_PICTURE );
823         NAMETRICK2(CEC_USER_CONTROL_CODE_,VIDEO_ON_DEMAND );
824         NAMETRICK2(CEC_USER_CONTROL_CODE_,ELECTRONIC_PROGRAM_GUIDE );
825         NAMETRICK2(CEC_USER_CONTROL_CODE_,TIMER_PROGRAMMING );
826         NAMETRICK2(CEC_USER_CONTROL_CODE_,INITIAL_CONFIGURATION );
827         NAMETRICK2(CEC_USER_CONTROL_CODE_,PLAY_FUNCTION );
828         NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE_PLAY_FUNCTION );
829         NAMETRICK2(CEC_USER_CONTROL_CODE_,RECORD_FUNCTION );
830         NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE_RECORD_FUNCTION );
831         NAMETRICK2(CEC_USER_CONTROL_CODE_,STOP_FUNCTION );
832         NAMETRICK2(CEC_USER_CONTROL_CODE_,MUTE_FUNCTION );
833         NAMETRICK2(CEC_USER_CONTROL_CODE_,RESTORE_VOLUME_FUNCTION );
834         NAMETRICK2(CEC_USER_CONTROL_CODE_,TUNE_FUNCTION );
835         NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT_MEDIA_FUNCTION );
836         NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT_AV_INPUT_FUNCTION );
837         NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT_AUDIO_INPUT_FUNCTION );
838         NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER_TOGGLE_FUNCTION );
839         NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER_OFF_FUNCTION );
840         NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER_ON_FUNCTION );
841         NAMETRICK2(CEC_USER_CONTROL_CODE_,F1_BLUE );
842         NAMETRICK2(CEC_USER_CONTROL_CODE_,F2_RED );
843         NAMETRICK2(CEC_USER_CONTROL_CODE_,F3_GREEN );
844         NAMETRICK2(CEC_USER_CONTROL_CODE_,F4_YELLOW );
845         NAMETRICK2(CEC_USER_CONTROL_CODE_,F5 );
846         NAMETRICK2(CEC_USER_CONTROL_CODE_,DATA );
847         NAMETRICK2(CEC_USER_CONTROL_CODE_,AN_RETURN );
848         NAMETRICK2(CEC_USER_CONTROL_CODE_,AN_CHANNELS_LIST );
849         NAMETRICK2(CEC_USER_CONTROL_CODE_,MAX );
850
851 }
852
853
854
855 char* RemoteLinux::HCWDesc(unsigned long long hcw)
856 {
857     //Determine type
858     unsigned int type =  hcw >> 32;
859     char *rt=NULL;
860     switch(type)
861     {
862     case W_HCW_KC:{
863         unsigned int vk=(ULONG)hcw;
864         rt=new char[10];
865         const char *desc=linux_keymap[vk];
866         if (desc) {
867                 strncpy(rt,desc,9);
868         } else {
869                 sprintf(rt,"0x%x",vk);
870         }
871                   }break;
872     case W_HCW_CEC:{
873         unsigned int vk=(ULONG)hcw;
874         rt=new char[10];
875         const char *desc=cec_keymap[vk];
876         if (desc) {
877                 strncpy(rt,desc,9);
878         } else {
879                 sprintf(rt,"0x%x",vk);
880         }
881                   }break;
882   /*
883     case W_HCW_LIRC:{
884         ULONG ri=(ULONG)hcw;
885         rt=new char[10];
886         sprintf(rt,"R: %X",ri);
887                   }break;*/
888
889     };
890     return rt;
891 }
892
893 void RemoteLinux::changePowerState(bool poweron){
894         if (cec_adap) {
895                 if (poweron) {
896                         //Log::getInstance()->log("Remote", Log::DEBUG, "CEC set active source" );
897                         cec_adap->SetActiveSource(cec_config.deviceTypes[0]);
898                         haspower=false;
899                 } else {
900                         //Log::getInstance()->log("Remote", Log::DEBUG, "CEC set inactive view" );
901                         cec_adap->SetInactiveView();
902                         haspower=false; //clear stuff
903                 }
904         }
905 }
906
907
908 int RemoteLinux::cecLogMessage(void *param, const cec_log_message message)
909 {
910         Log::getInstance()->log("Remote", Log::DEBUG, "CECLOG: %lld %d %s",message.time , message.level, message.message );
911         return 0;
912 }
913
914 int RemoteLinux::cecKeyPress(void*param, const cec_keypress key)
915 {
916         //Log::getInstance()->log("Remote", Log::DEBUG, "Incoming cec key %d %d", key.keycode,key.duration);
917         if (key.duration==0) ((RemoteLinux*)Remote::getInstance())->incomingCECkey(key.keycode);
918         return 1;
919 }
920 int RemoteLinux::cecCommand(void *param, const cec_command command)
921 {
922         Log::getInstance()->log("Remote", Log::DEBUG, "CECCommand: %d",command.opcode);
923         switch (command.opcode) {
924         case CEC_OPCODE_STANDBY: {
925                 if (command.initiator==CECDEVICE_TV) {
926                         ((RemoteLinux*)Remote::getInstance())->incomingPowerkey(POWEROFF);
927                 }
928         } break;
929         case CEC_OPCODE_DECK_CONTROL: {
930                 if (command.initiator==CECDEVICE_TV && command.parameters.size == 1
931                                 && command.parameters[0]==CEC_DECK_CONTROL_MODE_STOP) {
932                         ((RemoteLinux*)Remote::getInstance())->incomingCECkey(CEC_USER_CONTROL_CODE_STOP);
933
934                 }
935
936         } break;
937         case CEC_OPCODE_PLAY: {
938                 if (command.initiator==CECDEVICE_TV && command.parameters.size == 1) {
939                         if (command.parameters[0]==CEC_PLAY_MODE_PLAY_FORWARD) {
940                                 ((RemoteLinux*)Remote::getInstance())->incomingCECkey(CEC_USER_CONTROL_CODE_PLAY);
941                         } else if (command.parameters[0]==CEC_PLAY_MODE_PLAY_STILL) {
942                                 ((RemoteLinux*)Remote::getInstance())->incomingCECkey(CEC_USER_CONTROL_CODE_PAUSE);
943                         }
944                 }
945
946
947         } break;
948         default:
949                 break;
950         };
951         return 1;
952 }
953
954 int RemoteLinux::cecConfigurationChanged(void *param, const libcec_configuration config)
955 {
956         Log::getInstance()->log("Remote", Log::DEBUG, "CECConfig:"/*,config.string()*/);
957         return 1;
958
959 }
960
961 void  RemoteLinux::cecSourceActivated(void*param, const cec_logical_address address, const uint8_t activated)
962 {
963         Log::getInstance()->log("Remote", Log::DEBUG, "CECSourceActivated: %d %d", address, activated);
964         if (activated==1) {
965                 ((RemoteLinux*)Remote::getInstance())->incomingPowerkey(POWERON);
966         }
967 }
968
969 void RemoteLinux::incomingCECkey(int keys)
970 {
971         curcec=keys;
972         hascurcec=true;
973
974 }
975
976 void RemoteLinux::incomingPowerkey(UCHAR key){
977         haspower=true;
978         powerkey=key;
979 }
980
981 bool RemoteLinux::loadOptionsfromServer(VDR* vdr)
982 {
983
984    // Set remote keys
985   char * name;
986   name = vdr->configLoad("RemoteLinux", "HandleVolume");
987
988   if (name != NULL) {
989                 if (STRCASECMP(name, "Vomp") == 0) {
990                         cechandlesvolume=false;
991                 } else if (STRCASECMP(name, "Cec") == 0) {
992                         cechandlesvolume=true;
993                 }
994         delete[] name;
995         }
996   return Remote::loadOptionsfromServer(vdr);
997 }
998
999 bool RemoteLinux::saveOptionstoServer()
1000 {
1001         if (cechandlesvolume) VDR::getInstance()->configSave("RemoteLinux", "HandleVolume","Cec");
1002         else VDR::getInstance()->configSave("RemoteLinux", "HandleVolume","Vomp");
1003
1004     return Remote::saveOptionstoServer();
1005 }
1006
1007 bool RemoteLinux::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
1008 {
1009     if (!Remote::addOptionsToPanes(panenumber,options,pane)) return false;
1010
1011
1012     Option* option;
1013     if (panenumber == 2)
1014     {
1015         static const char* volumeopts[]={"Vomp","Cec"};
1016         option = new Option(100,tr("Volume handled by"), "RemoteLinux","HandleVolume",Option::TYPE_TEXT,/*4,2*/2,0,0,volumeopts,NULL,false,this);
1017         options->push_back(option);
1018         pane->addOptionLine(option);
1019     }
1020
1021     return true;
1022 }
1023
1024 bool RemoteLinux::handleOptionChanges(Option* option)
1025 {
1026     if (Remote::handleOptionChanges(option))
1027                 return true;
1028         switch (option->id) {
1029         case 100: {
1030                 if (STRCASECMP(option->options[option->userSetChoice], "Vomp") == 0) {
1031                         cechandlesvolume=false;
1032                 }  else if (STRCASECMP(option->options[option->userSetChoice], "Cec")
1033                                 == 0) {
1034                         cechandlesvolume=true;
1035                 }
1036                 Log::getInstance()->log("Remote", Log::DEBUG, "Set volume handling to to %s %d",option->options[option->userSetChoice],cechandlesvolume);
1037                 return true;
1038         }
1039         break;
1040         };
1041         return false;
1042
1043 }
1044
1045 void RemoteLinux::volumeUp()
1046 {
1047         cec_adap->VolumeUp();
1048 }
1049
1050 void RemoteLinux::volumeDown()
1051 {
1052         cec_adap->VolumeDown();
1053 }
1054
1055 void RemoteLinux::volumeMute()
1056 {
1057         cec_adap->MuteAudio();
1058 }
1059