cscg22-gearboy

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

SDL_DirectFB_window.c (16891B)


      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#include "../../SDL_internal.h"
     22
     23#if SDL_VIDEO_DRIVER_DIRECTFB
     24
     25#include "SDL_DirectFB_video.h"
     26#include "SDL_DirectFB_modes.h"
     27#include "SDL_DirectFB_window.h"
     28#include "SDL_DirectFB_shape.h"
     29
     30#if SDL_DIRECTFB_OPENGL
     31#include "SDL_DirectFB_opengl.h"
     32#endif
     33
     34#include "SDL_syswm.h"
     35
     36#include "../SDL_pixels_c.h"
     37
     38int
     39DirectFB_CreateWindow(_THIS, SDL_Window * window)
     40{
     41    SDL_DFB_DEVICEDATA(_this);
     42    SDL_DFB_DISPLAYDATA(window);
     43    DFB_WindowData *windata = NULL;
     44    DFBWindowOptions wopts;
     45    DFBWindowDescription desc;
     46    int x, y;
     47    int bshaped = 0;
     48
     49    SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
     50    SDL_memset(&desc, 0, sizeof(DFBWindowDescription));
     51    windata = (DFB_WindowData *) window->driverdata;
     52
     53    windata->is_managed = devdata->has_own_wm;
     54#if 1
     55    SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
     56                                                       DFSCL_NORMAL));
     57    SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
     58                                                          DLSCL_ADMINISTRATIVE));
     59#endif
     60    /* FIXME ... ughh, ugly */
     61    if (window->x == -1000 && window->y == -1000)
     62        bshaped = 1;
     63
     64    /* Fill the window description. */
     65    x = window->x;
     66    y = window->y;
     67
     68    DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
     69
     70    /* Create Window */
     71    desc.caps = 0;
     72    desc.flags =
     73        DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
     74
     75    if (bshaped) {
     76        desc.flags |= DWDESC_CAPS;
     77        desc.caps |= DWCAPS_ALPHACHANNEL;
     78    }
     79    else
     80    {
     81        desc.flags |= DWDESC_PIXELFORMAT;
     82    }
     83
     84    if (!(window->flags & SDL_WINDOW_BORDERLESS))
     85        desc.caps |= DWCAPS_NODECORATION;
     86
     87    desc.posx = x;
     88    desc.posy = y;
     89    desc.width = windata->size.w;
     90    desc.height = windata->size.h;
     91    desc.pixelformat = dispdata->pixelformat;
     92    desc.surface_caps = DSCAPS_PREMULTIPLIED;
     93#if DIRECTFB_MAJOR_VERSION == 1 && DIRECTFB_MINOR_VERSION >= 6
     94    if (window->flags & SDL_WINDOW_OPENGL) {
     95        desc.surface_caps |= DSCAPS_GL;
     96    }
     97#endif
     98
     99    /* Create the window. */
    100    SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
    101                                                   &windata->dfbwin));
    102
    103    /* Set Options */
    104    SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
    105
    106    /* explicit rescaling of surface */
    107    wopts |= DWOP_SCALE;
    108    if (window->flags & SDL_WINDOW_RESIZABLE) {
    109        wopts &= ~DWOP_KEEP_SIZE;
    110    }
    111    else {
    112        wopts |= DWOP_KEEP_SIZE;
    113    }
    114
    115    if (window->flags & SDL_WINDOW_FULLSCREEN) {
    116        wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
    117        SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
    118    }
    119
    120    if (bshaped) {
    121        wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
    122        wopts &= ~DWOP_OPAQUE_REGION;
    123    }
    124
    125    SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
    126
    127    /* See what we got */
    128    SDL_DFB_CHECK(DirectFB_WM_GetClientSize
    129                     (_this, window, &window->w, &window->h));
    130
    131    /* Get the window's surface. */
    132    SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
    133                                                 &windata->window_surface));
    134
    135    /* And get a subsurface for rendering */
    136    SDL_DFB_CHECKERR(windata->window_surface->
    137                     GetSubSurface(windata->window_surface, &windata->client,
    138                                   &windata->surface));
    139
    140    SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));
    141
    142    /* Create Eventbuffer */
    143
    144    SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
    145                                                        &windata->
    146                                                        eventbuffer));
    147    SDL_DFB_CHECKERR(windata->dfbwin->
    148                     EnableEvents(windata->dfbwin, DWET_ALL));
    149
    150    /* Create a font */
    151    /* FIXME: once during Video_Init */
    152    windata->font = NULL;
    153
    154    /* Make it the top most window. */
    155    SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
    156
    157    /* remember parent */
    158    /* windata->sdlwin = window; */
    159
    160    /* Add to list ... */
    161
    162    windata->next = devdata->firstwin;
    163    windata->opacity = 0xFF;
    164    devdata->firstwin = window;
    165
    166    /* Draw Frame */
    167    DirectFB_WM_RedrawLayout(_this, window);
    168
    169    return 0;
    170  error:
    171    SDL_DFB_RELEASE(windata->surface);
    172    SDL_DFB_RELEASE(windata->dfbwin);
    173    return -1;
    174}
    175
    176int
    177DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
    178{
    179    return SDL_Unsupported();
    180}
    181
    182void
    183DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
    184{
    185    SDL_DFB_WINDOWDATA(window);
    186
    187    if (windata->is_managed) {
    188        windata->wm_needs_redraw = 1;
    189        DirectFB_WM_RedrawLayout(_this, window);
    190    } else {
    191        SDL_Unsupported();
    192    }
    193}
    194
    195void
    196DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
    197{
    198    SDL_DFB_DEVICEDATA(_this);
    199    SDL_DFB_WINDOWDATA(window);
    200    SDL_Surface *surface = NULL;
    201
    202    if (icon) {
    203        SDL_PixelFormat format;
    204        DFBSurfaceDescription dsc;
    205        Uint32 *dest;
    206        Uint32 *p;
    207        int pitch, i;
    208
    209        /* Convert the icon to ARGB for modern window managers */
    210        SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
    211        surface = SDL_ConvertSurface(icon, &format, 0);
    212        if (!surface) {
    213            return;
    214        }
    215        dsc.flags =
    216            DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
    217        dsc.caps = DSCAPS_VIDEOONLY;
    218        dsc.width = surface->w;
    219        dsc.height = surface->h;
    220        dsc.pixelformat = DSPF_ARGB;
    221
    222        SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
    223                                                     &windata->icon));
    224
    225        SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
    226                                             (void *) &dest, &pitch));
    227
    228        p = surface->pixels;
    229        for (i = 0; i < surface->h; i++)
    230            memcpy((char *) dest + i * pitch,
    231                   (char *) p + i * surface->pitch, 4 * surface->w);
    232
    233        SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
    234        SDL_FreeSurface(surface);
    235    } else {
    236        SDL_DFB_RELEASE(windata->icon);
    237    }
    238    return;
    239  error:
    240    SDL_FreeSurface(surface);
    241    SDL_DFB_RELEASE(windata->icon);
    242    return;
    243}
    244
    245void
    246DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
    247{
    248    SDL_DFB_WINDOWDATA(window);
    249    int x, y;
    250
    251    x = window->x;
    252    y = window->y;
    253
    254    DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
    255    SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
    256}
    257
    258void
    259DirectFB_SetWindowSize(_THIS, SDL_Window * window)
    260{
    261    SDL_DFB_WINDOWDATA(window);
    262
    263    if(SDL_IsShapedWindow(window))
    264        DirectFB_ResizeWindowShape(window);
    265
    266    if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
    267        int cw;
    268        int ch;
    269
    270        /* Make sure all events are disabled for this operation ! */
    271        SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
    272                                                        DWET_ALL));
    273        SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));
    274
    275        if (cw != window->w || ch != window->h) {
    276
    277            DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
    278            SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
    279                                                     windata->size.w,
    280                                                     windata->size.h));
    281        }
    282
    283        SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
    284                     (_this, window, &window->w, &window->h));
    285        DirectFB_AdjustWindowSurface(window);
    286
    287        SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
    288                                                       DWET_ALL));
    289
    290    }
    291    return;
    292  error:
    293    SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
    294    return;
    295}
    296
    297void
    298DirectFB_ShowWindow(_THIS, SDL_Window * window)
    299{
    300    SDL_DFB_WINDOWDATA(window);
    301
    302    SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));
    303
    304}
    305
    306void
    307DirectFB_HideWindow(_THIS, SDL_Window * window)
    308{
    309    SDL_DFB_WINDOWDATA(window);
    310
    311    SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
    312    SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
    313}
    314
    315void
    316DirectFB_RaiseWindow(_THIS, SDL_Window * window)
    317{
    318    SDL_DFB_WINDOWDATA(window);
    319
    320    SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
    321    SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
    322}
    323
    324void
    325DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
    326{
    327    SDL_DFB_WINDOWDATA(window);
    328    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    329    DFBWindowOptions wopts;
    330
    331    SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
    332                                 &windata->restore.x, &windata->restore.y));
    333    SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
    334                             &windata->restore.h));
    335
    336    DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ;
    337
    338    SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
    339    SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
    340                            display->current_mode.w, display->current_mode.h));
    341
    342    /* Set Options */
    343    SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
    344    wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
    345    SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
    346}
    347
    348void
    349DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
    350{
    351    /* FIXME: Size to 32x32 ? */
    352
    353    SDL_Unsupported();
    354}
    355
    356void
    357DirectFB_RestoreWindow(_THIS, SDL_Window * window)
    358{
    359    SDL_DFB_WINDOWDATA(window);
    360    DFBWindowOptions wopts;
    361
    362    /* Set Options */
    363    SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
    364    wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
    365    SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
    366
    367    /* Window layout */
    368    DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED),
    369        windata->restore.w, windata->restore.h);
    370    SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
    371                            windata->restore.h));
    372    SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
    373                            windata->restore.y));
    374
    375    if (!(window->flags & SDL_WINDOW_RESIZABLE))
    376        wopts |= DWOP_KEEP_SIZE;
    377
    378    if (window->flags & SDL_WINDOW_FULLSCREEN)
    379        wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
    380    SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
    381
    382
    383}
    384
    385void
    386DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
    387{
    388    SDL_DFB_DEVICEDATA(_this);
    389    SDL_DFB_WINDOWDATA(window);
    390    DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
    391
    392    if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
    393        if (gwindata != NULL)
    394        {
    395            SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
    396            SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
    397        }
    398        SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
    399        SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
    400        devdata->grabbed_window = window;
    401    } else {
    402        SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
    403        SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
    404        devdata->grabbed_window = NULL;
    405    }
    406}
    407
    408void
    409DirectFB_DestroyWindow(_THIS, SDL_Window * window)
    410{
    411    SDL_DFB_DEVICEDATA(_this);
    412    SDL_DFB_WINDOWDATA(window);
    413    DFB_WindowData *p;
    414
    415    /* Some cleanups */
    416    SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
    417    SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
    418
    419#if SDL_DIRECTFB_OPENGL
    420    DirectFB_GL_DestroyWindowContexts(_this, window);
    421#endif
    422
    423    if (window->shaper)
    424    {
    425        SDL_ShapeData *data = window->shaper->driverdata;
    426        SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
    427        SDL_DFB_RELEASE(data->surface);
    428        SDL_DFB_FREE(data);
    429        SDL_DFB_FREE(window->shaper);
    430    }
    431
    432    SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
    433    SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
    434    SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
    435    SDL_DFB_RELEASE(windata->icon);
    436    SDL_DFB_RELEASE(windata->font);
    437    SDL_DFB_RELEASE(windata->eventbuffer);
    438    SDL_DFB_RELEASE(windata->surface);
    439    SDL_DFB_RELEASE(windata->window_surface);
    440
    441    SDL_DFB_RELEASE(windata->dfbwin);
    442
    443    /* Remove from list ... */
    444
    445    p = devdata->firstwin->driverdata;
    446
    447    while (p && p->next != window)
    448        p = (p->next ? p->next->driverdata : NULL);
    449    if (p)
    450        p->next = windata->next;
    451    else
    452        devdata->firstwin = windata->next;
    453    SDL_free(windata);
    454    return;
    455}
    456
    457SDL_bool
    458DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
    459                         struct SDL_SysWMinfo * info)
    460{
    461    SDL_DFB_DEVICEDATA(_this);
    462    SDL_DFB_WINDOWDATA(window);
    463
    464    if (info->version.major == SDL_MAJOR_VERSION &&
    465        info->version.minor == SDL_MINOR_VERSION) {
    466        info->subsystem = SDL_SYSWM_DIRECTFB;
    467        info->info.dfb.dfb = devdata->dfb;
    468        info->info.dfb.window = windata->dfbwin;
    469        info->info.dfb.surface = windata->surface;
    470        return SDL_TRUE;
    471    } else {
    472        SDL_SetError("Application not compiled with SDL %d.%d\n",
    473                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
    474        return SDL_FALSE;
    475    }
    476}
    477
    478void
    479DirectFB_AdjustWindowSurface(SDL_Window * window)
    480{
    481    SDL_DFB_WINDOWDATA(window);
    482    int adjust = windata->wm_needs_redraw;
    483    int cw, ch;
    484
    485    DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
    486
    487    SDL_DFB_CHECKERR(windata->
    488                     window_surface->GetSize(windata->window_surface, &cw,
    489                                             &ch));
    490    if (cw != windata->size.w || ch != windata->size.h) {
    491        adjust = 1;
    492    }
    493
    494    if (adjust) {
    495#if SDL_DIRECTFB_OPENGL
    496        DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
    497#endif
    498
    499#if (DFB_VERSION_ATLEAST(1,2,1))
    500        SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
    501                                                        windata->size.w,
    502                                                        windata->size.h));
    503        SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
    504                                                          windata->
    505                                                          window_surface,
    506                                                          &windata->client));
    507#else
    508        DFBWindowOptions opts;
    509
    510        SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
    511        /* recreate subsurface */
    512        SDL_DFB_RELEASE(windata->surface);
    513
    514        if (opts & DWOP_SCALE)
    515            SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
    516                                                            windata->size.w,
    517                                                            windata->size.h));
    518        SDL_DFB_CHECKERR(windata->window_surface->
    519                         GetSubSurface(windata->window_surface,
    520                                       &windata->client, &windata->surface));
    521#endif
    522        DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window);
    523
    524#if SDL_DIRECTFB_OPENGL
    525        DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
    526#endif
    527   }
    528  error:
    529    return;
    530}
    531
    532#endif /* SDL_VIDEO_DRIVER_DIRECTFB */