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
107
108
109
110
111
112
113
114
115
|
#include "app.hpp"
#include "json_helper.hpp"
#include "util.hpp"
#include "wayland.hpp"
#include <algorithm>
#include <json.h>
extern "C" {
#include <afb/afb-binding.h>
#include <systemd/sd-event.h>
}
namespace {
struct afb_instance {
std::unique_ptr<wl::display> display;
wm::App app;
afb_instance() : display{new wl::display}, app{this->display.get()} {}
int init();
};
struct afb_instance *g_afb_instance;
int afb_instance::init() {
if (!this->display->ok()) {
return -1;
}
return this->app.init();
}
int display_event_callback(sd_event_source *evs, int /*fd*/, uint32_t events,
void * /*data*/) {
if ((events & EPOLLHUP) != 0) {
logerror("The compositor hung up, dying now.");
delete g_afb_instance;
g_afb_instance = nullptr;
goto error;
}
if ((events & EPOLLIN) != 0u) {
if (g_afb_instance->app.dispatch_events() == -1) {
goto error;
}
}
return 0;
error:
sd_event_source_unref(evs);
return -1;
}
// _ _ _ _ _ _ _ ____
// | |__ (_)_ __ __| (_)_ __ __ _ (_)_ __ (_) |_ / /\ \
// | '_ \| | '_ \ / _` | | '_ \ / _` | | | '_ \| | __| | | |
// | |_) | | | | | (_| | | | | | (_| | | | | | | | |_| | | |
// |_.__/|_|_| |_|\__,_|_|_| |_|\__, |___|_|_| |_|_|\__| | | |
// |___/_____| \_\/_/
int binding_init_() {
lognotice("WinMan ver. %s", WINMAN_VERSION_STRING);
if (g_afb_instance != nullptr) {
logerror("Wayland context already initialized?");
return 0;
}
if (getenv("XDG_RUNTIME_DIR") == nullptr) {
logerror("Environment variable XDG_RUNTIME_DIR not set");
goto error;
}
g_afb_instance = new afb_instance;
if (g_afb_instance->init() == -1) {
logerror("Could not connect to compositor");
goto error;
}
{
int ret = sd_event_add_io(afb_daemon_get_event_loop(), nullptr,
g_afb_instance->display->get_fd(), EPOLLIN,
display_event_callback, g_afb_instance);
if (ret < 0) {
logerror("Could not initialize afb_instance event handler: %d", -ret);
goto error;
}
}
atexit([] { delete g_afb_instance; });
return 0;
error:
delete g_afb_instance;
g_afb_instance = nullptr;
return -1;
}
int binding_init() noexcept {
try {
return binding_init_();
} catch (std::exception &e) {
logerror("Uncaught exception in binding_init(): %s", e.what());
}
return -1;
}
} // namespace
#include "afb_binding_glue.inl"
extern "C" const struct afb_binding_v2 afbBindingV2 = {
"winman", nullptr, nullptr, winman_verbs, nullptr, binding_init, nullptr, 1};
|