// Steering Wheel Remote // // Douglas Thrift // // $Id$ #include #include #include #include #include #include #include #include #include #include struct Buttons { // XXX: this is probably little endian! enum Mask { None = 0xfb00, PlayPause = 0x0101, Previous = 0x1010, Next = 0x0808, VolumeDown = 0x0c04, VolumeUp = 0x0202 }; private: uint16_t buttons; public: inline bool Pressed(Mask mask) const { return ((buttons ^ None) & mask) == mask; } inline operator uint16_t() const { return buttons; } friend std::istream &operator>>(std::istream &, Buttons &); }; inline std::istream &operator>>(std::istream &input, Buttons &buttons) { if (!input.ignore(3)) return input; if (!input.read(reinterpret_cast(&buttons.buttons), sizeof (buttons.buttons))) return input; return input.ignore(3); } int Usage(const std::string &program) { std::cout << _B("Usage: ") << program << _B(" [-debug] [-device=device]") << std::endl; return 1; } int main(int argc, char *argv[]) { bool debug(false); std::string device; { Pcre::RegEx devicePath(_B("^-device=(/.+)$")); Pcre::RegEx deviceNumber(_B("^-device=([0-9]+)$")); Pcre::RegEx deviceName(_B("^-device=(.+)$")); _forall (int, index, 1, argc) if (argv[index] == _B("-debug")) debug = true; else if (Pcre::RegEx::Match match = devicePath(argv[index])) device = match[1]; else if (Pcre::RegEx::Match match = deviceNumber(argv[index])) device = _B("/dev/uhid") + match[1]; else if (Pcre::RegEx::Match match = deviceName(argv[index])) device = _B("/dev/") + match[1]; else return Usage(argv[0]); } if (device.empty()) return Usage(argv[0]); // if (!debug) // Posix::CheckError(::daemon(0, 0)); ext::ifdstream uhid(Posix::CheckError(::open(device.c_str(), O_RDONLY))); Buttons buttons; while (uhid >> buttons) switch (buttons) { case Buttons::None: break; default: if (buttons.Pressed(Buttons::PlayPause)) std::cout << _B("PlayPause "); if (buttons.Pressed(Buttons::Previous)) std::cout << _B("Previous "); if (buttons.Pressed(Buttons::Next)) std::cout << _B("Next "); if (buttons.Pressed(Buttons::VolumeDown)) std::cout << _B("VolumeDown "); if (buttons.Pressed(Buttons::VolumeUp)) std::cout << _B("VolumeUp"); std::cout << std::endl; } return 0; }