sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_DirectFB_video.c (15658B)


      1 /*
      2   Simple DirectMedia Layer
      3   Copyright (C) 1997-2020 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 /*
     26  * #include "SDL_DirectFB_keyboard.h"
     27  */
     28 #include "SDL_DirectFB_modes.h"
     29 #include "SDL_DirectFB_opengl.h"
     30 #include "SDL_DirectFB_vulkan.h"
     31 #include "SDL_DirectFB_window.h"
     32 #include "SDL_DirectFB_WM.h"
     33 
     34 
     35 /* DirectFB video driver implementation.
     36 */
     37 
     38 #include <fcntl.h>
     39 #include <unistd.h>
     40 #include <sys/mman.h>
     41 
     42 #include <directfb.h>
     43 #include <directfb_version.h>
     44 #include <directfb_strings.h>
     45 
     46 #include "SDL_video.h"
     47 #include "SDL_mouse.h"
     48 #include "../SDL_sysvideo.h"
     49 #include "../SDL_pixels_c.h"
     50 #include "../../events/SDL_events_c.h"
     51 #include "SDL_DirectFB_video.h"
     52 #include "SDL_DirectFB_events.h"
     53 #include "SDL_DirectFB_render.h"
     54 #include "SDL_DirectFB_mouse.h"
     55 #include "SDL_DirectFB_shape.h"
     56 
     57 
     58 #include "SDL_DirectFB_dyn.h"
     59 
     60 /* Initialization/Query functions */
     61 static int DirectFB_VideoInit(_THIS);
     62 static void DirectFB_VideoQuit(_THIS);
     63 
     64 static SDL_VideoDevice *DirectFB_CreateDevice(int devindex);
     65 
     66 VideoBootStrap DirectFB_bootstrap = {
     67     "directfb", "DirectFB",
     68     DirectFB_CreateDevice
     69 };
     70 
     71 static const DirectFBSurfaceDrawingFlagsNames(drawing_flags);
     72 static const DirectFBSurfaceBlittingFlagsNames(blitting_flags);
     73 static const DirectFBAccelerationMaskNames(acceleration_mask);
     74 
     75 /* DirectFB driver bootstrap functions */
     76 
     77 static void
     78 DirectFB_DeleteDevice(SDL_VideoDevice * device)
     79 {
     80     SDL_DirectFB_UnLoadLibrary();
     81     SDL_DFB_FREE(device->driverdata);
     82     SDL_DFB_FREE(device);
     83 }
     84 
     85 static SDL_VideoDevice *
     86 DirectFB_CreateDevice(int devindex)
     87 {
     88     SDL_VideoDevice *device;
     89 
     90     if (!SDL_DirectFB_LoadLibrary()) {
     91         return NULL;
     92     }
     93 
     94     /* Initialize all variables that we clean on shutdown */
     95     SDL_DFB_ALLOC_CLEAR(device, sizeof(SDL_VideoDevice));
     96 
     97     /* Set the function pointers */
     98     device->VideoInit = DirectFB_VideoInit;
     99     device->VideoQuit = DirectFB_VideoQuit;
    100     device->GetDisplayModes = DirectFB_GetDisplayModes;
    101     device->SetDisplayMode = DirectFB_SetDisplayMode;
    102     device->PumpEvents = DirectFB_PumpEventsWindow;
    103     device->CreateSDLWindow = DirectFB_CreateWindow;
    104     device->CreateSDLWindowFrom = DirectFB_CreateWindowFrom;
    105     device->SetWindowTitle = DirectFB_SetWindowTitle;
    106     device->SetWindowIcon = DirectFB_SetWindowIcon;
    107     device->SetWindowPosition = DirectFB_SetWindowPosition;
    108     device->SetWindowSize = DirectFB_SetWindowSize;
    109     device->SetWindowOpacity = DirectFB_SetWindowOpacity;
    110     device->ShowWindow = DirectFB_ShowWindow;
    111     device->HideWindow = DirectFB_HideWindow;
    112     device->RaiseWindow = DirectFB_RaiseWindow;
    113     device->MaximizeWindow = DirectFB_MaximizeWindow;
    114     device->MinimizeWindow = DirectFB_MinimizeWindow;
    115     device->RestoreWindow = DirectFB_RestoreWindow;
    116     device->SetWindowGrab = DirectFB_SetWindowGrab;
    117     device->DestroyWindow = DirectFB_DestroyWindow;
    118     device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
    119 
    120     /* !!! FIXME: implement SetWindowBordered */
    121 
    122 #if SDL_DIRECTFB_OPENGL
    123     device->GL_LoadLibrary = DirectFB_GL_LoadLibrary;
    124     device->GL_GetProcAddress = DirectFB_GL_GetProcAddress;
    125     device->GL_MakeCurrent = DirectFB_GL_MakeCurrent;
    126 
    127     device->GL_CreateContext = DirectFB_GL_CreateContext;
    128     device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval;
    129     device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval;
    130     device->GL_SwapWindow = DirectFB_GL_SwapWindow;
    131     device->GL_DeleteContext = DirectFB_GL_DeleteContext;
    132 
    133 #endif
    134 
    135     /* Shaped window support */
    136     device->shape_driver.CreateShaper = DirectFB_CreateShaper;
    137     device->shape_driver.SetWindowShape = DirectFB_SetWindowShape;
    138     device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape;
    139 
    140 #if SDL_VIDEO_VULKAN
    141     device->Vulkan_LoadLibrary = DirectFB_Vulkan_LoadLibrary;
    142     device->Vulkan_UnloadLibrary = DirectFB_Vulkan_UnloadLibrary;
    143     device->Vulkan_GetInstanceExtensions = DirectFB_Vulkan_GetInstanceExtensions;
    144     device->Vulkan_CreateSurface = DirectFB_Vulkan_CreateSurface;
    145 #endif
    146 
    147     device->free = DirectFB_DeleteDevice;
    148 
    149     return device;
    150   error:
    151     if (device)
    152         SDL_free(device);
    153     return (0);
    154 }
    155 
    156 static void
    157 DirectFB_DeviceInformation(IDirectFB * dfb)
    158 {
    159     DFBGraphicsDeviceDescription desc;
    160     int n;
    161 
    162     dfb->GetDeviceDescription(dfb, &desc);
    163 
    164     SDL_DFB_LOG( "DirectFB Device Information");
    165     SDL_DFB_LOG( "===========================");
    166     SDL_DFB_LOG( "Name:           %s", desc.name);
    167     SDL_DFB_LOG( "Vendor:         %s", desc.vendor);
    168     SDL_DFB_LOG( "Driver Name:    %s", desc.driver.name);
    169     SDL_DFB_LOG( "Driver Vendor:  %s", desc.driver.vendor);
    170     SDL_DFB_LOG( "Driver Version: %d.%d", desc.driver.major,
    171             desc.driver.minor);
    172 
    173     SDL_DFB_LOG( "Video memory:   %d", desc.video_memory);
    174 
    175     SDL_DFB_LOG( "Blitting flags:");
    176     for (n = 0; blitting_flags[n].flag; n++) {
    177         if (desc.blitting_flags & blitting_flags[n].flag)
    178             SDL_DFB_LOG( "    %s", blitting_flags[n].name);
    179     }
    180 
    181     SDL_DFB_LOG( "Drawing flags:");
    182     for (n = 0; drawing_flags[n].flag; n++) {
    183         if (desc.drawing_flags & drawing_flags[n].flag)
    184             SDL_DFB_LOG( "    %s", drawing_flags[n].name);
    185     }
    186 
    187 
    188     SDL_DFB_LOG( "Acceleration flags:");
    189     for (n = 0; acceleration_mask[n].mask; n++) {
    190         if (desc.acceleration_mask & acceleration_mask[n].mask)
    191             SDL_DFB_LOG( "    %s", acceleration_mask[n].name);
    192     }
    193 
    194 
    195 }
    196 
    197 static int readBoolEnv(const char *env_name, int def_val)
    198 {
    199     char *stemp;
    200 
    201     stemp = SDL_getenv(env_name);
    202     if (stemp)
    203         return atoi(stemp);
    204     else
    205         return def_val;
    206 }
    207 
    208 static int
    209 DirectFB_VideoInit(_THIS)
    210 {
    211     IDirectFB *dfb = NULL;
    212     DFB_DeviceData *devdata = NULL;
    213     DFBResult ret;
    214 
    215     SDL_DFB_ALLOC_CLEAR(devdata, sizeof(*devdata));
    216 
    217     SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));
    218 
    219     /* avoid switching to the framebuffer when we
    220      * are running X11 */
    221     ret = readBoolEnv(DFBENV_USE_X11_CHECK , 1);
    222     if (ret) {
    223         if (SDL_getenv("DISPLAY"))
    224             DirectFBSetOption("system", "x11");
    225         else
    226             DirectFBSetOption("disable-module", "x11input");
    227     }
    228 
    229     devdata->use_linux_input = readBoolEnv(DFBENV_USE_LINUX_INPUT, 1);       /* default: on */
    230 
    231     if (!devdata->use_linux_input)
    232     {
    233         SDL_DFB_LOG("Disabling linux input\n");
    234         DirectFBSetOption("disable-module", "linux_input");
    235     }
    236 
    237     SDL_DFB_CHECKERR(DirectFBCreate(&dfb));
    238 
    239     DirectFB_DeviceInformation(dfb);
    240 
    241     devdata->use_yuv_underlays = readBoolEnv(DFBENV_USE_YUV_UNDERLAY, 0);     /* default: off */
    242     devdata->use_yuv_direct = readBoolEnv(DFBENV_USE_YUV_DIRECT, 0);      /* default is off! */
    243 
    244     /* Create global Eventbuffer for axis events */
    245     if (devdata->use_linux_input) {
    246         SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_ALL,
    247                                                      DFB_TRUE,
    248                                                      &devdata->events));
    249     } else {
    250         SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_AXES
    251                                                      /* DICAPS_ALL */ ,
    252                                                      DFB_TRUE,
    253                                                      &devdata->events));
    254     }
    255 
    256     /* simple window manager support */
    257     devdata->has_own_wm = readBoolEnv(DFBENV_USE_WM, 0);
    258 
    259     devdata->initialized = 1;
    260 
    261     devdata->dfb = dfb;
    262     devdata->firstwin = NULL;
    263     devdata->grabbed_window = NULL;
    264 
    265     _this->driverdata = devdata;
    266 
    267     DirectFB_InitModes(_this);
    268 
    269 #if SDL_DIRECTFB_OPENGL
    270     DirectFB_GL_Initialize(_this);
    271 #endif
    272 
    273     DirectFB_InitMouse(_this);
    274     DirectFB_InitKeyboard(_this);
    275 
    276     return 0;
    277 
    278 
    279   error:
    280     SDL_DFB_FREE(devdata);
    281     SDL_DFB_RELEASE(dfb);
    282     return -1;
    283 }
    284 
    285 static void
    286 DirectFB_VideoQuit(_THIS)
    287 {
    288     DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata;
    289 
    290     DirectFB_QuitModes(_this);
    291     DirectFB_QuitKeyboard(_this);
    292     DirectFB_QuitMouse(_this);
    293 
    294     devdata->events->Reset(devdata->events);
    295     SDL_DFB_RELEASE(devdata->events);
    296     SDL_DFB_RELEASE(devdata->dfb);
    297 
    298 #if SDL_DIRECTFB_OPENGL
    299     DirectFB_GL_Shutdown(_this);
    300 #endif
    301 
    302     devdata->initialized = 0;
    303 }
    304 
    305 /* DirectFB driver general support functions */
    306 
    307 static const struct {
    308     DFBSurfacePixelFormat dfb;
    309     Uint32 sdl;
    310 } pixelformat_tab[] =
    311 {
    312     { DSPF_RGB32, SDL_PIXELFORMAT_RGB888 },             /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
    313     { DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 },            /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */
    314     { DSPF_RGB16, SDL_PIXELFORMAT_RGB565 },             /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
    315     { DSPF_RGB332, SDL_PIXELFORMAT_RGB332 },            /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
    316     { DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 },        /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */
    317     { DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 },        /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */
    318     { DSPF_RGB24, SDL_PIXELFORMAT_RGB24 },              /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
    319     { DSPF_RGB444, SDL_PIXELFORMAT_RGB444 },            /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */
    320     { DSPF_YV12, SDL_PIXELFORMAT_YV12 },                /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */
    321     { DSPF_I420,SDL_PIXELFORMAT_IYUV },                 /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */
    322     { DSPF_YUY2, SDL_PIXELFORMAT_YUY2 },                /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */
    323     { DSPF_UYVY, SDL_PIXELFORMAT_UYVY },                /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */
    324     { DSPF_RGB555, SDL_PIXELFORMAT_RGB555 },            /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */
    325 #if (DFB_VERSION_ATLEAST(1,5,0))
    326     { DSPF_ABGR, SDL_PIXELFORMAT_ABGR8888 },            /* 32 bit ABGR (4  byte, alpha 8@24, blue 8@16, green 8@8, red 8@0) */
    327 #endif
    328 #if (ENABLE_LUT8)
    329     { DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 },              /* 8 bit LUT (8 bit color and alpha lookup from palette) */
    330 #endif
    331 
    332 #if (DFB_VERSION_ATLEAST(1,2,0))
    333     { DSPF_BGR555, SDL_PIXELFORMAT_BGR555 },            /* 16 bit BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */
    334 #else
    335     { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR555 },
    336 #endif
    337 
    338     /* Pfff ... nonmatching formats follow */
    339 
    340     { DSPF_ALUT44, SDL_PIXELFORMAT_UNKNOWN },           /* 8 bit ALUT (1 byte, alpha 4@4, color lookup 4@0) */
    341     { DSPF_A8, SDL_PIXELFORMAT_UNKNOWN },               /*  8 bit alpha (1 byte, alpha 8@0), e.g. anti-aliased glyphs */
    342     { DSPF_AiRGB, SDL_PIXELFORMAT_UNKNOWN },            /*  32 bit ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */
    343     { DSPF_A1, SDL_PIXELFORMAT_UNKNOWN },               /*  1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */
    344     { DSPF_NV12, SDL_PIXELFORMAT_UNKNOWN },             /*  12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CbCr [15:0] plane) */
    345     { DSPF_NV16, SDL_PIXELFORMAT_UNKNOWN },             /*  16 bit YUV (8 bit Y plane followed by one 16 bit half width CbCr [15:0] plane) */
    346     { DSPF_ARGB2554, SDL_PIXELFORMAT_UNKNOWN },         /*  16 bit ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */
    347     { DSPF_NV21, SDL_PIXELFORMAT_UNKNOWN },             /*  12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CrCb [15:0] plane) */
    348     { DSPF_AYUV, SDL_PIXELFORMAT_UNKNOWN },             /*  32 bit AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */
    349     { DSPF_A4, SDL_PIXELFORMAT_UNKNOWN },               /*  4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */
    350     { DSPF_ARGB1666, SDL_PIXELFORMAT_UNKNOWN },         /*  1 bit alpha (3 byte/ alpha 1@18, red 6@16, green 6@6, blue 6@0) */
    351     { DSPF_ARGB6666, SDL_PIXELFORMAT_UNKNOWN },         /*  6 bit alpha (3 byte/ alpha 6@18, red 6@16, green 6@6, blue 6@0) */
    352     { DSPF_RGB18, SDL_PIXELFORMAT_UNKNOWN },            /*  6 bit RGB (3 byte/ red 6@16, green 6@6, blue 6@0) */
    353     { DSPF_LUT2, SDL_PIXELFORMAT_UNKNOWN },             /*  2 bit LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */
    354 
    355 #if (DFB_VERSION_ATLEAST(1,3,0))
    356     { DSPF_RGBA4444, SDL_PIXELFORMAT_UNKNOWN },         /* 16 bit RGBA (2 byte, red 4@12, green 4@8, blue 4@4, alpha 4@0) */
    357 #endif
    358 
    359 #if (DFB_VERSION_ATLEAST(1,4,3))
    360     { DSPF_RGBA5551, SDL_PIXELFORMAT_UNKNOWN },         /*  16 bit RGBA (2 byte, red 5@11, green 5@6, blue 5@1, alpha 1@0) */
    361     { DSPF_YUV444P, SDL_PIXELFORMAT_UNKNOWN },          /*  24 bit full YUV planar (8 bit Y plane followed by an 8 bit Cb and an 8 bit Cr plane) */
    362     { DSPF_ARGB8565, SDL_PIXELFORMAT_UNKNOWN },         /*  24 bit ARGB (3 byte, alpha 8@16, red 5@11, green 6@5, blue 5@0) */
    363     { DSPF_AVYU, SDL_PIXELFORMAT_UNKNOWN },             /*  32 bit AVYU 4:4:4 (4 byte, alpha 8@24, Cr 8@16, Y 8@8, Cb 8@0) */
    364     { DSPF_VYU, SDL_PIXELFORMAT_UNKNOWN },              /*  24 bit VYU 4:4:4 (3 byte, Cr 8@16, Y 8@8, Cb 8@0)  */
    365 #endif
    366 
    367     { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB },
    368     { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1MSB },
    369     { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4LSB },
    370     { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4MSB },
    371     { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR24 },
    372     { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR888 },
    373     { DSPF_UNKNOWN, SDL_PIXELFORMAT_RGBA8888 },
    374     { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGRA8888 },
    375     { DSPF_UNKNOWN, SDL_PIXELFORMAT_ARGB2101010 },
    376     { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR4444 },
    377     { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR1555 },
    378     { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR565 },
    379     { DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU },                        /**< Packed mode: Y0+V0+Y1+U0 (1 pla */
    380 };
    381 
    382 Uint32
    383 DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat)
    384 {
    385     int i;
    386 
    387     for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
    388         if (pixelformat_tab[i].dfb == pixelformat)
    389         {
    390             return pixelformat_tab[i].sdl;
    391         }
    392     return SDL_PIXELFORMAT_UNKNOWN;
    393 }
    394 
    395 DFBSurfacePixelFormat
    396 DirectFB_SDLToDFBPixelFormat(Uint32 format)
    397 {
    398     int i;
    399 
    400     for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
    401         if (pixelformat_tab[i].sdl == format)
    402         {
    403             return pixelformat_tab[i].dfb;
    404         }
    405     return DSPF_UNKNOWN;
    406 }
    407 
    408 void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo* ri)
    409 {
    410     int i, j;
    411 
    412     for (i=0, j=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
    413         if (pixelformat_tab[i].sdl != SDL_PIXELFORMAT_UNKNOWN)
    414             ri->texture_formats[j++] = pixelformat_tab[i].sdl;
    415     ri->num_texture_formats = j;
    416 }
    417 
    418 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */