2 Copyright 2004-2005 Chris Tallon; 2012 Marten Richter
4 This file is part of VOMP.
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.
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.
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.
21 #include "remotelinux.h"
23 #include <linux/input.h>
24 #include <sys/types.h>
35 #define W_G_HCW(type,code) ( (((ULLONG)(type))<<32) | code)
37 #define W_HCW_KC 1 /* key code as defined by kernel for keyboard and remotes through /dev/input */
38 #define W_HCW_CEC 2 /* HDMI_CEC */
39 #define W_HCW_LIRC 3 /* remote control LIRC*/
42 RemoteLinux::RemoteLinux()
53 RemoteLinux::~RemoteLinux()
55 for (unsigned int i=0; i<devices.size();i++) {
60 #define test_bit(input,b) ((1 << ((b) % 8))&(input)[b / 8] )
63 int RemoteLinux::init(char* devName)
65 if (initted) return 0;
70 for (int eventid=0;eventid<100;eventid++){
72 sprintf(buffer,"/dev/input/event%d",eventid);
76 if (stat(buffer,&test_buf)==0) {
77 Log::getInstance()->log("Remote", Log::NOTICE, "Probe /dev/input/event%d",eventid);
79 unsigned long ev_type=0;
80 int new_fd=open(buffer,O_RDONLY);
82 Log::getInstance()->log("Remote", Log::NOTICE, "Can not open /dev/input/event%d",eventid);
85 if (ioctl(new_fd, EVIOCGBIT(0, EV_MAX), &ev_type) < 0) {
86 Log::getInstance()->log("Remote", Log::NOTICE, "Ioctl failed /dev/input/event%d %d",eventid,errno);
89 //Now test if it generates keyboard presses
90 if (test_bit((char*)&ev_type , EV_KEY)) {
91 Log::getInstance()->log("Remote", Log::NOTICE, "Add /dev/input/event%d to List",eventid);
92 devices.push_back(new_fd);
110 int RemoteLinux::shutdown()
112 if (!initted) return 0;
118 UCHAR RemoteLinux::getButtonPress(int waitType)
121 how = 1 - start new wait
122 how = 2 - continue wait
127 struct timeval* passToSelect = NULL;
135 else if (waitType == 1)
141 else if (waitType == 2)
143 if ((tv.tv_sec == 0) && (tv.tv_usec == 0)) // protection in case timer = 0
150 else if (waitType == 3)
159 for (int i=0; i<devices.size();i++) {
160 int cur_fd=devices[i];
161 maxfd=max(cur_fd,maxfd);
162 FD_SET(cur_fd, &readfds);
167 retval = select(maxfd + 1, &readfds, NULL, NULL, &tv);
168 // 0 = nothing happened
169 // 1 = data arrived (actually num of descriptors that changed)
170 // other value = signal or error
171 if (retval == 0) return NA_NONE;
172 if (retval == -1) return NA_SIGNAL;
175 for (int i=0; i<devices.size();i++) {
176 int cur_fd=devices[i];
177 if (FD_ISSET(cur_fd, &readfds)) {
178 struct input_event ev;
179 int count = read(cur_fd, &ev, sizeof(ev));
180 if (count==sizeof(ev)) {
181 if (ev.type==EV_KEY && ev.value==1) {
182 return (UCHAR) TranslateHWC(W_G_HCW(W_HCW_KC,ev.code));
194 void RemoteLinux::clearBuffer()
196 while(getButtonPress(3) != NA_NONE);
199 UCHAR RemoteLinux::TranslateHWCFixed(ULLONG code)
203 case W_G_HCW(W_HCW_KC,KEY_DOWN):
205 case W_G_HCW(W_HCW_KC,KEY_UP):
207 case W_G_HCW(W_HCW_KC,KEY_LEFT):
209 case W_G_HCW(W_HCW_KC,KEY_RIGHT):
211 case W_G_HCW(W_HCW_KC,KEY_M):
213 case W_G_HCW(W_HCW_KC,KEY_BACKSPACE):
215 case W_G_HCW(W_HCW_KC,KEY_ENTER):
216 case W_G_HCW(W_HCW_KC,KEY_SPACE):
217 case W_G_HCW(W_HCW_KC,KEY_OK):
226 const char*RemoteLinux::HardcodedTranslateStr(UCHAR command)
241 return tr("Backspace, Back");
243 return tr("Return, Space");
251 void RemoteLinux::InitHWCListwithDefaults()
253 //Processing VK_Messages
254 translist[W_G_HCW(W_HCW_KC,KEY_9)] = NINE;
255 translist[W_G_HCW(W_HCW_KC,KEY_8)] = EIGHT;
256 translist[W_G_HCW(W_HCW_KC,KEY_7)] = SEVEN;
257 translist[W_G_HCW(W_HCW_KC,KEY_6)] = SIX;
258 translist[W_G_HCW(W_HCW_KC,KEY_5)] = FIVE;
259 translist[W_G_HCW(W_HCW_KC,KEY_4)] = FOUR;
260 translist[W_G_HCW(W_HCW_KC,KEY_3)] = THREE;
261 translist[W_G_HCW(W_HCW_KC,KEY_2)] = TWO;
262 translist[W_G_HCW(W_HCW_KC,KEY_1)] = ONE;
263 translist[W_G_HCW(W_HCW_KC,KEY_0)] = ZERO;
264 translist[W_G_HCW(W_HCW_KC,KEY_KPDOT)] = STAR;
265 // translist[W_G_HCW(W_HCW_KC,KEY_#)] = HASH;
267 translist[W_G_HCW(W_HCW_KC,KEY_KP9)] = NINE;
268 translist[W_G_HCW(W_HCW_KC,KEY_KP8)] = EIGHT;
269 translist[W_G_HCW(W_HCW_KC,KEY_KP7)] = SEVEN;
270 translist[W_G_HCW(W_HCW_KC,KEY_KP6)] = SIX;
271 translist[W_G_HCW(W_HCW_KC,KEY_KP5)] = FIVE;
272 translist[W_G_HCW(W_HCW_KC,KEY_KP4)] = FOUR;
273 translist[W_G_HCW(W_HCW_KC,KEY_KP3)] = THREE;
274 translist[W_G_HCW(W_HCW_KC,KEY_KP2)] = TWO;
275 translist[W_G_HCW(W_HCW_KC,KEY_KP1)] = ONE;
276 translist[W_G_HCW(W_HCW_KC,KEY_KP0)] = ZERO;
278 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_9)] = NINE;
279 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_8)] = EIGHT;
280 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_7)] = SEVEN;
281 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_6)] = SIX;
282 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_5)] = FIVE;
283 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_4)] = FOUR;
284 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_3)] = THREE;
285 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_2)] = TWO;
286 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_1)] = ONE;
287 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_0)] = ZERO;
288 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_STAR)] = STAR;
289 translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_POUND)] = HASH;
292 translist[W_G_HCW(W_HCW_KC,KEY_J)] = GO; //j for JUMP TO instead of go to
293 translist[W_G_HCW(W_HCW_KC,KEY_R)] = RED;
294 translist[W_G_HCW(W_HCW_KC,KEY_G)] = GREEN;
295 translist[W_G_HCW(W_HCW_KC,KEY_Y)] = YELLOW;
296 translist[W_G_HCW(W_HCW_KC,KEY_B)] = BLUE;
297 //Processing Remote Style Messages
298 translist[W_G_HCW(W_HCW_KC,KEY_GREEN)] = GREEN;
299 translist[W_G_HCW(W_HCW_KC,KEY_RED)] = RED;
300 translist[W_G_HCW(W_HCW_KC,KEY_YELLOW)] = YELLOW;
301 translist[W_G_HCW(W_HCW_KC,KEY_BLUE)] = BLUE;
302 translist[W_G_HCW(W_HCW_KC,KEY_MENU)] = MENU;
304 translist[W_G_HCW(W_HCW_KC,KEY_RECORD)] = RECORD;
305 translist[W_G_HCW(W_HCW_KC,KEY_PLAY)] = PLAY; //Playback Televison
306 translist[W_G_HCW(W_HCW_KC,KEY_PAUSE)] = PAUSE;
307 translist[W_G_HCW(W_HCW_KC,KEY_STOP)] = STOP;
308 translist[W_G_HCW(W_HCW_KC,KEY_PLAYPAUSE)] = PLAYPAUSE;
309 translist[W_G_HCW(W_HCW_KC,KEY_P)] = PLAYPAUSE;
310 translist[W_G_HCW(W_HCW_KC,KEY_NEXT)] = SKIPFORWARD;
311 translist[W_G_HCW(W_HCW_KC,KEY_PREVIOUS)] = SKIPBACK;
312 translist[W_G_HCW(W_HCW_KC,KEY_FORWARD)] = FORWARD;
313 translist[W_G_HCW(W_HCW_KC,KEY_BACK)] = REVERSE;
314 translist[W_G_HCW(W_HCW_KC,KEY_MUTE)] = MUTE;
315 translist[W_G_HCW(W_HCW_KC,KEY_F9)] = VOLUMEUP;
316 translist[W_G_HCW(W_HCW_KC,KEY_F10)] = VOLUMEDOWN;
317 translist[W_G_HCW(W_HCW_KC,KEY_VOLUMEUP)] = VOLUMEUP;
318 translist[W_G_HCW(W_HCW_KC,KEY_VOLUMEDOWN)] = VOLUMEDOWN;
319 translist[W_G_HCW(W_HCW_KC,KEY_CHANNELUP)] = CHANNELUP;
320 translist[W_G_HCW(W_HCW_KC,KEY_CHANNELDOWN)] = CHANNELDOWN;
321 translist[W_G_HCW(W_HCW_KC,KEY_PAGEUP)] = CHANNELUP;
322 translist[W_G_HCW(W_HCW_KC,KEY_PAGEDOWN)] = CHANNELDOWN;
327 #define NAMETRICK(pre, code) linux_keymap[pre ## code]= #code
328 //extracte from linux/input.h
330 static const char * linux_keymap[KEY_MAX+1];
332 void RemoteLinux::InitKeymap()
334 for (int i=0;i<KEY_MAX+1;i++) {
335 linux_keymap[i]=NULL;
337 NAMETRICK(KEY_,RESERVED);
349 NAMETRICK(KEY_,MINUS);
350 NAMETRICK(KEY_,EQUAL);
351 NAMETRICK(KEY_,BACKSPACE);
363 NAMETRICK(KEY_,LEFTBRACE);
364 NAMETRICK(KEY_,RIGHTBRACE);
365 NAMETRICK(KEY_,ENTER);
366 NAMETRICK(KEY_,LEFTCTRL);
376 NAMETRICK(KEY_,SEMICOLON);
377 NAMETRICK(KEY_,APOSTROPHE);
378 NAMETRICK(KEY_,GRAVE);
379 NAMETRICK(KEY_,LEFTSHIFT);
380 NAMETRICK(KEY_,BACKSLASH);
388 NAMETRICK(KEY_,COMMA);
390 NAMETRICK(KEY_,SLASH);
391 NAMETRICK(KEY_,RIGHTSHIFT);
392 NAMETRICK(KEY_,KPASTERISK);
393 NAMETRICK(KEY_,LEFTALT);
394 NAMETRICK(KEY_,SPACE);
395 NAMETRICK(KEY_,CAPSLOCK);
406 NAMETRICK(KEY_,NUMLOCK);
407 NAMETRICK(KEY_,SCROLLLOCK);
411 NAMETRICK(KEY_,KPMINUS);
415 NAMETRICK(KEY_,KPPLUS);
420 NAMETRICK(KEY_,KPDOT);
423 NAMETRICK(KEY_,KPENTER);
424 NAMETRICK(KEY_,RIGHTCTRL);
425 NAMETRICK(KEY_,KPSLASH);
426 NAMETRICK(KEY_,SYSRQ);
427 NAMETRICK(KEY_,RIGHTALT);
428 NAMETRICK(KEY_,LINEFEED);
429 NAMETRICK(KEY_,HOME);
431 NAMETRICK(KEY_,PAGEUP);
432 NAMETRICK(KEY_,LEFT);
433 NAMETRICK(KEY_,RIGHT);
435 NAMETRICK(KEY_,DOWN);
436 NAMETRICK(KEY_,PAGEDOWN);
437 NAMETRICK(KEY_,INSERT);
438 NAMETRICK(KEY_,DELETE);
439 NAMETRICK(KEY_,MACRO);
440 NAMETRICK(KEY_,MUTE);
441 NAMETRICK(KEY_,VOLUMEDOWN);
442 NAMETRICK(KEY_,VOLUMEUP);
443 NAMETRICK(KEY_,POWER);
444 NAMETRICK(KEY_,KPEQUAL);
445 NAMETRICK(KEY_,KPPLUSMINUS);
446 NAMETRICK(KEY_,PLAY);
447 NAMETRICK(KEY_,PAUSE);
448 NAMETRICK(KEY_,SCALE);
449 NAMETRICK(KEY_,KPCOMMA);
451 NAMETRICK(KEY_,LEFTMETA);
452 NAMETRICK(KEY_,RIGHTMETA);
453 NAMETRICK(KEY_,COMPOSE);
454 NAMETRICK(KEY_,STOP);
455 NAMETRICK(KEY_,AGAIN);
456 NAMETRICK(KEY_,PROPS);
457 NAMETRICK(KEY_,UNDO);
458 NAMETRICK(KEY_,FRONT);
459 NAMETRICK(KEY_,COPY);
460 NAMETRICK(KEY_,OPEN);
461 NAMETRICK(KEY_,PASTE);
462 NAMETRICK(KEY_,FIND);
464 NAMETRICK(KEY_,HELP);
465 NAMETRICK(KEY_,MENU);
466 NAMETRICK(KEY_,CALC);
467 NAMETRICK(KEY_,SETUP);
468 NAMETRICK(KEY_,SLEEP);
469 NAMETRICK(KEY_,WAKEUP);
470 NAMETRICK(KEY_,FILE);
471 NAMETRICK(KEY_,SENDFILE);
472 NAMETRICK(KEY_,DELETEFILE);
473 NAMETRICK(KEY_,XFER);
474 NAMETRICK(KEY_,PROG1);
475 NAMETRICK(KEY_,PROG2);
477 NAMETRICK(KEY_,MSDOS);
478 NAMETRICK(KEY_,COFFEE);
479 NAMETRICK(KEY_,DIRECTION);
480 NAMETRICK(KEY_,CYCLEWINDOWS);
481 NAMETRICK(KEY_,MAIL);
482 NAMETRICK(KEY_,BOOKMARKS);
483 NAMETRICK(KEY_,COMPUTER);
484 NAMETRICK(KEY_,BACK);
485 NAMETRICK(KEY_,FORWARD);
486 NAMETRICK(KEY_,CLOSECD);
487 NAMETRICK(KEY_,EJECTCD);
488 NAMETRICK(KEY_,EJECTCLOSECD);
489 NAMETRICK(KEY_,NEXTSONG);
490 NAMETRICK(KEY_,PLAYPAUSE);
491 NAMETRICK(KEY_,PREVIOUSSONG);
492 NAMETRICK(KEY_,STOPCD);
493 NAMETRICK(KEY_,RECORD);
494 NAMETRICK(KEY_,REWIND);
495 NAMETRICK(KEY_,PHONE);
497 NAMETRICK(KEY_,CONFIG);
498 NAMETRICK(KEY_,HOMEPAGE);
499 NAMETRICK(KEY_,REFRESH);
500 NAMETRICK(KEY_,EXIT);
501 NAMETRICK(KEY_,MOVE);
502 NAMETRICK(KEY_,EDIT);
503 NAMETRICK(KEY_,SCROLLUP);
504 NAMETRICK(KEY_,SCROLLDOWN);
505 NAMETRICK(KEY_,KPLEFTPAREN);
506 NAMETRICK(KEY_,KPRIGHTPAREN);
508 NAMETRICK(KEY_,REDO);
510 NAMETRICK(KEY_,SELECT);
511 NAMETRICK(KEY_,GOTO);
512 NAMETRICK(KEY_,CLEAR);
513 NAMETRICK(KEY_,POWER2);
514 NAMETRICK(KEY_,OPTION);
515 NAMETRICK(KEY_,INFO);
516 NAMETRICK(KEY_,TIME);
517 NAMETRICK(KEY_,VENDOR);
518 NAMETRICK(KEY_,ARCHIVE);
519 NAMETRICK(KEY_,PROGRAM);
520 NAMETRICK(KEY_,CHANNEL);
521 NAMETRICK(KEY_,FAVORITES);
525 NAMETRICK(KEY_,LANGUAGE);
526 NAMETRICK(KEY_,TITLE);
527 NAMETRICK(KEY_,SUBTITLE);
528 NAMETRICK(KEY_,ANGLE);
529 NAMETRICK(KEY_,ZOOM);
530 NAMETRICK(KEY_,MODE);
531 NAMETRICK(KEY_,KEYBOARD);
532 NAMETRICK(KEY_,SCREEN);
534 NAMETRICK(KEY_,GREEN);
535 NAMETRICK(KEY_,YELLOW);
536 NAMETRICK(KEY_,BLUE);
537 NAMETRICK(KEY_,CHANNELUP);
538 NAMETRICK(KEY_,CHANNELDOWN);
539 NAMETRICK(KEY_,FIRST);
540 NAMETRICK(KEY_,LAST);
542 NAMETRICK(KEY_,NEXT);
543 NAMETRICK(KEY_,RESTART);
544 NAMETRICK(KEY_,SLOW);
545 NAMETRICK(KEY_,SHUFFLE);
546 NAMETRICK(KEY_,BREAK);
547 NAMETRICK(KEY_,PREVIOUS);
548 NAMETRICK(KEY_,DIGITS);
549 NAMETRICK(KEY_,TEEN);
550 NAMETRICK(KEY_,TWEN);
551 NAMETRICK(KEY_,VIDEOPHONE);
552 NAMETRICK(KEY_,GAMES);
553 NAMETRICK(KEY_,ZOOMIN);
554 NAMETRICK(KEY_,ZOOMOUT);
555 NAMETRICK(KEY_,ZOOMRESET);
556 NAMETRICK(KEY_,DOLLAR);
557 NAMETRICK(KEY_,EURO);
558 NAMETRICK(KEY_,FRAMEBACK);
559 NAMETRICK(KEY_,FRAMEFORWARD);
560 NAMETRICK(KEY_,CONTEXT_MENU);
561 NAMETRICK(KEY_,MEDIA_REPEAT);
562 NAMETRICK(KEY_,NUMERIC_0);
563 NAMETRICK(KEY_,NUMERIC_1);
564 NAMETRICK(KEY_,NUMERIC_2);
565 NAMETRICK(KEY_,NUMERIC_3);
566 NAMETRICK(KEY_,NUMERIC_4);
567 NAMETRICK(KEY_,NUMERIC_5);
568 NAMETRICK(KEY_,NUMERIC_6);
569 NAMETRICK(KEY_,NUMERIC_7);
570 NAMETRICK(KEY_,NUMERIC_8);
571 NAMETRICK(KEY_,NUMERIC_9);
572 NAMETRICK(KEY_,NUMERIC_STAR);
573 NAMETRICK(KEY_,NUMERIC_POUND);
581 char* RemoteLinux::HCWDesc(unsigned long long hcw)
584 unsigned int type = hcw >> 32;
589 unsigned int vk=(ULONG)hcw;
591 const char *desc=linux_keymap[vk];
595 sprintf(rt,"0x%x",vk);
601 ULONG scancode=OemKeyScan(ch);
604 GetKeyNameText(scancode << 16,rt,10);
609 sprintf(rt,"R: %X",ri);
623 void RemoteLinux::Signal() {
629 void RemoteLinux::SendPower()