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