74 unsigned long delay = CurrentTime; |
80 unsigned long delay = CurrentTime; |
75 int x = -1; |
81 int x = -1; |
76 int y = -1; |
82 int y = -1; |
77 } currentEvent; |
83 } currentEvent; |
78 |
84 |
|
85 class Device { |
|
86 public: |
|
87 relpipe::common::type::Integer id = -1; |
|
88 relpipe::common::type::StringX name; |
|
89 relpipe::common::type::StringX type; |
|
90 } currentDevice; |
|
91 |
79 Display display; |
92 Display display; |
80 Configuration& configuration; |
93 Configuration& configuration; |
|
94 RelationType relationType = RelationType::UNSUPPORTED; |
|
95 relpipe::common::type::StringX relationName; |
81 std::vector<relpipe::reader::handlers::AttributeMetadata> attributes; |
96 std::vector<relpipe::reader::handlers::AttributeMetadata> attributes; |
82 relpipe::common::type::Integer attributeIndex = 0; |
97 relpipe::common::type::Integer attributeIndex = 0; |
83 public: |
98 public: |
84 |
99 |
85 X11Handler(Configuration& configuration) : configuration(configuration) { |
100 X11Handler(Configuration& configuration) : configuration(configuration) { |
86 display.display = XOpenDisplay(nullptr); |
101 display.display = XOpenDisplay(nullptr); |
87 } |
102 } |
88 |
103 |
89 void startRelation(relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override { |
104 void startRelation(relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override { |
90 // TODO: check relation name, print waring if it does not match |
105 this->attributes = attributes; |
91 if (display.display) { |
106 this->relationName = name; |
92 if (this->attributes.empty()) { |
107 |
93 this->attributes = attributes; |
108 if (relationName == L"x11_input_device") { |
94 } else { |
109 this->relationType = RelationType::DEVICES; |
95 throw std::logic_error("Only a single relation can be converted to the X11 format."); |
110 } else if (relationName == L"x11_input_event") { |
96 } |
111 this->relationType = RelationType::EVENTS; |
|
112 if (display.display == nullptr) throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable."); |
97 } else { |
113 } else { |
98 throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable."); |
114 this->relationType = RelationType::UNSUPPORTED; |
99 } |
115 std::wcerr << L"Unsupported relation: " << relationName << std::endl; |
100 |
116 // TODO: throw exception? |
|
117 } |
101 } |
118 } |
102 |
119 |
103 void attribute(const relpipe::common::type::StringX& value) override { |
120 void attribute(const relpipe::common::type::StringX& value) override { |
|
121 if (relationType == RelationType::DEVICES) attributeOfDevice(value); |
|
122 else if (relationType == RelationType::EVENTS) attributeOfEvent(value); |
|
123 else attributeOfUnsupported(value); |
|
124 } |
|
125 |
|
126 private: |
|
127 |
|
128 void attributeOfDevice(const relpipe::common::type::StringX& value) { |
|
129 if (attributes[attributeIndex].getAttributeName() == L"id") currentDevice.id = stol(value); |
|
130 else if (attributes[attributeIndex].getAttributeName() == L"name") currentDevice.name = value; |
|
131 else if (attributes[attributeIndex].getAttributeName() == L"type") currentDevice.type = value; |
|
132 // else: ignore other attributes |
|
133 |
|
134 attributeIndex++; |
|
135 |
|
136 if (attributeIndex % attributes.size() == 0) { |
|
137 if (configuration.debug) std::wcerr << L"Device: id = „" << currentDevice.id << L"“ name = „" << currentDevice.name << L"“ type = „" << currentDevice.type << L"“" << std::endl; |
|
138 attributeIndex = 0; |
|
139 currentEvent = Event(); |
|
140 } |
|
141 } |
|
142 |
|
143 void attributeOfUnsupported(const relpipe::common::type::StringX& value) { |
|
144 if (configuration.debug) std::wcerr << L"Unsupported relation „" << relationName << L"“ has attribute „" << value << L"“" << std::endl; |
|
145 } |
|
146 |
|
147 void attributeOfEvent(const relpipe::common::type::StringX& value) { |
104 // TODO: strictly expect correct data types (integers)? |
148 // TODO: strictly expect correct data types (integers)? |
105 // TODO: shorter codes (k/b/m, p/r) instead of names or both? |
149 // TODO: shorter codes (k/b/m, p/r) instead of names or both? |
106 if (attributes[attributeIndex].getAttributeName() == L"device") { |
150 if (attributes[attributeIndex].getAttributeName() == L"device") { |
107 // TODO: maybe add some filtering based on device ID |
151 // TODO: maybe add some filtering based on device ID |
108 } else if (attributes[attributeIndex].getAttributeName() == L"type") { |
152 } else if (attributes[attributeIndex].getAttributeName() == L"type") { |