SDL  2.0
SDL_mirwindow.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 /*
23  Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
24 */
25 
26 #include "../../SDL_internal.h"
27 
28 #if SDL_VIDEO_DRIVER_MIR
29 
30 #include "../SDL_egl_c.h"
31 #include "../SDL_sysvideo.h"
32 
33 #include "SDL_mirevents.h"
34 #include "SDL_mirwindow.h"
35 
36 #include "SDL_mirdyn.h"
37 
38 int
39 IsSurfaceValid(MIR_Window* mir_window)
40 {
41  if (!MIR_mir_surface_is_valid(mir_window->surface)) {
42  const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
43  return SDL_SetError("Failed to created a mir surface: %s", error);
44  }
45 
46  return 0;
47 }
48 
49 int
51 {
52  MIR_Window* mir_window;
54  MirPixelFormat pixel_format;
55  MirBufferUsage buffer_usage;
56 
57  MirSurfaceSpec* spec;
58 
59  mir_window = SDL_calloc(1, sizeof(MIR_Window));
60  if (!mir_window)
61  return SDL_OutOfMemory();
62 
63  mir_data = _this->driverdata;
64  window->driverdata = mir_window;
65 
66  if (window->x == SDL_WINDOWPOS_UNDEFINED)
67  window->x = 0;
68 
69  if (window->y == SDL_WINDOWPOS_UNDEFINED)
70  window->y = 0;
71 
72  mir_window->mir_data = mir_data;
73  mir_window->sdl_window = window;
74 
75  pixel_format = MIR_mir_connection_get_egl_pixel_format(mir_data->connection,
76  _this->egl_data->egl_display,
77  _this->egl_data->egl_config);
78 
79  mir_data->pixel_format = pixel_format;
80  if (pixel_format == mir_pixel_format_invalid) {
81  return SDL_SetError("Failed to find a valid pixel format.");
82  }
83 
84  buffer_usage = mir_buffer_usage_hardware;
85  if (mir_data->software)
86  buffer_usage = mir_buffer_usage_software;
87 
88  spec = MIR_mir_connection_create_spec_for_normal_surface(mir_data->connection,
89  window->w,
90  window->h,
91  pixel_format);
92 
93  MIR_mir_surface_spec_set_buffer_usage(spec, buffer_usage);
94  MIR_mir_surface_spec_set_name(spec, "Mir surface");
95 
96  mir_window->surface = MIR_mir_surface_create_sync(spec);
97  MIR_mir_surface_set_event_handler(mir_window->surface, MIR_HandleEvent, window);
98 
99  MIR_mir_surface_spec_release(spec);
100 
101  if (!MIR_mir_surface_is_valid(mir_window->surface)) {
102  const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
103  return SDL_SetError("Failed to created a mir surface: %s", error);
104  }
105 
106  if (window->flags & SDL_WINDOW_OPENGL) {
107  EGLNativeWindowType egl_native_window =
108  (EGLNativeWindowType)MIR_mir_buffer_stream_get_egl_native_window(
109  MIR_mir_surface_get_buffer_stream(mir_window->surface));
110 
111  mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
112 
113  if (mir_window->egl_surface == EGL_NO_SURFACE) {
114  return SDL_SetError("Failed to created a window surface %p",
115  _this->egl_data->egl_display);
116  }
117  }
118  else {
119  mir_window->egl_surface = EGL_NO_SURFACE;
120  }
121 
122  mir_data->current_window = mir_window;
123 
124  return 0;
125 }
126 
127 void
129 {
130  MIR_Data* mir_data = _this->driverdata;
131  MIR_Window* mir_window = window->driverdata;
132 
133  if (mir_data) {
134  SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
135  MIR_mir_surface_release_sync(mir_window->surface);
136 
137  mir_data->current_window = NULL;
138 
139  SDL_free(mir_window);
140  }
141  window->driverdata = NULL;
142 }
143 
144 SDL_bool
146 {
147  if (info->version.major == SDL_MAJOR_VERSION &&
148  info->version.minor == SDL_MINOR_VERSION) {
149  MIR_Window* mir_window = window->driverdata;
150 
151  info->subsystem = SDL_SYSWM_MIR;
152  info->info.mir.connection = mir_window->mir_data->connection;
153  info->info.mir.surface = mir_window->surface;
154 
155  return SDL_TRUE;
156  }
157 
158  return SDL_FALSE;
159 }
160 
161 void
163  SDL_VideoDisplay* display,
164  SDL_bool fullscreen)
165 {
166  MIR_Data* mir_data = _this->driverdata;
167  MIR_Window* mir_window = window->driverdata;
168  MirSurfaceSpec* spec;
169  MirSurfaceState state;
170 
171  if (IsSurfaceValid(mir_window) < 0)
172  return;
173 
174  if (fullscreen) {
175  state = mir_surface_state_fullscreen;
176  } else {
177  state = mir_surface_state_restored;
178  }
179 
180  spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
181  MIR_mir_surface_spec_set_state(spec, state);
182 
183  MIR_mir_surface_apply_spec(mir_window->surface, spec);
184  MIR_mir_surface_spec_release(spec);
185 }
186 
187 void
189 {
190  MIR_Data* mir_data = _this->driverdata;
191  MIR_Window* mir_window = window->driverdata;
192  MirSurfaceSpec* spec;
193 
194  if (IsSurfaceValid(mir_window) < 0)
195  return;
196 
197  spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
198  MIR_mir_surface_spec_set_state(spec, mir_surface_state_maximized);
199 
200  MIR_mir_surface_apply_spec(mir_window->surface, spec);
201  MIR_mir_surface_spec_release(spec);
202 }
203 
204 void
206 {
207  MIR_Data* mir_data = _this->driverdata;
208  MIR_Window* mir_window = window->driverdata;
209  MirSurfaceSpec* spec;
210 
211  if (IsSurfaceValid(mir_window) < 0)
212  return;
213 
214  spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
215  MIR_mir_surface_spec_set_state(spec, mir_surface_state_minimized);
216 
217  MIR_mir_surface_apply_spec(mir_window->surface, spec);
218  MIR_mir_surface_spec_release(spec);
219 }
220 
221 void
223 {
224  MIR_Data* mir_data = _this->driverdata;
225  MIR_Window* mir_window = window->driverdata;
226  MirSurfaceSpec* spec;
227 
228  if (IsSurfaceValid(mir_window) < 0)
229  return;
230 
231  spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
232  MIR_mir_surface_spec_set_state(spec, mir_surface_state_restored);
233 
234  MIR_mir_surface_apply_spec(mir_window->surface, spec);
235  MIR_mir_surface_spec_release(spec);
236 }
237 
238 void
240 {
241  MIR_Data* mir_data = _this->driverdata;
242  MIR_Window* mir_window = window->driverdata;
243  MirSurfaceSpec* spec;
244 
245  if (IsSurfaceValid(mir_window) < 0)
246  return;
247 
248  spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
249  MIR_mir_surface_spec_set_state(spec, mir_surface_state_hidden);
250 
251  MIR_mir_surface_apply_spec(mir_window->surface, spec);
252  MIR_mir_surface_spec_release(spec);
253 }
254 
255 void
257 {
258  MIR_Data* mir_data = _this->driverdata;
259  MIR_Window* mir_window = window->driverdata;
260  MirSurfaceSpec* spec;
261 
262  if (IsSurfaceValid(mir_window) < 0)
263  return;
264 
265  /* You cannot set the x/y of a mir window! So only update w/h */
266  spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
267  MIR_mir_surface_spec_set_width (spec, window->w);
268  MIR_mir_surface_spec_set_height(spec, window->h);
269 
270  MIR_mir_surface_apply_spec(mir_window->surface, spec);
271  MIR_mir_surface_spec_release(spec);
272 }
273 
274 void
276 {
277  MIR_Data* mir_data = _this->driverdata;
278  MIR_Window* mir_window = window->driverdata;
279  MirSurfaceSpec* spec;
280 
281  if (IsSurfaceValid(mir_window) < 0)
282  return;
283 
284  spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
285  MIR_mir_surface_spec_set_min_width (spec, window->min_w);
286  MIR_mir_surface_spec_set_min_height(spec, window->min_h);
287 
288  MIR_mir_surface_apply_spec(mir_window->surface, spec);
289  MIR_mir_surface_spec_release(spec);
290 }
291 
292 void
294 {
295  MIR_Data* mir_data = _this->driverdata;
296  MIR_Window* mir_window = window->driverdata;
297  MirSurfaceSpec* spec;
298 
299  if (IsSurfaceValid(mir_window) < 0)
300  return;
301 
302  spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
303  MIR_mir_surface_spec_set_max_width (spec, window->max_w);
304  MIR_mir_surface_spec_set_max_height(spec, window->max_h);
305 
306  MIR_mir_surface_apply_spec(mir_window->surface, spec);
307  MIR_mir_surface_spec_release(spec);
308 }
309 
310 void
312 {
313  MIR_Data* mir_data = _this->driverdata;
314  MIR_Window* mir_window = window->driverdata;
315  char const* title = window->title ? window->title : "";
316  MirSurfaceSpec* spec;
317 
318  if (IsSurfaceValid(mir_window) < 0)
319  return;
320 
321  spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
322  MIR_mir_surface_spec_set_name(spec, title);
323 
324  MIR_mir_surface_apply_spec(mir_window->surface, spec);
325  MIR_mir_surface_spec_release(spec);
326 }
327 
328 #endif /* SDL_VIDEO_DRIVER_MIR */
329 
330 /* vi: set ts=4 sw=4 expandtab: */
struct SDL_SysWMinfo::@18::@21 mir
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
void MIR_MinimizeWindow(_THIS, SDL_Window *window)
void MIR_HideWindow(_THIS, SDL_Window *window)
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
int MIR_CreateWindow(_THIS, SDL_Window *window)
SDL_Window * window
MirPixelFormat pixel_format
Definition: SDL_mirvideo.h:39
struct xkb_state * state
SDL_version version
Definition: SDL_syswm.h:183
Uint8 major
Definition: SDL_version.h:53
void MIR_DestroyWindow(_THIS, SDL_Window *window)
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:184
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:120
static SDL_VideoDevice * _this
Definition: SDL_video.c:114
SDL_bool
Definition: SDL_stdinc.h:126
SDL_AudioSpec spec
Definition: loopwave.c:35
MirConnection * connection
Definition: SDL_mirvideo.h:36
SDL_bool software
Definition: SDL_mirvideo.h:38
void * SDL_calloc(size_t nmemb, size_t size)
MIR_Window * current_window
Definition: SDL_mirvideo.h:37
#define _THIS
void MIR_RestoreWindow(_THIS, SDL_Window *window)
void SDL_free(void *mem)
void MIR_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
void MIR_MaximizeWindow(_THIS, SDL_Window *window)
MIR_Data * mir_data
Definition: SDL_mirwindow.h:36
Uint8 minor
Definition: SDL_version.h:54
char * title
Definition: SDL_sysvideo.h:75
void MIR_SetWindowTitle(_THIS, SDL_Window *window)
#define NULL
Definition: begin_code.h:143
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
EGLSurface egl_surface
Definition: SDL_mirwindow.h:39
#define SDL_SetError
The type used to identify a window.
Definition: SDL_sysvideo.h:71
Uint32 pixel_format
Definition: testoverlay2.c:152
union SDL_SysWMinfo::@18 info
void * driverdata
Definition: SDL_sysvideo.h:106
MirSurface * surface
Definition: SDL_mirwindow.h:38
Uint32 flags
Definition: SDL_sysvideo.h:81
SDL_bool MIR_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
void MIR_SetWindowMaximumSize(_THIS, SDL_Window *window)
void MIR_HandleEvent(MirSurface *surface, MirEvent const *ev, void *context)
void MIR_SetWindowMinimumSize(_THIS, SDL_Window *window)
void MIR_SetWindowSize(_THIS, SDL_Window *window)
SDL_Window * sdl_window
Definition: SDL_mirwindow.h:35