// Copyright 2021, 2022 Benjamin Barenblat // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. // X events. #ifndef GLPLANET_SRC_X_EVENT_H_ #define GLPLANET_SRC_X_EVENT_H_ #include #include #include #include "src/x/types.h" #include "third_party/abseil/absl/types/variant.h" namespace x_internal { template void XcbDowncast(const From& from, To& to) noexcept { static_assert(sizeof(From) >= sizeof(To)); memcpy(&to, &from, sizeof(To)); } } // namespace x_internal namespace x { class ExposeEvent final { public: explicit ExposeEvent(const xcb_expose_event_t& event) noexcept : event_(event) {} explicit ExposeEvent(const xcb_generic_event_t& event) noexcept { x_internal::XcbDowncast(event, event_); } ExposeEvent(const ExposeEvent&) noexcept = default; ExposeEvent& operator=(const ExposeEvent&) noexcept = default; ExposeEvent(ExposeEvent&&) noexcept = default; ExposeEvent& operator=(ExposeEvent&&) noexcept = default; xcb_expose_event_t& AsXcbEvent() noexcept { return event_; } const xcb_expose_event_t& AsXcbEvent() const noexcept { return event_; } private: xcb_expose_event_t event_; }; class ConfigureNotifyEvent final { public: explicit ConfigureNotifyEvent( const xcb_configure_notify_event_t& event) noexcept : event_(event) {} explicit ConfigureNotifyEvent(const xcb_generic_event_t& event) noexcept { x_internal::XcbDowncast(event, event_); } ConfigureNotifyEvent(const ConfigureNotifyEvent&) noexcept = default; ConfigureNotifyEvent& operator=(const ConfigureNotifyEvent&) noexcept = default; ConfigureNotifyEvent(ConfigureNotifyEvent&&) noexcept = default; ConfigureNotifyEvent& operator=(ConfigureNotifyEvent&&) noexcept = default; int width() const noexcept { return event_.width; } int height() const noexcept { return event_.height; } xcb_configure_notify_event_t& AsXcbEvent() noexcept { return event_; } const xcb_configure_notify_event_t& AsXcbEvent() const noexcept { return event_; } private: xcb_configure_notify_event_t event_; }; class ClientMessageEvent final { public: explicit ClientMessageEvent(const xcb_client_message_event_t& event) noexcept : event_(event) {} explicit ClientMessageEvent(const xcb_generic_event_t& event) noexcept { x_internal::XcbDowncast(event, event_); } ClientMessageEvent(const ClientMessageEvent&) noexcept = default; ClientMessageEvent& operator=(const ClientMessageEvent&) noexcept = default; ClientMessageEvent(ClientMessageEvent&&) noexcept = default; ClientMessageEvent& operator=(ClientMessageEvent&&) noexcept = default; Id type() const noexcept { return event_.type; } xcb_client_message_event_t& AsXcbEvent() noexcept { return event_; } const xcb_client_message_event_t& AsXcbEvent() const noexcept { return event_; } private: xcb_client_message_event_t event_; }; // An X event that doesn't fit into any of the previous classes. class UnknownEvent final { public: explicit UnknownEvent(const xcb_generic_event_t& event) : event_(event) {} UnknownEvent(const UnknownEvent&) noexcept = default; UnknownEvent& operator=(const UnknownEvent&) noexcept = default; UnknownEvent(UnknownEvent&&) noexcept = default; UnknownEvent& operator=(UnknownEvent&&) noexcept = default; xcb_generic_event_t& AsXcbEvent() noexcept { return event_; } const xcb_generic_event_t& AsXcbEvent() const noexcept { return event_; } private: xcb_generic_event_t event_; }; using Event = absl::variant; Event FromXcbGenericEvent(const xcb_generic_event_t&) noexcept; std::array SerializeEvent(const Event&) noexcept; } // namespace x #endif // GLPLANET_SRC_X_EVENT_H_