123 int keyRelease = UNUSED; |
123 int keyRelease = UNUSED; |
124 int proximityIn = UNUSED; |
124 int proximityIn = UNUSED; |
125 int proximityOut = UNUSED; |
125 int proximityOut = UNUSED; |
126 } eventType; |
126 } eventType; |
127 |
127 |
128 void registerEvents(const Display& display, const XDeviceInfo* deviceInfo) { |
128 void registerEvents(const Display& display, int screen, const XDeviceInfo* deviceInfo) { |
129 bool registerProximityEvents = false; // TODO: proximity? |
129 bool registerProximityEvents = false; // TODO: proximity? |
130 |
130 |
131 Device device; |
131 Device device; |
132 Window window; |
132 Window window; |
133 int screen; |
|
134 |
133 |
135 int eventCount = 0; |
134 int eventCount = 0; |
136 XEventClass events[7]; // TODO: check array size |
135 XEventClass events[7]; // TODO: check array size |
137 XInputClassInfo* classInfo; |
136 XInputClassInfo* classInfo; |
138 int classIndex; |
137 int classIndex; |
139 |
138 |
140 screen = DefaultScreen(display.display); |
|
141 window = RootWindow(display.display, screen); |
139 window = RootWindow(display.display, screen); |
142 // TODO: configurable window from which we capture the events or optionally open our own window (can also provide some visual feedback/info) |
140 // TODO: configurable window from which we capture the events or optionally open our own window (can also provide some visual feedback/info) |
143 // Currently we can do something like: |
141 // Currently we can do something like: |
144 // Xephyr :5 -screen 1920x1080 |
142 // Xephyr :5 -screen 1920x1080 |
145 // DISPLAY=:5 relpipe-in-x11 --list-input-devices false --list-input-events true | … |
143 // DISPLAY=:5 relpipe-in-x11 --list-input-devices false --list-input-events true | … |
196 { |
194 { |
197 DeviceInfoList devices; |
195 DeviceInfoList devices; |
198 devices.items = XListInputDevices(display.display, &devices.size); |
196 devices.items = XListInputDevices(display.display, &devices.size); |
199 for (int i = 0; i < devices.size; i++) { |
197 for (int i = 0; i < devices.size; i++) { |
200 if (devices[i]->type) { |
198 if (devices[i]->type) { |
201 registerEvents(display, devices[i]); |
199 for (int screenCount = XScreenCount(display.display), screen = 0; screen < screenCount; screen++) |
|
200 registerEvents(display, screen, devices[i]); |
202 } |
201 } |
203 } |
202 } |
204 } |
203 } |
205 |
204 |
206 for (XEvent event; true;) { |
205 for (XEvent event; true;) { |
295 XFree(classHint.res_class); |
294 XFree(classHint.res_class); |
296 XFree(classHint.res_name); |
295 XFree(classHint.res_name); |
297 } |
296 } |
298 |
297 |
299 writer->writeAttribute(std::to_wstring(window)); |
298 writer->writeAttribute(std::to_wstring(window)); |
300 // writer->writeAttribute(std::to_wstring(screen?)); |
299 writer->writeAttribute(std::to_wstring(windowAttributes.root)); |
301 // writer->writeAttribute(std::to_wstring(root_win)); |
|
302 writer->writeAttribute(std::to_wstring(parentWindow)); |
300 writer->writeAttribute(std::to_wstring(parentWindow)); |
303 writer->writeAttribute(&level, typeid (level)); |
301 writer->writeAttribute(&level, typeid (level)); |
304 writer->writeAttribute(fetchWindowName(display, window)); |
302 writer->writeAttribute(fetchWindowName(display, window)); |
305 writer->writeAttribute(resClass); |
303 writer->writeAttribute(resClass); |
306 writer->writeAttribute(resName); |
304 writer->writeAttribute(resName); |
315 } |
313 } |
316 |
314 |
317 void listWindows(const Display& display, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) { |
315 void listWindows(const Display& display, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) { |
318 writer->startRelation(L"x11_window",{ |
316 writer->startRelation(L"x11_window",{ |
319 {L"id", relpipe::writer::TypeId::INTEGER}, |
317 {L"id", relpipe::writer::TypeId::INTEGER}, |
320 // {L"screen", relpipe::writer::TypeId::INTEGER}, |
318 {L"root", relpipe::writer::TypeId::INTEGER}, |
321 // {L"root", relpipe::writer::TypeId::INTEGER}, |
|
322 {L"parent", relpipe::writer::TypeId::INTEGER}, |
319 {L"parent", relpipe::writer::TypeId::INTEGER}, |
323 {L"level", relpipe::writer::TypeId::INTEGER}, |
320 {L"level", relpipe::writer::TypeId::INTEGER}, |
324 {L"name", relpipe::writer::TypeId::STRING}, |
321 {L"name", relpipe::writer::TypeId::STRING}, |
325 {L"res_class", relpipe::writer::TypeId::STRING}, |
322 {L"res_class", relpipe::writer::TypeId::STRING}, |
326 {L"res_name", relpipe::writer::TypeId::STRING}, |
323 {L"res_name", relpipe::writer::TypeId::STRING}, |
328 {L"y", relpipe::writer::TypeId::INTEGER}, |
325 {L"y", relpipe::writer::TypeId::INTEGER}, |
329 {L"width", relpipe::writer::TypeId::INTEGER}, |
326 {L"width", relpipe::writer::TypeId::INTEGER}, |
330 {L"height", relpipe::writer::TypeId::INTEGER}, |
327 {L"height", relpipe::writer::TypeId::INTEGER}, |
331 }, true); |
328 }, true); |
332 |
329 |
333 int screen = DefaultScreen(display.display); |
330 for (int screenCount = XScreenCount(display.display), screen = 0; screen < screenCount; screen++) { |
334 Window window = RootWindow(display.display, screen); |
331 Window root = RootWindow(display.display, screen); |
335 |
332 listWindow(display, root, 0, configuration, writer, relationalWriterFlush); |
336 listWindow(display, window, 0, configuration, writer, relationalWriterFlush); |
333 } |
|
334 } |
|
335 |
|
336 void listScreens(const Display& display, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) { |
|
337 writer->startRelation(L"x11_screen",{ |
|
338 {L"id", relpipe::writer::TypeId::INTEGER}, |
|
339 {L"root", relpipe::writer::TypeId::INTEGER}, |
|
340 {L"width", relpipe::writer::TypeId::INTEGER}, |
|
341 {L"height", relpipe::writer::TypeId::INTEGER}, |
|
342 // {L"width_mm", relpipe::writer::TypeId::INTEGER}, |
|
343 // {L"height_mm", relpipe::writer::TypeId::INTEGER}, |
|
344 }, true); |
|
345 |
|
346 for (int screenCount = XScreenCount(display.display), screen = 0; screen < screenCount; screen++) { |
|
347 Window root = RootWindow(display.display, screen); |
|
348 XWindowAttributes attributes; |
|
349 if (!XGetWindowAttributes(display.display, root, &attributes)) |
|
350 throw std::invalid_argument("Unable to get attributes for window: " + std::to_string(root)); |
|
351 |
|
352 writer->writeAttribute(std::to_wstring(screen)); |
|
353 writer->writeAttribute(std::to_wstring(root)); |
|
354 writer->writeAttribute(std::to_wstring(attributes.width)); |
|
355 writer->writeAttribute(std::to_wstring(attributes.height)); |
|
356 // writer->writeAttribute(std::to_wstring(attributes.screen->mwidth)); |
|
357 // writer->writeAttribute(std::to_wstring(attributes.screen->mheight)); |
|
358 } |
|
359 |
337 } |
360 } |
338 |
361 |
339 static int handleXError(::Display* display, XErrorEvent* errorEvent) { |
362 static int handleXError(::Display* display, XErrorEvent* errorEvent) { |
340 std::wcerr << L"X11 error:" |
363 std::wcerr << L"X11 error:" |
341 << L" display=" << errorEvent->display |
364 << L" display=" << errorEvent->display |
360 |
383 |
361 if (display.display) { |
384 if (display.display) { |
362 if (configuration.listInputDevices) listInputDevices(display, configuration, writer, relationalWriterFlush); |
385 if (configuration.listInputDevices) listInputDevices(display, configuration, writer, relationalWriterFlush); |
363 if (configuration.listInputEvents) listInputEvents(display, configuration, writer, relationalWriterFlush); |
386 if (configuration.listInputEvents) listInputEvents(display, configuration, writer, relationalWriterFlush); |
364 if (configuration.listWindows) listWindows(display, configuration, writer, relationalWriterFlush); |
387 if (configuration.listWindows) listWindows(display, configuration, writer, relationalWriterFlush); |
365 // TODO: list screens |
388 if (configuration.listScreens) listScreens(display, configuration, writer, relationalWriterFlush); |
366 } else { |
389 } else { |
367 throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable."); |
390 throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable."); |
368 } |
391 } |
369 } |
392 } |
370 }; |
393 }; |