cscg22-gearboy

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

SDL_waylandwindow.c (8476B)


      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#include "../../SDL_internal.h"
     23
     24#if SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL
     25
     26#include "../SDL_sysvideo.h"
     27#include "../../events/SDL_windowevents_c.h"
     28#include "../SDL_egl_c.h"
     29#include "SDL_waylandwindow.h"
     30#include "SDL_waylandvideo.h"
     31#include "SDL_waylandtouch.h"
     32
     33static void
     34handle_ping(void *data, struct wl_shell_surface *shell_surface,
     35            uint32_t serial)
     36{
     37    wl_shell_surface_pong(shell_surface, serial);
     38}
     39
     40static void
     41handle_configure(void *data, struct wl_shell_surface *shell_surface,
     42                 uint32_t edges, int32_t width, int32_t height)
     43{
     44    SDL_WindowData *wind = (SDL_WindowData *)data;
     45    SDL_Window *window = wind->sdlwindow;
     46    struct wl_region *region;
     47
     48    window->w = width;
     49    window->h = height;
     50    WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
     51
     52    region = wl_compositor_create_region(wind->waylandData->compositor);
     53    wl_region_add(region, 0, 0, window->w, window->h);
     54    wl_surface_set_opaque_region(wind->surface, region);
     55    wl_region_destroy(region);
     56    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, window->w, window->h);
     57}
     58
     59static void
     60handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
     61{
     62}
     63
     64static const struct wl_shell_surface_listener shell_surface_listener = {
     65    handle_ping,
     66    handle_configure,
     67    handle_popup_done
     68};
     69
     70#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
     71static void
     72handle_onscreen_visibility(void *data,
     73        struct qt_extended_surface *qt_extended_surface, int32_t visible)
     74{
     75}
     76
     77static void
     78handle_set_generic_property(void *data,
     79        struct qt_extended_surface *qt_extended_surface, const char *name,
     80        struct wl_array *value)
     81{
     82}
     83
     84static void
     85handle_close(void *data, struct qt_extended_surface *qt_extended_surface)
     86{
     87    SDL_WindowData *window = (SDL_WindowData *)data;
     88    SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
     89}
     90
     91static const struct qt_extended_surface_listener extended_surface_listener = {
     92    handle_onscreen_visibility,
     93    handle_set_generic_property,
     94    handle_close,
     95};
     96#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
     97
     98SDL_bool
     99Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
    100{
    101    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    102
    103    info->info.wl.display = data->waylandData->display;
    104    info->info.wl.surface = data->surface;
    105    info->info.wl.shell_surface = data->shell_surface;
    106    info->subsystem = SDL_SYSWM_WAYLAND;
    107
    108    return SDL_TRUE;
    109}
    110
    111void Wayland_ShowWindow(_THIS, SDL_Window *window)
    112{
    113    SDL_WindowData *wind = window->driverdata;
    114
    115    if (window->flags & SDL_WINDOW_FULLSCREEN)
    116        wl_shell_surface_set_fullscreen(wind->shell_surface,
    117                                        WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
    118                                        0, NULL);
    119    else
    120        wl_shell_surface_set_toplevel(wind->shell_surface);
    121
    122    WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
    123}
    124
    125void
    126Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
    127                            SDL_VideoDisplay * _display, SDL_bool fullscreen)
    128{
    129    SDL_WindowData *wind = window->driverdata;
    130
    131    if (fullscreen)
    132        wl_shell_surface_set_fullscreen(wind->shell_surface,
    133                                        WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE,
    134                                        0, NULL);
    135    else
    136        wl_shell_surface_set_toplevel(wind->shell_surface);
    137
    138    WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
    139}
    140
    141int Wayland_CreateWindow(_THIS, SDL_Window *window)
    142{
    143    SDL_WindowData *data;
    144    SDL_VideoData *c;
    145    struct wl_region *region;
    146
    147    data = calloc(1, sizeof *data);
    148    if (data == NULL)
    149        return 0;
    150
    151    c = _this->driverdata;
    152    window->driverdata = data;
    153
    154    if (!(window->flags & SDL_WINDOW_OPENGL)) {
    155        SDL_GL_LoadLibrary(NULL);
    156        window->flags |= SDL_WINDOW_OPENGL;
    157    }
    158
    159    if (window->x == SDL_WINDOWPOS_UNDEFINED) {
    160        window->x = 0;
    161    }
    162    if (window->y == SDL_WINDOWPOS_UNDEFINED) {
    163        window->y = 0;
    164    }
    165
    166    data->waylandData = c;
    167    data->sdlwindow = window;
    168
    169    data->surface =
    170        wl_compositor_create_surface(c->compositor);
    171    wl_surface_set_user_data(data->surface, data);
    172    data->shell_surface = wl_shell_get_shell_surface(c->shell,
    173                                                     data->surface);
    174#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH    
    175    if (c->surface_extension) {
    176        data->extended_surface = qt_surface_extension_get_extended_surface(
    177                c->surface_extension, data->surface);
    178    }
    179#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
    180
    181    /**
    182     * If the user specified 0x0 as the size (turned to 1x1 by SDL_CreateWindow
    183     * in SDL_video.c), we want to make the window fill the whole screen
    184     **/
    185    if (window->w == 1) {
    186        window->w = c->screen_allocation.width;
    187    }
    188    if (window->h == 1) {
    189        window->h = c->screen_allocation.height;
    190    }
    191
    192    data->egl_window = WAYLAND_wl_egl_window_create(data->surface,
    193                                            window->w, window->h);
    194
    195    /* Create the GLES window surface */
    196    data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
    197    
    198    if (data->egl_surface == EGL_NO_SURFACE) {
    199        SDL_SetError("failed to create a window surface");
    200        return -1;
    201    }
    202
    203    if (data->shell_surface) {
    204        wl_shell_surface_set_user_data(data->shell_surface, data);
    205        wl_shell_surface_add_listener(data->shell_surface,
    206                                      &shell_surface_listener, data);
    207    }
    208
    209#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
    210    if (data->extended_surface) {
    211        qt_extended_surface_set_user_data(data->extended_surface, data);
    212        qt_extended_surface_add_listener(data->extended_surface,
    213                                         &extended_surface_listener, data);
    214    }
    215#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
    216
    217    region = wl_compositor_create_region(c->compositor);
    218    wl_region_add(region, 0, 0, window->w, window->h);
    219    wl_surface_set_opaque_region(data->surface, region);
    220    wl_region_destroy(region);
    221
    222    WAYLAND_wl_display_flush(c->display);
    223
    224    return 0;
    225}
    226
    227void Wayland_SetWindowSize(_THIS, SDL_Window * window)
    228{
    229    SDL_VideoData *data = _this->driverdata;
    230    SDL_WindowData *wind = window->driverdata;
    231    struct wl_region *region;
    232
    233    WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
    234
    235    region =wl_compositor_create_region(data->compositor);
    236    wl_region_add(region, 0, 0, window->w, window->h);
    237    wl_surface_set_opaque_region(wind->surface, region);
    238    wl_region_destroy(region);
    239}
    240
    241void Wayland_DestroyWindow(_THIS, SDL_Window *window)
    242{
    243    SDL_VideoData *data = _this->driverdata;
    244    SDL_WindowData *wind = window->driverdata;
    245
    246    if (data) {
    247        SDL_EGL_DestroySurface(_this, wind->egl_surface);
    248        WAYLAND_wl_egl_window_destroy(wind->egl_window);
    249
    250        if (wind->shell_surface)
    251            wl_shell_surface_destroy(wind->shell_surface);
    252
    253#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
    254        if (wind->extended_surface)
    255            qt_extended_surface_destroy(wind->extended_surface);
    256#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
    257        wl_surface_destroy(wind->surface);
    258
    259        SDL_free(wind);
    260        WAYLAND_wl_display_flush(data->display);
    261    }
    262    window->driverdata = NULL;
    263}
    264
    265#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */
    266
    267/* vi: set ts=4 sw=4 expandtab: */