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}, |