mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-20 22:16:49 +01:00
426 lines
15 KiB
C
426 lines
15 KiB
C
/*
|
|
Simple DirectMedia Layer
|
|
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
*/
|
|
#include "../../SDL_internal.h"
|
|
|
|
#if SDL_VIDEO_DRIVER_DIRECTFB
|
|
|
|
#include "SDL_DirectFB_video.h"
|
|
|
|
#include "SDL_DirectFB_events.h"
|
|
/*
|
|
* #include "SDL_DirectFB_keyboard.h"
|
|
*/
|
|
#include "SDL_DirectFB_modes.h"
|
|
#include "SDL_DirectFB_mouse.h"
|
|
#include "SDL_DirectFB_opengl.h"
|
|
#include "SDL_DirectFB_window.h"
|
|
#include "SDL_DirectFB_WM.h"
|
|
|
|
|
|
/* DirectFB video driver implementation.
|
|
*/
|
|
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/mman.h>
|
|
|
|
#include <directfb.h>
|
|
#include <directfb_version.h>
|
|
#include <directfb_strings.h>
|
|
|
|
#include "SDL_video.h"
|
|
#include "SDL_mouse.h"
|
|
#include "../SDL_sysvideo.h"
|
|
#include "../SDL_pixels_c.h"
|
|
#include "../../events/SDL_events_c.h"
|
|
#include "SDL_DirectFB_video.h"
|
|
#include "SDL_DirectFB_events.h"
|
|
#include "SDL_DirectFB_render.h"
|
|
#include "SDL_DirectFB_mouse.h"
|
|
#include "SDL_DirectFB_shape.h"
|
|
|
|
|
|
#include "SDL_DirectFB_dyn.h"
|
|
|
|
/* Initialization/Query functions */
|
|
static int DirectFB_VideoInit(_THIS);
|
|
static void DirectFB_VideoQuit(_THIS);
|
|
|
|
static int DirectFB_Available(void);
|
|
static SDL_VideoDevice *DirectFB_CreateDevice(int devindex);
|
|
|
|
VideoBootStrap DirectFB_bootstrap = {
|
|
"directfb", "DirectFB",
|
|
DirectFB_Available, DirectFB_CreateDevice
|
|
};
|
|
|
|
static const DirectFBSurfaceDrawingFlagsNames(drawing_flags);
|
|
static const DirectFBSurfaceBlittingFlagsNames(blitting_flags);
|
|
static const DirectFBAccelerationMaskNames(acceleration_mask);
|
|
|
|
/* DirectFB driver bootstrap functions */
|
|
|
|
static int
|
|
DirectFB_Available(void)
|
|
{
|
|
if (!SDL_DirectFB_LoadLibrary())
|
|
return 0;
|
|
SDL_DirectFB_UnLoadLibrary();
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
DirectFB_DeleteDevice(SDL_VideoDevice * device)
|
|
{
|
|
SDL_DirectFB_UnLoadLibrary();
|
|
SDL_DFB_FREE(device->driverdata);
|
|
SDL_DFB_FREE(device);
|
|
}
|
|
|
|
static SDL_VideoDevice *
|
|
DirectFB_CreateDevice(int devindex)
|
|
{
|
|
SDL_VideoDevice *device;
|
|
|
|
if (!SDL_DirectFB_LoadLibrary()) {
|
|
return NULL;
|
|
}
|
|
|
|
/* Initialize all variables that we clean on shutdown */
|
|
SDL_DFB_ALLOC_CLEAR(device, sizeof(SDL_VideoDevice));
|
|
|
|
/* Set the function pointers */
|
|
|
|
/* Set the function pointers */
|
|
device->VideoInit = DirectFB_VideoInit;
|
|
device->VideoQuit = DirectFB_VideoQuit;
|
|
device->GetDisplayModes = DirectFB_GetDisplayModes;
|
|
device->SetDisplayMode = DirectFB_SetDisplayMode;
|
|
device->PumpEvents = DirectFB_PumpEventsWindow;
|
|
device->CreateWindow = DirectFB_CreateWindow;
|
|
device->CreateWindowFrom = DirectFB_CreateWindowFrom;
|
|
device->SetWindowTitle = DirectFB_SetWindowTitle;
|
|
device->SetWindowIcon = DirectFB_SetWindowIcon;
|
|
device->SetWindowPosition = DirectFB_SetWindowPosition;
|
|
device->SetWindowSize = DirectFB_SetWindowSize;
|
|
device->SetWindowOpacity = DirectFB_SetWindowOpacity;
|
|
device->ShowWindow = DirectFB_ShowWindow;
|
|
device->HideWindow = DirectFB_HideWindow;
|
|
device->RaiseWindow = DirectFB_RaiseWindow;
|
|
device->MaximizeWindow = DirectFB_MaximizeWindow;
|
|
device->MinimizeWindow = DirectFB_MinimizeWindow;
|
|
device->RestoreWindow = DirectFB_RestoreWindow;
|
|
device->SetWindowGrab = DirectFB_SetWindowGrab;
|
|
device->DestroyWindow = DirectFB_DestroyWindow;
|
|
device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
|
|
|
|
/* !!! FIXME: implement SetWindowBordered */
|
|
|
|
#if SDL_DIRECTFB_OPENGL
|
|
device->GL_LoadLibrary = DirectFB_GL_LoadLibrary;
|
|
device->GL_GetProcAddress = DirectFB_GL_GetProcAddress;
|
|
device->GL_MakeCurrent = DirectFB_GL_MakeCurrent;
|
|
|
|
device->GL_CreateContext = DirectFB_GL_CreateContext;
|
|
device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval;
|
|
device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval;
|
|
device->GL_SwapWindow = DirectFB_GL_SwapWindow;
|
|
device->GL_DeleteContext = DirectFB_GL_DeleteContext;
|
|
|
|
#endif
|
|
|
|
/* Shaped window support */
|
|
device->shape_driver.CreateShaper = DirectFB_CreateShaper;
|
|
device->shape_driver.SetWindowShape = DirectFB_SetWindowShape;
|
|
device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape;
|
|
|
|
device->free = DirectFB_DeleteDevice;
|
|
|
|
return device;
|
|
error:
|
|
if (device)
|
|
SDL_free(device);
|
|
return (0);
|
|
}
|
|
|
|
static void
|
|
DirectFB_DeviceInformation(IDirectFB * dfb)
|
|
{
|
|
DFBGraphicsDeviceDescription desc;
|
|
int n;
|
|
|
|
dfb->GetDeviceDescription(dfb, &desc);
|
|
|
|
SDL_DFB_LOG( "DirectFB Device Information");
|
|
SDL_DFB_LOG( "===========================");
|
|
SDL_DFB_LOG( "Name: %s", desc.name);
|
|
SDL_DFB_LOG( "Vendor: %s", desc.vendor);
|
|
SDL_DFB_LOG( "Driver Name: %s", desc.driver.name);
|
|
SDL_DFB_LOG( "Driver Vendor: %s", desc.driver.vendor);
|
|
SDL_DFB_LOG( "Driver Version: %d.%d", desc.driver.major,
|
|
desc.driver.minor);
|
|
|
|
SDL_DFB_LOG( "Video memory: %d", desc.video_memory);
|
|
|
|
SDL_DFB_LOG( "Blitting flags:");
|
|
for (n = 0; blitting_flags[n].flag; n++) {
|
|
if (desc.blitting_flags & blitting_flags[n].flag)
|
|
SDL_DFB_LOG( " %s", blitting_flags[n].name);
|
|
}
|
|
|
|
SDL_DFB_LOG( "Drawing flags:");
|
|
for (n = 0; drawing_flags[n].flag; n++) {
|
|
if (desc.drawing_flags & drawing_flags[n].flag)
|
|
SDL_DFB_LOG( " %s", drawing_flags[n].name);
|
|
}
|
|
|
|
|
|
SDL_DFB_LOG( "Acceleration flags:");
|
|
for (n = 0; acceleration_mask[n].mask; n++) {
|
|
if (desc.acceleration_mask & acceleration_mask[n].mask)
|
|
SDL_DFB_LOG( " %s", acceleration_mask[n].name);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
static int readBoolEnv(const char *env_name, int def_val)
|
|
{
|
|
char *stemp;
|
|
|
|
stemp = SDL_getenv(env_name);
|
|
if (stemp)
|
|
return atoi(stemp);
|
|
else
|
|
return def_val;
|
|
}
|
|
|
|
static int
|
|
DirectFB_VideoInit(_THIS)
|
|
{
|
|
IDirectFB *dfb = NULL;
|
|
DFB_DeviceData *devdata = NULL;
|
|
DFBResult ret;
|
|
|
|
SDL_DFB_ALLOC_CLEAR(devdata, sizeof(*devdata));
|
|
|
|
SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));
|
|
|
|
/* avoid switching to the framebuffer when we
|
|
* are running X11 */
|
|
ret = readBoolEnv(DFBENV_USE_X11_CHECK , 1);
|
|
if (ret) {
|
|
if (SDL_getenv("DISPLAY"))
|
|
DirectFBSetOption("system", "x11");
|
|
else
|
|
DirectFBSetOption("disable-module", "x11input");
|
|
}
|
|
|
|
/* FIXME: Reenable as default once multi kbd/mouse interface is sorted out */
|
|
devdata->use_linux_input = readBoolEnv(DFBENV_USE_LINUX_INPUT, 0); /* default: on */
|
|
|
|
if (!devdata->use_linux_input)
|
|
{
|
|
SDL_DFB_LOG("Disabling linux input\n");
|
|
DirectFBSetOption("disable-module", "linux_input");
|
|
}
|
|
|
|
SDL_DFB_CHECKERR(DirectFBCreate(&dfb));
|
|
|
|
DirectFB_DeviceInformation(dfb);
|
|
|
|
devdata->use_yuv_underlays = readBoolEnv(DFBENV_USE_YUV_UNDERLAY, 0); /* default: off */
|
|
devdata->use_yuv_direct = readBoolEnv(DFBENV_USE_YUV_DIRECT, 0); /* default is off! */
|
|
|
|
/* Create global Eventbuffer for axis events */
|
|
if (devdata->use_linux_input) {
|
|
SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_ALL,
|
|
DFB_TRUE,
|
|
&devdata->events));
|
|
} else {
|
|
SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_AXES
|
|
/* DICAPS_ALL */ ,
|
|
DFB_TRUE,
|
|
&devdata->events));
|
|
}
|
|
|
|
/* simple window manager support */
|
|
devdata->has_own_wm = readBoolEnv(DFBENV_USE_WM, 0);
|
|
|
|
devdata->initialized = 1;
|
|
|
|
devdata->dfb = dfb;
|
|
devdata->firstwin = NULL;
|
|
devdata->grabbed_window = NULL;
|
|
|
|
_this->driverdata = devdata;
|
|
|
|
DirectFB_InitModes(_this);
|
|
|
|
#if SDL_DIRECTFB_OPENGL
|
|
DirectFB_GL_Initialize(_this);
|
|
#endif
|
|
|
|
DirectFB_InitMouse(_this);
|
|
DirectFB_InitKeyboard(_this);
|
|
|
|
return 0;
|
|
|
|
|
|
error:
|
|
SDL_DFB_FREE(devdata);
|
|
SDL_DFB_RELEASE(dfb);
|
|
return -1;
|
|
}
|
|
|
|
static void
|
|
DirectFB_VideoQuit(_THIS)
|
|
{
|
|
DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata;
|
|
|
|
DirectFB_QuitModes(_this);
|
|
DirectFB_QuitKeyboard(_this);
|
|
DirectFB_QuitMouse(_this);
|
|
|
|
devdata->events->Reset(devdata->events);
|
|
SDL_DFB_RELEASE(devdata->events);
|
|
SDL_DFB_RELEASE(devdata->dfb);
|
|
|
|
#if SDL_DIRECTFB_OPENGL
|
|
DirectFB_GL_Shutdown(_this);
|
|
#endif
|
|
|
|
devdata->initialized = 0;
|
|
}
|
|
|
|
/* DirectFB driver general support functions */
|
|
|
|
static const struct {
|
|
DFBSurfacePixelFormat dfb;
|
|
Uint32 sdl;
|
|
} pixelformat_tab[] =
|
|
{
|
|
{ DSPF_RGB32, SDL_PIXELFORMAT_RGB888 }, /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
|
|
{ DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 }, /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */
|
|
{ DSPF_RGB16, SDL_PIXELFORMAT_RGB565 }, /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
|
|
{ DSPF_RGB332, SDL_PIXELFORMAT_RGB332 }, /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
|
|
{ DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 }, /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */
|
|
{ DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 }, /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */
|
|
{ DSPF_RGB24, SDL_PIXELFORMAT_RGB24 }, /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
|
|
{ DSPF_RGB444, SDL_PIXELFORMAT_RGB444 }, /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */
|
|
{ DSPF_YV12, SDL_PIXELFORMAT_YV12 }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */
|
|
{ DSPF_I420,SDL_PIXELFORMAT_IYUV }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */
|
|
{ DSPF_YUY2, SDL_PIXELFORMAT_YUY2 }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */
|
|
{ DSPF_UYVY, SDL_PIXELFORMAT_UYVY }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */
|
|
{ DSPF_RGB555, SDL_PIXELFORMAT_RGB555 }, /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */
|
|
#if (ENABLE_LUT8)
|
|
{ DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 }, /* 8 bit LUT (8 bit color and alpha lookup from palette) */
|
|
#endif
|
|
|
|
#if (DFB_VERSION_ATLEAST(1,2,0))
|
|
{ DSPF_BGR555, SDL_PIXELFORMAT_BGR555 }, /* 16 bit BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */
|
|
#else
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR555 },
|
|
#endif
|
|
|
|
/* Pfff ... nonmatching formats follow */
|
|
|
|
{ DSPF_ALUT44, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit ALUT (1 byte, alpha 4@4, color lookup 4@0) */
|
|
{ DSPF_A8, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit alpha (1 byte, alpha 8@0), e.g. anti-aliased glyphs */
|
|
{ DSPF_AiRGB, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */
|
|
{ DSPF_A1, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */
|
|
{ DSPF_NV12, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CbCr [15:0] plane) */
|
|
{ DSPF_NV16, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit YUV (8 bit Y plane followed by one 16 bit half width CbCr [15:0] plane) */
|
|
{ DSPF_ARGB2554, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */
|
|
{ DSPF_NV21, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CrCb [15:0] plane) */
|
|
{ DSPF_AYUV, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */
|
|
{ DSPF_A4, SDL_PIXELFORMAT_UNKNOWN }, /* 4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */
|
|
{ DSPF_ARGB1666, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (3 byte/ alpha 1@18, red 6@16, green 6@6, blue 6@0) */
|
|
{ DSPF_ARGB6666, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit alpha (3 byte/ alpha 6@18, red 6@16, green 6@6, blue 6@0) */
|
|
{ DSPF_RGB18, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit RGB (3 byte/ red 6@16, green 6@6, blue 6@0) */
|
|
{ DSPF_LUT2, SDL_PIXELFORMAT_UNKNOWN }, /* 2 bit LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */
|
|
|
|
#if (DFB_VERSION_ATLEAST(1,3,0))
|
|
{ DSPF_RGBA4444, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 4@12, green 4@8, blue 4@4, alpha 4@0) */
|
|
#endif
|
|
|
|
#if (DFB_VERSION_ATLEAST(1,4,3))
|
|
{ DSPF_RGBA5551, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 5@11, green 5@6, blue 5@1, alpha 1@0) */
|
|
{ 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) */
|
|
{ DSPF_ARGB8565, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit ARGB (3 byte, alpha 8@16, red 5@11, green 6@5, blue 5@0) */
|
|
{ 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) */
|
|
{ DSPF_VYU, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit VYU 4:4:4 (3 byte, Cr 8@16, Y 8@8, Cb 8@0) */
|
|
#endif
|
|
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1MSB },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4LSB },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4MSB },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR24 },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR888 },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_RGBA8888 },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR8888 },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGRA8888 },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ARGB2101010 },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR4444 },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR1555 },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR565 },
|
|
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU }, /**< Packed mode: Y0+V0+Y1+U0 (1 pla */
|
|
};
|
|
|
|
Uint32
|
|
DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
|
|
if (pixelformat_tab[i].dfb == pixelformat)
|
|
{
|
|
return pixelformat_tab[i].sdl;
|
|
}
|
|
return SDL_PIXELFORMAT_UNKNOWN;
|
|
}
|
|
|
|
DFBSurfacePixelFormat
|
|
DirectFB_SDLToDFBPixelFormat(Uint32 format)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
|
|
if (pixelformat_tab[i].sdl == format)
|
|
{
|
|
return pixelformat_tab[i].dfb;
|
|
}
|
|
return DSPF_UNKNOWN;
|
|
}
|
|
|
|
void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo* ri)
|
|
{
|
|
int i, j;
|
|
|
|
for (i=0, j=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
|
|
if (pixelformat_tab[i].sdl != SDL_PIXELFORMAT_UNKNOWN)
|
|
ri->texture_formats[j++] = pixelformat_tab[i].sdl;
|
|
ri->num_texture_formats = j;
|
|
}
|
|
|
|
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|