diff --git a/include/miroil/miroil/surface.h b/include/miroil/miroil/surface.h new file mode 100644 index 00000000000..d3dcd0e52f5 --- /dev/null +++ b/include/miroil/miroil/surface.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 Canonical, Ltd. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 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 warranties of MERCHANTABILITY, + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +#ifndef MIROIL_SURFACE_H +#define MIROIL_SURFACE_H +#include +#include +#include +#include +#include + +namespace mir { + namespace scene { class Surface; } + namespace shell { class InputTargeter; } + namespace geometry { struct Rectangle; } + namespace graphics { class CursorImage; } + namespace compositor { class BufferStream; } +} + +namespace miroil { + +class SurfaceObserver; +class SurfaceObserverImpl; + +using CompositorID = void const*; + +class Surface +{ +public: + Surface(std::shared_ptr wrapped); + ~Surface() = default; + + auto getWrapped() const -> mir::scene::Surface*; + void add_observer(std::shared_ptr const& observer); + void remove_observer(std::shared_ptr const& observer); + + int buffers_ready_for_compositor(void const* compositor_id) const; + auto generate_renderables(miroil::CompositorID id) const -> mir::graphics::RenderableList; + + bool is_confined_to_window(); + void set_orientation(MirOrientation orientation); + void set_keymap(MirInputDeviceId id, std::string const& model, std::string const& layout, + std::string const& variant, std::string const& options); + + void set_confine_pointer_state(MirPointerConfinementState state); + auto parent() const -> std::shared_ptr; + + /// Top-left corner (of the window frame if present) + mir::geometry::Point top_left() const; + bool visible() const; + + // TODO a legacy of old interactions and needs removing + int configure(MirWindowAttrib attrib, int value); + // TODO a legacy of old interactions and needs removing + int query(MirWindowAttrib attrib) const; + +private: + std::shared_ptr wrapped; + std::unordered_map, std::shared_ptr> observers; +}; + +} + +#endif diff --git a/include/miroil/miroil/surface_observer.h b/include/miroil/miroil/surface_observer.h new file mode 100644 index 00000000000..322e4f26a44 --- /dev/null +++ b/include/miroil/miroil/surface_observer.h @@ -0,0 +1,65 @@ +/* + * Copyright © 2021 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 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 . + */ +#include +#include +#include +#include +#include +#include +#include + +namespace mir { namespace scene { class SurfaceObserver; } } +namespace mir { namespace scene { class Surface; } } +namespace mir { namespace input { enum class InputReceptionMode; } } + +struct MirEvent; +struct MirInputEvent; + +namespace miroil +{ + +class SurfaceObserver +{ +public: + SurfaceObserver() = default; + SurfaceObserver(SurfaceObserver const&) = delete; + SurfaceObserver& operator=(SurfaceObserver const&) = delete; + virtual ~SurfaceObserver(); + + virtual void attrib_changed(mir::scene::Surface const* surf, MirWindowAttrib attrib, int value) = 0; + virtual void window_resized_to(mir::scene::Surface const* surf, mir::geometry::Size const& window_size) = 0; + virtual void content_resized_to(mir::scene::Surface const* surf, mir::geometry::Size const& content_size) = 0; + virtual void moved_to(mir::scene::Surface const* surf, mir::geometry::Point const& top_left) = 0; + virtual void hidden_set_to(mir::scene::Surface const* surf, bool hide) = 0; + virtual void frame_posted(mir::scene::Surface const* surf, int frames_available, mir::geometry::Size const& size) = 0; + virtual void alpha_set_to(mir::scene::Surface const* surf, float alpha) = 0; + virtual void orientation_set_to(mir::scene::Surface const* surf, MirOrientation orientation) = 0; + virtual void transformation_set_to(mir::scene::Surface const* surf, glm::mat4 const& t) = 0; + virtual void reception_mode_set_to(mir::scene::Surface const* surf, mir::input::InputReceptionMode mode) = 0; + virtual void cursor_image_set_to(mir::scene::Surface const* surf, mir::graphics::CursorImage const& image) = 0; + virtual void client_surface_close_requested(mir::scene::Surface const* surf) = 0; + virtual void keymap_changed(mir::scene::Surface const* surf, MirInputDeviceId id, std::string const& model, + std::string const& layout, std::string const& variant, std::string const& options) = 0; + virtual void renamed(mir::scene::Surface const* surf, char const* name) = 0; + virtual void cursor_image_removed(mir::scene::Surface const* surf) = 0; + virtual void placed_relative(mir::scene::Surface const* surf, mir::geometry::Rectangle const& placement) = 0; + virtual void input_consumed(mir::scene::Surface const* surf, MirEvent const* event) = 0; + virtual void start_drag_and_drop(mir::scene::Surface const* surf, std::vector const& handle) = 0; + virtual void depth_layer_set_to(mir::scene::Surface const* surf, MirDepthLayer depth_layer) = 0; + virtual void application_id_set_to(mir::scene::Surface const* surf, std::string const& application_id) = 0; +}; + +} diff --git a/src/miroil/CMakeLists.txt b/src/miroil/CMakeLists.txt index cbd0e32ab0c..46d17fda6e8 100644 --- a/src/miroil/CMakeLists.txt +++ b/src/miroil/CMakeLists.txt @@ -25,6 +25,8 @@ add_library(miroil SHARED prompt_session_listener.cpp ${miroil_include}/miroil/prompt_session_listener.h prompt_session_manager.cpp ${miroil_include}/miroil/prompt_session_manager.h set_compositor.cpp ${miroil_include}/miroil/set_compositor.h + surface.cpp ${miroil_include}/miroil/surface.h + surface_observer.cpp ${miroil_include}/miroil/surface_observer.h ${miroil_include}/miroil/display_configuration_storage.h ${miroil_include}/miroil/display_id.h ) diff --git a/src/miroil/surface.cpp b/src/miroil/surface.cpp new file mode 100644 index 00000000000..9cb6c4a07c4 --- /dev/null +++ b/src/miroil/surface.cpp @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2021 Canonical, Ltd. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 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 warranties of MERCHANTABILITY, + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +#include +#include +#include "mir/scene/surface.h" +#include "mir/scene/surface_observer.h" + +namespace miroil { + +class SurfaceObserverImpl : public mir::scene::SurfaceObserver +{ +public: + SurfaceObserverImpl(std::shared_ptr const & wrapped); + virtual ~SurfaceObserverImpl(); + + void alpha_set_to(mir::scene::Surface const* surf, float alpha) override; + void application_id_set_to(mir::scene::Surface const* surf, std::string const& application_id) override; + void attrib_changed(mir::scene::Surface const* surf, MirWindowAttrib attrib, int value) override; + void client_surface_close_requested(mir::scene::Surface const* surf) override; + void content_resized_to(mir::scene::Surface const* surf, mir::geometry::Size const& content_size) override; + void cursor_image_removed(mir::scene::Surface const* surf) override; + void cursor_image_set_to(mir::scene::Surface const* surf, mir::graphics::CursorImage const& image) override; + void depth_layer_set_to(mir::scene::Surface const* surf, MirDepthLayer depth_layer) override; + void frame_posted(mir::scene::Surface const* surf, int frames_available, mir::geometry::Size const& size) override; + void hidden_set_to(mir::scene::Surface const* surf, bool hide) override; + void input_consumed(mir::scene::Surface const* surf, MirEvent const* event) override; + void keymap_changed(mir::scene::Surface const* surf, MirInputDeviceId id, std::string const& model, + std::string const& layout, std::string const& variant, std::string const& options) override; + void moved_to(mir::scene::Surface const* surf, mir::geometry::Point const& top_left) override; + void orientation_set_to(mir::scene::Surface const* surf, MirOrientation orientation) override; + void placed_relative(mir::scene::Surface const* surf, mir::geometry::Rectangle const& placement) override; + void reception_mode_set_to(mir::scene::Surface const* surf, mir::input::InputReceptionMode mode) override; + void renamed(mir::scene::Surface const* surf, char const* name); + void start_drag_and_drop(mir::scene::Surface const* surf, std::vector const& handle) override; + void transformation_set_to(mir::scene::Surface const* surf, glm::mat4 const& t) override; + void window_resized_to(mir::scene::Surface const* surf, mir::geometry::Size const& window_size) override; + +private: + std::shared_ptr listener; +}; + +} + +miroil::SurfaceObserverImpl::SurfaceObserverImpl(std::shared_ptr const & wrapped) +: listener(wrapped) +{ +} + +miroil::SurfaceObserverImpl::~SurfaceObserverImpl() = default; + +void miroil::SurfaceObserverImpl::alpha_set_to(mir::scene::Surface const* surf, float alpha) +{ + listener->alpha_set_to(surf, alpha); +} + +void miroil::SurfaceObserverImpl::application_id_set_to(mir::scene::Surface const* surf, std::string const& application_id) +{ + listener->application_id_set_to(surf, application_id); +} + +void miroil::SurfaceObserverImpl::attrib_changed(mir::scene::Surface const* surf, MirWindowAttrib attrib, int value) +{ + listener->attrib_changed(surf, attrib, value); +} + +void miroil::SurfaceObserverImpl::client_surface_close_requested(mir::scene::Surface const* surf) +{ + listener->client_surface_close_requested(surf); +} + +void miroil::SurfaceObserverImpl::content_resized_to(mir::scene::Surface const* surf, mir::geometry::Size const& content_size) +{ + listener->content_resized_to(surf, content_size); +} + +void miroil::SurfaceObserverImpl::cursor_image_removed(mir::scene::Surface const* surf) +{ + listener->cursor_image_removed(surf); +} + +void miroil::SurfaceObserverImpl::cursor_image_set_to(mir::scene::Surface const* surf, mir::graphics::CursorImage const& image) +{ + listener->cursor_image_set_to(surf, image); +} + +void miroil::SurfaceObserverImpl::depth_layer_set_to(mir::scene::Surface const* surf, MirDepthLayer depth_layer) +{ + listener->depth_layer_set_to(surf, depth_layer); +} + +void miroil::SurfaceObserverImpl::frame_posted(mir::scene::Surface const* surf, int frames_available, mir::geometry::Size const& size) +{ + listener->frame_posted(surf, frames_available, size); +} + +void miroil::SurfaceObserverImpl::hidden_set_to(mir::scene::Surface const* surf, bool hide) +{ + listener->hidden_set_to(surf, hide); +} + +void miroil::SurfaceObserverImpl::input_consumed(mir::scene::Surface const* surf, MirEvent const* event) +{ + listener->input_consumed(surf, event); +} + +void miroil::SurfaceObserverImpl::keymap_changed(mir::scene::Surface const* surf, MirInputDeviceId id, std::string const& model, + std::string const& layout, std::string const& variant, std::string const& options) +{ + listener->keymap_changed(surf, id, model, layout, variant, options); +} + +void miroil::SurfaceObserverImpl::moved_to(mir::scene::Surface const* surf, mir::geometry::Point const& top_left) +{ + listener->moved_to(surf, top_left); +} + +void miroil::SurfaceObserverImpl::orientation_set_to(mir::scene::Surface const* surf, MirOrientation orientation) +{ + listener->orientation_set_to(surf, orientation); +} + +void miroil::SurfaceObserverImpl::placed_relative(mir::scene::Surface const* surf, mir::geometry::Rectangle const& placement) +{ + listener->placed_relative(surf, placement); +} + +void miroil::SurfaceObserverImpl::renamed(mir::scene::Surface const* surf, char const* name) +{ + listener->renamed(surf, name); +} + +void miroil::SurfaceObserverImpl::start_drag_and_drop(mir::scene::Surface const* surf, std::vector const& handle) +{ + listener->start_drag_and_drop(surf, handle); +} + +void miroil::SurfaceObserverImpl::transformation_set_to(mir::scene::Surface const* surf, glm::mat4 const& t) +{ + listener->transformation_set_to(surf, t); +} + +void miroil::SurfaceObserverImpl::window_resized_to(mir::scene::Surface const* surf, mir::geometry::Size const& window_size) +{ + listener->window_resized_to(surf, window_size); +} + +void miroil::SurfaceObserverImpl::reception_mode_set_to(mir::scene::Surface const* surf, mir::input::InputReceptionMode mode) +{ + listener->reception_mode_set_to(surf, mode); +} + +miroil::Surface::Surface(std::shared_ptr wrapped) +: wrapped(wrapped) +{ +} + +void miroil::Surface::add_observer(std::shared_ptr const& observer) +{ + auto it = observers.find(observer); + if (it == observers.end()) { + std::shared_ptr impl = std::make_shared(observer); + + wrapped->add_observer(impl); + observers.insert({observer, impl}); + } +} + +bool miroil::Surface::is_confined_to_window() +{ + // Code for Mir < 2.3 + return (wrapped->confine_pointer_state() == mir_pointer_confined_to_window); + + // Code for Mir >= 2.3 + // return (wrapped->confine_pointer_state() == mir_pointer_confined_oneshot || wrapped->confine_pointer_state() == mir_pointer_confined_persistent); +} + +void miroil::Surface::remove_observer(std::shared_ptr const& observer) +{ + auto it = observers.find(observer); + if (it != observers.end()) { + wrapped->remove_observer(it->second); + observers.erase(it); + } +} + +auto miroil::Surface::getWrapped() const +-> mir::scene::Surface * +{ + return wrapped.get(); +} + +int miroil::Surface::buffers_ready_for_compositor(void const* compositor_id) const +{ + return wrapped->buffers_ready_for_compositor(compositor_id); +} + +auto miroil::Surface::generate_renderables(miroil::CompositorID id) const +-> mir::graphics::RenderableList +{ + return wrapped->generate_renderables(id); +} + +void miroil::Surface::set_orientation(MirOrientation orientation) +{ + wrapped->set_orientation(orientation); +} + +void miroil::Surface::set_keymap(MirInputDeviceId id, std::string const& model, std::string const& layout, + std::string const& variant, std::string const& options) +{ + wrapped->set_keymap(id, model, layout, variant, options); +} + +void miroil::Surface::set_confine_pointer_state(MirPointerConfinementState state) +{ + wrapped->set_confine_pointer_state(state); +} + +auto miroil::Surface::parent() const +-> std::shared_ptr +{ + return wrapped->parent(); +} + +auto miroil::Surface::top_left() const +-> mir::geometry::Point +{ + return wrapped->top_left(); +} + +bool miroil::Surface::visible() const +{ + return wrapped->visible(); +} + +int miroil::Surface::configure(MirWindowAttrib attrib, int value) +{ + return wrapped->configure(attrib, value); +} + +int miroil::Surface::query(MirWindowAttrib attrib) const +{ + return wrapped->query(attrib); +} diff --git a/src/miroil/surface_observer.cpp b/src/miroil/surface_observer.cpp new file mode 100644 index 00000000000..215630eceeb --- /dev/null +++ b/src/miroil/surface_observer.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2021 Canonical, Ltd. + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License version 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 warranties of MERCHANTABILITY, + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +miroil::SurfaceObserver::~SurfaceObserver() = default; diff --git a/src/miroil/symbols.map b/src/miroil/symbols.map index 4d386ffe5c7..4e510778ef1 100644 --- a/src/miroil/symbols.map +++ b/src/miroil/symbols.map @@ -22,6 +22,7 @@ global: miroil::GLBuffer::?GLBuffer*; miroil::GLBuffer::GLBuffer*; miroil::GLBuffer::bind*; + miroil::GLBuffer::has_alpha_channel*; miroil::GLBuffer::operator*; miroil::GLBuffer::reset*; miroil::GLBuffer::size*; @@ -63,6 +64,25 @@ global: miroil::PromptSessionManager::suspend_prompt_session*; miroil::SetCompositor::SetCompositor*; miroil::SetCompositor::operator*; + miroil::Surface::?Surface*; + miroil::Surface::Surface*; + miroil::Surface::add_observer*; + miroil::Surface::buffers_ready_for_compositor*; + miroil::Surface::configure*; + miroil::Surface::generate_renderables*; + miroil::Surface::getWrapped*; + miroil::Surface::is_confined_to_window*; + miroil::Surface::parent*; + miroil::Surface::query*; + miroil::Surface::remove_observer*; + miroil::Surface::set_confine_pointer_state*; + miroil::Surface::set_keymap*; + miroil::Surface::set_orientation*; + miroil::Surface::top_left*; + miroil::Surface::visible*; + miroil::SurfaceObserver::?SurfaceObserver*; + miroil::SurfaceObserver::SurfaceObserver*; + miroil::SurfaceObserver::operator*; miroil::dispatch_input_event*; non-virtual?thunk?to?miroil::Compositor::?Compositor*; non-virtual?thunk?to?miroil::DisplayConfigurationPolicy::?DisplayConfigurationPolicy*; @@ -70,6 +90,7 @@ global: non-virtual?thunk?to?miroil::EventBuilder::?EventBuilder*; non-virtual?thunk?to?miroil::InputDeviceObserver::?InputDeviceObserver*; non-virtual?thunk?to?miroil::PromptSessionListener::?PromptSessionListener*; + non-virtual?thunk?to?miroil::SurfaceObserver::?SurfaceObserver*; typeinfo?for?miroil::Compositor; typeinfo?for?miroil::DisplayConfigurationOptions; typeinfo?for?miroil::DisplayConfigurationOptions::DisplayMode; @@ -90,6 +111,8 @@ global: typeinfo?for?miroil::PromptSessionListener; typeinfo?for?miroil::PromptSessionManager; typeinfo?for?miroil::SetCompositor; + typeinfo?for?miroil::Surface; + typeinfo?for?miroil::SurfaceObserver; vtable?for?miroil::Compositor; vtable?for?miroil::DisplayConfigurationOptions; vtable?for?miroil::DisplayConfigurationOptions::DisplayMode; @@ -110,6 +133,8 @@ global: vtable?for?miroil::PromptSessionListener; vtable?for?miroil::PromptSessionManager; vtable?for?miroil::SetCompositor; + vtable?for?miroil::Surface; + vtable?for?miroil::SurfaceObserver; }; local: *;