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
|
/*
* Copyright © Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 or 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "wayland_surface.h"
namespace geom = mir::geometry;
// If building against newer Wayland protocol definitions we may miss trailing fields
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
wl_shell_surface_listener const WaylandSurface::shell_surface_listener {
handle_ping,
handle_configure,
[](auto, auto){} // popup_done
};
#pragma GCC diagnostic pop
mir::geometry::Size const WaylandSurface::default_size{640, 480};
WaylandSurface::WaylandSurface(WaylandApp const* app)
: app_{app},
surface_{wl_compositor_create_surface(app->compositor()), wl_surface_destroy},
shell_surface_{wl_shell_get_shell_surface(app->shell(), surface_), wl_shell_surface_destroy},
configured_size_{default_size}
{
wl_shell_surface_add_listener(shell_surface_, &shell_surface_listener, this);
}
void WaylandSurface::attach_buffer(wl_buffer* buffer, int scale)
{
if (buffer_scale != scale)
{
wl_surface_set_buffer_scale(surface_, scale);
buffer_scale = scale;
}
wl_surface_attach(surface_, buffer, 0, 0);
}
void WaylandSurface::commit() const
{
wl_surface_commit(surface_);
}
void WaylandSurface::set_fullscreen(wl_output* output)
{
wl_shell_surface_set_fullscreen(
shell_surface_,
WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
0,
output);
}
void WaylandSurface::add_frame_callback(std::function<void()>&& func)
{
WaylandCallback::create(wl_surface_frame(surface_), std::move(func));
}
void WaylandSurface::handle_ping(void* data, struct wl_shell_surface*, uint32_t serial)
{
auto const self = static_cast<WaylandSurface*>(data);
wl_shell_surface_pong(self->shell_surface_, serial);
}
void WaylandSurface::handle_configure(void* data, wl_shell_surface*, uint32_t /*edges*/, int32_t w, int32_t h)
{
auto const self = static_cast<WaylandSurface*>(data);
geom::Width width{w};
geom::Height height{h};
bool changed{false};
if (width > geom::Width{} && width != self->configured_size_.width)
{
self->configured_size_.width = geom::Width{width};
changed = true;
}
if (height > geom::Height{} && height != self->configured_size_.height)
{
self->configured_size_.height = geom::Height{height};
changed = true;
}
if (changed)
{
self->configured();
}
}
|