SDL_DirectFB_video.c (15551B)
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 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 */ 64static int DirectFB_VideoInit(_THIS); 65static void DirectFB_VideoQuit(_THIS); 66 67static int DirectFB_Available(void); 68static SDL_VideoDevice *DirectFB_CreateDevice(int devindex); 69 70VideoBootStrap DirectFB_bootstrap = { 71 "directfb", "DirectFB", 72 DirectFB_Available, DirectFB_CreateDevice 73}; 74 75static const DirectFBSurfaceDrawingFlagsNames(drawing_flags); 76static const DirectFBSurfaceBlittingFlagsNames(blitting_flags); 77static const DirectFBAccelerationMaskNames(acceleration_mask); 78 79/* DirectFB driver bootstrap functions */ 80 81static int 82DirectFB_Available(void) 83{ 84 if (!SDL_DirectFB_LoadLibrary()) 85 return 0; 86 SDL_DirectFB_UnLoadLibrary(); 87 return 1; 88} 89 90static void 91DirectFB_DeleteDevice(SDL_VideoDevice * device) 92{ 93 SDL_DirectFB_UnLoadLibrary(); 94 SDL_DFB_FREE(device->driverdata); 95 SDL_DFB_FREE(device); 96} 97 98static SDL_VideoDevice * 99DirectFB_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 free(device); 160 return (0); 161} 162 163static void 164DirectFB_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 204static 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 215static int 216DirectFB_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 293static void 294DirectFB_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 315static 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 388Uint32 389DirectFB_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 401DFBSurfacePixelFormat 402DirectFB_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 414void 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 */