39 #include <wayland-client-protocol-extra.hpp>
40 #include <linux/input.h>
41 #include <wayland-cursor.hpp>
48 using namespace wayland;
51 template <
typename R,
typename T,
typename... Args>
52 std::function<R(Args...)> bind_mem_fn(R(T::* func)(Args...), T *t)
54 return [func, t] (Args... args)
56 return (t->*func)(args...);
74 shared_mem_t(
size_t size)
85 std::srand(std::time(
nullptr));
86 ss <<
'/' << std::rand();
90 fd = shm_open(name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600);
92 throw std::runtime_error(
"shm_open failed.");
95 if(ftruncate(fd, size) < 0)
96 throw std::runtime_error(
"ftruncate failed.");
99 mem = mmap(
nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
100 if(mem == MAP_FAILED)
101 throw std::runtime_error(
"mmap failed.");
104 ~shared_mem_t() noexcept(false)
108 if(munmap(mem, len) < 0)
109 throw std::runtime_error(
"munmap failed.");
111 throw std::runtime_error(
"close failed.");
112 if(shm_unlink(name.c_str()) < 0)
113 throw std::runtime_error(
"shm_unlink failed");
149 cursor_image_t cursor_image;
153 std::shared_ptr<shared_mem_t> shared_mem;
154 std::array<buffer_t, 2> buffer;
161 void draw(uint32_t serial = 0)
163 float h = ((serial >> 4) & 0xFF)/255.0;
166 int hi = static_cast<int>(h*6);
170 float t = v*(1-s*(1-f));
196 uint32_t pixel = (0x80 << 24)
197 | (static_cast<uint32_t>(r * 255.0) << 16)
198 | (static_cast<uint32_t>(g * 255.0) << 8)
199 | static_cast<uint32_t>(b * 255.0);
201 std::fill_n(static_cast<uint32_t*>(shared_mem->get_mem())+cur_buf*320*240, 320*240, pixel);
202 surface.
attach(buffer.at(cur_buf), 0, 0);
203 surface.
damage(0, 0, 320, 240);
210 frame_cb = surface.
frame();
211 frame_cb.
on_done() = bind_mem_fn(&example::draw,
this);
220 registry.
on_global() = [&] (uint32_t name, std::string interface, uint32_t version)
222 if(interface == compositor_t::interface_name)
223 registry.
bind(name, compositor, version);
224 else if(interface == shell_t::interface_name)
225 registry.
bind(name, shell, version);
226 else if(interface == xdg_wm_base_t::interface_name)
227 registry.
bind(name, xdg_wm_base, version);
228 else if(interface == seat_t::interface_name)
229 registry.
bind(name, seat, version);
230 else if(interface == shm_t::interface_name)
231 registry.
bind(name, shm, version);
247 xdg_wm_base.
on_ping() = [&] (uint32_t serial) { xdg_wm_base.
pong(serial); };
252 xdg_toplevel.
on_close() = [&] () { running =
false; };
257 shell_surface.
on_ping() = [&] (uint32_t serial) { shell_surface.
pong(serial); };
267 throw std::runtime_error(
"No keyboard found.");
269 throw std::runtime_error(
"No pointer found.");
275 shared_mem = std::make_shared<shared_mem_t>(2*320*240*4);
276 auto pool = shm.
create_pool(shared_mem->get_fd(), 2*320*240*4);
277 for(
unsigned int c = 0; c < 2; c++)
278 buffer.at(c) = pool.create_buffer(c*320*240*4, 320, 240, 320*4, shm_format::argb8888);
282 cursor_theme_t cursor_theme = cursor_theme_t(
"default", 16, shm);
283 cursor_t cursor = cursor_theme.get_cursor(
"cross");
284 cursor_image = cursor.image(0);
285 cursor_buffer = cursor_image.get_buffer();
293 cursor_surface.
attach(cursor_buffer, 0, 0);
294 cursor_surface.
damage(0, 0, cursor_image.width(), cursor_image.height());
296 pointer.
set_cursor(serial, cursor_surface, 0, 0);
300 pointer.
on_button() = [&] (uint32_t serial, uint32_t time, uint32_t button, pointer_button_state state)
302 if(button == BTN_LEFT && state == pointer_button_state::pressed)
305 xdg_toplevel.
move(seat, serial);
307 shell_surface.
move(seat, serial);
312 keyboard.
on_key() = [&] (uint32_t, uint32_t, uint32_t key, keyboard_key_state state)
314 if(key == KEY_Q && state == keyboard_key_state::pressed)