summaryrefslogtreecommitdiff
path: root/c++/window/xcb.h
blob: 902ea177b8be42b284134babdba8f9cc6ede1c79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#pragma once

#ifndef SAW_UNIX_XCB
#error "XCB is not supported"
#endif

#include "backends.h"
#include "device.h"
#include "window.h"

#include <map>

#include <X11/Xlib-xcb.h>
#include <X11/Xlib.h>

namespace saw {
namespace gfx {
template<typename T>
class window;

template<typename T>
class device;

template<>
class device<backend::linux_xcb> final {
private:
	::Display *display_;
	int screen_;

	xcb_connection_t *xcb_connection_;
	xcb_screen_t *xcb_screen_;

	own<input_stream> async_notifier_;
	conveyor_sink async_conveyor_;

	std::map<xcb_window_t, window<backend::linux_xcb> *> windows_;

	std::vector<xcb_generic_event_t *> pending_events_;

	friend class window<backend::linux_xcb>;
public:
	own<window<backend::linux_xcb>> create_xcb_window(const video_mode& vid_mod, std::string_view title_view, int visual_id);
	void xcb_window_was_destroyed(xcb_window_t window_id);
public:
	device(::Display *display, int screen, xcb_connection_t *xcb_connection,
			xcb_screen_t *xcb_screen, own<input_stream> && an);

	~device();

	void handle_events();

	own<window<backend::linux_xcb>> create_window(const video_mode& vid_mod, std::string_view title_view);

	void flush();

	// XCB specific info for other classes
	
	::Display* get_xcb_display() {
		return display_;
	}

	int get_xcb_screen() const {
		return screen_;
	}
};

error_or<own<device<backend::linux_xcb>>> create_xcb_device(io_provider& provider);

template<>
class window<backend::linux_xcb> final {
private:
	device<backend::linux_xcb> *device_;

	xcb_window_t xcb_window_;
	xcb_colormap_t xcb_colormap_;

	video_mode video_mode_;
	std::string window_title_;

	own<conveyor_feeder<data<schema::WindowEvents>>> event_feeder = nullptr;
public:
	window(device<backend::linux_xcb>& dev_, xcb_window_t xcb_win, xcb_colormap_t xcb_colormap_, const video_mode& vid_mode_, const std::string_view& title_view_);

	~window();

	void show();
	void hide();

	const video_mode& get_video_mode() const;

	const std::string_view get_title() const;

	void resize(uint64_t width, uint64_t height);

	conveyor<data<schema::WindowEvents>> on_event();

	void resize_event(uint64_t x, uint64_t y, uint64_t width, uint64_t height);
	void mouse_event(int16_t x, int16_t y, uint16_t state, bool pressed);
	void mouse_move_event(int16_t x, int16_t y);
	void keyboard_event(int16_t x, int16_t y, uint32_t keycode, bool pressed, bool repeat);

	// XCB specific things
	xcb_window_t get_xcb_window_handle() const;
};
}
}