From fc2f5b2cd655f1391f2abda1b39e37cdec98a951 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Fri, 17 Oct 2003 15:35:43 +0000 Subject: Initial revision --- lib/driver/rc.cpp | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 lib/driver/rc.cpp (limited to 'lib/driver/rc.cpp') diff --git a/lib/driver/rc.cpp b/lib/driver/rc.cpp new file mode 100644 index 00000000..790c5f6c --- /dev/null +++ b/lib/driver/rc.cpp @@ -0,0 +1,245 @@ +#include + +#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. + */ + +int eRCDevice::getKeyCompatibleCode(const eRCKey &) const +{ + return -1; +} + +eRCDevice::eRCDevice(eString 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=new eSocketNotifier(eApp, handle, eSocketNotifier::Read); + CONNECT(sn->activated, eRCShortDriver::keyPressed); + eRCInput::getInstance()->setFile(handle); + } +} + +eRCShortDriver::~eRCShortDriver() +{ + if (handle>=0) + close(handle); + if (sn) + delete sn; +} + +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((int)&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=new eSocketNotifier(eApp, handle, eSocketNotifier::Read); + CONNECT(sn->activated, eRCInputEventDriver::keyPressed); + eRCInput::getInstance()->setFile(handle); + } +} + +eString eRCInputEventDriver::getDeviceName() +{ + char name[128]=""; + if (handle >= 0) + ::ioctl(handle, EVIOCGNAME(128), name); + return name; +} + +eRCInputEventDriver::~eRCInputEventDriver() +{ + if (handle>=0) + close(handle); + if (sn) + delete sn; +} + +eRCConfig::eRCConfig() +{ + reload(); +} + +eRCConfig::~eRCConfig() +{ + save(); +} + +void eRCConfig::set( int delay, int repeat ) +{ + rdelay = delay; + rrate = repeat; +} + +void eRCConfig::reload() +{ + rdelay=500; + rrate=100; + if ( eConfig::getInstance()->getKey("/ezap/rc/repeatRate", rrate) ) + save(); + eConfig::getInstance()->getKey("/ezap/rc/repeatDelay", rdelay); +} + +void eRCConfig::save() +{ + eConfig::getInstance()->setKey("/ezap/rc/repeatRate", rrate); + eConfig::getInstance()->setKey("/ezap/rc/repeatDelay", rdelay); +} + +eRCInput *eRCInput::instance; + +eRCInput::eRCInput() +{ + ASSERT( !instance); + instance=this; + handle = -1; + locked = 0; +} + +eRCInput::~eRCInput() +{ +} + +void eRCInput::close() +{ +} + +bool eRCInput::open() +{ + return false; +} + +int eRCInput::lock() +{ + locked=1; + return handle; +} + +void eRCInput::unlock() +{ + if (locked) + locked=0; +} + +void eRCInput::setFile(int newh) +{ + handle=newh; +} + +void eRCInput::addDevice(const eString &id, eRCDevice *dev) +{ + devices.insert(std::pair(id, dev)); +} + +void eRCInput::removeDevice(const eString &id) +{ + devices.erase(id); +} + +eRCDevice *eRCInput::getDevice(const eString &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"); -- cgit v1.2.3