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 MirPixelFormat
50 FindValidPixelFormat(MIR_Data* mir_data)
51 {
52  unsigned int pf_size = 32;
53  unsigned int valid_formats;
54  unsigned int f;
55 
56  MirPixelFormat formats[pf_size];
57  MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats,
58  pf_size, &valid_formats);
59 
60  for (f = 0; f < valid_formats; f++) {
61  MirPixelFormat cur_pf = formats[f];
62 
63  if (cur_pf == mir_pixel_format_abgr_8888 ||
64  cur_pf == mir_pixel_format_xbgr_8888 ||
65  cur_pf == mir_pixel_format_argb_8888 ||
66  cur_pf == mir_pixel_format_xrgb_8888) {
67 
68  return cur_pf;
69  }
70  }
71 
72  return mir_pixel_format_invalid;
73 }
74 
75 int
77 {
78  MIR_Window* mir_window;
79  MIR_Data* mir_data;
80 
81  MirSurfaceParameters surfaceparm =
82  {
83  .name = "MirSurface",
84  .width = window->w,
85  .height = window->h,
86  .pixel_format = mir_pixel_format_invalid,
87  .buffer_usage = mir_buffer_usage_hardware,
88  .output_id = mir_display_output_id_invalid
89  };
90 
91  MirEventDelegate delegate = {
93  window
94  };
95 
96  mir_window = SDL_calloc(1, sizeof(MIR_Window));
97  if (!mir_window)
98  return SDL_OutOfMemory();
99 
100  mir_data = _this->driverdata;
101  window->driverdata = mir_window;
102 
103  if (mir_data->software)
104  surfaceparm.buffer_usage = mir_buffer_usage_software;
105 
106  if (window->x == SDL_WINDOWPOS_UNDEFINED)
107  window->x = 0;
108 
109  if (window->y == SDL_WINDOWPOS_UNDEFINED)
110  window->y = 0;
111 
112  mir_window->mir_data = mir_data;
113  mir_window->sdl_window = window;
114 
115  surfaceparm.pixel_format = FindValidPixelFormat(mir_data);
116  if (surfaceparm.pixel_format == mir_pixel_format_invalid) {
117  return SDL_SetError("Failed to find a valid pixel format.");
118  }
119 
120  mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
121  if (!MIR_mir_surface_is_valid(mir_window->surface)) {
122  const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
123  return SDL_SetError("Failed to created a mir surface: %s", error);
124  }
125 
126  if (window->flags & SDL_WINDOW_OPENGL) {
127  EGLNativeWindowType egl_native_window =
128  (EGLNativeWindowType)MIR_mir_surface_get_egl_native_window(mir_window->surface);
129 
130  mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
131 
132  if (mir_window->egl_surface == EGL_NO_SURFACE) {
133  return SDL_SetError("Failed to created a window surface %p",
134  _this->egl_data->egl_display);
135  }
136  }
137  else {
138  mir_window->egl_surface = EGL_NO_SURFACE;
139  }
140 
141  MIR_mir_surface_set_event_handler(mir_window->surface, &delegate);
142 
143  return 0;
144 }
145 
146 void
148 {
149  MIR_Data* mir_data = _this->driverdata;
150  MIR_Window* mir_window = window->driverdata;
151 
152  if (mir_data) {
153  SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
154  MIR_mir_surface_release_sync(mir_window->surface);
155 
156  SDL_free(mir_window);
157  }
158  window->driverdata = NULL;
159 }
160 
161 SDL_bool
163 {
164  if (info->version.major == SDL_MAJOR_VERSION &&
165  info->version.minor == SDL_MINOR_VERSION) {
166  MIR_Window* mir_window = window->driverdata;
167 
168  info->subsystem = SDL_SYSWM_MIR;
169  info->info.mir.connection = mir_window->mir_data->connection;
170  info->info.mir.surface = mir_window->surface;
171 
172  return SDL_TRUE;
173  }
174 
175  return SDL_FALSE;
176 }
177 
178 void
180  SDL_VideoDisplay* display,
181  SDL_bool fullscreen)
182 {
183  MIR_Window* mir_window = window->driverdata;
184 
185  if (IsSurfaceValid(mir_window) < 0)
186  return;
187 
188  if (fullscreen) {
189  MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_fullscreen);
190  } else {
191  MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_restored);
192  }
193 }
194 
195 void
197 {
198  MIR_Window* mir_window = window->driverdata;
199 
200  if (IsSurfaceValid(mir_window) < 0)
201  return;
202 
203  MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_maximized);
204 }
205 
206 void
208 {
209  MIR_Window* mir_window = window->driverdata;
210 
211  if (IsSurfaceValid(mir_window) < 0)
212  return;
213 
214  MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_minimized);
215 }
216 
217 void
219 {
220  MIR_Window* mir_window = window->driverdata;
221 
222  if (IsSurfaceValid(mir_window) < 0)
223  return;
224 
225  MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_restored);
226 }
227 
228 #endif /* SDL_VIDEO_DRIVER_MIR */
229 
230 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
void MIR_MinimizeWindow(_THIS, SDL_Window *window)
struct wl_surface * surface
Definition: SDL_syswm.h:242
static SDL_PixelFormat * formats
Definition: SDL_pixels.c:485
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
int MIR_CreateWindow(_THIS, SDL_Window *window)
SDL_Window * window
SDL_version version
Definition: SDL_syswm.h:183
Uint8 major
Definition: SDL_version.h:53
GLfloat f
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
MirConnection * connection
Definition: SDL_mirvideo.h:34
SDL_bool software
Definition: SDL_mirvideo.h:35
void * SDL_calloc(size_t nmemb, size_t size)
#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
void MIR_HandleInput(MirSurface *surface, MirEvent const *ev, void *context)
#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
union SDL_SysWMinfo::@18 info
void * driverdata
Definition: SDL_sysvideo.h:106
MirSurface * surface
Definition: SDL_mirwindow.h:38
SDL_bool MIR_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
SDL_Window * sdl_window
Definition: SDL_mirwindow.h:35