# HG changeset patch # User František Kučera # Date 1616958122 -7200 # Node ID 2c4e533e9e337df091ff7c80a9ffc2dd6764d8f2 # Parent 6851c08c62606b8d79f6d1fdebd163ab4ed31d63 first working version diff -r 6851c08c6260 -r 2c4e533e9e33 src/X11Handler.h --- a/src/X11Handler.h Sun Mar 28 19:09:44 2021 +0200 +++ b/src/X11Handler.h Sun Mar 28 21:02:02 2021 +0200 @@ -51,24 +51,47 @@ } }; + class Event { + public: + + enum class Type { + KEY, + BUTTON, + MOTION, + UNKNOWN + }; + + enum class State { + PRESSED, + RELEASED, + UNKNOWN + }; + + Type type = Type::UNKNOWN; + State state = State::UNKNOWN; + int key = -1; + int button = -1; + unsigned long screen = 0; + unsigned long delay = 1; + int x = -1; + int y = -1; + } currentEvent; + Display display; - std::ostream& output; // TODO: remove Configuration& configuration; - const char QUOTE = '"'; // TODO: remove std::wstring_convert> convertor; // TODO: probably not needed - std::vector firstAttributes; - relpipe::common::type::Integer valueCount = 0; + std::vector attributes; + relpipe::common::type::Integer attributeIndex = 0; public: - X11Handler(std::ostream& output, Configuration& configuration) : output(output), configuration(configuration) { + X11Handler(Configuration& configuration) : configuration(configuration) { display.display = XOpenDisplay(nullptr); } void startRelation(relpipe::common::type::StringX name, std::vector attributes) override { if (display.display) { - if (firstAttributes.empty()) { - firstAttributes = attributes; - if (configuration.writeHeader) for (auto attr : attributes) attribute(attr.getAttributeName()); + if (this->attributes.empty()) { + this->attributes = attributes; } else { throw std::logic_error("Only a single relation can be converted to the X11 format."); } @@ -79,29 +102,53 @@ } void attribute(const relpipe::common::type::StringX& value) override { - valueCount++; - - if (value.size() > 0) { - output << QUOTE; - for (auto ch : convertor.to_bytes(value)) { - if (ch == QUOTE) output << QUOTE << QUOTE; - else output << ch; - } - output << QUOTE; + if (attributes[attributeIndex].getAttributeName() == L"device") { + // TODO: maybe add some filtering based on device ID + } else if (attributes[attributeIndex].getAttributeName() == L"type") { + if (value == L"key") currentEvent.type = Event::Type::KEY; + else if (value == L"button") currentEvent.type = Event::Type::BUTTON; + else if (value == L"motion") currentEvent.type = Event::Type::MOTION; + else currentEvent.type == Event::Type::UNKNOWN; // TODO: throw exception or print warning? + } else if (attributes[attributeIndex].getAttributeName() == L"state") { + if (value == L"pressed") currentEvent.state = Event::State::PRESSED; + else if (value == L"released") currentEvent.state = Event::State::RELEASED; + else currentEvent.state == Event::State::UNKNOWN; // TODO: throw exception or print warning? + } else if (attributes[attributeIndex].getAttributeName() == L"button") { + currentEvent.button = stol(value); + } else if (attributes[attributeIndex].getAttributeName() == L"key") { + currentEvent.key = stol(value); + } else if (attributes[attributeIndex].getAttributeName() == L"delay") { + currentEvent.delay = stoul(value); + } else if (attributes[attributeIndex].getAttributeName() == L"screen") { + currentEvent.screen = stol(value); + } else if (attributes[attributeIndex].getAttributeName() == L"x") { + currentEvent.x = stol(value); + } else if (attributes[attributeIndex].getAttributeName() == L"y") { + currentEvent.y = stol(value); + } else { + // ignore other attributes } - if (valueCount % firstAttributes.size()) { - output << ","; - } else { - output << "\r\n"; - valueCount = 0; - // XTestFakeKeyEvent(display.display, 38, true, 0); - // XTestFakeKeyEvent(display.display, 38, false, 0); + attributeIndex++; + + if (attributeIndex % attributes.size() == 0) { + if (currentEvent.type == Event::Type::KEY) { + XTestFakeKeyEvent(display.display, currentEvent.key, currentEvent.state == Event::State::PRESSED, 1); + } else if (currentEvent.type == Event::Type::BUTTON) { + XTestFakeButtonEvent(display.display, currentEvent.button, currentEvent.state == Event::State::PRESSED, currentEvent.delay); + } else if (currentEvent.type == Event::Type::MOTION) { + XTestFakeMotionEvent(display.display, currentEvent.screen, currentEvent.x, currentEvent.y, currentEvent.delay); + } else { + std::wcerr << L"Unsupported event" << std::endl; + } + + attributeIndex = 0; + currentEvent = Event(); } } void endOfPipe() { - output.flush(); + // XTestDiscard(display.display); // TODO: wait before discard? } }; diff -r 6851c08c6260 -r 2c4e533e9e33 src/relpipe-out-x11.cpp --- a/src/relpipe-out-x11.cpp Sun Mar 28 19:09:44 2021 +0200 +++ b/src/relpipe-out-x11.cpp Sun Mar 28 21:02:02 2021 +0200 @@ -36,14 +36,14 @@ int main(int argc, char**argv) { CLI cli(argc, argv); CLI::untieStdIO(); - + int resultCode = CLI::EXIT_CODE_UNEXPECTED_ERROR; try { CLIParser cliParser; Configuration configuration = cliParser.parse(cli.arguments()); std::shared_ptr reader(Factory::create(std::cin)); - X11Handler handler(std::cout, configuration); + X11Handler handler(configuration); reader->addHandler(&handler); reader->process();