bug #238
[enigma2.git] / lib / driver / rc.h
1 #ifndef __rc_h
2 #define __rc_h
3
4 #include <list>
5 #include <map>
6
7 #include <lib/base/ebase.h>
8 #include <libsig_comp.h>
9 #include <string>
10
11 class eRCInput;
12 class eRCDriver;
13 class eRCKey;
14
15 #ifndef SWIG
16
17 /**
18  * \brief A remote control.
19  *
20  * Handles one remote control. Gets codes from a \ref eRCDriver. Produces events in \ref eRCInput.
21  */
22 class eRCDevice: public Object
23 {
24 protected:
25         eRCInput *input;
26         eRCDriver *driver;
27         std::string id;
28 public:
29         /**
30          * \brief Constructs a new remote control.
31          *
32          * \param id The identifier of the RC, for use in settings.
33          * \param input The \ref eRCDriver where this remote gets its codes from.
34          */
35         eRCDevice(std::string id, eRCDriver *input);
36         ~eRCDevice();
37         /**
38          * \brief Handles a device specific code.
39          *
40          * Generates events in \ref eRCInput. code is highly device- and driver dependant.
41          * For Example, it might be 16bit codes with one bit make/break or special codes
42          * for repeat.
43          */
44         virtual void handleCode(long code)=0;
45         /**
46          * \brief Get user readable description.
47          * \result The description.
48          */
49         virtual const char *getDescription() const=0;
50         const std::string getIdentifier() const { return id; }
51         /**
52          * \brief Get a description for a specific key.
53          * \param key The key to get the description for.
54          * \result User readable description of given key.
55          */
56 };
57
58 /**
59  * Receives codes from one or more remote controls.
60  */
61 class eRCDriver: public Object
62 {
63 protected:
64         std::list<eRCDevice*> listeners;
65         eRCInput *input;
66         int enabled;
67 public:
68         /**
69          * \brief Constructs a driver.
70          *
71          * \param input The RCInput to bind this driver to.
72          */
73         eRCDriver(eRCInput *input);
74         /**
75          * \brief Get pointer to key-consumer.
76          */
77         eRCInput *getInput() const { return input; }
78         /**
79          * \brief Adds a code lister
80          */
81         void addCodeListener(eRCDevice *dev)
82         {
83                 listeners.push_back(dev);
84         }
85         void removeCodeListener(eRCDevice *dev)
86         {
87                 listeners.remove(dev);
88         }
89         ~eRCDriver();
90         
91         void enable(int en) { enabled=en; }
92 };
93
94 class eRCShortDriver: public eRCDriver
95 {
96 protected:
97         int handle;
98         ePtr<eSocketNotifier> sn;
99         void keyPressed(int);
100 public:
101         eRCShortDriver(const char *filename);
102         ~eRCShortDriver();
103 };
104
105 class eRCInputEventDriver: public eRCDriver
106 {
107 protected:
108         int handle;
109         ePtr<eSocketNotifier> sn;
110         void keyPressed(int);
111 public:
112         std::string getDeviceName();
113         eRCInputEventDriver(const char *filename);
114         ~eRCInputEventDriver();
115 };
116
117 class eRCKey
118 {
119 public:
120         eRCDevice *producer;
121         int code, flags;
122
123         eRCKey(eRCDevice *producer, int code, int flags): 
124                 producer(producer), code(code), flags(flags)
125         {
126         }
127         enum
128         {
129                         /* there are not really flags.. */
130                 flagMake=0,
131                 flagBreak=1,
132                 flagRepeat=2,
133                 flagLong=3,
134                         /* but this is. */
135                 flagAscii=4,
136         };
137
138         bool operator<(const eRCKey &r) const
139         {
140                 if (r.producer == producer)
141                 {
142                         if (r.code == code)
143                         {
144                                 if (r.flags < flags)
145                                         return 1;
146                                 else
147                                         return 0;
148                         } else if (r.code < code)
149                                 return 1;
150                         else
151                                 return 0;
152                 } else if (r.producer < producer)
153                         return 1;
154                 else
155                         return 0;
156         }
157 };
158
159 class eRCConfig
160 {
161 public:
162         eRCConfig();
163         ~eRCConfig();
164         void reload();
165         void save();
166         void set(int delay, int repeat);
167         int rdelay, // keypress delay after first keypress to begin of repeat (in ms)
168                 rrate;          // repeat rate (in ms)
169 };
170
171 #endif
172
173 class eRCInput: public Object
174 {
175         int locked;     
176         int handle;
177         static eRCInput *instance;
178         int keyboardMode;
179 #ifdef SWIG
180         eRCInput();
181         ~eRCInput();
182 public:
183 #else
184 public:
185         struct lstr
186         {
187                 bool operator()(const std::string &a, const std::string &b) const
188                 {
189                         return a<b;
190                 }
191         };
192 protected:
193         std::map<std::string,eRCDevice*,lstr> devices;
194 public:
195         Signal1<void, const eRCKey&> keyEvent;
196         eRCInput();
197         ~eRCInput();
198
199         void close();
200         bool open();
201
202         void setFile(int handle);
203
204         /* This is only relevant for "keyboard"-styled input devices,
205            i.e. not plain remote controls. It's up to the input device
206            driver to decide wheter an input device is a keyboard or
207            not.
208            
209            kmNone will ignore all Ascii Characters sent from the 
210            keyboard/console driver, only give normal keycodes to the
211            application.
212            
213            kmAscii will filter out all keys which produce ascii characters,
214            and send them instead. Note that Modifiers like shift will still
215            be send. Control keys which produce escape codes are send using
216            normal keycodes. 
217            
218            kmAll will ignore all keycodes, and send everything as ascii,
219            including escape codes. Pretty much useless, since you should
220            lock the console and pass this as the console fd for making the
221            tc* stuff working.
222         */
223
224         void keyPressed(const eRCKey &key)
225         {
226                 /*emit*/ keyEvent(key);
227         }
228         
229         void addDevice(const std::string &id, eRCDevice *dev);
230         void removeDevice(const std::string &id);
231         eRCDevice *getDevice(const std::string &id);
232         std::map<std::string,eRCDevice*,lstr> &getDevices();
233
234         eRCConfig config;
235 #endif
236         enum { kmNone, kmAscii, kmAll };
237         void setKeyboardMode(int mode) { keyboardMode = mode; }
238         int  getKeyboardMode() { return keyboardMode; }
239         static eRCInput *getInstance() { return instance; }
240         int lock();
241         void unlock();
242         int islocked() { return locked; }
243 };
244
245 #endif