1// LAF OS Library
2// Copyright (C) 2020-2022 Igara Studio S.A.
3//
4// This file is released under the terms of the MIT license.
5// Read LICENSE.txt for more information.
6
7#ifndef OS_X11_XINPUT_INCLUDED
8#define OS_X11_XINPUT_INCLUDED
9#pragma once
10
11#include "base/dll.h"
12#include "os/event.h"
13#include "os/x11/keys.h"
14#include "os/x11/mouse.h"
15
16#include <X11/Xlib.h>
17#include <X11/extensions/XInput.h>
18
19#include <map>
20#include <vector>
21
22namespace os {
23
24class XInput {
25 // To avoid depending on the libXi statically, we can load the
26 // libXi.so dynamically.
27 typedef XDeviceInfo* (*XListInputDevices_Func)(::Display*, int*);
28 typedef void (*XFreeDeviceList_Func)(XDeviceInfo*);
29 typedef XDevice* (*XOpenDevice_Func)(::Display*, XID);
30 typedef int (*XCloseDevice_Func)(::Display*, XDevice*);
31 typedef int (*XSelectExtensionEvent_Func)(::Display*, ::Window, XEventClass*, int);
32
33 XListInputDevices_Func XListInputDevices;
34 XFreeDeviceList_Func XFreeDeviceList;
35 XOpenDevice_Func XOpenDevice;
36 XCloseDevice_Func XCloseDevice;
37 XSelectExtensionEvent_Func XSelectExtensionEvent;
38
39public:
40 ~XInput();
41
42 void load(::Display* display);
43 void unload(::Display* display);
44
45 void selectExtensionEvents(::Display* display, ::Window window);
46 bool handleExtensionEvent(const XEvent& xevent);
47 void convertExtensionEvent(const XEvent& xevent,
48 Event& ev,
49 int scale,
50 Time& time);
51
52private:
53 void addEvent(int type, XEventClass eventClass, Event::Type ourEventype);
54
55 struct Info {
56 PointerType pointerType;
57 int minPressure = 0;
58 int maxPressure = 1000;
59 };
60
61 base::dll m_xi = nullptr;
62 std::vector<XDevice*> m_openDevices;
63 std::map<XID, Info> m_info;
64 std::vector<XEventClass> m_eventClasses;
65 std::vector<Event::Type> m_eventTypes;
66};
67
68} // namespace os
69
70#endif
71