src/X11Command.h
branchv_0
changeset 10 803beead60c4
parent 9 c8d681753bc2
child 11 3948229234cd
equal deleted inserted replaced
9:c8d681753bc2 10:803beead60c4
    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 #include <X11/Xutil.h>
       
    27 #include <X11/Xatom.h>
    27 
    28 
    28 #include "Configuration.h"
    29 #include "Configuration.h"
    29 
    30 
    30 namespace relpipe {
    31 namespace relpipe {
    31 namespace in {
    32 namespace in {
   278 		XFree(property.value);
   279 		XFree(property.value);
   279 
   280 
   280 		return convertor.from_bytes(name);
   281 		return convertor.from_bytes(name);
   281 	}
   282 	}
   282 
   283 
       
   284 	void* findWindowProperty(const Display& display, Window window, Atom atom, long* length, Atom* type, int* size) {
       
   285 		// FIXME: review code
       
   286 		Atom actualType;
       
   287 		int actualFormat;
       
   288 		unsigned long itemCount;
       
   289 		unsigned long byteCount;
       
   290 		unsigned long bytesAfter;
       
   291 		unsigned char* result = nullptr;
       
   292 		int status;
       
   293 		unsigned long max_len = 500000;
       
   294 
       
   295 		status = XGetWindowProperty(display.display, window, atom, 0, (max_len + 3) / 4, False, AnyPropertyType, &actualType, &actualFormat, &itemCount, &bytesAfter, &result);
       
   296 		if (status == BadWindow) throw std::invalid_argument("Unable to get window property: BadWindow");
       
   297 		if (status != Success) throw std::invalid_argument("Unable to get window property: other error: " + std::to_string(status));
       
   298 
       
   299 		if (actualFormat == 32) byteCount = sizeof (long);
       
   300 		else if (actualFormat == 16) byteCount = sizeof (short);
       
   301 		else if (actualFormat == 8) byteCount = 1;
       
   302 		else if (actualFormat == 0) byteCount = 0;
       
   303 		else throw std::invalid_argument("Unable to get window property: unexpected format");
       
   304 		*length = min(itemCount * byteCount, max_len);
       
   305 		*type = actualType;
       
   306 		*size = actualFormat;
       
   307 		return (void*) result;
       
   308 	}
       
   309 
       
   310 	relpipe::common::type::Integer findWindowPropertyInteger(const Display& display, Window window, std::string propertyName) {
       
   311 		long length = -1;
       
   312 		Atom type = -1;
       
   313 		int size = -1;
       
   314 		void* rawResult = findWindowProperty(display, window, XInternAtom(display.display, propertyName.c_str(), False), &length, &type, &size);
       
   315 
       
   316 		relpipe::common::type::Integer result = -1; // TODO: null
       
   317 		if (size = 32 && type == XA_CARDINAL) result = *((uint32_t*) rawResult);
       
   318 		// TODO: review code
       
   319 		// TODO: support also other types (other integers, boolean, string etc.)
       
   320 
       
   321 		XFree(rawResult);
       
   322 
       
   323 		return result;
       
   324 	}
       
   325 
   283 	void listWindow(const Display& display, Window window, relpipe::common::type::Integer level, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
   326 	void listWindow(const Display& display, Window window, relpipe::common::type::Integer level, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
   284 		Window rootWindow;
   327 		Window rootWindow;
   285 		Window parentWindow;
   328 		Window parentWindow;
   286 		unsigned int childrenCount;
   329 		unsigned int childrenCount;
   287 		Window* childrenList;
   330 		Window* childrenList;
   300 			if (classHint.res_name) resName = convertor.from_bytes(classHint.res_name);
   343 			if (classHint.res_name) resName = convertor.from_bytes(classHint.res_name);
   301 			XFree(classHint.res_class);
   344 			XFree(classHint.res_class);
   302 			XFree(classHint.res_name);
   345 			XFree(classHint.res_name);
   303 		}
   346 		}
   304 
   347 
       
   348 		// The PID as reported by the application itself in the property. Some applications do not report their PID.
       
   349 		relpipe::common::type::Integer processId = findWindowPropertyInteger(display, window, "_NET_WM_PID");
       
   350 		// TODO: support also other properties: customizable through options or all in a nested structure/relation/xml
       
   351 
   305 		writer->writeAttribute(std::to_wstring(window));
   352 		writer->writeAttribute(std::to_wstring(window));
   306 		writer->writeAttribute(std::to_wstring(windowAttributes.root));
   353 		writer->writeAttribute(std::to_wstring(windowAttributes.root));
   307 		writer->writeAttribute(std::to_wstring(parentWindow));
   354 		writer->writeAttribute(std::to_wstring(parentWindow));
   308 		writer->writeAttribute(&level, typeid (level));
   355 		writer->writeAttribute(&level, typeid (level));
       
   356 		writer->writeAttribute(&processId, typeid (processId));
   309 		writer->writeAttribute(fetchWindowName(display, window));
   357 		writer->writeAttribute(fetchWindowName(display, window));
   310 		writer->writeAttribute(resClass);
   358 		writer->writeAttribute(resClass);
   311 		writer->writeAttribute(resName);
   359 		writer->writeAttribute(resName);
   312 		writer->writeAttribute(std::to_wstring(windowAttributes.x));
   360 		writer->writeAttribute(std::to_wstring(windowAttributes.x));
   313 		writer->writeAttribute(std::to_wstring(windowAttributes.y));
   361 		writer->writeAttribute(std::to_wstring(windowAttributes.y));
   323 		writer->startRelation(L"x11_window",{
   371 		writer->startRelation(L"x11_window",{
   324 			{L"id", relpipe::writer::TypeId::INTEGER},
   372 			{L"id", relpipe::writer::TypeId::INTEGER},
   325 			{L"root", relpipe::writer::TypeId::INTEGER},
   373 			{L"root", relpipe::writer::TypeId::INTEGER},
   326 			{L"parent", relpipe::writer::TypeId::INTEGER},
   374 			{L"parent", relpipe::writer::TypeId::INTEGER},
   327 			{L"level", relpipe::writer::TypeId::INTEGER},
   375 			{L"level", relpipe::writer::TypeId::INTEGER},
       
   376 			{L"process", relpipe::writer::TypeId::INTEGER},
   328 			{L"name", relpipe::writer::TypeId::STRING},
   377 			{L"name", relpipe::writer::TypeId::STRING},
   329 			{L"res_class", relpipe::writer::TypeId::STRING},
   378 			{L"res_class", relpipe::writer::TypeId::STRING},
   330 			{L"res_name", relpipe::writer::TypeId::STRING},
   379 			{L"res_name", relpipe::writer::TypeId::STRING},
   331 			{L"x", relpipe::writer::TypeId::INTEGER},
   380 			{L"x", relpipe::writer::TypeId::INTEGER},
   332 			{L"y", relpipe::writer::TypeId::INTEGER},
   381 			{L"y", relpipe::writer::TypeId::INTEGER},