📄 sdl_directfb_video.c
字号:
/* SDL - Simple DirectMedia Layer Copyright (C) 1997-2006 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Sam Lantinga slouken@libsdl.org MGA CRTC2 support by Thomas Jarosch - tomj@simonv.com CRTC2 support is inspired by mplayer's dfbmga driver written by Ville Syrj��<syrjala@sci.fi>*/#include "SDL_config.h"/* DirectFB video driver implementation.*/#include <fcntl.h>#include <unistd.h>#include <sys/mman.h>#include <directfb.h>#include <directfb_version.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_yuv.h"/* The implementation dependent data for the window manager cursor */struct WMcursor { int unused;};/* Initialization/Query functions */static int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat);static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);static void DirectFB_VideoQuit(_THIS);/* Hardware surface functions */static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface);static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface);static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface);static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface);static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha);static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface);static int DirectFB_ShowWMCursor(_THIS, WMcursor *cursor);/* Various screen update functions available */static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects);/* This is the rect EnumModes2 uses */struct DirectFBEnumRect { SDL_Rect r; struct DirectFBEnumRect* next;};static struct DirectFBEnumRect *enumlist = NULL;/* DirectFB driver bootstrap functions */static int DirectFB_Available(void){ return 1;}static void DirectFB_DeleteDevice(SDL_VideoDevice *device){ SDL_free(device->hidden); SDL_free(device);}static SDL_VideoDevice *DirectFB_CreateDevice(int devindex){ SDL_VideoDevice *device; /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); if (device) { SDL_memset (device, 0, (sizeof *device)); device->hidden = (struct SDL_PrivateVideoData *) malloc (sizeof (*device->hidden)); } if (device == NULL || device->hidden == NULL) { SDL_OutOfMemory(); if (device) { free (device); } return(0); } SDL_memset (device->hidden, 0, sizeof (*device->hidden)); /* Set the function pointers */ device->VideoInit = DirectFB_VideoInit; device->ListModes = DirectFB_ListModes; device->SetVideoMode = DirectFB_SetVideoMode; device->SetColors = DirectFB_SetColors; device->UpdateRects = NULL; device->CreateYUVOverlay = DirectFB_CreateYUVOverlay; device->VideoQuit = DirectFB_VideoQuit; device->AllocHWSurface = DirectFB_AllocHWSurface; device->CheckHWBlit = DirectFB_CheckHWBlit; device->FillHWRect = DirectFB_FillHWRect; device->SetHWColorKey = DirectFB_SetHWColorKey; device->SetHWAlpha = DirectFB_SetHWAlpha; device->LockHWSurface = DirectFB_LockHWSurface; device->UnlockHWSurface = DirectFB_UnlockHWSurface; device->FlipHWSurface = DirectFB_FlipHWSurface; device->FreeHWSurface = DirectFB_FreeHWSurface; device->ShowWMCursor = DirectFB_ShowWMCursor; device->SetCaption = NULL; device->SetIcon = NULL; device->IconifyWindow = NULL; device->GrabInput = NULL; device->GetWMInfo = NULL; device->InitOSKeymap = DirectFB_InitOSKeymap; device->PumpEvents = DirectFB_PumpEvents; device->free = DirectFB_DeleteDevice; return device;}VideoBootStrap DirectFB_bootstrap = { "directfb", "DirectFB", DirectFB_Available, DirectFB_CreateDevice};static DFBSurfacePixelFormat GetFormatForBpp (int bpp, IDirectFBDisplayLayer *layer){ DFBDisplayLayerConfig dlc; int bytes = (bpp + 7) / 8; layer->GetConfiguration (layer, &dlc); if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1) return dlc.pixelformat; switch (bytes) { case 1: return DSPF_LUT8; case 2: return DSPF_RGB16; case 3: return DSPF_RGB24; case 4: return DSPF_RGB32; } return DSPF_UNKNOWN;}static DFBEnumerationResult EnumModesCallback (int width, int height, int bpp, void *data){ SDL_VideoDevice *this = (SDL_VideoDevice *)data; struct DirectFBEnumRect *enumrect; HIDDEN->nummodes++; if (enumlist && enumlist->r.w == width && enumlist->r.h == height) return DFENUM_OK; enumrect = SDL_calloc(1, sizeof(struct DirectFBEnumRect)); if (!enumrect) { SDL_OutOfMemory(); return DFENUM_CANCEL; } enumrect->r.w = (Uint16)width; enumrect->r.h = (Uint16)height; enumrect->next = enumlist; enumlist = enumrect; return DFENUM_OK;}struct private_hwdata { IDirectFBSurface *surface; IDirectFBPalette *palette;};void SetDirectFBerror (const char *function, DFBResult code){ const char *error = DirectFBErrorString (code); if (error) SDL_SetError("%s: %s", function, error); else SDL_SetError("Unknown error code from %s", function);}static DFBSurfacePixelFormat SDLToDFBPixelFormat (SDL_PixelFormat *format){ if (format->Rmask && format->Gmask && format->Bmask) { switch (format->BitsPerPixel) { case 8: return DSPF_LUT8; case 16: if (format->Rmask == 0xF800 && format->Gmask == 0x07E0 && format->Bmask == 0x001F) return DSPF_RGB16; /* fall through */ case 15: if (format->Rmask == 0x7C00 && format->Gmask == 0x03E0 && format->Bmask == 0x001F) return DSPF_ARGB1555; break; case 24: if (format->Rmask == 0xFF0000 && format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF) return DSPF_RGB24; break; case 32: if (format->Rmask == 0xFF0000 && format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF) { if (format->Amask == 0xFF000000) return DSPF_ARGB; else return DSPF_RGB32; } break; } } else { switch (format->BitsPerPixel) { case 8: return DSPF_LUT8; case 15: return DSPF_ARGB1555; case 16: return DSPF_RGB16; case 24: return DSPF_RGB24; case 32: return DSPF_RGB32; } } return DSPF_UNKNOWN;}static SDL_Palette *AllocatePalette(int size){ SDL_Palette *palette; SDL_Color *colors; palette = SDL_calloc (1, sizeof(SDL_Palette)); if (!palette) { SDL_OutOfMemory(); return NULL; } colors = SDL_calloc (size, sizeof(SDL_Color)); if (!colors) { SDL_OutOfMemory(); return NULL; } palette->ncolors = size; palette->colors = colors; return palette;}static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat, SDL_PixelFormat *format){ format->Amask = format->Rmask = format->Gmask = format->Bmask = 0; format->BitsPerPixel = format->BytesPerPixel = 0; switch (pixelformat) { case DSPF_A8: format->Amask = 0x000000FF; break; case DSPF_ARGB1555: format->Rmask = 0x00007C00; format->Gmask = 0x000003E0; format->Bmask = 0x0000001F; break; case DSPF_RGB16: format->Rmask = 0x0000F800; format->Gmask = 0x000007E0; format->Bmask = 0x0000001F; break; case DSPF_ARGB: format->Amask = 0; /* apps don't seem to like that: 0xFF000000; */ /* fall through */ case DSPF_RGB24: case DSPF_RGB32: format->Rmask = 0x00FF0000; format->Gmask = 0x0000FF00; format->Bmask = 0x000000FF; break; case DSPF_LUT8: format->Rmask = 0x000000FF; format->Gmask = 0x000000FF; format->Bmask = 0x000000FF; if (!format->palette) format->palette = AllocatePalette(256); break; default: fprintf (stderr, "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n", pixelformat); return -1; } format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8; format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat); return 0;}int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat){ int i; DFBResult ret;#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23) DFBCardCapabilities caps;#else DFBGraphicsDeviceDescription caps;#endif DFBDisplayLayerConfig dlc; struct DirectFBEnumRect *rect; IDirectFB *dfb = NULL; IDirectFBDisplayLayer *layer = NULL; IDirectFBEventBuffer *events = NULL; HIDDEN->c2layer = NULL, HIDDEN->c2frame = NULL; HIDDEN->enable_mga_crtc2 = 0; HIDDEN->mga_crtc2_stretch_overscan = 1; ret = DirectFBInit (NULL, NULL); if (ret) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -