SDL_mirwindow.c
Go to the documentation of this file.
/*
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_egl_c.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_keyboard_c.h"
#include "SDL_mirevents.h"
#include "SDL_mirwindow.h"
#include "SDL_mirdyn.h"
static int
IsMirWindowValid(MIR_Window* mir_window)
{
if (!MIR_mir_window_is_valid(mir_window->window)) {
const char* error = MIR_mir_window_get_error_message(mir_window->window);
return SDL_SetError("Failed to create a mir surface: %s", error);
}
return 1;
}
static MirPixelFormat
FindValidPixelFormat(MIR_Data* mir_data)
{
unsigned int pf_size = 32;
unsigned int valid_formats;
unsigned int f;
MirPixelFormat formats[pf_size];
MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats,
pf_size, &valid_formats);
for (f = 0; f < valid_formats; f++) {
MirPixelFormat cur_pf = formats[f];
if (cur_pf == mir_pixel_format_abgr_8888 ||
cur_pf == mir_pixel_format_xbgr_8888 ||
cur_pf == mir_pixel_format_argb_8888 ||
cur_pf == mir_pixel_format_xrgb_8888) {
return cur_pf;
}
}
return mir_pixel_format_invalid;
}
int
MIR_CreateWindow(_THIS, SDL_Window* window)
{
MIR_Window* mir_window;
MIR_Data* mir_data;
MirPixelFormat pixel_format;
MirBufferUsage buffer_usage;
MirWindowSpec* spec;
mir_window = SDL_calloc(1, sizeof(MIR_Window));
if (!mir_window)
return SDL_OutOfMemory();
mir_data = _this->driverdata;
window->driverdata = mir_window;
if (window->x == SDL_WINDOWPOS_UNDEFINED)
window->x = 0;
if (window->y == SDL_WINDOWPOS_UNDEFINED)
window->y = 0;
mir_window->mir_data = mir_data;
mir_window->sdl_window = window;
if (window->flags & SDL_WINDOW_OPENGL) {
pixel_format = MIR_mir_connection_get_egl_pixel_format(mir_data->connection,
_this->egl_data->egl_display,
_this->egl_data->egl_config);
}
else {
pixel_format = FindValidPixelFormat(mir_data);
}
mir_data->pixel_format = pixel_format;
if (pixel_format == mir_pixel_format_invalid) {
return SDL_SetError("Failed to find a valid pixel format.");
}
buffer_usage = mir_buffer_usage_hardware;
if (mir_data->software)
buffer_usage = mir_buffer_usage_software;
spec = MIR_mir_create_normal_window_spec(mir_data->connection,
window->w,
window->h);
MIR_mir_window_spec_set_buffer_usage(spec, buffer_usage);
MIR_mir_window_spec_set_name(spec, "Mir surface");
MIR_mir_window_spec_set_pixel_format(spec, pixel_format);
if (window->flags & SDL_WINDOW_INPUT_FOCUS)
SDL_SetKeyboardFocus(window);
mir_window->window = MIR_mir_create_window_sync(spec);
MIR_mir_window_set_event_handler(mir_window->window, MIR_HandleEvent, window);
MIR_mir_window_spec_release(spec);
if (!MIR_mir_window_is_valid(mir_window->window)) {
return SDL_SetError("Failed to create a mir surface: %s",
MIR_mir_window_get_error_message(mir_window->window));
}
if (window->flags & SDL_WINDOW_OPENGL) {
EGLNativeWindowType egl_native_window =
(EGLNativeWindowType)MIR_mir_buffer_stream_get_egl_native_window(
MIR_mir_window_get_buffer_stream(mir_window->window));
mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
if (mir_window->egl_surface == EGL_NO_SURFACE) {
return SDL_SetError("Failed to create a window surface %p",
_this->egl_data->egl_display);
}
}
else {
mir_window->egl_surface = EGL_NO_SURFACE;
}
mir_data->current_window = mir_window;
return 0;
}
void
MIR_DestroyWindow(_THIS, SDL_Window* window)
{
MIR_Data* mir_data = _this->driverdata;
MIR_Window* mir_window = window->driverdata;
if (mir_data) {
SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
MIR_mir_window_release_sync(mir_window->window);
mir_data->current_window = NULL;
SDL_free(mir_window);
}
window->driverdata = NULL;
}
SDL_bool
MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info)
{
if (info->version.major == SDL_MAJOR_VERSION &&
info->version.minor == SDL_MINOR_VERSION) {
MIR_Window* mir_window = window->driverdata;
info->subsystem = SDL_SYSWM_MIR;
info->info.mir.connection = mir_window->mir_data->connection;
// Cannot change this to window due to it being in the public API
info->info.mir.surface = mir_window->window;
return SDL_TRUE;
}
return SDL_FALSE;
}
static void
UpdateMirWindowState(MIR_Data* mir_data, MIR_Window* mir_window, MirWindowState window_state)
{
if (IsMirWindowValid(mir_window)) {
MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
MIR_mir_window_spec_set_state(spec, window_state);
MIR_mir_window_apply_spec(mir_window->window, spec);
MIR_mir_window_spec_release(spec);
}
}
void
MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
SDL_VideoDisplay* display,
SDL_bool fullscreen)
{
if (IsMirWindowValid(window->driverdata)) {
MirWindowState state;
if (fullscreen) {
state = mir_window_state_fullscreen;
}
else {
state = mir_window_state_restored;
}
UpdateMirWindowState(_this->driverdata, window->driverdata, state);
}
}
void
MIR_MaximizeWindow(_THIS, SDL_Window* window)
{
UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_maximized);
}
void
MIR_MinimizeWindow(_THIS, SDL_Window* window)
{
UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_minimized);
}
void
MIR_RestoreWindow(_THIS, SDL_Window * window)
{
UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_restored);
}
void
MIR_HideWindow(_THIS, SDL_Window* window)
{
UpdateMirWindowState(_this->driverdata, window->driverdata, mir_window_state_hidden);
}
void
MIR_SetWindowSize(_THIS, SDL_Window* window)
{
MIR_Data* mir_data = _this->driverdata;
MIR_Window* mir_window = window->driverdata;
if (IsMirWindowValid(mir_window)) {
MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
MIR_mir_window_spec_set_width (spec, window->w);
MIR_mir_window_spec_set_height(spec, window->h);
MIR_mir_window_apply_spec(mir_window->window, spec);
}
}
void
MIR_SetWindowMinimumSize(_THIS, SDL_Window* window)
{
MIR_Data* mir_data = _this->driverdata;
MIR_Window* mir_window = window->driverdata;
if (IsMirWindowValid(mir_window)) {
MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
MIR_mir_window_spec_set_min_width (spec, window->min_w);
MIR_mir_window_spec_set_min_height(spec, window->min_h);
MIR_mir_window_apply_spec(mir_window->window, spec);
}
}
void
MIR_SetWindowMaximumSize(_THIS, SDL_Window* window)
{
MIR_Data* mir_data = _this->driverdata;
MIR_Window* mir_window = window->driverdata;
if (IsMirWindowValid(mir_window)) {
MirWindowSpec* spec = MIR_mir_create_window_spec(mir_data->connection);
MIR_mir_window_spec_set_max_width (spec, window->max_w);
MIR_mir_window_spec_set_max_height(spec, window->max_h);
MIR_mir_window_apply_spec(mir_window->window, spec);
}
}
void
MIR_SetWindowTitle(_THIS, SDL_Window* window)
{
MIR_Data* mir_data = _this->driverdata;
MIR_Window* mir_window = window->driverdata;
char const* title = window->title ? window->title : "";
MirWindowSpec* spec;
if (IsMirWindowValid(mir_window) < 0)
return;
spec = MIR_mir_create_window_spec(mir_data->connection);
MIR_mir_window_spec_set_name(spec, title);
MIR_mir_window_apply_spec(mir_window->window, spec);
MIR_mir_window_spec_release(spec);
}
void
MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed)
{
MIR_Data* mir_data = _this->driverdata;
MIR_Window* mir_window = window->driverdata;
MirPointerConfinementState confined = mir_pointer_unconfined;
MirWindowSpec* spec;
if (grabbed)
confined = mir_pointer_confined_to_window;
spec = MIR_mir_create_window_spec(mir_data->connection);
MIR_mir_window_spec_set_pointer_confinement(spec, confined);
MIR_mir_window_apply_spec(mir_window->window, spec);
MIR_mir_window_spec_release(spec);
}
int
MIR_SetWindowGammaRamp(_THIS, SDL_Window* window, Uint16 const* ramp)
{
MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata;
Uint32 ramp_size = 256;
// FIXME Need to apply the changes to the output, once that public API function is around
if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) {
MIR_mir_output_set_gamma(output,
ramp + ramp_size * 0,
ramp + ramp_size * 1,
ramp + ramp_size * 2,
ramp_size);
return 0;
}
return -1;
}
int
MIR_GetWindowGammaRamp(_THIS, SDL_Window* window, Uint16* ramp)
{
MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata;
Uint32 ramp_size = 256;
if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) {
if (MIR_mir_output_get_gamma_size(output) == ramp_size) {
MIR_mir_output_get_gamma(output,
ramp + ramp_size * 0,
ramp + ramp_size * 1,
ramp + ramp_size * 2,
ramp_size);
return 0;
}
}
return -1;
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */
SDL_SysWMinfo::mir
struct SDL_SysWMinfo::@18::@21 mir
SDL_MINOR_VERSION
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
MIR_MinimizeWindow
void MIR_MinimizeWindow(_THIS, SDL_Window *window)
SDL_TRUE
Definition: SDL_stdinc.h:142
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
MIR_HideWindow
void MIR_HideWindow(_THIS, SDL_Window *window)
SDL_mirevents.h
SDL_Window::w
int w
Definition: SDL_sysvideo.h:80
EGL_NO_SURFACE
#define EGL_NO_SURFACE
Definition: egl.h:100
MIR_GetWindowGammaRamp
int MIR_GetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 *ramp)
SDL_MAJOR_VERSION
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
SDL_Window::x
int x
Definition: SDL_sysvideo.h:79
MIR_CreateWindow
int MIR_CreateWindow(_THIS, SDL_Window *window)
EGLNativeWindowType
HWND EGLNativeWindowType
Definition: eglplatform.h:78
MIR_Data::pixel_format
MirPixelFormat pixel_format
Definition: SDL_mirvideo.h:41
SDL_FALSE
Definition: SDL_stdinc.h:141
state
struct xkb_state * state
Definition: SDL_waylandsym.h:113
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:377
SDL_SysWMinfo::version
SDL_version version
Definition: SDL_syswm.h:196
SDL_version::major
Uint8 major
Definition: SDL_version.h:53
SDL_mirwindow.h
MIR_Window
Definition: SDL_mirwindow.h:34
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
MIR_DestroyWindow
void MIR_DestroyWindow(_THIS, SDL_Window *window)
SDL_SysWMinfo::subsystem
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:197
SDL_WINDOWPOS_UNDEFINED
#define SDL_WINDOWPOS_UNDEFINED
Definition: SDL_video.h:130
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:181
MIR_SetWindowGrab
void MIR_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
MIR_HandleEvent
void MIR_HandleEvent(MirWindow *, MirEvent const *ev, void *context)
MIR_Data
Definition: SDL_mirvideo.h:35
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
spec
SDL_AudioSpec spec
Definition: loopwave.c:31
MIR_Data::connection
MirConnection * connection
Definition: SDL_mirvideo.h:37
MIR_Data::software
SDL_bool software
Definition: SDL_mirvideo.h:40
MIR_Data::current_window
MIR_Window * current_window
Definition: SDL_mirvideo.h:39
SDL_SysWMinfo
Definition: SDL_syswm.h:194
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
MIR_RestoreWindow
void MIR_RestoreWindow(_THIS, SDL_Window *window)
MIR_SetWindowFullscreen
void MIR_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
sort_controllers.output
output
Definition: sort_controllers.py:10
SDL_Window::min_w
int min_w
Definition: SDL_sysvideo.h:81
MIR_MaximizeWindow
void MIR_MaximizeWindow(_THIS, SDL_Window *window)
MIR_Window::mir_data
MIR_Data * mir_data
Definition: SDL_mirwindow.h:36
SDL_version::minor
Uint8 minor
Definition: SDL_version.h:54
MIR_Window::window
MirWindow * window
Definition: SDL_mirwindow.h:38
SDL_Window::title
char * title
Definition: SDL_sysvideo.h:77
SDL_Window::y
int y
Definition: SDL_sysvideo.h:79
SDL_mirdyn.h
MIR_SetWindowGammaRamp
int MIR_SetWindowGammaRamp(_THIS, SDL_Window *window, Uint16 const *ramp)
MIR_SetWindowTitle
void MIR_SetWindowTitle(_THIS, SDL_Window *window)
SDL_VideoDisplay
Definition: SDL_sysvideo.h:125
SDL_Window::h
int h
Definition: SDL_sysvideo.h:80
NULL
#define NULL
Definition: begin_code.h:164
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:139
SDL_WINDOW_INPUT_FOCUS
Definition: SDL_video.h:109
MIR_Window::egl_surface
EGLSurface egl_surface
Definition: SDL_mirwindow.h:39
SDL_Window::min_h
int min_h
Definition: SDL_sysvideo.h:81
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_Window::max_w
int max_w
Definition: SDL_sysvideo.h:82
SDL_GetDisplayForWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1073
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
formats
EGLint EGLint * formats
Definition: eglext.h:718
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:73
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:169
SDL_Window::max_h
int max_h
Definition: SDL_sysvideo.h:82
SDL_SysWMinfo::info
union SDL_SysWMinfo::@18 info
SDL_WINDOW_OPENGL
Definition: SDL_video.h:101
SDL_Window::driverdata
void * driverdata
Definition: SDL_sysvideo.h:111
SDL_Window::flags
Uint32 flags
Definition: SDL_sysvideo.h:83
MIR_GetWindowWMInfo
SDL_bool MIR_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
MIR_SetWindowMaximumSize
void MIR_SetWindowMaximumSize(_THIS, SDL_Window *window)
SDL_SYSWM_MIR
Definition: SDL_syswm.h:125
MIR_SetWindowMinimumSize
void MIR_SetWindowMinimumSize(_THIS, SDL_Window *window)
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:138
MIR_SetWindowSize
void MIR_SetWindowSize(_THIS, SDL_Window *window)
MIR_Window::sdl_window
SDL_Window * sdl_window
Definition: SDL_mirwindow.h:35