better solution to add possibility to delete eSocketNotifiers,
[vuplus_dvbapp] / lib / driver / rcconsole.cpp
1 #include <lib/base/init.h>
2 #include <lib/base/init_num.h>
3 #include <lib/base/eerror.h>
4 #include <lib/driver/rcconsole.h>
5 #include <stdio.h>
6 #include <fcntl.h>
7
8 eRCConsoleDriver::eRCConsoleDriver(const char *filename): eRCDriver(eRCInput::getInstance())
9 {
10         handle=open(filename, O_RDONLY|O_NONBLOCK);
11         if (handle<0)
12         {
13                 eDebug("failed to open %s", filename);
14                 sn=0;
15         } else
16         {
17                 sn=eSocketNotifier::create(eApp, handle, eSocketNotifier::Read);
18                 CONNECT(sn->activated, eRCConsoleDriver::keyPressed);
19                 eRCInput::getInstance()->setFile(handle);
20         }
21         
22                 /* set console mode */
23         struct termios t;
24         tcgetattr(handle, &t);
25         ot = t;
26         t.c_lflag &= ~(ECHO | ICANON | ECHOK | ECHOE | ECHONL);
27         tcsetattr(handle, TCSANOW,&t);
28 }
29
30 eRCConsoleDriver::~eRCConsoleDriver()
31 {
32         tcsetattr(handle,TCSANOW, &ot);
33         if (handle>=0)
34                 close(handle);
35 }
36
37 void eRCConsoleDriver::keyPressed(int)
38 {
39         unsigned char data[16];
40         unsigned char *d = data;
41         int num = read(handle, data, 16);
42         int code=-1;
43         
44         int km = input->getKeyboardMode();
45
46         if (km == eRCInput::kmNone)
47                 return;
48
49         while (num--)
50         {
51 //              eDebug("console code %08x\n", *d);
52                 if (km == eRCInput::kmAll)
53                         code = *d++;
54                 else
55                 {
56                         if (*d == 27) // escape code
57                         {
58                                 while (num)
59                                 {
60                                         num--;
61                                         if (*++d != '[')
62                                                 break;
63                                 }
64                                 code = -1;
65                         } else
66                                 code = *d;
67                         ++d;
68
69                         if (code < 32)                  /* control characters */
70                                 code = -1;
71                         else switch(code)
72                         {
73                         case 0x35:  // mute
74                         case 0x7E:  // mute, einfg, entf
75                         case 0x7F:  // backspace
76                         code = -1;
77                         default:
78                                 break;
79                         }
80                 }
81
82                 if (code != -1)
83                         for (std::list<eRCDevice*>::iterator i(listeners.begin()); i!=listeners.end(); ++i)
84                         {
85 //                              eDebug("ascii %08x", code);
86                                 (*i)->handleCode(code);
87                         }
88         }
89 }
90
91 void eRCConsole::handleCode(long code)
92 {
93         input->keyPressed(eRCKey(this, code, eRCKey::flagAscii));
94 }
95
96 eRCConsole::eRCConsole(eRCDriver *driver)
97                         : eRCDevice("Console", driver)
98 {
99 }
100
101 const char *eRCConsole::getDescription() const
102 {
103         return "Console";
104 }
105
106 const char *eRCConsole::getKeyDescription(const eRCKey &key) const
107 {
108         return 0;
109 }
110
111 int eRCConsole::getKeyCompatibleCode(const eRCKey &key) const
112 {
113         return key.code;
114 }
115
116 class eRCConsoleInit
117 {
118         eRCConsoleDriver driver;
119         eRCConsole device;
120 public:
121         eRCConsoleInit(): driver("/dev/vc/0"), device(&driver)
122         {
123         }
124 };
125
126 eAutoInitP0<eRCConsoleInit> init_rcconsole(eAutoInitNumbers::rc+1, "Console RC Driver");