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
|
#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;
};
}
}
|