OGLplus  (0.59.0) a C++ wrapper for rendering APIs

display.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_INTEROP_X11_DISPLAY_HPP
10 #define EAGINE_INTEROP_X11_DISPLAY_HPP
11 
12 #include <eagine/array_size.hpp>
13 #include <eagine/assert.hpp>
14 #include <X11/Xlib.h>
15 #include <cassert>
16 #include <cstdio>
17 #include <stdexcept>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 namespace eagine::x11 {
23 
24 template <typename ObjectType, typename Deleter = int(ObjectType*)>
25 class object {
26 private:
27  ObjectType* _pimpl{nullptr};
28  Deleter* _deleter{nullptr};
29 
30 protected:
31  object(ObjectType* pimpl, Deleter* deleter, const char* error_message)
32  : _pimpl(pimpl)
33  , _deleter(deleter) {
34  EAGINE_ASSERT(_deleter);
35  if(!_pimpl) {
36  throw std::runtime_error(error_message);
37  }
38  }
39 
40 public:
41  object(object&& temp) noexcept
42  : _pimpl(std::exchange(temp._pimpl, nullptr))
43  , _deleter(std::exchange(temp._deleter, nullptr)) {}
44 
45  object(const object&) = delete;
46  auto operator=(object&&) = delete;
47  auto operator=(const object&) = delete;
48 
49  ~object() {
50  if(_pimpl) {
51  _deleter(_pimpl);
52  }
53  }
54 
55  auto get() const noexcept -> ObjectType* {
56  EAGINE_ASSERT(_pimpl);
57  return _pimpl;
58  }
59 
60  operator ObjectType*() const noexcept {
61  return get();
62  }
63 
64  auto operator->() const noexcept -> ObjectType* {
65  return get();
66  }
67 };
68 
69 class display : public object<::Display> {
70 private:
71  static auto _any_event(::Display*, ::XEvent*, ::XPointer) -> Bool {
72  return True;
73  }
74 
75 public:
76  display(const char* name = nullptr)
77  : object<::Display>(
78  ::XOpenDisplay(name),
79  ::XCloseDisplay,
80  "Error opening X Display") {}
81 
82  auto next_event(XEvent& event) const -> bool {
83  return ::XCheckIfEvent(
84  this->get(), &event, &_any_event, ::XPointer()) == True;
85  }
86 };
87 
88 class screen_names : public std::vector<std::string> {
89 public:
90  screen_names() {
91  char namebuf[16];
92  auto name = static_cast<char*>(namebuf);
93  int display = 0;
94  while(true) {
95  int screen = 0;
96  while(true) {
97  std::snprintf( // NOLINT(hicpp-vararg)
98  name,
99  array_size(namebuf),
100  ":%d.%d",
101  display,
102  screen);
103 
104  if(auto tmp{::XOpenDisplay(name)}) {
105  push_back(name);
106  ::XCloseDisplay(tmp);
107  } else if(screen != 0) {
108  break;
109  } else {
110  return;
111  }
112  ++screen;
113  }
114  ++display;
115  }
116  }
117 };
118 
119 template <typename HandleType, typename Deleter = int(::Display*, HandleType)>
120 class display_object {
121 private:
122  const display& _display;
123  HandleType _handle;
124 
125  Deleter* _deleter{nullptr};
126 
127 protected:
128  auto display_ref() const -> auto& {
129  return _display;
130  }
131 
132  display_object(
133  const display& dpy,
134  HandleType handle,
135  Deleter* deleter,
136  const char* error_message)
137  : _display(dpy)
138  , _handle(handle)
139  , _deleter(deleter) {
140  EAGINE_ASSERT(_deleter);
141  if(!_handle) {
142  throw std::runtime_error(error_message);
143  }
144  }
145 
146 public:
147  display_object(display_object&& temp) noexcept
148  : _display(temp._display)
149  , _handle(std::exchange(temp._handle, 0))
150  , _deleter(std::exchange(temp._deleter, nullptr)) {}
151 
152  display_object(const display_object&) = delete;
153  auto operator=(display_object&&) = delete;
154  auto operator=(const display_object&) = delete;
155 
156  ~display_object() {
157  if(_handle) {
158  _deleter(_display, _handle);
159  }
160  }
161 
162  auto handle() const -> HandleType {
163  return _handle;
164  }
165 
166  operator HandleType() const {
167  return handle();
168  }
169 };
170 
171 template <typename HandleType>
172 class base_display_object {
173 private:
174  HandleType _handle;
175 
176 public:
177  template <typename Derived, typename Deleter>
178  base_display_object(const display_object<Derived, Deleter>& derived)
179  : _handle(derived.handle()) {}
180 
181  auto handle() const -> HandleType {
182  return _handle;
183  }
184 
185  operator HandleType() const {
186  return handle();
187  }
188 };
189 
190 } // namespace eagine::x11
191 
192 #endif
X11 wrapper code is placed in this namespace.
Definition: x11.hpp:11
static constexpr auto array_size(const T(&)[N]) noexcept
Returns the number of elements in the array passed as argument.
Definition: array_size.hpp:19

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).