summaryrefslogtreecommitdiff
path: root/src/x/event.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/x/event.h')
-rw-r--r--src/x/event.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/x/event.h b/src/x/event.h
new file mode 100644
index 0000000..8b9dd24
--- /dev/null
+++ b/src/x/event.h
@@ -0,0 +1,137 @@
+// 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 <string.h>
+#include <xcb/xcb.h>
+
+#include <array>
+
+#include "src/x/types.h"
+#include "third_party/abseil/absl/types/variant.h"
+
+namespace x_internal {
+
+template <typename From, typename To>
+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<UnknownEvent, ExposeEvent, ConfigureNotifyEvent,
+ ClientMessageEvent>;
+
+Event FromXcbGenericEvent(const xcb_generic_event_t&) noexcept;
+
+std::array<char, 32> SerializeEvent(const Event&) noexcept;
+
+} // namespace x
+
+#endif // GLPLANET_SRC_X_EVENT_H_