39 #include <wayland-client-protocol-extra.hpp> 40 #include <linux/input.h> 41 #include <wayland-cursor.hpp> 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(0));
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(NULL, 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;
161 void draw(uint32_t serial = 0)
163 float h = ((serial >> 4) & 0xFF)/255.0;
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[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);
243 throw std::runtime_error(
"No keyboard found.");
245 throw std::runtime_error(
"No pointer found.");
248 shared_mem = std::shared_ptr<shared_mem_t>(
new shared_mem_t(2*320*240*4));
249 auto pool = shm.
create_pool(shared_mem->get_fd(), 2*320*240*4);
250 for(
unsigned int c = 0; c < 2; c++)
251 buffer[c] = pool.create_buffer(c*320*240*4, 320, 240, 320*4, shm_format::argb8888);
260 xdg_wm_base.
on_ping() = [&] (uint32_t serial) { xdg_wm_base.
pong(serial); };
264 xdg_toplevel.
on_close() = [&] () { running =
false; };
269 shell_surface.
on_ping() = [&] (uint32_t serial) { shell_surface.
pong(serial); };
279 cursor_theme_t cursor_theme = cursor_theme_t(
"default", 16, shm);
280 cursor_t cursor = cursor_theme.get_cursor(
"cross");
281 cursor_image = cursor.image(0);
282 cursor_buffer = cursor_image.get_buffer();
290 cursor_surface.
attach(cursor_buffer, 0, 0);
291 cursor_surface.
damage(0, 0, cursor_image.width(), cursor_image.height());
293 pointer.
set_cursor(serial, cursor_surface, 0, 0);
297 pointer.
on_button() = [&] (uint32_t serial, uint32_t time, uint32_t button, pointer_button_state state)
299 if(button == BTN_LEFT && state == pointer_button_state::pressed)
302 xdg_toplevel.
move(seat, serial);
304 shell_surface.
move(seat, serial);
309 keyboard.
on_key() = [&] (uint32_t, uint32_t, uint32_t key, keyboard_key_state state)
311 if(key == KEY_Q && state == keyboard_key_state::pressed)
create desktop-style surfaces
std::function< void(uint32_t)> & on_ping()
ping client
void pong(uint32_t serial)
respond to a ping event
std::function< void(uint32_t)> & on_done()
done event
void move(seat_t seat, uint32_t serial)
start an interactive move
registry_t get_registry()
get global registry object
shm_pool_t create_pool(int fd, int32_t size)
create a shm pool
Represents a connection to the compositor and acts as a proxy to the display singleton object...
desktop user interface surface base interface
std::function< void(uint32_t, uint32_t, uint32_t, keyboard_key_state)> & on_key()
key event
std::function< void(uint32_t)> & on_ping()
check if the client is alive
proxy_t bind(uint32_t name, proxy_t &interface, uint32_t version)
bind an object to the display
void set_title(std::string title)
set surface title
desktop-style metadata interface
std::function< void()> & on_close()
surface wants to be closed
shell_surface_t get_shell_surface(surface_t surface)
create a shell surface from a surface
void set_cursor(uint32_t serial, surface_t surface, int32_t hotspot_x, int32_t hotspot_y)
set the pointer surface
void set_title(std::string title)
set surface title
void commit()
commit pending surface state
void pong(uint32_t serial)
respond to a ping event
std::function< void(uint32_t, uint32_t, uint32_t, pointer_button_state)> & on_button()
pointer button event
std::function< void(uint32_t, std::string, uint32_t)> & on_global()
announce global object
pointer_t get_pointer()
return pointer object
int dispatch()
Process incoming events.
static const detail::bitfield< 3, 12 > pointer
the seat has pointer devices
void move(seat_t seat, uint32_t serial)
start an interactive move
static const detail::bitfield< 3, 12 > keyboard
the seat has one or more keyboards
void set_toplevel()
make the surface a toplevel surface
create desktop-style surfaces
void damage(int32_t x, int32_t y, int32_t width, int32_t height)
mark part of the surface damaged
surface_t create_surface()
create new surface
xdg_surface_t get_xdg_surface(surface_t surface)
create a shell surface from a surface
xdg_toplevel_t get_toplevel()
assign the xdg_toplevel surface role
void attach(buffer_t buffer, int32_t x, int32_t y)
set the surface contents
std::function< void(seat_capability)> & on_capabilities()
seat capabilities changed
int roundtrip()
Block until all pending request are processed by the server.
callback_t frame()
request a frame throttling hint
keyboard_t get_keyboard()
return keyboard object
std::function< void(uint32_t, surface_t, double, double)> & on_enter()
enter event