be7b68cef3484e271741cc8e3e69d3cc3a457104
[openblackhole/openblackhole-enigma2.git] / lib / python / Components / InputDevice.py
1 from config import config, ConfigSlider, ConfigSubsection, ConfigYesNo, ConfigText, ConfigInteger
2 from Tools.Directories import pathExists
3 from SystemInfo import SystemInfo
4 from fcntl import ioctl
5 import os
6 import struct
7
8 # asm-generic/ioctl.h
9 IOC_NRBITS = 8L
10 IOC_TYPEBITS = 8L
11 IOC_SIZEBITS = 13L
12 IOC_DIRBITS = 3L
13
14 IOC_NRSHIFT = 0L
15 IOC_TYPESHIFT = IOC_NRSHIFT+IOC_NRBITS
16 IOC_SIZESHIFT = IOC_TYPESHIFT+IOC_TYPEBITS
17 IOC_DIRSHIFT = IOC_SIZESHIFT+IOC_SIZEBITS
18
19 IOC_READ = 2L
20
21 def EVIOCGNAME(length):
22         return (IOC_READ<<IOC_DIRSHIFT)|(length<<IOC_SIZESHIFT)|(0x45<<IOC_TYPESHIFT)|(0x06<<IOC_NRSHIFT)
23
24
25 class inputDevices:
26
27         def __init__(self):
28                 self.Devices = {}
29                 self.currentDevice = ""
30                 self.getInputDevices()
31
32         def getInputDevices(self):
33                 devices = os.listdir("/dev/input/")
34
35                 for evdev in devices:
36                         try:
37                                 buffer = "\0"*512
38                                 self.fd = os.open("/dev/input/" + evdev, os.O_RDWR | os.O_NONBLOCK)
39                                 self.name = ioctl(self.fd, EVIOCGNAME(256), buffer)
40                                 self.name = self.name[:self.name.find("\0")]
41                                 os.close(self.fd)
42                         except (IOError,OSError), err:
43                                 print '[iInputDevices] getInputDevices ' + evdev + ' <ERROR: ioctl(EVIOCGNAME): ' + str(err) + ' >'
44                                 self.name = None
45
46                         if self.name:
47                                 self.Devices[evdev] = {'name': self.name, 'type': self.getInputDeviceType(self.name),'enabled': False, 'configuredName': None }
48
49
50         def getInputDeviceType(self,name):
51                 if "remote control" in name:
52                         return "remote"
53                 elif "keyboard" in name:
54                         return "keyboard"
55                 elif "mouse" in name:
56                         return "mouse"
57                 else:
58                         print "Unknown device type:",name
59                         return None
60
61         def getDeviceName(self, x):
62                 if x in self.Devices.keys():
63                         return self.Devices[x].get("name", x)
64                 else:
65                         return "Unknown device name"
66
67         def getDeviceList(self):
68                 return sorted(self.Devices.iterkeys())
69
70         def setDeviceAttribute(self, device, attribute, value):
71                 #print "[iInputDevices] setting for device", device, "attribute", attribute, " to value", value
72                 if self.Devices.has_key(device):
73                         self.Devices[device][attribute] = value
74
75         def getDeviceAttribute(self, device, attribute):
76                 if self.Devices.has_key(device):
77                         if self.Devices[device].has_key(attribute):
78                                 return self.Devices[device][attribute]
79                 return None
80
81         def setEnabled(self, device, value):
82                 oldval = self.getDeviceAttribute(device, 'enabled')
83                 #print "[iInputDevices] setEnabled for device %s to %s from %s" % (device,value,oldval)
84                 self.setDeviceAttribute(device, 'enabled', value)
85                 if oldval is True and value is False:
86                         self.setDefaults(device)
87
88         def setName(self, device, value):
89                 #print "[iInputDevices] setName for device %s to %s" % (device,value)
90                 self.setDeviceAttribute(device, 'configuredName', value)
91
92         #struct input_event {
93         #       struct timeval time;    -> ignored
94         #       __u16 type;             -> EV_REP (0x14)
95         #       __u16 code;             -> REP_DELAY (0x00) or REP_PERIOD (0x01)
96         #       __s32 value;            -> DEFAULTS: 700(REP_DELAY) or 100(REP_PERIOD)
97         #}; -> size = 16
98
99         def setDefaults(self, device):
100                 print "[iInputDevices] setDefaults for device %s" % (device)
101                 self.setDeviceAttribute(device, 'configuredName', None)
102                 event_repeat = struct.pack('iihhi', 0, 0, 0x14, 0x01, 100)
103                 event_delay = struct.pack('iihhi', 0, 0, 0x14, 0x00, 700)
104                 fd = os.open("/dev/input/" + device, os.O_RDWR)
105                 os.write(fd, event_repeat)
106                 os.write(fd, event_delay)
107                 os.close(fd)
108
109         def setRepeat(self, device, value): #REP_PERIOD
110                 if self.getDeviceAttribute(device, 'enabled') == True:
111                         print "[iInputDevices] setRepeat for device %s to %d ms" % (device,value)
112                         event = struct.pack('iihhi', 0, 0, 0x14, 0x01, int(value))
113                         fd = os.open("/dev/input/" + device, os.O_RDWR)
114                         os.write(fd, event)
115                         os.close(fd)
116
117         def setDelay(self, device, value): #REP_DELAY
118                 if self.getDeviceAttribute(device, 'enabled') == True:
119                         print "[iInputDevices] setDelay for device %s to %d ms" % (device,value)
120                         event = struct.pack('iihhi', 0, 0, 0x14, 0x00, int(value))
121                         fd = os.open("/dev/input/" + device, os.O_RDWR)
122                         os.write(fd, event)
123                         os.close(fd)
124
125
126 class InitInputDevices:
127
128         def __init__(self):
129                 self.currentDevice = ""
130                 self.createConfig()
131
132         def createConfig(self, *args):
133                 config.inputDevices = ConfigSubsection()
134                 for device in sorted(iInputDevices.Devices.iterkeys()):
135                         self.currentDevice = device
136                         #print "[InitInputDevices] -> creating config entry for device: %s -> %s  " % (self.currentDevice, iInputDevices.Devices[device]["name"])
137                         self.setupConfigEntries(self.currentDevice)
138                         self.currentDevice = ""
139
140         def inputDevicesEnabledChanged(self,configElement):
141                 if self.currentDevice != "" and iInputDevices.currentDevice == "":
142                         iInputDevices.setEnabled(self.currentDevice, configElement.value)
143                 elif iInputDevices.currentDevice != "":
144                         iInputDevices.setEnabled(iInputDevices.currentDevice, configElement.value)
145
146         def inputDevicesNameChanged(self,configElement):
147                 if self.currentDevice != "" and iInputDevices.currentDevice == "":
148                         iInputDevices.setName(self.currentDevice, configElement.value)
149                         if configElement.value != "":
150                                 devname = iInputDevices.getDeviceAttribute(self.currentDevice, 'name')
151                                 if devname != configElement.value:
152                                         cmd = "config.inputDevices." + self.currentDevice + ".enabled.value = False"
153                                         exec (cmd)
154                                         cmd = "config.inputDevices." + self.currentDevice + ".enabled.save()"
155                                         exec (cmd)
156                 elif iInputDevices.currentDevice != "":
157                         iInputDevices.setName(iInputDevices.currentDevice, configElement.value)
158
159         def inputDevicesRepeatChanged(self,configElement):
160                 if self.currentDevice != "" and iInputDevices.currentDevice == "":
161                         iInputDevices.setRepeat(self.currentDevice, configElement.value)
162                 elif iInputDevices.currentDevice != "":
163                         iInputDevices.setRepeat(iInputDevices.currentDevice, configElement.value)
164
165         def inputDevicesDelayChanged(self,configElement):
166                 if self.currentDevice != "" and iInputDevices.currentDevice == "":
167                         iInputDevices.setDelay(self.currentDevice, configElement.value)
168                 elif iInputDevices.currentDevice != "":
169                         iInputDevices.setDelay(iInputDevices.currentDevice, configElement.value)
170
171         def setupConfigEntries(self,device):
172                 cmd = "config.inputDevices." + device + " = ConfigSubsection()"
173                 exec (cmd)
174                 cmd = "config.inputDevices." + device + ".enabled = ConfigYesNo(default = False)"
175                 exec (cmd)
176                 cmd = "config.inputDevices." + device + ".enabled.addNotifier(self.inputDevicesEnabledChanged,config.inputDevices." + device + ".enabled)"
177                 exec (cmd)
178                 cmd = "config.inputDevices." + device + '.name = ConfigText(default="")'
179                 exec (cmd)
180                 cmd = "config.inputDevices." + device + ".name.addNotifier(self.inputDevicesNameChanged,config.inputDevices." + device + ".name)"
181                 exec (cmd)
182                 cmd = "config.inputDevices." + device + ".repeat = ConfigSlider(default=100, increment = 10, limits=(0, 500))"
183                 exec (cmd)
184                 cmd = "config.inputDevices." + device + ".repeat.addNotifier(self.inputDevicesRepeatChanged,config.inputDevices." + device + ".repeat)"
185                 exec (cmd)
186                 cmd = "config.inputDevices." + device + ".delay = ConfigSlider(default=700, increment = 100, limits=(0, 5000))"
187                 exec (cmd)
188                 cmd = "config.inputDevices." + device + ".delay.addNotifier(self.inputDevicesDelayChanged,config.inputDevices." + device + ".delay)"
189                 exec (cmd)
190
191
192 iInputDevices = inputDevices()
193
194
195 config.plugins.remotecontroltype = ConfigSubsection()
196 config.plugins.remotecontroltype.rctype = ConfigInteger(default = 0)
197
198 class RcTypeControl():
199         def __init__(self):
200                 if SystemInfo["RcTypeChangable"] and pathExists('/proc/stb/info/boxtype'):
201                         self.isSupported = True
202
203                         fd = open('/proc/stb/info/boxtype', 'r')
204                         self.boxType = fd.read()
205                         fd.close()
206
207                         if config.plugins.remotecontroltype.rctype.value != 0:
208                                 self.writeRcType(config.plugins.remotecontroltype.rctype.value)
209                 else:
210                         self.isSupported = False
211
212         def multipleRcSupported(self):
213                 return self.isSupported
214
215         def getBoxType(self):
216                 return self.boxType
217
218         def writeRcType(self, rctype):
219                 fd = open('/proc/stb/ir/rc/type', 'w')
220                 fd.write('%d' % (rctype))
221                 fd.close()
222
223 iRcTypeControl = RcTypeControl()