cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_mirwindow.c (6447B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 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
     38int
     39IsSurfaceValid(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
     49MirPixelFormat
     50FindValidPixelFormat(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
     75int
     76MIR_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
    146void
    147MIR_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
    161SDL_bool
    162MIR_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
    178void
    179MIR_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_type(mir_window->surface, mir_surface_state_fullscreen);
    190    } else {
    191        MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_restored);
    192    }
    193}
    194
    195void
    196MIR_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_type(mir_window->surface, mir_surface_state_maximized);
    204}
    205
    206void
    207MIR_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_type(mir_window->surface, mir_surface_state_minimized);
    215}
    216
    217void
    218MIR_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_type(mir_window->surface, mir_surface_state_restored);
    226}
    227
    228#endif /* SDL_VIDEO_DRIVER_MIR */
    229
    230/* vi: set ts=4 sw=4 expandtab: */