--- a/src/X11Handler.h Thu Apr 01 21:19:50 2021 +0200
+++ b/src/X11Handler.h Fri Apr 02 18:34:52 2021 +0200
@@ -40,6 +40,12 @@
class X11Handler : public relpipe::reader::handlers::RelationalReaderStringHandler {
private:
+ enum class RelationType {
+ UNSUPPORTED,
+ DEVICES,
+ EVENTS,
+ };
+
class Display {
public:
::Display* display = nullptr;
@@ -76,8 +82,17 @@
int y = -1;
} currentEvent;
+ class Device {
+ public:
+ relpipe::common::type::Integer id = -1;
+ relpipe::common::type::StringX name;
+ relpipe::common::type::StringX type;
+ } currentDevice;
+
Display display;
Configuration& configuration;
+ RelationType relationType = RelationType::UNSUPPORTED;
+ relpipe::common::type::StringX relationName;
std::vector<relpipe::reader::handlers::AttributeMetadata> attributes;
relpipe::common::type::Integer attributeIndex = 0;
public:
@@ -87,20 +102,49 @@
}
void startRelation(relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
- // TODO: check relation name, print waring if it does not match
- if (display.display) {
- if (this->attributes.empty()) {
- this->attributes = attributes;
- } else {
- throw std::logic_error("Only a single relation can be converted to the X11 format.");
- }
+ this->attributes = attributes;
+ this->relationName = name;
+
+ if (relationName == L"x11_input_device") {
+ this->relationType = RelationType::DEVICES;
+ } else if (relationName == L"x11_input_event") {
+ this->relationType = RelationType::EVENTS;
+ if (display.display == nullptr) throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable.");
} else {
- throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable.");
+ this->relationType = RelationType::UNSUPPORTED;
+ std::wcerr << L"Unsupported relation: " << relationName << std::endl;
+ // TODO: throw exception?
}
-
}
void attribute(const relpipe::common::type::StringX& value) override {
+ if (relationType == RelationType::DEVICES) attributeOfDevice(value);
+ else if (relationType == RelationType::EVENTS) attributeOfEvent(value);
+ else attributeOfUnsupported(value);
+ }
+
+private:
+
+ void attributeOfDevice(const relpipe::common::type::StringX& value) {
+ if (attributes[attributeIndex].getAttributeName() == L"id") currentDevice.id = stol(value);
+ else if (attributes[attributeIndex].getAttributeName() == L"name") currentDevice.name = value;
+ else if (attributes[attributeIndex].getAttributeName() == L"type") currentDevice.type = value;
+ // else: ignore other attributes
+
+ attributeIndex++;
+
+ if (attributeIndex % attributes.size() == 0) {
+ if (configuration.debug) std::wcerr << L"Device: id = „" << currentDevice.id << L"“ name = „" << currentDevice.name << L"“ type = „" << currentDevice.type << L"“" << std::endl;
+ attributeIndex = 0;
+ currentEvent = Event();
+ }
+ }
+
+ void attributeOfUnsupported(const relpipe::common::type::StringX& value) {
+ if (configuration.debug) std::wcerr << L"Unsupported relation „" << relationName << L"“ has attribute „" << value << L"“" << std::endl;
+ }
+
+ void attributeOfEvent(const relpipe::common::type::StringX& value) {
// TODO: strictly expect correct data types (integers)?
// TODO: shorter codes (k/b/m, p/r) instead of names or both?
if (attributes[attributeIndex].getAttributeName() == L"device") {