MirAL
window_spec.h
Go to the documentation of this file.
1 /*
2  * Copyright © 2016-2017 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by: Alan Griffiths <alan@octopull.co.uk>
17  */
18 
19 #ifndef MIR_CLIENT_WINDOW_SPEC_H
20 #define MIR_CLIENT_WINDOW_SPEC_H
21 
22 #include <mir/client/window.h>
24 
25 #include <mir_toolkit/mir_connection.h>
26 
27 #if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
28 #include <mir_toolkit/mir_surface.h>
29 #else
30 #include <mir_toolkit/mir_window.h>
31 #endif
32 
33 #include <memory>
34 
35 // Forward compatibility hacks for earlier Mir versions
36 #if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
37 using MirWindowCallback = mir_surface_callback;
38 using MirWindowEventCallback = mir_surface_event_callback;
39 auto const mir_create_window_spec = mir_connection_create_spec_for_changes;
40 auto const mir_window_spec_set_event_handler = mir_surface_spec_set_event_handler;
41 auto const mir_window_spec_set_name = mir_surface_spec_set_name;
42 auto const mir_window_spec_set_width = mir_surface_spec_set_width;
43 auto const mir_window_spec_set_height = mir_surface_spec_set_height;
44 auto const mir_window_spec_set_width_increment = mir_surface_spec_set_width_increment;
45 auto const mir_window_spec_set_height_increment = mir_surface_spec_set_height_increment;
46 auto const mir_window_spec_set_buffer_usage = mir_surface_spec_set_buffer_usage;
47 auto const mir_window_spec_set_pixel_format = mir_surface_spec_set_pixel_format;
48 auto const mir_window_spec_set_type = mir_surface_spec_set_type;
49 auto const mir_window_spec_set_shell_chrome = mir_surface_spec_set_shell_chrome;
50 auto const mir_window_spec_set_min_width = mir_surface_spec_set_min_width;
51 auto const mir_window_spec_set_min_height = mir_surface_spec_set_min_height;
52 auto const mir_window_spec_set_max_width = mir_surface_spec_set_max_width;
53 auto const mir_window_spec_set_max_height = mir_surface_spec_set_max_height;
54 auto const mir_window_spec_set_parent = mir_surface_spec_set_parent;
55 auto const mir_window_spec_set_state = mir_surface_spec_set_state;
56 auto const mir_window_spec_set_fullscreen_on_output = mir_surface_spec_set_fullscreen_on_output;
57 auto const mir_create_window = mir_surface_create;
58 auto const mir_create_window_sync = mir_surface_create_sync;
59 auto const mir_window_apply_spec = mir_surface_apply_spec;
60 auto const mir_window_spec_release = mir_surface_spec_release;
61 
62 #if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
63 auto const mir_window_spec_set_placement = mir_surface_spec_set_placement;
64 #endif
65 #endif
66 
67 namespace mir
68 {
69 namespace client
70 {
72 class WindowSpec
73 {
74 public:
75  explicit WindowSpec(MirWindowSpec* spec) : self{spec, deleter} {}
76 
77  static auto for_normal_window(MirConnection* connection, int width, int height, MirPixelFormat format) -> WindowSpec
78  {
79 #if MIR_CLIENT_VERSION <= MIR_VERSION_NUMBER(3, 4, 0)
80  return WindowSpec{mir_connection_create_spec_for_normal_surface(connection, width, height, format)};
81 #else
82  auto spec = WindowSpec{mir_create_normal_window_spec(connection, width, height)};
83  mir_window_spec_set_pixel_format(spec, format);
84  return spec;
85 #endif
86  }
87 
88 #if MIR_CLIENT_VERSION > MIR_VERSION_NUMBER(3, 4, 0)
89  static auto for_normal_window(MirConnection* connection, int width, int height) -> WindowSpec
90  {
91  return WindowSpec{mir_create_normal_window_spec(connection, width, height)};
92  }
93 #endif
94 
95  static auto for_menu(MirConnection* connection,
96  int width,
97  int height,
98  MirPixelFormat format,
99  MirWindow* parent,
100  MirRectangle* rect,
101  MirEdgeAttachment edge) -> WindowSpec
102  {
103 #if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
104  return WindowSpec{mir_connection_create_spec_for_menu(connection, width, height, format, parent, rect, edge)};
105 #else
106  auto spec = WindowSpec{mir_create_menu_window_spec(connection, width, height, parent, rect, edge)};
107  mir_window_spec_set_pixel_format(spec, format);
108  return spec;
109 #endif
110  }
111 
112 #if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
113  static auto for_tip(MirConnection* connection,
114  int width,
115  int height,
116  MirPixelFormat format,
117  MirWindow* parent,
118  MirRectangle* rect,
119  MirEdgeAttachment edge) -> WindowSpec
120  {
121 #if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
122  return WindowSpec{mir_connection_create_spec_for_tip(connection, width, height, format, parent, rect, edge)};
123 #else
124  auto spec = WindowSpec{mir_create_tip_window_spec(connection, width, height, parent, rect, edge)};
125  mir_window_spec_set_pixel_format(spec, format);
126  return spec;
127 #endif
128  }
129 #endif
130 
131  static auto for_dialog(MirConnection* connection,
132  int width,
133  int height,
134  MirPixelFormat format)-> WindowSpec
135  {
136 #if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
137  return WindowSpec{mir_connection_create_spec_for_dialog(connection, width, height, format)};
138 #else
139  auto spec = WindowSpec{mir_create_dialog_window_spec(connection, width, height)};
140  mir_window_spec_set_pixel_format(spec, format);
141  return spec;
142 #endif
143  }
144 
145  static auto for_dialog(MirConnection* connection,
146  int width,
147  int height,
148  MirPixelFormat format,
149  MirWindow* parent) -> WindowSpec
150  {
151  return for_dialog(connection, width, height, format).set_parent(parent);
152  }
153 
154  static auto for_input_method(MirConnection* connection, int width, int height, MirWindow* parent)
155  {
156 #if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 5, 0)
157  auto spec = WindowSpec{mir_create_input_method_window_spec(connection, width, height)}
158 #else
159  auto spec = WindowSpec{mir_create_surface_spec(connection)}
160  .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
161  .set_pixel_format(mir_pixel_format_invalid) // Required protobuf field for create_window()
162  .set_size(width, height)
163  .set_type(mir_window_type_inputmethod)
164 #endif
165  .set_parent(parent);
166  return spec;
167  }
168 
169  static auto for_satellite(MirConnection* connection, int width, int height, MirWindow* parent)
170  {
171  // There's no mir_create_satellite_window_spec()
172  return WindowSpec{mir_create_window_spec(connection)}
173  .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
174  .set_pixel_format(mir_pixel_format_invalid) // Required protobuf field for create_window()
175  .set_size(width, height)
176  .set_type(mir_window_type_satellite)
177  .set_parent(parent);
178  }
179 
180  static auto for_gloss(MirConnection* connection, int width, int height)
181  {
182  // There's no mir_create_gloss_window_spec()
183  return WindowSpec{mir_create_window_spec(connection)}
184  .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
185  .set_pixel_format(mir_pixel_format_invalid) // Required protobuf field for create_window()
186  .set_size(width, height)
187  .set_type(mir_window_type_gloss);
188  }
189 
190  static auto for_changes(MirConnection* connection) -> WindowSpec
191  {
192  return WindowSpec{mir_create_window_spec(connection)};
193  }
194 
195  auto set_buffer_usage(MirBufferUsage usage) -> WindowSpec&
196  {
197  mir_window_spec_set_buffer_usage(*this, usage);
198  return *this;
199  }
200 
201  auto set_pixel_format(MirPixelFormat format) -> WindowSpec&
202  {
203  mir_window_spec_set_pixel_format(*this, format);
204  return *this;
205  }
206 
207  auto set_type(MirWindowType type) -> WindowSpec&
208  {
209  mir_window_spec_set_type(*this, type);
210  return *this;
211  }
212 
213  auto set_shell_chrome(MirShellChrome chrome) -> WindowSpec&
214  {
215  mir_window_spec_set_shell_chrome(*this, chrome);
216  return *this;
217  }
218 
219  auto set_min_size(int min_width, int min_height) -> WindowSpec&
220  {
221  mir_window_spec_set_min_width(*this, min_width);
222  mir_window_spec_set_min_height(*this, min_height);
223  return *this;
224  }
225 
226  auto set_max_size(int max_width, int max_height) -> WindowSpec&
227  {
228  mir_window_spec_set_max_width(*this, max_width);
229  mir_window_spec_set_max_height(*this, max_height);
230  return *this;
231  }
232 
233  auto set_size_inc(int width_inc, int height_inc) -> WindowSpec&
234  {
235  mir_window_spec_set_width_increment(*this, width_inc);
236  mir_window_spec_set_height_increment(*this, height_inc);
237  return *this;
238  }
239 
240  auto set_size(int width, int height) -> WindowSpec&
241  {
242  mir_window_spec_set_width(*this, width);
243  mir_window_spec_set_height(*this, height);
244  return *this;
245  }
246 
247  auto set_name(char const* name) -> WindowSpec&
248  {
249  mir_window_spec_set_name(*this, name);
250  return *this;
251  }
252 
253  auto set_event_handler(MirWindowEventCallback callback, void* context) -> WindowSpec&
254  {
255  mir_window_spec_set_event_handler(*this, callback, context);
256  return *this;
257  }
258 
259  auto set_fullscreen_on_output(uint32_t output_id) -> WindowSpec&
260  {
261  mir_window_spec_set_fullscreen_on_output(*this, output_id);
262  return *this;
263  }
264 
265 #if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
266  auto set_placement(const MirRectangle* rect,
267  MirPlacementGravity rect_gravity,
268  MirPlacementGravity surface_gravity,
269  MirPlacementHints placement_hints,
270  int offset_dx,
271  int offset_dy) -> WindowSpec&
272  {
273  mir_window_spec_set_placement(*this, rect, rect_gravity, surface_gravity, placement_hints, offset_dx, offset_dy);
274  return *this;
275  }
276 #else
277  auto set_placement(const MirRectangle* /*rect*/,
278  MirPlacementGravity /*rect_gravity*/,
279  MirPlacementGravity /*surface_gravity*/,
280  MirPlacementHints /*placement_hints*/,
281  int /*offset_dx*/,
282  int /*offset_dy*/) -> WindowSpec&
283  {
284  return *this;
285  }
286 #endif
287 
288  auto set_parent(MirWindow* parent) -> WindowSpec&
289  {
290  mir_window_spec_set_parent(*this, parent);
291  return *this;
292  }
293 
294  auto set_state(MirWindowState state) -> WindowSpec&
295  {
296  mir_window_spec_set_state(*this, state);
297  return *this;
298  }
299 
300  template<typename Context>
301  void create_window(void (* callback)(MirWindow*, Context*), Context* context) const
302  {
303  mir_create_window(*this, reinterpret_cast<MirWindowCallback>(callback), context);
304  }
305 
306  auto create_window() const -> Window
307  {
308  return Window{mir_create_window_sync(*this)};
309  }
310 
311  void apply_to(MirWindow* window) const
312  {
313  mir_window_apply_spec(window, *this);
314  }
315 
316  operator MirWindowSpec*() const { return self.get(); }
317 
318 private:
319  static void deleter(MirWindowSpec* spec) { mir_window_spec_release(spec); }
320  std::shared_ptr<MirWindowSpec> self;
321 };
322 
323 // Provide a deleted overload to avoid double release "accidents".
324 void mir_window_spec_release(WindowSpec const& spec) = delete;
325 void mir_surface_spec_release(WindowSpec const& spec) = delete;
326 }
327 }
328 
329 #endif //MIRAL_TOOLKIT_WINDOW_SPEC_H_H
Definition: connection.h:26

Copyright © 2016 Canonical Ltd.
Generated on Fri Mar 3 10:22:14 UTC 2017