#include #include #include #include #include #include #include #include #include /* * note on the enigma input layer: * the enigma input layer (rc*) supports n different devices which * all have completely different interfaces, mapped down to 32bit + * make/break/release codes mapped down (via xml files) to "actions". * this was necessary to support multiple remote controls with proprietary * interfaces. now everybody is using input devices, and thus adding * another input layer seems to be a bit overkill. BUT: * image a remote control with two hundred buttons. each and every function * in enigma can be bound to a button. no need to use them twice. * for example, you would have KEY_MENU assigned to a menu for setup etc., * but no audio and video settings, since you have special keys for that, * and you don't want to display a big menu with entries that are available * with another single key. * then image a remote control with ten buttons. do you really want to waste * KEY_MENU for a simple menu? you need the audio/video settings there too. * take this just as a (bad) example. another (better) example might be front- * button-keys. usually you have KEY_UP, KEY_DOWN, KEY_POWER. you don't want * them to behave like the remote-control-KEY_UP, KEY_DOWN and KEY_POWER, * don't you? * so here we can map same keys of different input devices to different * actions. have fun. */ eRCDevice::eRCDevice(std::string id, eRCDriver *driver): driver(driver), id(id) { input=driver->getInput(); driver->addCodeListener(this); eRCInput::getInstance()->addDevice(id, this); } eRCDevice::~eRCDevice() { driver->removeCodeListener(this); eRCInput::getInstance()->removeDevice(id.c_str()); } eRCDriver::eRCDriver(eRCInput *input): input(input), enabled(1) { } eRCDriver::~eRCDriver() { for (std::list::iterator i=listeners.begin(); i!=listeners.end(); ++i) delete *i; } void eRCShortDriver::keyPressed(int) { __u16 rccode; while (1) { if (read(handle, &rccode, 2)!=2) break; if (enabled && !input->islocked()) for (std::list::iterator i(listeners.begin()); i!=listeners.end(); ++i) (*i)->handleCode(rccode); } } eRCShortDriver::eRCShortDriver(const char *filename): eRCDriver(eRCInput::getInstance()) { handle=open(filename, O_RDONLY|O_NONBLOCK); if (handle<0) { eDebug("failed to open %s", filename); sn=0; } else { sn=eSocketNotifier::create(eApp, handle, eSocketNotifier::Read); CONNECT(sn->activated, eRCShortDriver::keyPressed); } } eRCShortDriver::~eRCShortDriver() { if (handle>=0) close(handle); } void eRCInputEventDriver::keyPressed(int) { struct input_event ev; while (1) { if (read(handle, &ev, sizeof(struct input_event))!=sizeof(struct input_event)) break; if (enabled && !input->islocked()) for (std::list::iterator i(listeners.begin()); i!=listeners.end(); ++i) (*i)->handleCode((long)&ev); } } eRCInputEventDriver::eRCInputEventDriver(const char *filename): eRCDriver(eRCInput::getInstance()) { handle=open(filename, O_RDONLY|O_NONBLOCK); if (handle<0) { eDebug("failed to open %s", filename); sn=0; } else { sn=eSocketNotifier::create(eApp, handle, eSocketNotifier::Read); CONNECT(sn->activated, eRCInputEventDriver::keyPressed); } } std::string eRCInputEventDriver::getDeviceName() { char name[128]=""; if (handle >= 0) ::ioctl(handle, EVIOCGNAME(128), name); return name; } void eRCInputEventDriver::setExclusive(bool b) { if (handle >= 0) { int grab = b; if (::ioctl(handle, EVIOCGRAB, grab) < 0) perror("EVIOCGRAB"); } } eRCInputEventDriver::~eRCInputEventDriver() { if (handle>=0) close(handle); } eRCConfig::eRCConfig() { reload(); } eRCConfig::~eRCConfig() { save(); } void eRCConfig::set( int delay, int repeat ) { rdelay = delay; rrate = repeat; } void eRCConfig::reload() { rdelay=500; rrate=100; } void eRCConfig::save() { } eRCInput *eRCInput::instance; eRCInput::eRCInput() { ASSERT( !instance); instance=this; locked = 0; keyboardMode = kmNone; } eRCInput::~eRCInput() { } void eRCInput::close() { } bool eRCInput::open() { return false; } void eRCInput::lock() { locked=1; for (std::map::iterator i=devices.begin(); i != devices.end(); ++i) i->second->setExclusive(false); } void eRCInput::unlock() { locked=0; for (std::map::iterator i=devices.begin(); i != devices.end(); ++i) i->second->setExclusive(true); } void eRCInput::addDevice(const std::string &id, eRCDevice *dev) { devices.insert(std::pair(id, dev)); } void eRCInput::removeDevice(const std::string &id) { devices.erase(id); } eRCDevice *eRCInput::getDevice(const std::string &id) { std::map::iterator i=devices.find(id); if (i == devices.end()) { eDebug("failed, possible choices are:"); for (std::map::iterator i=devices.begin(); i != devices.end(); ++i) eDebug("%s", i->first.c_str()); return 0; } return i->second; } std::map &eRCInput::getDevices() { return devices; } eAutoInitP0 init_rcinput(eAutoInitNumbers::rc, "RC Input layer");