1 /*
2 Copyright (c) 2012-2020 Maarten Baert <maarten-baert@hotmail.com>
3 
4 This file is part of SimpleScreenRecorder.
5 
6 SimpleScreenRecorder is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10 
11 SimpleScreenRecorder is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with SimpleScreenRecorder.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #pragma once
21 #include "Global.h"
22 
23 struct Hotkey {
24 	unsigned int m_keycode, m_modifiers;
25 	inline bool operator==(const Hotkey& other) const { return (m_keycode == other.m_keycode && m_modifiers == other.m_modifiers); }
26 	inline bool operator<(const Hotkey& other) const { return (m_keycode < other.m_keycode || (m_keycode == other.m_keycode && m_modifiers < other.m_modifiers)); }
27 };
28 
29 class HotkeyCallback;
30 typedef std::multimap<Hotkey, HotkeyCallback*>::iterator HotkeyIterator;
31 
32 class HotkeyCallback : public QObject {
33 	Q_OBJECT
34 
35 private:
36 	bool m_is_bound;
37 	HotkeyIterator m_iterator;
38 
39 public:
40 	HotkeyCallback();
41 	~HotkeyCallback();
42 
43 	// X11 modifiers:
44 	// - Ctrl = ControlMask
45 	// - Shift = ShiftMask
46 	// - Alt = Mod1Mask
47 	// - Super = Mod4Mask
48 	void Bind(unsigned int keysym, unsigned int modifiers);
49 	void Unbind();
50 
51 public: // internal
52 	void Trigger();
53 
54 signals:
55 	void Triggered(); // important: always use a queued connection for consistent results
56 
57 };
58 
59 class HotkeyListener : public QObject {
60 	Q_OBJECT
61 
62 private:
63 	std::multimap<Hotkey, HotkeyCallback*> m_callbacks;
64 
65 	Display *m_x11_display;
66 	int m_x11_screen;
67 	Window m_x11_root;
68 
69 	bool m_has_xinput2;
70 	int m_xinput2_opcode;
71 	unsigned int m_xinput2_raw_modifiers;
72 	unsigned long m_xinput2_ignore_serial;
73 	std::set<int> m_xinput2_master_keyboards;
74 
75 	static HotkeyListener *s_instance;
76 
77 public:
78 	HotkeyListener();
79 	~HotkeyListener();
80 
81 private:
82 	void Init();
83 	void Free();
84 
85 	void GrabHotkey(const Hotkey& hotkey, bool enable);
86 	void ProcessHotkey(const Hotkey& hotkey);
87 
88 public:
GetInstance()89 	inline static HotkeyListener* GetInstance() { assert(s_instance != NULL); return s_instance; }
90 
91 public: // internal
92 	HotkeyIterator BindCallback(unsigned int keysym, unsigned int modifiers, HotkeyCallback* callback);
93 	void UnbindCallback(HotkeyIterator it);
94 
95 private slots:
96 	void ProcessEvents();
97 
98 };
99