src/X11Command.h
branchv_0
changeset 1 3bbf848b3565
parent 0 3493d6e7016e
child 2 8d44cba0a3d1
--- a/src/X11Command.h	Sat Mar 20 19:18:10 2021 +0100
+++ b/src/X11Command.h	Fri Mar 26 22:29:46 2021 +0100
@@ -19,6 +19,9 @@
 #include <codecvt>
 #include <memory>
 #include <iostream>
+#include <stdexcept>
+
+#include <X11/extensions/XInput.h>
 
 #include "Configuration.h"
 
@@ -29,43 +32,72 @@
 class X11Command {
 private:
 
+	class Display {
+	public:
+		::Display* display = nullptr;
+		// TODO: more OOP
+
+		virtual ~Display() {
+			if (display) XCloseDisplay(display);
+		}
+
+	};
+
+	class DeviceList {
+	public:
+		XDeviceInfo* items = nullptr;
+		int count = 0;
+		// TODO: more OOP
+
+		virtual ~DeviceList() {
+			if (items) XFreeDeviceList(items);
+		}
+
+	};
+
+
 	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings and use platform encoding as default
 
-	void processRelation(RelationConfiguration& configuration, std::shared_ptr<writer::RelationalWriter> writer) {
-		// Write header / metadata:
-		std::vector<relpipe::writer::AttributeMetadata> attributesMetadata;
-		for (AttributeRecipe ar : configuration.attributes) attributesMetadata.push_back({ar.name, ar.type});
-		writer->startRelation(configuration.relation, attributesMetadata, configuration.writeHeader);
+	void listInputDevices(Display& display, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer) {
+		writer->startRelation(L"x11_input_device",{
+			{L"id", relpipe::writer::TypeId::INTEGER},
+			{L"name", relpipe::writer::TypeId::STRING},
+			// TODO: device type name and ID
+		}, true);
 
-		// Write records from CLI:
-		for (auto value : configuration.values) writer->writeAttribute(value);
+		DeviceList devices;
+		devices.items = XListInputDevices(display.display, &devices.count);
 
-		// Write records from STDIN:
-		if (configuration.valueStream) {
-			std::stringstream rawValue;
-			while (true) {
-				char ch = 0;
-				configuration.valueStream->get(ch);
-				if (ch == 0 && configuration.valueStream->good()) {
-					writer->writeAttribute(convertor.from_bytes(rawValue.str()));
-					rawValue.str("");
-					rawValue.clear();
-				} else if (configuration.valueStream->good()) {
-					rawValue << ch;
-				} else if (configuration.valueStream->eof()) {
-					return;
-				} else {
-					throw relpipe::cli::RelpipeCLIException(L"Error while reading values from the input stream.", relpipe::cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exception
-				}
-			}
+		for (int i = 0; i < devices.count; i++) {
+			relpipe::common::type::Integer id = (devices.items + i)->id;
+			relpipe::common::type::StringX name = convertor.from_bytes((devices.items + i)->name);
+
+			writer->writeAttribute(&id, typeid (id));
+			writer->writeAttribute(&name, typeid (name));
+
 		}
+	}
 
+	void listInputEvents(Display& display, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer) {
+		writer->startRelation(L"x11_input_event",{
+			{L"device_id", relpipe::writer::TypeId::INTEGER},
+		}, true);
+
+		// TODO: list events
 	}
 
 public:
 
 	void process(Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer) {
-		for (RelationConfiguration& relationConfiguration : configuration.relationConfigurations) processRelation(relationConfiguration, writer);
+		Display display;
+		display.display = XOpenDisplay(nullptr);
+
+		if (display.display) {
+			if (configuration.listInputDevices) listInputDevices(display, configuration, writer);
+			if (configuration.listInputEvents) listInputEvents(display, configuration, writer);
+		} else {
+			throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable.");
+		}
 	}
 };