| /* |
| * Copyright © 2020 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 <http://www.gnu.org/licenses/>. |
| * |
| * Authored by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> |
| * William Wold <william.wold@canonical.com> |
| */ |
| |
| #ifndef WLCS_WL_PROXY_H_ |
| #define WLCS_WL_PROXY_H_ |
| |
| #include "wl_interface_descriptor.h" |
| #include "boost/throw_exception.hpp" |
| #include "boost/current_function.hpp" |
| |
| #include <string> |
| #include <stdexcept> |
| |
| struct wl_proxy; |
| |
| namespace wlcs |
| { |
| template<typename T> |
| class WlHandle |
| { |
| public: |
| explicit WlHandle(T* const proxy) |
| : proxy{proxy}, |
| owns_wl_object{true} |
| { |
| static_assert( |
| WlInterfaceDescriptor<T>::has_specialisation, |
| "Missing specialisation for WlInterfaceDescriptor"); |
| if (proxy == nullptr) |
| { |
| BOOST_THROW_EXCEPTION((std::logic_error{"Attempt to construct a WlHandle from null Wayland object"})); |
| } |
| } |
| |
| ~WlHandle() |
| { |
| if (owns_wl_object) |
| { |
| (*WlInterfaceDescriptor<T>::destructor)(proxy); |
| } |
| } |
| |
| WlHandle(WlHandle&& from) |
| : WlHandle(from.proxy) |
| { |
| from.owns_wl_object = false; |
| } |
| |
| WlHandle(WlHandle const&) = delete; |
| |
| auto operator=(WlHandle&&) -> WlHandle& = delete; |
| auto operator=(WlHandle const&) -> bool = delete; |
| |
| operator T*() const |
| { |
| // This is a precondition failure, but as this is a test-suite let's be generous and make it fail hard and fast |
| if (!owns_wl_object) |
| { |
| std::abort(); |
| } |
| return proxy; |
| } |
| |
| auto wl_proxy() const -> struct wl_proxy* |
| { |
| // This is a precondition failure, but as this is a test-suite let's be generous and make it fail hard and fast |
| if (!owns_wl_object) |
| { |
| std::abort(); |
| } |
| return static_cast<struct wl_proxy*>(proxy); |
| } |
| |
| private: |
| T* const proxy; |
| bool owns_wl_object; |
| }; |
| |
| template<typename WlType> |
| auto wrap_wl_object(WlType* proxy) -> WlHandle<WlType> |
| { |
| return WlHandle<WlType>{proxy}; |
| } |
| |
| } |
| |
| #endif // WLCS_WL_PROXY_H_ |