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