src/X11Command.h
branchv_0
changeset 7 039b3f8a3442
parent 5 7afa994c98f0
child 8 b498160cc2ab
equal deleted inserted replaced
6:1b17b8cdbfc3 7:039b3f8a3442
    21 #include <algorithm>
    21 #include <algorithm>
    22 #include <iostream>
    22 #include <iostream>
    23 #include <stdexcept>
    23 #include <stdexcept>
    24 
    24 
    25 #include <X11/extensions/XInput.h>
    25 #include <X11/extensions/XInput.h>
       
    26 #include <X11/Xutil.h>
    26 
    27 
    27 #include "Configuration.h"
    28 #include "Configuration.h"
    28 
    29 
    29 namespace relpipe {
    30 namespace relpipe {
    30 namespace in {
    31 namespace in {
   260 			// writer->writeAttribute(&yRoot, typeid (yRoot));
   261 			// writer->writeAttribute(&yRoot, typeid (yRoot));
   261 			relationalWriterFlush();
   262 			relationalWriterFlush();
   262 		}
   263 		}
   263 	}
   264 	}
   264 
   265 
       
   266 	relpipe::common::type::StringX fetchWindowName(const Display& display, Window window) {
       
   267 		relpipe::common::type::StringX name;
       
   268 		// TODO: this does not work → use XGetWMName(), XmbTextPropertyToTextList(), XFreeStringList() instead of XFetchName()
       
   269 		// char* rawName = nullptr;
       
   270 		// if (XFetchName(display.display, window, &rawName) && rawName) 
       
   271 		// name = convertor.from_bytes(rawName); // bad encoding, std::range_error – wstring_convert::from_bytes
       
   272 		// std::cout << "\n\n\n>>> " << rawName << " <<<\n\n\n"; // bad encoding, not UTF-8
       
   273 		//XFree(rawName);
       
   274 		return name;
       
   275 	}
       
   276 
       
   277 	void listWindow(const Display& display, Window window, relpipe::common::type::Integer level, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
       
   278 		Window rootWindow;
       
   279 		Window parentWindow;
       
   280 		unsigned int childrenCount;
       
   281 		Window* childrenList;
       
   282 		if (!XQueryTree(display.display, window, &rootWindow, &parentWindow, &childrenList, &childrenCount))
       
   283 			throw std::invalid_argument("Unable to query the tree for window: " + std::to_string(window));
       
   284 
       
   285 		XWindowAttributes windowAttributes;
       
   286 		if (!XGetWindowAttributes(display.display, window, &windowAttributes))
       
   287 			throw std::invalid_argument("Unable to get attributes for window: " + std::to_string(window));
       
   288 
       
   289 		XClassHint classHint;
       
   290 		relpipe::common::type::StringX resClass;
       
   291 		relpipe::common::type::StringX resName;
       
   292 		if (XGetClassHint(display.display, window, &classHint)) {
       
   293 			if (classHint.res_class) resClass = convertor.from_bytes(classHint.res_class);
       
   294 			if (classHint.res_name) resName = convertor.from_bytes(classHint.res_name);
       
   295 			XFree(classHint.res_class);
       
   296 			XFree(classHint.res_name);
       
   297 		}
       
   298 
       
   299 		writer->writeAttribute(std::to_wstring(window));
       
   300 		// writer->writeAttribute(std::to_wstring(screen?));
       
   301 		// writer->writeAttribute(std::to_wstring(root_win));
       
   302 		writer->writeAttribute(std::to_wstring(parentWindow));
       
   303 		writer->writeAttribute(&level, typeid (level));
       
   304 		writer->writeAttribute(fetchWindowName(display, window));
       
   305 		writer->writeAttribute(resClass);
       
   306 		writer->writeAttribute(resName);
       
   307 		writer->writeAttribute(std::to_wstring(windowAttributes.x));
       
   308 		writer->writeAttribute(std::to_wstring(windowAttributes.y));
       
   309 		writer->writeAttribute(std::to_wstring(windowAttributes.width));
       
   310 		writer->writeAttribute(std::to_wstring(windowAttributes.height));
       
   311 
       
   312 		for (unsigned int i = 0; i < childrenCount; i++) listWindow(display, childrenList[i], level + 1, configuration, writer, relationalWriterFlush);
       
   313 
       
   314 		XFree(childrenList);
       
   315 	}
       
   316 
       
   317 	void listWindows(const Display& display, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
       
   318 		writer->startRelation(L"x11_window",{
       
   319 			{L"id", relpipe::writer::TypeId::INTEGER},
       
   320 			// {L"screen", relpipe::writer::TypeId::INTEGER},
       
   321 			// {L"root", relpipe::writer::TypeId::INTEGER},
       
   322 			{L"parent", relpipe::writer::TypeId::INTEGER},
       
   323 			{L"level", relpipe::writer::TypeId::INTEGER},
       
   324 			{L"name", relpipe::writer::TypeId::STRING},
       
   325 			{L"res_class", relpipe::writer::TypeId::STRING},
       
   326 			{L"res_name", relpipe::writer::TypeId::STRING},
       
   327 			{L"x", relpipe::writer::TypeId::INTEGER},
       
   328 			{L"y", relpipe::writer::TypeId::INTEGER},
       
   329 			{L"width", relpipe::writer::TypeId::INTEGER},
       
   330 			{L"height", relpipe::writer::TypeId::INTEGER},
       
   331 		}, true);
       
   332 
       
   333 		int screen = DefaultScreen(display.display);
       
   334 		Window window = RootWindow(display.display, screen);
       
   335 
       
   336 		listWindow(display, window, 0, configuration, writer, relationalWriterFlush);
       
   337 	}
       
   338 
   265 	static int handleXError(::Display* display, XErrorEvent* errorEvent) {
   339 	static int handleXError(::Display* display, XErrorEvent* errorEvent) {
   266 		std::wcerr << L"X11 error:"
   340 		std::wcerr << L"X11 error:"
   267 				<< L" display=" << errorEvent->display
   341 				<< L" display=" << errorEvent->display
   268 				<< L" error_code=" << errorEvent->error_code
   342 				<< L" error_code=" << errorEvent->error_code
   269 				<< L" minor_code=" << errorEvent->minor_code
   343 				<< L" minor_code=" << errorEvent->minor_code
   285 		display.display = XOpenDisplay(nullptr);
   359 		display.display = XOpenDisplay(nullptr);
   286 
   360 
   287 		if (display.display) {
   361 		if (display.display) {
   288 			if (configuration.listInputDevices) listInputDevices(display, configuration, writer, relationalWriterFlush);
   362 			if (configuration.listInputDevices) listInputDevices(display, configuration, writer, relationalWriterFlush);
   289 			if (configuration.listInputEvents) listInputEvents(display, configuration, writer, relationalWriterFlush);
   363 			if (configuration.listInputEvents) listInputEvents(display, configuration, writer, relationalWriterFlush);
       
   364 			if (configuration.listWindows) listWindows(display, configuration, writer, relationalWriterFlush);
       
   365 			// TODO: list screens
   290 		} else {
   366 		} else {
   291 			throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable.");
   367 			throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable.");
   292 		}
   368 		}
   293 	}
   369 	}
   294 };
   370 };