Atlas - SDL_mirvideo.c
Home / ext / SDL2 / src / video / mir Lines: 1 | Size: 12665 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_assert.h" 31#include "SDL_log.h" 32 33#include "SDL_mirwindow.h" 34#include "SDL_video.h" 35 36#include "SDL_mirframebuffer.h" 37#include "SDL_mirmouse.h" 38#include "SDL_miropengl.h" 39#include "SDL_mirvideo.h" 40#include "SDL_mirvulkan.h" 41 42#include "SDL_mirdyn.h" 43 44#define MIR_DRIVER_NAME "mir" 45 46static const Uint32 mir_pixel_format_to_sdl_format[] = { 47 SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */ 48 SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */ 49 SDL_PIXELFORMAT_BGR888, /* mir_pixel_format_xbgr_8888 */ 50 SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */ 51 SDL_PIXELFORMAT_RGB888, /* mir_pixel_format_xrgb_8888 */ 52 SDL_PIXELFORMAT_BGR24, /* mir_pixel_format_bgr_888 */ 53 SDL_PIXELFORMAT_RGB24, /* mir_pixel_format_rgb_888 */ 54 SDL_PIXELFORMAT_RGB565, /* mir_pixel_format_rgb_565 */ 55 SDL_PIXELFORMAT_RGBA5551, /* mir_pixel_format_rgba_5551 */ 56 SDL_PIXELFORMAT_RGBA4444 /* mir_pixel_format_rgba_4444 */ 57}; 58 59Uint32 60MIR_GetSDLPixelFormat(MirPixelFormat format) 61{ 62 return mir_pixel_format_to_sdl_format[format]; 63} 64 65static int 66MIR_VideoInit(_THIS); 67 68static void 69MIR_VideoQuit(_THIS); 70 71static int 72MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect); 73 74static void 75MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display); 76 77static int 78MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode); 79 80static SDL_WindowShaper* 81MIR_CreateShaper(SDL_Window* window) 82{ 83 /* FIXME Im not sure if mir support this atm, will have to come back to this */ 84 return NULL; 85} 86 87static int 88MIR_SetWindowShape(SDL_WindowShaper* shaper, SDL_Surface* shape, SDL_WindowShapeMode* shape_mode) 89{ 90 return SDL_Unsupported(); 91} 92 93static int 94MIR_ResizeWindowShape(SDL_Window* window) 95{ 96 return SDL_Unsupported(); 97} 98 99static int 100MIR_Available() 101{ 102 int available = 0; 103 104 if (SDL_MIR_LoadSymbols()) { 105 106 /* Lets ensure we can connect to the mir server */ 107 MirConnection* connection = MIR_mir_connect_sync(NULL, SDL_FUNCTION); 108 109 if (!MIR_mir_connection_is_valid(connection)) { 110 SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Unable to connect to the mir server %s", 111 MIR_mir_connection_get_error_message(connection)); 112 113 return available; 114 } 115 116 MIR_mir_connection_release(connection); 117 118 available = 1; 119 SDL_MIR_UnloadSymbols(); 120 } 121 122 return available; 123} 124 125static void 126MIR_DeleteDevice(SDL_VideoDevice* device) 127{ 128 SDL_free(device); 129 SDL_MIR_UnloadSymbols(); 130} 131 132static void 133MIR_PumpEvents(_THIS) 134{ 135} 136 137static SDL_VideoDevice* 138MIR_CreateDevice(int device_index) 139{ 140 MIR_Data* mir_data; 141 SDL_VideoDevice* device = NULL; 142 143 if (!SDL_MIR_LoadSymbols()) { 144 return NULL; 145 } 146 147 device = SDL_calloc(1, sizeof(SDL_VideoDevice)); 148 if (!device) { 149 SDL_MIR_UnloadSymbols(); 150 SDL_OutOfMemory(); 151 return NULL; 152 } 153 154 mir_data = SDL_calloc(1, sizeof(MIR_Data)); 155 if (!mir_data) { 156 SDL_free(device); 157 SDL_MIR_UnloadSymbols(); 158 SDL_OutOfMemory(); 159 return NULL; 160 } 161 162 device->driverdata = mir_data; 163 164 /* mirvideo */ 165 device->VideoInit = MIR_VideoInit; 166 device->VideoQuit = MIR_VideoQuit; 167 device->GetDisplayBounds = MIR_GetDisplayBounds; 168 device->GetDisplayModes = MIR_GetDisplayModes; 169 device->SetDisplayMode = MIR_SetDisplayMode; 170 device->free = MIR_DeleteDevice; 171 172 /* miropengles */ 173 device->GL_SwapWindow = MIR_GL_SwapWindow; 174 device->GL_MakeCurrent = MIR_GL_MakeCurrent; 175 device->GL_CreateContext = MIR_GL_CreateContext; 176 device->GL_DeleteContext = MIR_GL_DeleteContext; 177 device->GL_LoadLibrary = MIR_GL_LoadLibrary; 178 device->GL_UnloadLibrary = MIR_GL_UnloadLibrary; 179 device->GL_GetSwapInterval = MIR_GL_GetSwapInterval; 180 device->GL_SetSwapInterval = MIR_GL_SetSwapInterval; 181 device->GL_GetProcAddress = MIR_GL_GetProcAddress; 182 183 /* mirwindow */ 184 device->CreateSDLWindow = MIR_CreateWindow; 185 device->DestroyWindow = MIR_DestroyWindow; 186 device->GetWindowWMInfo = MIR_GetWindowWMInfo; 187 device->SetWindowFullscreen = MIR_SetWindowFullscreen; 188 device->MaximizeWindow = MIR_MaximizeWindow; 189 device->MinimizeWindow = MIR_MinimizeWindow; 190 device->RestoreWindow = MIR_RestoreWindow; 191 device->ShowWindow = MIR_RestoreWindow; 192 device->HideWindow = MIR_HideWindow; 193 device->SetWindowSize = MIR_SetWindowSize; 194 device->SetWindowMinimumSize = MIR_SetWindowMinimumSize; 195 device->SetWindowMaximumSize = MIR_SetWindowMaximumSize; 196 device->SetWindowTitle = MIR_SetWindowTitle; 197 device->SetWindowGrab = MIR_SetWindowGrab; 198 device->SetWindowGammaRamp = MIR_SetWindowGammaRamp; 199 device->GetWindowGammaRamp = MIR_GetWindowGammaRamp; 200 201 device->CreateSDLWindowFrom = NULL; 202 device->SetWindowIcon = NULL; 203 device->RaiseWindow = NULL; 204 device->SetWindowBordered = NULL; 205 device->SetWindowResizable = NULL; 206 device->OnWindowEnter = NULL; 207 device->SetWindowPosition = NULL; 208 209 /* mirframebuffer */ 210 device->CreateWindowFramebuffer = MIR_CreateWindowFramebuffer; 211 device->UpdateWindowFramebuffer = MIR_UpdateWindowFramebuffer; 212 device->DestroyWindowFramebuffer = MIR_DestroyWindowFramebuffer; 213 214 device->shape_driver.CreateShaper = MIR_CreateShaper; 215 device->shape_driver.SetWindowShape = MIR_SetWindowShape; 216 device->shape_driver.ResizeWindowShape = MIR_ResizeWindowShape; 217 218 device->PumpEvents = MIR_PumpEvents; 219 220 device->SuspendScreenSaver = NULL; 221 222 device->StartTextInput = NULL; 223 device->StopTextInput = NULL; 224 device->SetTextInputRect = NULL; 225 226 device->HasScreenKeyboardSupport = NULL; 227 device->ShowScreenKeyboard = NULL; 228 device->HideScreenKeyboard = NULL; 229 device->IsScreenKeyboardShown = NULL; 230 231 device->SetClipboardText = NULL; 232 device->GetClipboardText = NULL; 233 device->HasClipboardText = NULL; 234 235 device->ShowMessageBox = NULL; 236 237#if SDL_VIDEO_VULKAN 238 device->Vulkan_LoadLibrary = MIR_Vulkan_LoadLibrary; 239 device->Vulkan_UnloadLibrary = MIR_Vulkan_UnloadLibrary; 240 device->Vulkan_GetInstanceExtensions = MIR_Vulkan_GetInstanceExtensions; 241 device->Vulkan_CreateSurface = MIR_Vulkan_CreateSurface; 242#endif 243 244 return device; 245} 246 247VideoBootStrap MIR_bootstrap = { 248 MIR_DRIVER_NAME, "SDL Mir video driver", 249 MIR_Available, MIR_CreateDevice 250}; 251 252static SDL_DisplayMode 253MIR_ConvertModeToSDLMode(MirOutputMode const* mode, MirPixelFormat format) 254{ 255 SDL_DisplayMode sdl_mode = { 256 .format = MIR_GetSDLPixelFormat(format), 257 .w = MIR_mir_output_mode_get_width(mode), 258 .h = MIR_mir_output_mode_get_height(mode), 259 .refresh_rate = MIR_mir_output_mode_get_refresh_rate(mode), 260 .driverdata = NULL 261 }; 262 263 return sdl_mode; 264} 265 266static void 267MIR_AddModeToDisplay(SDL_VideoDisplay* display, MirOutputMode const* mode, MirPixelFormat format) 268{ 269 SDL_DisplayMode sdl_mode = MIR_ConvertModeToSDLMode(mode, format); 270 SDL_AddDisplayMode(display, &sdl_mode); 271} 272 273static void 274MIR_InitDisplayFromOutput(_THIS, MirOutput* output) 275{ 276 SDL_VideoDisplay display; 277 int m; 278 279 MirPixelFormat format = MIR_mir_output_get_current_pixel_format(output); 280 int num_modes = MIR_mir_output_get_num_modes(output); 281 SDL_DisplayMode current_mode = MIR_ConvertModeToSDLMode(MIR_mir_output_get_current_mode(output), format); 282 283 SDL_zero(display); 284 285 // Unfortunate cast, but SDL_AddVideoDisplay will strdup this pointer so its read-only in this case. 286 display.name = (char*)MIR_mir_output_type_name(MIR_mir_output_get_type(output)); 287 288 for (m = 0; m < num_modes; m++) { 289 MirOutputMode const* mode = MIR_mir_output_get_mode(output, m); 290 MIR_AddModeToDisplay(&display, mode, format); 291 } 292 293 display.desktop_mode = current_mode; 294 display.current_mode = current_mode; 295 296 display.driverdata = output; 297 SDL_AddVideoDisplay(&display); 298} 299 300static void 301MIR_InitDisplays(_THIS) 302{ 303 MIR_Data* mir_data = _this->driverdata; 304 int num_outputs = MIR_mir_display_config_get_num_outputs(mir_data->display_config); 305 int d; 306 307 for (d = 0; d < num_outputs; d++) { 308 MirOutput* output = MIR_mir_display_config_get_mutable_output(mir_data->display_config, d); 309 SDL_bool enabled = MIR_mir_output_is_enabled(output); 310 MirOutputConnectionState state = MIR_mir_output_get_connection_state(output); 311 312 if (enabled && state == mir_output_connection_state_connected) { 313 MIR_InitDisplayFromOutput(_this, output); 314 } 315 } 316} 317 318static int 319MIR_VideoInit(_THIS) 320{ 321 MIR_Data* mir_data = _this->driverdata; 322 323 mir_data->connection = MIR_mir_connect_sync(NULL, SDL_FUNCTION); 324 mir_data->current_window = NULL; 325 mir_data->software = SDL_FALSE; 326 mir_data->pixel_format = mir_pixel_format_invalid; 327 328 if (!MIR_mir_connection_is_valid(mir_data->connection)) { 329 return SDL_SetError("Failed to connect to the mir server: %s", 330 MIR_mir_connection_get_error_message(mir_data->connection)); 331 } 332 333 mir_data->display_config = MIR_mir_connection_create_display_configuration(mir_data->connection); 334 335 MIR_InitDisplays(_this); 336 MIR_InitMouse(); 337 338 return 0; 339} 340 341static void 342MIR_CleanUpDisplayConfig(_THIS) 343{ 344 MIR_Data* mir_data = _this->driverdata; 345 int i; 346 347 // SDL_VideoQuit frees the display driverdata, we own it not them 348 for (i = 0; i < _this->num_displays; ++i) { 349 _this->displays[i].driverdata = NULL; 350 } 351 352 MIR_mir_display_config_release(mir_data->display_config); 353} 354 355static void 356MIR_VideoQuit(_THIS) 357{ 358 MIR_Data* mir_data = _this->driverdata; 359 360 MIR_CleanUpDisplayConfig(_this); 361 362 MIR_FiniMouse(); 363 364 MIR_GL_DeleteContext(_this, NULL); 365 MIR_GL_UnloadLibrary(_this); 366 367 MIR_mir_connection_release(mir_data->connection); 368 369 SDL_free(mir_data); 370 _this->driverdata = NULL; 371} 372 373static int 374MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect) 375{ 376 MirOutput const* output = display->driverdata; 377 378 rect->x = MIR_mir_output_get_position_x(output); 379 rect->y = MIR_mir_output_get_position_y(output); 380 rect->w = display->current_mode.w; 381 rect->h = display->current_mode.h; 382 383 return 0; 384} 385 386static void 387MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* display) 388{ 389} 390 391static int 392MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* display, SDL_DisplayMode* mode) 393{ 394 int m; 395 MirOutput* output = display->driverdata; 396 int num_modes = MIR_mir_output_get_num_modes(output); 397 Uint32 sdl_format = MIR_GetSDLPixelFormat( 398 MIR_mir_output_get_current_pixel_format(output)); 399 400 for (m = 0; m < num_modes; m++) { 401 MirOutputMode const* mir_mode = MIR_mir_output_get_mode(output, m); 402 int width = MIR_mir_output_mode_get_width(mir_mode); 403 int height = MIR_mir_output_mode_get_height(mir_mode); 404 double refresh_rate = MIR_mir_output_mode_get_refresh_rate(mir_mode); 405 406 if (mode->format == sdl_format && 407 mode->w == width && 408 mode->h == height && 409 mode->refresh_rate == refresh_rate) { 410 411 // FIXME Currently wont actually *set* anything. Need to wait for applying display changes 412 MIR_mir_output_set_current_mode(output, mir_mode); 413 return 0; 414 } 415 } 416 417 return -1; 418} 419 420#endif /* SDL_VIDEO_DRIVER_MIR */ 421 422/* vi: set ts=4 sw=4 expandtab: */ 423 424[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.