src/X11Handler.h
branchv_0
changeset 9 08c913c9662f
parent 8 6f5616572273
equal deleted inserted replaced
8:6f5616572273 9:08c913c9662f
    38 namespace x11 {
    38 namespace x11 {
    39 
    39 
    40 class X11Handler : public relpipe::reader::handlers::RelationalReaderStringHandler {
    40 class X11Handler : public relpipe::reader::handlers::RelationalReaderStringHandler {
    41 private:
    41 private:
    42 
    42 
       
    43 	enum class RelationType {
       
    44 		UNSUPPORTED,
       
    45 		DEVICES,
       
    46 		EVENTS,
       
    47 	};
       
    48 
    43 	class Display {
    49 	class Display {
    44 	public:
    50 	public:
    45 		::Display* display = nullptr;
    51 		::Display* display = nullptr;
    46 		// TODO: more OOP
    52 		// TODO: more OOP
    47 
    53 
    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") {