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 #include "SourceSink.h"
24 #include "MutexDataPair.h"
25 
26 class X11Input : public QObject, public VideoSource {
27 	Q_OBJECT
28 
29 private:
30 	struct Rect {
31 		unsigned int m_x1, m_y1, m_x2, m_y2;
RectRect32 		inline Rect() {}
RectRect33 		inline Rect(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) : m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2) {}
34 	};
35 	struct SharedData {
36 		unsigned int m_current_x, m_current_y, m_current_width, m_current_height;
37 	};
38 	typedef MutexDataPair<SharedData>::Lock SharedLock;
39 
40 private:
41 	unsigned int m_x, m_y, m_width, m_height;
42 	bool m_record_cursor, m_follow_cursor, m_follow_fullscreen;
43 
44 	std::atomic<uint32_t> m_frame_counter;
45 	int64_t m_fps_last_timestamp;
46 	uint32_t m_fps_last_counter;
47 	double m_fps_current;
48 
49 	Display *m_x11_display;
50 	int m_x11_screen;
51 	Window m_x11_root;
52 	Visual *m_x11_visual;
53 	int m_x11_depth;
54 	bool m_x11_use_shm;
55 	XImage *m_x11_image;
56 	XShmSegmentInfo m_x11_shm_info;
57 	bool m_x11_shm_server_attached;
58 
59 	Rect m_screen_bbox;
60 	std::vector<Rect> m_screen_rects;
61 	std::vector<Rect> m_screen_dead_space;
62 
63 	std::thread m_thread;
64 	MutexDataPair<SharedData> m_shared_data;
65 	std::atomic<bool> m_should_stop, m_error_occurred;
66 
67 public:
68 	X11Input(unsigned int x, unsigned int y, unsigned int width, unsigned int height, bool record_cursor, bool follow_cursor, bool follow_fullscreen);
69 	~X11Input();
70 
71 	// Reads the current recording rectangle.
72 	// This function is thread-safe.
73 	void GetCurrentRectangle(unsigned int* x, unsigned int* y, unsigned int* width, unsigned int* height);
74 
75 	// Reads the current size of the stream.
76 	// This function is thread-safe.
77 	void GetCurrentSize(unsigned int* width, unsigned int* height);
78 
79 	// Returns the total number of captured frames.
80 	// This function is thread-safe.
81 	double GetFPS();
82 
83 	// Returns whether an error has occurred in the input thread.
84 	// This function is thread-safe.
HasErrorOccurred()85 	inline bool HasErrorOccurred() { return m_error_occurred; }
86 
87 private:
88 	void Init();
89 	void Free();
90 
91 private:
92 	void AllocateImage(unsigned int width, unsigned int height);
93 	void FreeImage();
94 	void UpdateScreenConfiguration();
95 
96 private:
97 	void InputThread();
98 
99 signals:
100 	void CurrentRectangleChanged();
101 
102 };
103