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  static auto for_tip(MirConnection* connection,
113  int width,
114  int height,
115  MirPixelFormat format,
116  MirWindow* parent,
117  MirRectangle* rect,
118  MirEdgeAttachment edge) -> WindowSpec
119  {
120 #if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
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 #else
129  (void)rect;
130  (void)edge;
131  return WindowSpec{mir_create_surface_spec(connection)}
132  .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
133  .set_pixel_format(format) // Required protobuf field for create_window()
134  .set_size(width, height)
135  .set_parent(parent)
136  .set_type(mir_window_type_tip);
137 #endif
138  }
139 
140  static auto for_dialog(MirConnection* connection,
141  int width,
142  int height,
143  MirPixelFormat format)-> WindowSpec
144  {
145 #if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 5, 0)
146  return WindowSpec{mir_connection_create_spec_for_dialog(connection, width, height, format)};
147 #else
148  auto spec = WindowSpec{mir_create_dialog_window_spec(connection, width, height)};
149  mir_window_spec_set_pixel_format(spec, format);
150  return spec;
151 #endif
152  }
153 
154  static auto for_dialog(MirConnection* connection,
155  int width,
156  int height,
157  MirPixelFormat format,
158  MirWindow* parent) -> WindowSpec
159  {
160  return for_dialog(connection, width, height, format).set_parent(parent);
161  }
162 
163  static auto for_input_method(MirConnection* connection, int width, int height, MirWindow* parent)
164  {
165 #if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 5, 0)
166  auto spec = WindowSpec{mir_create_input_method_window_spec(connection, width, height)}
167 #else
168  auto spec = WindowSpec{mir_create_surface_spec(connection)}
169  .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
170  .set_pixel_format(mir_pixel_format_invalid) // Required protobuf field for create_window()
171  .set_size(width, height)
172  .set_type(mir_window_type_inputmethod)
173 #endif
174  .set_parent(parent);
175  return spec;
176  }
177 
178  static auto for_satellite(MirConnection* connection, int width, int height, MirWindow* parent)
179  {
180  // There's no mir_create_satellite_window_spec()
181  return WindowSpec{mir_create_window_spec(connection)}
182  .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
183  .set_pixel_format(mir_pixel_format_invalid) // Required protobuf field for create_window()
184  .set_size(width, height)
185  .set_type(mir_window_type_satellite)
186  .set_parent(parent);
187  }
188 
189  static auto for_gloss(MirConnection* connection, int width, int height)
190  {
191  // There's no mir_create_gloss_window_spec()
192  return WindowSpec{mir_create_window_spec(connection)}
193  .set_buffer_usage(mir_buffer_usage_hardware) // Required protobuf field for create_window()
194  .set_pixel_format(mir_pixel_format_invalid) // Required protobuf field for create_window()
195  .set_size(width, height)
196  .set_type(mir_window_type_gloss);
197  }
198 
199  static auto for_changes(MirConnection* connection) -> WindowSpec
200  {
201  return WindowSpec{mir_create_window_spec(connection)};
202  }
203 
204  auto set_buffer_usage(MirBufferUsage usage) -> WindowSpec&
205  {
206  mir_window_spec_set_buffer_usage(*this, usage);
207  return *this;
208  }
209 
210  auto set_pixel_format(MirPixelFormat format) -> WindowSpec&
211  {
212  mir_window_spec_set_pixel_format(*this, format);
213  return *this;
214  }
215 
216  auto set_type(MirWindowType type) -> WindowSpec&
217  {
218  mir_window_spec_set_type(*this, type);
219  return *this;
220  }
221 
222  auto set_shell_chrome(MirShellChrome chrome) -> WindowSpec&
223  {
224  mir_window_spec_set_shell_chrome(*this, chrome);
225  return *this;
226  }
227 
228  auto set_min_size(int min_width, int min_height) -> WindowSpec&
229  {
230  mir_window_spec_set_min_width(*this, min_width);
231  mir_window_spec_set_min_height(*this, min_height);
232  return *this;
233  }
234 
235  auto set_max_size(int max_width, int max_height) -> WindowSpec&
236  {
237  mir_window_spec_set_max_width(*this, max_width);
238  mir_window_spec_set_max_height(*this, max_height);
239  return *this;
240  }
241 
242  auto set_size_inc(int width_inc, int height_inc) -> WindowSpec&
243  {
244  mir_window_spec_set_width_increment(*this, width_inc);
245  mir_window_spec_set_height_increment(*this, height_inc);
246  return *this;
247  }
248 
249  auto set_size(int width, int height) -> WindowSpec&
250  {
251  mir_window_spec_set_width(*this, width);
252  mir_window_spec_set_height(*this, height);
253  return *this;
254  }
255 
256  auto set_name(char const* name) -> WindowSpec&
257  {
258  mir_window_spec_set_name(*this, name);
259  return *this;
260  }
261 
262  auto set_event_handler(MirWindowEventCallback callback, void* context) -> WindowSpec&
263  {
264  mir_window_spec_set_event_handler(*this, callback, context);
265  return *this;
266  }
267 
268  auto set_fullscreen_on_output(uint32_t output_id) -> WindowSpec&
269  {
270  mir_window_spec_set_fullscreen_on_output(*this, output_id);
271  return *this;
272  }
273 
274 #if MIR_CLIENT_VERSION >= MIR_VERSION_NUMBER(3, 4, 0)
275  auto set_placement(const MirRectangle* rect,
276  MirPlacementGravity rect_gravity,
277  MirPlacementGravity surface_gravity,
278  MirPlacementHints placement_hints,
279  int offset_dx,
280  int offset_dy) -> WindowSpec&
281  {
282  mir_window_spec_set_placement(*this, rect, rect_gravity, surface_gravity, placement_hints, offset_dx, offset_dy);
283  return *this;
284  }
285 #else
286  auto set_placement(const MirRectangle* /*rect*/,
287  MirPlacementGravity /*rect_gravity*/,
288  MirPlacementGravity /*surface_gravity*/,
289  MirPlacementHints /*placement_hints*/,
290  int /*offset_dx*/,
291  int /*offset_dy*/) -> WindowSpec&
292  {
293  return *this;
294  }
295 #endif
296 
297  auto set_parent(MirWindow* parent) -> WindowSpec&
298  {
299  mir_window_spec_set_parent(*this, parent);
300  return *this;
301  }
302 
303  auto set_state(MirWindowState state) -> WindowSpec&
304  {
305  mir_window_spec_set_state(*this, state);
306  return *this;
307  }
308 
309  template<typename Context>
310  void create_window(void (* callback)(MirWindow*, Context*), Context* context) const
311  {
312  mir_create_window(*this, reinterpret_cast<MirWindowCallback>(callback), context);
313  }
314 
315  auto create_window() const -> Window
316  {
317  return Window{mir_create_window_sync(*this)};
318  }
319 
320  void apply_to(MirWindow* window) const
321  {
322  mir_window_apply_spec(window, *this);
323  }
324 
325  operator MirWindowSpec*() const { return self.get(); }
326 
327 private:
328  static void deleter(MirWindowSpec* spec) { mir_window_spec_release(spec); }
329  std::shared_ptr<MirWindowSpec> self;
330 };
331 
332 // Provide a deleted overload to avoid double release "accidents".
333 void mir_window_spec_release(WindowSpec const& spec) = delete;
334 void mir_surface_spec_release(WindowSpec const& spec) = delete;
335 }
336 }
337 
338 #endif //MIRAL_TOOLKIT_WINDOW_SPEC_H_H
Definition: blob.h:26

Copyright © 2016 Canonical Ltd.
Generated on Thu Mar 30 14:25:04 UTC 2017