0eb54be014addf4d73d67e328ea1d97486b549ba
[platform/upstream/SDL.git] / src / video / mir / SDL_mirwindow.c
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
76 MIR_CreateWindow(_THIS, SDL_Window* window)
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 = {
92         MIR_HandleInput,
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
147 MIR_DestroyWindow(_THIS, SDL_Window* window)
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
162 MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info)
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
179 MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
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
196 MIR_MaximizeWindow(_THIS, SDL_Window* window)
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
207 MIR_MinimizeWindow(_THIS, SDL_Window* window)
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
218 MIR_RestoreWindow(_THIS, SDL_Window * window)
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: */