Support Uno4k/Ultimo4k
[vuplus_openvuplus_3.0] / meta-openvuplus / recipes-vuplus / enigma2 / enigma2 / enigma2_vuplus_inputhotplug.patch
1 This patch received help from openpli E2, thank to "Mike Looijmans <milo-software@users.sourceforge.net>"
2 diff --git a/lib/driver/Makefile.am b/lib/driver/Makefile.am
3 index a781229..28c7c55 100755
4 --- a/lib/driver/Makefile.am
5 +++ b/lib/driver/Makefile.am
6 @@ -30,6 +30,7 @@ driverinclude_HEADERS = \
7         rcdbox.h \
8         rcdreambox2.h \
9         rcinput.h \
10 +       rcinput_swig.h \
11         rfmod.h \
12         hdmi_cec.h
13  
14 diff --git a/lib/driver/rcinput.cpp b/lib/driver/rcinput.cpp
15 old mode 100644
16 new mode 100755
17 index 64757c5..84792f5
18 --- a/lib/driver/rcinput.cpp
19 +++ b/lib/driver/rcinput.cpp
20 @@ -180,8 +180,26 @@ const char *eRCDeviceInputDev::getDescription() const
21  
22  class eInputDeviceInit
23  {
24 -       ePtrList<eRCInputEventDriver> m_drivers;
25 -       ePtrList<eRCDeviceInputDev> m_devices;
26 +       struct element
27 +       {
28 +               public:
29 +                       char *m_filename;
30 +                       eRCInputEventDriver *m_driver;
31 +                       eRCDeviceInputDev *m_device;
32 +
33 +                       element(const char *filename, eRCInputEventDriver *driver, eRCDeviceInputDev *device):
34 +                               m_filename(strdup(filename)), m_driver(driver), m_device(device)
35 +                       {
36 +                       }
37 +                       ~element()
38 +                       {
39 +                               delete m_device;
40 +                               delete m_driver;
41 +                               free(m_filename);
42 +                       }
43 +       };
44 +       typedef std::vector<element*> itemlist;
45 +       itemlist m_items;
46  public:
47         eInputDeviceInit()
48         {
49 @@ -193,9 +211,8 @@ public:
50                         sprintf(filename, "/dev/input/event%d", i);
51                         if (stat(filename, &s))
52                                 break;
53 -                       eRCInputEventDriver *p;
54 -                       m_drivers.push_back(p = new eRCInputEventDriver(filename));
55 -                       m_devices.push_back(new eRCDeviceInputDev(p));
56 +
57 +                       add(filename);
58                         ++i;
59                 }
60                 eDebug("Found %d input devices!", i);
61 @@ -203,14 +220,60 @@ public:
62         
63         ~eInputDeviceInit()
64         {
65 -               while (m_drivers.size())
66 +               for (itemlist::iterator it = m_items.begin(); it != m_items.end(); ++it)
67                 {
68 -                       delete m_devices.back();
69 -                       m_devices.pop_back();
70 -                       delete m_drivers.back();
71 -                       m_drivers.pop_back();
72 +                       delete (*it);
73                 }
74         }
75 +
76 +       void add(const char* filename)
77 +       {
78 +               bool no_exist = false;
79 +               for (itemlist::iterator it = m_items.begin(); it != m_items.end(); ++it)
80 +               {
81 +                       if (strcmp((*it)->m_filename, filename) == 0)
82 +                       {
83 +                               eDebug("[eInputDeviceInit] %s is already added.", filename);
84 +                               no_exist = true;
85 +                               break;
86 +                       }
87 +               }
88 +
89 +               if (!no_exist)
90 +               {
91 +                       eDebug("[eInputDeviceInit] adding device %s", filename);
92 +                       eRCInputEventDriver *driver = new eRCInputEventDriver(filename);
93 +                       eRCDeviceInputDev *device = new eRCDeviceInputDev(driver);
94 +                       m_items.push_back(new element(filename, driver, device));
95 +               }
96 +       }
97 +
98 +       void remove(const char* filename)
99 +       {
100 +               for (itemlist::iterator it = m_items.begin(); it != m_items.end(); ++it)
101 +               {
102 +                       if (strcmp((*it)->m_filename, filename) == 0)
103 +                       {
104 +                               eDebug("[eInputDeviceInit] remove device %s", filename);
105 +
106 +                               delete *it;
107 +                               m_items.erase(it);
108 +                               return;
109 +                       }
110 +               }
111 +               eDebug("[eInputDeviceInit] Remove '%s', not found", filename);
112 +       }
113  };
114  
115  eAutoInitP0<eInputDeviceInit> init_rcinputdev(eAutoInitNumbers::rc+1, "input device driver");
116 +
117 +void addInputDevice(const char* filename)
118 +{
119 +       init_rcinputdev->add(filename);
120 +}
121 +
122 +void removeInputDevice(const char* filename)
123 +{
124 +       init_rcinputdev->remove(filename);
125 +}
126 +
127 diff --git a/lib/driver/rcinput_swig.h b/lib/driver/rcinput_swig.h
128 new file mode 100644
129 index 0000000..f640f58
130 --- /dev/null
131 +++ b/lib/driver/rcinput_swig.h
132 @@ -0,0 +1,3 @@
133 +void addInputDevice(const char* filename);
134 +void removeInputDevice(const char* filename);
135 +
136 diff --git a/lib/python/Components/InputHotplug.py b/lib/python/Components/InputHotplug.py
137 new file mode 100644
138 index 0000000..267be03
139 --- /dev/null
140 +++ b/lib/python/Components/InputHotplug.py
141 @@ -0,0 +1,39 @@
142 +import Netlink
143 +import enigma
144 +import os
145 +
146 +class NetlinkReader():
147 +       def __init__(self):
148 +               from twisted.internet import reactor
149 +               self.nls = Netlink.NetlinkSocket()
150 +               reactor.addReader(self)
151 +
152 +       def fileno(self):
153 +               return self.nls.fileno()
154 +       def doRead(self):
155 +               for event in self.nls.parse():
156 +                       try:
157 +                               subsystem = event['SUBSYSTEM']
158 +                               if subsystem == 'input':
159 +                                       devname = event['DEVNAME']
160 +                                       action = event['ACTION']
161 +                                       if action == 'add':
162 +                                               print "New input device detected:", devname
163 +                                               enigma.addInputDevice(os.path.join('/dev', devname));
164 +                                       elif action == 'remove':
165 +                                               print "Removed input device:", devname
166 +                                               enigma.removeInputDevice(os.path.join('/dev', devname));
167 +                               elif subsystem == 'net':
168 +                                       from Network import iNetwork
169 +                                       iNetwork.hotplug(event)
170 +                       except KeyError:
171 +                               # Ignore "not found"
172 +                               pass
173 +       def connectionLost(self, failure):
174 +               # Ignore...
175 +               print "connectionLost?", failure
176 +               self.nls.close()
177 +       def logPrefix(self):
178 +               return 'NetlinkReader'
179 +
180 +reader = NetlinkReader()
181 diff --git a/lib/python/Components/Makefile.am b/lib/python/Components/Makefile.am
182 index b5ef068..748caf5 100755
183 --- a/lib/python/Components/Makefile.am
184 +++ b/lib/python/Components/Makefile.am
185 @@ -19,4 +19,4 @@ install_PYTHON = \
186         Element.py Playlist.py ParentalControl.py ParentalControlList.py \
187         Ipkg.py SelectionList.py Scanner.py SystemInfo.py DreamInfoHandler.py \
188         Task.py language_cache.py Console.py ResourceManager.py TuneTest.py \
189 -       Keyboard.py Sensors.py FanControl.py
190 +       Keyboard.py Sensors.py FanControl.py InputHotplug.py Netlink.py
191 diff --git a/lib/python/Components/Netlink.py b/lib/python/Components/Netlink.py
192 new file mode 100644
193 index 0000000..026f420
194 --- /dev/null
195 +++ b/lib/python/Components/Netlink.py
196 @@ -0,0 +1,33 @@
197 +# Listen to hotplug events. Can be used to listen for hotplug events and
198 +# similar things, like network connections being (un)plugged.
199 +import os
200 +import socket
201 +
202 +class NetlinkSocket(socket.socket):
203 +       def __init__(self):
204 +               NETLINK_KOBJECT_UEVENT = 15 # hasn't landed in socket yet, see linux/netlink.h
205 +               socket.socket.__init__(self, socket.AF_NETLINK, socket.SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)
206 +               self.bind((os.getpid(), -1))
207 +
208 +       def parse(self):
209 +               data = self.recv(512)
210 +               event = {}
211 +               for item in data.split('\x00'):
212 +                       if not item:
213 +                               # terminator
214 +                               yield event
215 +                               event = {}
216 +                       else:
217 +                               try:
218 +                                       k,v = item.split('=', 1)
219 +                                       event[k] = v
220 +                               except:
221 +                                       event[None] = item
222 +
223 +# Quick unit test (you can run this on any Linux machine)
224 +if __name__ == '__main__':
225 +       nls = NetlinkSocket()
226 +       print "socket no:", nls.fileno()
227 +       while 1:
228 +               for item in nls.parse():
229 +                       print repr(item)
230 diff --git a/lib/python/Components/Network.py b/lib/python/Components/Network.py
231 index c39d1ba..2390bac 100755
232 --- a/lib/python/Components/Network.py
233 +++ b/lib/python/Components/Network.py
234 @@ -693,6 +693,21 @@ class Network:
235                         for p in plugins.getPlugins(PluginDescriptor.WHERE_NETWORKCONFIG_READ):
236                                 p(reason=self.config_ready)
237  
238 +       def hotplug(self, event):
239 +               interface = event['INTERFACE']
240 +               if self.isBlacklisted(interface):
241 +                       return
242 +               action = event['ACTION']
243 +               if action == "add":
244 +                       print "[Network] Add new interface:", interface
245 +                       self.getAddrInet(interface, None)
246 +               elif action == "remove":
247 +                       print "[Network] Removed interface:", interface
248 +                       try:
249 +                               del self.ifaces[interface]
250 +                       except KeyError:
251 +                               pass
252 +
253         def getInterfacesNameserverList(self, iface):
254                 result = []
255                 nameservers = self.getAdapterAttribute(iface, "dns-nameservers")
256 diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i
257 index e9a8161..dc49082 100755
258 --- a/lib/python/enigma_python.i
259 +++ b/lib/python/enigma_python.i
260 @@ -44,6 +44,7 @@ is usually caused by not marking PSignals as immutable.
261  #include <lib/base/nconfig.h>
262  #include <lib/base/message.h>
263  #include <lib/driver/rc.h>
264 +#include <lib/driver/rcinput_swig.h>
265  #include <lib/service/event.h>
266  #include <lib/service/iservice.h>
267  #include <lib/service/service.h>
268 @@ -169,6 +170,7 @@ typedef long time_t;
269  %include <lib/base/etpm.h>
270  %include <lib/base/nconfig.h>
271  %include <lib/driver/rc.h>
272 +%include <lib/driver/rcinput_swig.h>
273  %include <lib/gdi/fb.h>
274  %include <lib/gdi/font.h>
275  %include <lib/gdi/gpixmap.h>
276 diff --git a/mytest.py b/mytest.py
277 index 99695e0..1daf20b 100755
278 --- a/mytest.py
279 +++ b/mytest.py
280 @@ -544,6 +544,7 @@ skin.loadSkinData(getDesktop(0))
281  profile("InputDevice")
282  import Components.InputDevice
283  Components.InputDevice.InitInputDevices()
284 +import Components.InputHotplug
285  
286  profile("AVSwitch")
287  import Components.AVSwitch