cave-story-solaris/external/SDL2/src/video/mir/SDL_mirvideo.c
Clownacy ac465d29b4 Mean CMake dependency overhaul
I'm taking a page from Dolphin's book, and including copies of each
dependency's source code. This combines the ease of use of including
pre-built libraries instead of needing to navigate a package manager
 - as is (or was) the case for MSVC - with the portability of using
packages. Granted, this method's more of a jack of all trades,
master of none, since it's *less* user-friendly than prebuilt
packages (compilation times), and you don't get the per-distro
compatibility fixes you'd get from a package manager.

You can still use system libs if you want. In fact, it's still the
default behaviour: compiling the libs manually is just a fallback.
I'll add an option to force-enable this soon, however, since it's a
nicer way to produce static MSYS2 builds than the hackish nightmare
that I was using before. Not to mention, having my own copy of the
sources means I can provide my own fixes and tweaks your package
manager may not. For example, I can combine MSYS2's FreeType
subpixel rendering with vcpkg's fix for SDL2 exporting its symbols
in static builds.
2019-04-26 01:52:02 +01:00

423 lines
12 KiB
C

/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_MIR
#include "SDL_assert.h"
#include "SDL_log.h"
#include "SDL_mirwindow.h"
#include "SDL_video.h"
#include "SDL_mirframebuffer.h"
#include "SDL_mirmouse.h"
#include "SDL_miropengl.h"
#include "SDL_mirvideo.h"
#include "SDL_mirvulkan.h"
#include "SDL_mirdyn.h"
#define MIR_DRIVER_NAME "mir"
static const Uint32 mir_pixel_format_to_sdl_format[] = {
SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */
SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */
SDL_PIXELFORMAT_BGR888, /* mir_pixel_format_xbgr_8888 */
SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */
SDL_PIXELFORMAT_RGB888, /* mir_pixel_format_xrgb_8888 */
SDL_PIXELFORMAT_BGR24, /* mir_pixel_format_bgr_888 */
SDL_PIXELFORMAT_RGB24, /* mir_pixel_format_rgb_888 */
SDL_PIXELFORMAT_RGB565, /* mir_pixel_format_rgb_565 */
SDL_PIXELFORMAT_RGBA5551, /* mir_pixel_format_rgba_5551 */
SDL_PIXELFORMAT_RGBA4444 /* mir_pixel_format_rgba_4444 */
};
Uint32
MIR_GetSDLPixelFormat(MirPixelFormat format)
{
return mir_pixel_format_to_sdl_format[format];
}
static int
MIR_VideoInit(_THIS);
static void
MIR_VideoQuit(_THIS);
static int
MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect);
static void
MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display);
static int
MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode);
static SDL_WindowShaper*
MIR_CreateShaper(SDL_Window* window)
{
/* FIXME Im not sure if mir support this atm, will have to come back to this */
return NULL;
}
static int
MIR_SetWindowShape(SDL_WindowShaper* shaper, SDL_Surface* shape, SDL_WindowShapeMode* shape_mode)
{
return SDL_Unsupported();
}
static int
MIR_ResizeWindowShape(SDL_Window* window)
{
return SDL_Unsupported();
}
static int
MIR_Available()
{
int available = 0;
if (SDL_MIR_LoadSymbols()) {
/* Lets ensure we can connect to the mir server */
MirConnection* connection = MIR_mir_connect_sync(NULL, SDL_FUNCTION);
if (!MIR_mir_connection_is_valid(connection)) {
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Unable to connect to the mir server %s",
MIR_mir_connection_get_error_message(connection));
return available;
}
MIR_mir_connection_release(connection);
available = 1;
SDL_MIR_UnloadSymbols();
}
return available;
}
static void
MIR_DeleteDevice(SDL_VideoDevice* device)
{
SDL_free(device);
SDL_MIR_UnloadSymbols();
}
static void
MIR_PumpEvents(_THIS)
{
}
static SDL_VideoDevice*
MIR_CreateDevice(int device_index)
{
MIR_Data* mir_data;
SDL_VideoDevice* device = NULL;
if (!SDL_MIR_LoadSymbols()) {
return NULL;
}
device = SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
SDL_MIR_UnloadSymbols();
SDL_OutOfMemory();
return NULL;
}
mir_data = SDL_calloc(1, sizeof(MIR_Data));
if (!mir_data) {
SDL_free(device);
SDL_MIR_UnloadSymbols();
SDL_OutOfMemory();
return NULL;
}
device->driverdata = mir_data;
/* mirvideo */
device->VideoInit = MIR_VideoInit;
device->VideoQuit = MIR_VideoQuit;
device->GetDisplayBounds = MIR_GetDisplayBounds;
device->GetDisplayModes = MIR_GetDisplayModes;
device->SetDisplayMode = MIR_SetDisplayMode;
device->free = MIR_DeleteDevice;
/* miropengles */
device->GL_SwapWindow = MIR_GL_SwapWindow;
device->GL_MakeCurrent = MIR_GL_MakeCurrent;
device->GL_CreateContext = MIR_GL_CreateContext;
device->GL_DeleteContext = MIR_GL_DeleteContext;
device->GL_LoadLibrary = MIR_GL_LoadLibrary;
device->GL_UnloadLibrary = MIR_GL_UnloadLibrary;
device->GL_GetSwapInterval = MIR_GL_GetSwapInterval;
device->GL_SetSwapInterval = MIR_GL_SetSwapInterval;
device->GL_GetProcAddress = MIR_GL_GetProcAddress;
/* mirwindow */
device->CreateSDLWindow = MIR_CreateWindow;
device->DestroyWindow = MIR_DestroyWindow;
device->GetWindowWMInfo = MIR_GetWindowWMInfo;
device->SetWindowFullscreen = MIR_SetWindowFullscreen;
device->MaximizeWindow = MIR_MaximizeWindow;
device->MinimizeWindow = MIR_MinimizeWindow;
device->RestoreWindow = MIR_RestoreWindow;
device->ShowWindow = MIR_RestoreWindow;
device->HideWindow = MIR_HideWindow;
device->SetWindowSize = MIR_SetWindowSize;
device->SetWindowMinimumSize = MIR_SetWindowMinimumSize;
device->SetWindowMaximumSize = MIR_SetWindowMaximumSize;
device->SetWindowTitle = MIR_SetWindowTitle;
device->SetWindowGrab = MIR_SetWindowGrab;
device->SetWindowGammaRamp = MIR_SetWindowGammaRamp;
device->GetWindowGammaRamp = MIR_GetWindowGammaRamp;
device->CreateSDLWindowFrom = NULL;
device->SetWindowIcon = NULL;
device->RaiseWindow = NULL;
device->SetWindowBordered = NULL;
device->SetWindowResizable = NULL;
device->OnWindowEnter = NULL;
device->SetWindowPosition = NULL;
/* mirframebuffer */
device->CreateWindowFramebuffer = MIR_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = MIR_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = MIR_DestroyWindowFramebuffer;
device->shape_driver.CreateShaper = MIR_CreateShaper;
device->shape_driver.SetWindowShape = MIR_SetWindowShape;
device->shape_driver.ResizeWindowShape = MIR_ResizeWindowShape;
device->PumpEvents = MIR_PumpEvents;
device->SuspendScreenSaver = NULL;
device->StartTextInput = NULL;
device->StopTextInput = NULL;
device->SetTextInputRect = NULL;
device->HasScreenKeyboardSupport = NULL;
device->ShowScreenKeyboard = NULL;
device->HideScreenKeyboard = NULL;
device->IsScreenKeyboardShown = NULL;
device->SetClipboardText = NULL;
device->GetClipboardText = NULL;
device->HasClipboardText = NULL;
device->ShowMessageBox = NULL;
#if SDL_VIDEO_VULKAN
device->Vulkan_LoadLibrary = MIR_Vulkan_LoadLibrary;
device->Vulkan_UnloadLibrary = MIR_Vulkan_UnloadLibrary;
device->Vulkan_GetInstanceExtensions = MIR_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = MIR_Vulkan_CreateSurface;
#endif
return device;
}
VideoBootStrap MIR_bootstrap = {
MIR_DRIVER_NAME, "SDL Mir video driver",
MIR_Available, MIR_CreateDevice
};
static SDL_DisplayMode
MIR_ConvertModeToSDLMode(MirOutputMode const* mode, MirPixelFormat format)
{
SDL_DisplayMode sdl_mode = {
.format = MIR_GetSDLPixelFormat(format),
.w = MIR_mir_output_mode_get_width(mode),
.h = MIR_mir_output_mode_get_height(mode),
.refresh_rate = MIR_mir_output_mode_get_refresh_rate(mode),
.driverdata = NULL
};
return sdl_mode;
}
static void
MIR_AddModeToDisplay(SDL_VideoDisplay* display, MirOutputMode const* mode, MirPixelFormat format)
{
SDL_DisplayMode sdl_mode = MIR_ConvertModeToSDLMode(mode, format);
SDL_AddDisplayMode(display, &sdl_mode);
}
static void
MIR_InitDisplayFromOutput(_THIS, MirOutput* output)
{
SDL_VideoDisplay display;
int m;
MirPixelFormat format = MIR_mir_output_get_current_pixel_format(output);
int num_modes = MIR_mir_output_get_num_modes(output);
SDL_DisplayMode current_mode = MIR_ConvertModeToSDLMode(MIR_mir_output_get_current_mode(output), format);
SDL_zero(display);
// Unfortunate cast, but SDL_AddVideoDisplay will strdup this pointer so its read-only in this case.
display.name = (char*)MIR_mir_output_type_name(MIR_mir_output_get_type(output));
for (m = 0; m < num_modes; m++) {
MirOutputMode const* mode = MIR_mir_output_get_mode(output, m);
MIR_AddModeToDisplay(&display, mode, format);
}
display.desktop_mode = current_mode;
display.current_mode = current_mode;
display.driverdata = output;
SDL_AddVideoDisplay(&display);
}
static void
MIR_InitDisplays(_THIS)
{
MIR_Data* mir_data = _this->driverdata;
int num_outputs = MIR_mir_display_config_get_num_outputs(mir_data->display_config);
int d;
for (d = 0; d < num_outputs; d++) {
MirOutput* output = MIR_mir_display_config_get_mutable_output(mir_data->display_config, d);
SDL_bool enabled = MIR_mir_output_is_enabled(output);
MirOutputConnectionState state = MIR_mir_output_get_connection_state(output);
if (enabled && state == mir_output_connection_state_connected) {
MIR_InitDisplayFromOutput(_this, output);
}
}
}
static int
MIR_VideoInit(_THIS)
{
MIR_Data* mir_data = _this->driverdata;
mir_data->connection = MIR_mir_connect_sync(NULL, SDL_FUNCTION);
mir_data->current_window = NULL;
mir_data->software = SDL_FALSE;
mir_data->pixel_format = mir_pixel_format_invalid;
if (!MIR_mir_connection_is_valid(mir_data->connection)) {
return SDL_SetError("Failed to connect to the mir server: %s",
MIR_mir_connection_get_error_message(mir_data->connection));
}
mir_data->display_config = MIR_mir_connection_create_display_configuration(mir_data->connection);
MIR_InitDisplays(_this);
MIR_InitMouse();
return 0;
}
static void
MIR_CleanUpDisplayConfig(_THIS)
{
MIR_Data* mir_data = _this->driverdata;
int i;
// SDL_VideoQuit frees the display driverdata, we own it not them
for (i = 0; i < _this->num_displays; ++i) {
_this->displays[i].driverdata = NULL;
}
MIR_mir_display_config_release(mir_data->display_config);
}
static void
MIR_VideoQuit(_THIS)
{
MIR_Data* mir_data = _this->driverdata;
MIR_CleanUpDisplayConfig(_this);
MIR_FiniMouse();
MIR_GL_DeleteContext(_this, NULL);
MIR_GL_UnloadLibrary(_this);
MIR_mir_connection_release(mir_data->connection);
SDL_free(mir_data);
_this->driverdata = NULL;
}
static int
MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect)
{
MirOutput const* output = display->driverdata;
rect->x = MIR_mir_output_get_position_x(output);
rect->y = MIR_mir_output_get_position_y(output);
rect->w = display->current_mode.w;
rect->h = display->current_mode.h;
return 0;
}
static void
MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* display)
{
}
static int
MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* display, SDL_DisplayMode* mode)
{
int m;
MirOutput* output = display->driverdata;
int num_modes = MIR_mir_output_get_num_modes(output);
Uint32 sdl_format = MIR_GetSDLPixelFormat(
MIR_mir_output_get_current_pixel_format(output));
for (m = 0; m < num_modes; m++) {
MirOutputMode const* mir_mode = MIR_mir_output_get_mode(output, m);
int width = MIR_mir_output_mode_get_width(mir_mode);
int height = MIR_mir_output_mode_get_height(mir_mode);
double refresh_rate = MIR_mir_output_mode_get_refresh_rate(mir_mode);
if (mode->format == sdl_format &&
mode->w == width &&
mode->h == height &&
mode->refresh_rate == refresh_rate) {
// FIXME Currently wont actually *set* anything. Need to wait for applying display changes
MIR_mir_output_set_current_mode(output, mir_mode);
return 0;
}
}
return -1;
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */