src/X11Command.h
author František Kučera <franta-hg@frantovo.cz>
Fri, 02 Apr 2021 10:54:46 +0200
branchv_0
changeset 4 820c4a4a3ed8
parent 3 72384bb5c66e
child 5 7afa994c98f0
permissions -rw-r--r--
register events only for supported devices
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     1
/**
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     2
 * Relational pipes
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     3
 * Copyright © 2021 František Kučera (Frantovo.cz, GlobalCode.info)
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     4
 *
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     5
 * This program is free software: you can redistribute it and/or modify
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     6
 * it under the terms of the GNU General Public License as published by
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     7
 * the Free Software Foundation, version 3 of the License.
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     8
 *
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     9
 * This program is distributed in the hope that it will be useful,
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    12
 * GNU General Public License for more details.
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    13
 *
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    14
 * You should have received a copy of the GNU General Public License
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    16
 */
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    17
#pragma once
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    18
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    19
#include <codecvt>
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    20
#include <memory>
2
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    21
#include <algorithm>
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    22
#include <iostream>
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    23
#include <stdexcept>
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    24
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    25
#include <X11/extensions/XInput.h>
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    26
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    27
#include "Configuration.h"
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    28
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    29
namespace relpipe {
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    30
namespace in {
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    31
namespace x11 {
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    32
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    33
class X11Command {
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    34
private:
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    35
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    36
	class Display {
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    37
	public:
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    38
		::Display* display = nullptr;
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    39
		// TODO: more OOP
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    40
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    41
		virtual ~Display() {
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    42
			if (display) XCloseDisplay(display);
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    43
		}
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    44
	};
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    45
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    46
	class Device {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    47
	public:
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    48
		XDevice* device = nullptr;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    49
		// TODO: more OOP
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    50
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    51
		virtual ~Device() {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    52
			if (device) XFree(device);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    53
		}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    54
	};
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    55
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    56
	class DeviceInfoList {
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    57
	public:
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    58
		XDeviceInfo* items = nullptr;
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    59
		int size = 0;
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    60
		// TODO: more OOP
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    61
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    62
		XDeviceInfo* operator[](int index) const {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    63
			if (index < size) return items + index;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    64
			else throw std::out_of_range("invalid index of XDeviceInfo");
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    65
		}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    66
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    67
		virtual ~DeviceInfoList() {
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    68
			if (items) XFreeDeviceList(items);
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    69
		}
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    70
	};
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    71
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    72
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    73
	std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: use platform encoding as default
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    74
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    75
	relpipe::common::type::StringX getDeviceType(const Display& display, const XDeviceInfo* device) {
2
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    76
		if (device && device->type) {
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    77
			char* raw = XGetAtomName(display.display, device->type);
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    78
			if (raw) {
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    79
				relpipe::common::type::StringX type = convertor.from_bytes(raw);
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    80
				XFree(raw);
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    81
				transform(type.begin(), type.end(), type.begin(), ::tolower);
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    82
				return type;
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    83
			}
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    84
		}
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    85
		return L"";
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    86
	}
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    87
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    88
	void listInputDevices(const Display& display, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    89
		writer->startRelation(L"x11_input_device",{
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    90
			{L"id", relpipe::writer::TypeId::INTEGER},
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    91
			{L"name", relpipe::writer::TypeId::STRING},
2
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    92
			{L"type", relpipe::writer::TypeId::STRING},
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    93
		}, true);
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    94
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    95
		DeviceInfoList devices;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    96
		devices.items = XListInputDevices(display.display, &devices.size);
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    97
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    98
		for (int i = 0; i < devices.size; i++) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
    99
			relpipe::common::type::Integer id = devices[i]->id;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   100
			relpipe::common::type::StringX name = convertor.from_bytes(devices[i]->name);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   101
			relpipe::common::type::StringX type = getDeviceType(display, devices[i]);
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   102
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   103
			writer->writeAttribute(&id, typeid (id));
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   104
			writer->writeAttribute(&name, typeid (name));
2
8d44cba0a3d1 list input devices: add type
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   105
			writer->writeAttribute(&type, typeid (type));
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   106
		}
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   107
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   108
		relationalWriterFlush();
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   109
	}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   110
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   111
	/**
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   112
	 * Fields of this structure are filled in DeviceKeyPress(), DeviceButtonPress() … macros.
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   113
	 */
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   114
	class EventType {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   115
	private:
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   116
		const static int UNUSED = -1;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   117
	public:
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   118
		int motion = UNUSED;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   119
		int buttonPress = UNUSED;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   120
		int buttonRelease = UNUSED;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   121
		int keyPress = UNUSED;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   122
		int keyRelease = UNUSED;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   123
		int proximityIn = UNUSED;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   124
		int proximityOut = UNUSED;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   125
	} eventType;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   126
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   127
	void registerEvents(const Display& display, const XDeviceInfo* deviceInfo) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   128
		bool registerProximityEvents = false; // TODO: proximity?
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   129
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   130
		Device device;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   131
		Window window;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   132
		int screen;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   133
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   134
		int eventCount = 0;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   135
		XEventClass events[7]; // TODO: check array size
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   136
		XInputClassInfo* classInfo;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   137
		int classIndex;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   138
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   139
		screen = DefaultScreen(display.display);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   140
		window = RootWindow(display.display, screen);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   141
		// TODO: configurable window from which we capture the events or optionally open our own window (can also provide some visual feedback/info)
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   142
		// Currently we can do something like:
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   143
		//   Xephyr  :5 -screen 1920x1080
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   144
		//   DISPLAY=:5 relpipe-in-x11 --list-input-devices false --list-input-events true | …
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   145
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   146
		device.device = XOpenDevice(display.display, deviceInfo->id);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   147
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   148
		if (device.device) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   149
			if (device.device->num_classes > 0) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   150
				for (classInfo = device.device->classes, classIndex = 0; classIndex < deviceInfo->num_classes; classInfo++, classIndex++) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   151
					if (classInfo->input_class == KeyClass) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   152
						DeviceKeyPress(device.device, eventType.keyPress, events[eventCount]);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   153
						eventCount++;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   154
						DeviceKeyRelease(device.device, eventType.keyRelease, events[eventCount]);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   155
						eventCount++;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   156
					} else if (classInfo->input_class == ButtonClass) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   157
						DeviceButtonPress(device.device, eventType.buttonPress, events[eventCount]);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   158
						eventCount++;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   159
						DeviceButtonRelease(device.device, eventType.buttonRelease, events[eventCount]);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   160
						eventCount++;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   161
					} else if (classInfo->input_class == ValuatorClass) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   162
						DeviceMotionNotify(device.device, eventType.motion, events[eventCount]);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   163
						eventCount++;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   164
						if (registerProximityEvents) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   165
							ProximityIn(device.device, eventType.proximityIn, events[eventCount]);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   166
							eventCount++;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   167
							ProximityOut(device.device, eventType.proximityOut, events[eventCount]);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   168
							eventCount++;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   169
						}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   170
					}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   171
				}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   172
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   173
				int result = XSelectExtensionEvent(display.display, window, events, eventCount);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   174
				if (result != Success) throw std::logic_error("Unable to register events from device: " + std::to_string(deviceInfo->id) + " Result: " + std::to_string(result));
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   175
			}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   176
		} else {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   177
			throw std::invalid_argument("Unable to open the device: " + std::to_string(deviceInfo->id));
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   178
		}
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   179
	}
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   180
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   181
	void listInputEvents(Display& display, Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   182
		writer->startRelation(L"x11_input_event",{
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   183
			{L"device", relpipe::writer::TypeId::INTEGER},
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   184
			{L"type", relpipe::writer::TypeId::STRING},
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   185
			{L"state", relpipe::writer::TypeId::STRING},
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   186
			{L"key", relpipe::writer::TypeId::INTEGER},
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   187
			{L"button", relpipe::writer::TypeId::INTEGER},
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   188
			{L"x", relpipe::writer::TypeId::INTEGER},
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   189
			{L"y", relpipe::writer::TypeId::INTEGER},
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   190
			// {L"x_root", relpipe::writer::TypeId::INTEGER},
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   191
			// {L"y_root", relpipe::writer::TypeId::INTEGER},
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   192
		}, true);
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   193
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   194
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   195
		{
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   196
			DeviceInfoList devices;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   197
			devices.items = XListInputDevices(display.display, &devices.size);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   198
			for (int i = 0; i < devices.size; i++) {
4
820c4a4a3ed8 register events only for supported devices
František Kučera <franta-hg@frantovo.cz>
parents: 3
diff changeset
   199
				if (devices[i]->type) {
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   200
					registerEvents(display, devices[i]);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   201
				}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   202
			}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   203
		}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   204
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   205
		for (XEvent event; true;) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   206
			XNextEvent(display.display, &event);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   207
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   208
			relpipe::common::type::Integer device = -1; // TODO: null
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   209
			relpipe::common::type::StringX type;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   210
			relpipe::common::type::StringX state;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   211
			relpipe::common::type::Integer button = -1; // TODO: null
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   212
			relpipe::common::type::Integer key = -1; // TODO: null
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   213
			relpipe::common::type::Integer x = -1; // TODO: null
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   214
			relpipe::common::type::Integer y = -1; // TODO: null
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   215
			// relpipe::common::type::Integer xRoot = -1; // TODO: null
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   216
			// relpipe::common::type::Integer yRoot = -1; // TODO: null
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   217
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   218
			if (event.type == eventType.motion) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   219
				XDeviceMotionEvent* e = (XDeviceMotionEvent*) & event;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   220
				device = e->deviceid;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   221
				type = L"motion";
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   222
				x = e->x;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   223
				y = e->y;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   224
				// xRoot = e->x_root;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   225
				// yRoot = e->y_root;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   226
			} else if (event.type == eventType.buttonPress || event.type == eventType.buttonRelease) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   227
				XDeviceButtonEvent* e = (XDeviceButtonEvent*) & event;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   228
				device = e->deviceid;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   229
				type = L"button";
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   230
				state = event.type == eventType.buttonPress ? L"pressed" : L"released";
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   231
				button = e->button;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   232
				x = e->x;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   233
				y = e->y;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   234
				// xRoot = e->x_root;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   235
				// yRoot = e->y_root;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   236
			} else if (event.type == eventType.keyPress || event.type == eventType.keyRelease) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   237
				XDeviceKeyEvent* e = (XDeviceKeyEvent*) & event;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   238
				device = e->deviceid;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   239
				type = L"key";
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   240
				state = event.type == eventType.keyPress ? L"pressed" : L"released";
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   241
				key = e->keycode;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   242
				x = e->x;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   243
				y = e->y;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   244
				// xRoot = e->x_root;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   245
				// yRoot = e->y_root;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   246
			} else if (event.type == eventType.proximityIn || event.type == eventType.proximityOut) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   247
				XProximityNotifyEvent* e = (XProximityNotifyEvent*) & event;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   248
				device = e->deviceid;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   249
				type = L"proximity";
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   250
			}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   251
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   252
			writer->writeAttribute(&device, typeid (device));
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   253
			writer->writeAttribute(type);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   254
			writer->writeAttribute(state);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   255
			writer->writeAttribute(&key, typeid (key));
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   256
			writer->writeAttribute(&button, typeid (button));
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   257
			writer->writeAttribute(&x, typeid (x));
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   258
			writer->writeAttribute(&y, typeid (y));
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   259
			// writer->writeAttribute(&xRoot, typeid (xRoot));
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   260
			// writer->writeAttribute(&yRoot, typeid (yRoot));
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   261
			relationalWriterFlush();
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   262
		}
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   263
	}
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   264
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   265
	static int handleXError(::Display* display, XErrorEvent* errorEvent) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   266
		// FIXME: print error
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   267
		return 0;
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   268
	}
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   269
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   270
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   271
public:
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   272
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   273
	void process(Configuration& configuration, std::shared_ptr<writer::RelationalWriter> writer, std::function<void() > relationalWriterFlush) {
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   274
		XSetErrorHandler(handleXError);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   275
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   276
		Display display;
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   277
		display.display = XOpenDisplay(nullptr);
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   278
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   279
		if (display.display) {
3
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   280
			if (configuration.listInputDevices) listInputDevices(display, configuration, writer, relationalWriterFlush);
72384bb5c66e list input events: first working version
František Kučera <franta-hg@frantovo.cz>
parents: 2
diff changeset
   281
			if (configuration.listInputEvents) listInputEvents(display, configuration, writer, relationalWriterFlush);
1
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   282
		} else {
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   283
			throw std::invalid_argument("Unable to open display. Please check the $DISPLAY variable.");
3bbf848b3565 Configuration + CLIParser + command for listing X11 devices
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   284
		}
0
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   285
	}
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   286
};
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   287
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   288
}
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   289
}
3493d6e7016e project skeleton
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   290
}