Atlas - SDL_mirwindow.c

Home / ext / SDL2 / src / video / mir Lines: 1 | Size: 11324 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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, <[email protected]> 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#include "../../events/SDL_keyboard_c.h" 33 34#include "SDL_mirevents.h" 35#include "SDL_mirwindow.h" 36 37#include "SDL_mirdyn.h" 38 39static int 40IsMirWindowValid(MIR_Window* mir_window) 41{ 42 if (!MIR_mir_window_is_valid(mir_window->window)) { 43 const char* error = MIR_mir_window_get_error_message(mir_window->window); 44 return SDL_SetError("Failed to create a mir surface: %s", error); 45 } 46 47 return 1; 48} 49 50static MirPixelFormat 51FindValidPixelFormat(MIR_Data* mir_data) 52{ 53 unsigned int pf_size = 32; 54 unsigned int valid_formats; 55 unsigned int f; 56 57 MirPixelFormat formats[pf_size]; 58 MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats, 59 pf_size, &valid_formats); 60 61 for (f = 0; f < valid_formats; f++) { 62 MirPixelFormat cur_pf = formats[f]; 63 64 if (cur_pf == mir_pixel_format_abgr_8888 || 65 cur_pf == mir_pixel_format_xbgr_8888 || 66 cur_pf == mir_pixel_format_argb_8888 || 67 cur_pf == mir_pixel_format_xrgb_8888) { 68 69 return cur_pf; 70 } 71 } 72 73 return mir_pixel_format_invalid; 74} 75 76int 77MIR_CreateWindow(_THIS, SDL_Window* window) 78{ 79 MIR_Window* mir_window; 80 MIR_Data* mir_data; 81 MirPixelFormat pixel_format; 82 MirBufferUsage buffer_usage; 83 84 MirWindowSpec* spec; 85 86 mir_window = SDL_calloc(1, sizeof(MIR_Window)); 87 if (!mir_window) 88 return SDL_OutOfMemory(); 89 90 mir_data = _this->driverdata; 91 window->driverdata = mir_window; 92 93 if (window->x == SDL_WINDOWPOS_UNDEFINED) 94 window->x = 0; 95 96 if (window->y == SDL_WINDOWPOS_UNDEFINED) 97 window->y = 0; 98 99 mir_window->mir_data = mir_data; 100 mir_window->sdl_window = window; 101 102 if (window->flags & SDL_WINDOW_OPENGL) { 103 pixel_format = MIR_mir_connection_get_egl_pixel_format(mir_data->connection, 104 _this->egl_data->egl_display, 105 _this->egl_data->egl_config); 106 } 107 else { 108 pixel_format = FindValidPixelFormat(mir_data); 109 } 110 111 mir_data->pixel_format = pixel_format; 112 if (pixel_format == mir_pixel_format_invalid) { 113 return SDL_SetError("Failed to find a valid pixel format."); 114 } 115 116 buffer_usage = mir_buffer_usage_hardware; 117 if (mir_data->software) 118 buffer_usage = mir_buffer_usage_software; 119 120 spec = MIR_mir_create_normal_window_spec(mir_data->connection, 121 window->w, 122 window->h); 123 124 MIR_mir_window_spec_set_buffer_usage(spec, buffer_usage); 125 MIR_mir_window_spec_set_name(spec, "Mir surface"); 126 MIR_mir_window_spec_set_pixel_format(spec, pixel_format); 127 128 if (window->flags & SDL_WINDOW_INPUT_FOCUS) 129 SDL_SetKeyboardFocus(window); 130 131 mir_window->window = MIR_mir_create_window_sync(spec); 132 MIR_mir_window_set_event_handler(mir_window->window, MIR_HandleEvent, window); 133 134 MIR_mir_window_spec_release(spec); 135 136 if (!MIR_mir_window_is_valid(mir_window->window)) { 137 return SDL_SetError("Failed to create a mir surface: %s", 138 MIR_mir_window_get_error_message(mir_window->window)); 139 } 140 141 if (window->flags & SDL_WINDOW_OPENGL) { 142 EGLNativeWindowType egl_native_window = 143 (EGLNativeWindowType)MIR_mir_buffer_stream_get_egl_native_window( 144 MIR_mir_window_get_buffer_stream(mir_window->window)); 145 146 mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window); 147 148 if (mir_window->egl_surface == EGL_NO_SURFACE) { 149 return SDL_SetError("Failed to create a window surface %p", 150 _this->egl_data->egl_display); 151 } 152 } 153 else { 154 mir_window->egl_surface = EGL_NO_SURFACE; 155 } 156 157 mir_data->current_window = mir_window; 158 159 return 0; 160} 161 162void 163MIR_DestroyWindow(_THIS, SDL_Window* window) 164{ 165 MIR_Data* mir_data = _this->driverdata; 166 MIR_Window* mir_window = window->driverdata; 167 168 if (mir_data) { 169 SDL_EGL_DestroySurface(_this, mir_window->egl_surface); 170 MIR_mir_window_release_sync(mir_window->window); 171 172 mir_data->current_window = NULL; 173 174 SDL_free(mir_window); 175 } 176 window->driverdata = NULL; 177} 178 179SDL_bool 180MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info) 181{ 182 if (info->version.major == SDL_MAJOR_VERSION && 183 info->version.minor == SDL_MINOR_VERSION) { 184 MIR_Window* mir_window = window->driverdata; 185 186 info->subsystem = SDL_SYSWM_MIR; 187 info->info.mir.connection = mir_window->mir_data->connection; 188 // Cannot change this to window due to it being in the public API 189 info->info.mir.surface = mir_window->window; 190 191 return SDL_TRUE; 192 } 193 194 return SDL_FALSE; 195} 196 197static void 198UpdateMirWindowState(MIR_Data* mir_data, MIR_Window* mir_window, MirWindowState window_state) 199{ 200 if (IsMirWindowValid(mir_window)) { 201 MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection); 202 MIR_mir_window_spec_set_state(spec, window_state); 203 204 MIR_mir_window_apply_spec(mir_window->window, spec); 205 MIR_mir_window_spec_release(spec); 206 } 207} 208 209void 210MIR_SetWindowFullscreen(_THIS, SDL_Window* window, 211 SDL_VideoDisplay* display, 212 SDL_bool fullscreen) 213{ 214 if (IsMirWindowValid(window->driverdata)) { 215 MirWindowState state; 216 217 if (fullscreen) { 218 state = mir_window_state_fullscreen; 219 } 220 else { 221 state = mir_window_state_restored; 222 } 223 224 UpdateMirWindowState(_this->driverdata, window->driverdata, state); 225 } 226} 227 228void 229MIR_MaximizeWindow(_THIS, SDL_Window* window) 230{ 231 UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_maximized); 232} 233 234void 235MIR_MinimizeWindow(_THIS, SDL_Window* window) 236{ 237 UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_minimized); 238} 239 240void 241MIR_RestoreWindow(_THIS, SDL_Window * window) 242{ 243 UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_restored); 244} 245 246void 247MIR_HideWindow(_THIS, SDL_Window* window) 248{ 249 UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_hidden); 250} 251 252void 253MIR_SetWindowSize(_THIS, SDL_Window* window) 254{ 255 MIR_Data* mir_data = _this->driverdata; 256 MIR_Window* mir_window = window->driverdata; 257 258 if (IsMirWindowValid(mir_window)) { 259 MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection); 260 MIR_mir_window_spec_set_width (spec, window->w); 261 MIR_mir_window_spec_set_height(spec, window->h); 262 263 MIR_mir_window_apply_spec(mir_window->window, spec); 264 } 265} 266 267void 268MIR_SetWindowMinimumSize(_THIS, SDL_Window* window) 269{ 270 MIR_Data* mir_data = _this->driverdata; 271 MIR_Window* mir_window = window->driverdata; 272 273 if (IsMirWindowValid(mir_window)) { 274 MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection); 275 MIR_mir_window_spec_set_min_width (spec, window->min_w); 276 MIR_mir_window_spec_set_min_height(spec, window->min_h); 277 278 MIR_mir_window_apply_spec(mir_window->window, spec); 279 } 280} 281 282void 283MIR_SetWindowMaximumSize(_THIS, SDL_Window* window) 284{ 285 MIR_Data* mir_data = _this->driverdata; 286 MIR_Window* mir_window = window->driverdata; 287 288 if (IsMirWindowValid(mir_window)) { 289 MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection); 290 MIR_mir_window_spec_set_max_width (spec, window->max_w); 291 MIR_mir_window_spec_set_max_height(spec, window->max_h); 292 293 MIR_mir_window_apply_spec(mir_window->window, spec); 294 } 295} 296 297void 298MIR_SetWindowTitle(_THIS, SDL_Window* window) 299{ 300 MIR_Data* mir_data = _this->driverdata; 301 MIR_Window* mir_window = window->driverdata; 302 char const* title = window->title ? window->title : ""; 303 MirWindowSpec* spec; 304 305 if (IsMirWindowValid(mir_window) < 0) 306 return; 307 308 spec = MIR_mir_create_window_spec(mir_data->connection); 309 MIR_mir_window_spec_set_name(spec, title); 310 311 MIR_mir_window_apply_spec(mir_window->window, spec); 312 MIR_mir_window_spec_release(spec); 313} 314 315void 316MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed) 317{ 318 MIR_Data* mir_data = _this->driverdata; 319 MIR_Window* mir_window = window->driverdata; 320 MirPointerConfinementState confined = mir_pointer_unconfined; 321 MirWindowSpec* spec; 322 323 if (grabbed) 324 confined = mir_pointer_confined_to_window; 325 326 spec = MIR_mir_create_window_spec(mir_data->connection); 327 MIR_mir_window_spec_set_pointer_confinement(spec, confined); 328 329 MIR_mir_window_apply_spec(mir_window->window, spec); 330 MIR_mir_window_spec_release(spec); 331} 332 333int 334MIR_SetWindowGammaRamp(_THIS, SDL_Window* window, Uint16 const* ramp) 335{ 336 MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata; 337 Uint32 ramp_size = 256; 338 339 // FIXME Need to apply the changes to the output, once that public API function is around 340 if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) { 341 MIR_mir_output_set_gamma(output, 342 ramp + ramp_size * 0, 343 ramp + ramp_size * 1, 344 ramp + ramp_size * 2, 345 ramp_size); 346 return 0; 347 } 348 349 return -1; 350} 351 352int 353MIR_GetWindowGammaRamp(_THIS, SDL_Window* window, Uint16* ramp) 354{ 355 MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata; 356 Uint32 ramp_size = 256; 357 358 if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) { 359 if (MIR_mir_output_get_gamma_size(output) == ramp_size) { 360 MIR_mir_output_get_gamma(output, 361 ramp + ramp_size * 0, 362 ramp + ramp_size * 1, 363 ramp + ramp_size * 2, 364 ramp_size); 365 return 0; 366 } 367 } 368 369 return -1; 370} 371 372#endif /* SDL_VIDEO_DRIVER_MIR */ 373 374/* vi: set ts=4 sw=4 expandtab: */ 375
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.