Mercurial > sdl-ios-xcode
view src/video/directfb/SDL_DirectFB_video.c @ 2288:e9bcf004c324
Merged fix for bug #482 from SDL 1.2 revision 3492.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 29 Dec 2007 20:13:23 +0000 |
parents | 1e690901ecd7 |
children | e1da92da346c e82a0e3e9b0e |
line wrap: on
line source
/* 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 SDL1.3 implementation by couriersud@arcor.de */ /* TODO: Various * Add Mouse support from 1.2 directfb driver * - Interface is defined in SDL_Mouse.c.h * - Default Cursor automatically created */ #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" /* This is the rect EnumModes2 uses */ struct DirectFBEnumRect { SDL_Rect r; struct DirectFBEnumRect *next; }; struct DirectFB_GLContext { IDirectFBGL *context; }; /* Initialization/Query functions */ static int DirectFB_VideoInit(_THIS); static void DirectFB_VideoQuit(_THIS); static int DirectFB_CreateWindow(_THIS, SDL_Window * window); static int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); static void DirectFB_SetWindowTitle(_THIS, SDL_Window * window); static void DirectFB_SetWindowPosition(_THIS, SDL_Window * window); static void DirectFB_SetWindowSize(_THIS, SDL_Window * window); static void DirectFB_ShowWindow(_THIS, SDL_Window * window); static void DirectFB_HideWindow(_THIS, SDL_Window * window); static void DirectFB_RaiseWindow(_THIS, SDL_Window * window); static void DirectFB_MaximizeWindow(_THIS, SDL_Window * window); static void DirectFB_MinimizeWindow(_THIS, SDL_Window * window); static void DirectFB_RestoreWindow(_THIS, SDL_Window * window); static void DirectFB_SetWindowGrab(_THIS, SDL_Window * window); static void DirectFB_DestroyWindow(_THIS, SDL_Window * window); static SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); static void DirectFB_GetDisplayModes(_THIS); static int DirectFB_SetDisplayMode(_THIS, SDL_DisplayMode * mode); static int DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp); static int DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp); #if SDL_DIRECTFB_OPENGL static int DirectFB_GL_LoadLibrary(_THIS, const char *path); static void DirectFB_GL_UnloadLibrary(_THIS); static void *DirectFB_GL_GetProcAddress(_THIS, const char *proc); static SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window); static int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); static int DirectFB_GL_SetSwapInterval(_THIS, int interval); static int DirectFB_GL_GetSwapInterval(_THIS); static void DirectFB_GL_SwapWindow(_THIS, SDL_Window * window); static void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context); #endif /* DirectFB driver bootstrap functions */ static int DirectFB_Available(void) { return 1; } static void DirectFB_DeleteDevice(SDL_VideoDevice * device) { SDL_free(device->driverdata); SDL_free(device); } static SDL_VideoDevice * DirectFB_CreateDevice(int devindex) { SDL_VideoDevice *device; /* Initialize all variables that we clean on shutdown */ SDL_DFB_CALLOC(device, 1, sizeof(SDL_VideoDevice)); SDL_DFB_CALLOC(device->gl_data, 1, sizeof(*device->gl_data)); /* Set the function pointers */ /* Set the function pointers */ device->VideoInit = DirectFB_VideoInit; device->VideoQuit = DirectFB_VideoQuit; device->GetDisplayModes = DirectFB_GetDisplayModes; device->SetDisplayMode = DirectFB_SetDisplayMode; #if 0 device->SetDisplayGammaRamp = DirectFB_SetDisplayGammaRamp; device->GetDisplayGammaRamp = DirectFB_GetDisplayGammaRamp; #else device->SetDisplayGammaRamp = NULL; device->GetDisplayGammaRamp = NULL; #endif device->PumpEvents = DirectFB_PumpEventsWindow; device->CreateWindow = DirectFB_CreateWindow; device->CreateWindowFrom = DirectFB_CreateWindowFrom; device->SetWindowTitle = DirectFB_SetWindowTitle; device->SetWindowPosition = DirectFB_SetWindowPosition; device->SetWindowSize = DirectFB_SetWindowSize; 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; #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 device->free = DirectFB_DeleteDevice; return device; error: if (device) free(device); return (0); } VideoBootStrap DirectFB_bootstrap = { "directfb", "DirectFB", DirectFB_Available, DirectFB_CreateDevice }; static DFBEnumerationResult EnumModesCallback(int width, int height, int bpp, void *data) { SDL_VideoDisplay *this = (SDL_VideoDisplay *) data; DFB_DisplayData *dispdata = (DFB_DisplayData *) this->driverdata; SDL_DisplayMode mode; mode.w = width; mode.h = height; mode.refresh_rate = 0; mode.driverdata = NULL; mode.format = 0; if (dispdata->nummodes < DFB_MAX_MODES) { dispdata->modelist[dispdata->nummodes++] = mode; } SDL_DFB_DEBUG("w %d h %d bpp %d\n", width, height, bpp); return DFENUM_OK; } static int DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat, Uint32 * fmt) { switch (pixelformat) { case DSPF_ALUT44: *fmt = SDL_PIXELFORMAT_INDEX4LSB; break; case DSPF_LUT8: *fmt = SDL_PIXELFORMAT_INDEX8; break; case DSPF_RGB332: *fmt = SDL_PIXELFORMAT_RGB332; break; case DSPF_ARGB4444: *fmt = SDL_PIXELFORMAT_ARGB4444; break; case SDL_PIXELFORMAT_ARGB1555: *fmt = SDL_PIXELFORMAT_ARGB1555; break; case DSPF_RGB16: *fmt = SDL_PIXELFORMAT_RGB565; break; case DSPF_RGB24: *fmt = SDL_PIXELFORMAT_RGB24; break; case DSPF_RGB32: *fmt = SDL_PIXELFORMAT_RGB888; break; case DSPF_ARGB: *fmt = SDL_PIXELFORMAT_ARGB8888; break; case DSPF_YV12: *fmt = SDL_PIXELFORMAT_YV12; break; /* Planar mode: Y + V + U (3 planes) */ case DSPF_I420: *fmt = SDL_PIXELFORMAT_IYUV; break; /* Planar mode: Y + U + V (3 planes) */ case DSPF_YUY2: *fmt = SDL_PIXELFORMAT_YUY2; break; /* Packed mode: Y0+U0+Y1+V0 (1 plane) */ case DSPF_UYVY: *fmt = SDL_PIXELFORMAT_UYVY; break; /* Packed mode: U0+Y0+V0+Y1 (1 plane) */ default: return -1; } return 0; } static DFBEnumerationResult cbScreens(DFBScreenID screen_id, DFBScreenDescription desc, void *callbackdata) { DFB_DeviceData *devdata = (DFB_DeviceData *) callbackdata; devdata->screenid[devdata->numscreens++] = screen_id; return DFENUM_OK; } DFBEnumerationResult cbLayers(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc, void *callbackdata) { DFB_DeviceData *devdata = (DFB_DeviceData *) callbackdata; if (desc.caps & DLCAPS_SURFACE) { if ((desc.type & DLTF_GRAPHICS) && (desc.type & DLTF_VIDEO)) { if (devdata->vidlayer[devdata->aux] == -1) devdata->vidlayer[devdata->aux] = layer_id; } else if (desc.type & DLTF_GRAPHICS) { if (devdata->gralayer[devdata->aux] == -1) devdata->gralayer[devdata->aux] = layer_id; } } return DFENUM_OK; } static int DirectFB_VideoInit(_THIS) { #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; SDL_VideoDisplay display; DFB_DisplayData *dispdata; DFB_DeviceData *devdata; SDL_DisplayMode mode; SDL_Keyboard keyboard; int i; DFBResult ret; int tcw[DFB_MAX_SCREENS]; int tch[DFB_MAX_SCREENS]; SDL_zero(keyboard); SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL)); SDL_DFB_CHECKERR(DirectFBCreate(&dfb)); SDL_DFB_CALLOC(devdata, 1, sizeof(*devdata)); devdata->numscreens = 0; for (i = 0; i < DFB_MAX_SCREENS; i++) { devdata->gralayer[i] = -1; devdata->vidlayer[i] = -1; } SDL_DFB_CHECKERR(dfb->EnumScreens(dfb, &cbScreens, devdata)); for (i = 0; i < devdata->numscreens; i++) { IDirectFBScreen *screen; SDL_DFB_CHECKERR(dfb->GetScreen(dfb, devdata->screenid[i], &screen)); devdata->aux = i; SDL_DFB_CHECKERR(screen-> EnumDisplayLayers(screen, &cbLayers, devdata)); screen->GetSize(screen, &tcw[i], &tch[i]); screen->Release(screen); } /* Query card capabilities */ dfb->GetDeviceDescription(dfb, &caps); SDL_DFB_DEBUG("SDL directfb video driver - %s %s\n", __DATE__, __TIME__); SDL_DFB_DEBUG("Using %s (%s) driver.\n", caps.name, caps.vendor); SDL_DFB_DEBUG("Found %d screens\n", devdata->numscreens); for (i = 0; i < devdata->numscreens; i++) { //SDL_DFB_CHECKERR( dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer) ); SDL_DFB_CHECKERR(dfb-> GetDisplayLayer(dfb, devdata->gralayer[i], &layer)); //SDL_DFB_CHECKERR( dfb->CreateInputEventBuffer (dfb, DICAPS_ALL, DFB_FALSE, &events) ); SDL_DFB_CHECKERR(layer-> SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE)); layer->EnableCursor(layer, 1); SDL_DFB_CHECKERR(layer->SetCursorOpacity(layer, 0xC0)); SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED)); /* Query layer configuration to determine the current mode and pixelformat */ layer->GetConfiguration(layer, &dlc); DFBToSDLPixelFormat(dlc.pixelformat, &mode.format); mode.w = dlc.width; mode.h = dlc.height; mode.refresh_rate = 0; mode.driverdata = NULL; SDL_DFB_CALLOC(dispdata, 1, sizeof(*dispdata)); dispdata->layer = layer; dispdata->pixelformat = dlc.pixelformat; dispdata->cw = tcw[i]; dispdata->ch = tch[i]; /* YUV - Video layer */ dispdata->vidID = devdata->vidlayer[i]; SDL_zero(display); display.desktop_mode = mode; display.current_mode = mode; display.driverdata = dispdata; /* Enumerate the available fullscreen modes */ SDL_DFB_CALLOC(dispdata->modelist, DFB_MAX_MODES, sizeof(SDL_DisplayMode)); SDL_DFB_CHECKERR(dfb-> EnumVideoModes(dfb, EnumModesCallback, &display)); SDL_AddVideoDisplay(&display); } devdata->initialized = 1; devdata->dfb = dfb; devdata->firstwin = NULL; _this->driverdata = devdata; #if SDL_DIRECTFB_OPENGL /* Opengl */ _this->gl_data->gl_active = 0; _this->gl_data->gl_context = NULL; #endif DirectFB_AddRenderDriver(_this); DirectFB_InitMouse(_this); //devdata->mouse = SDL_AddMouse(&mouse, -1); devdata->keyboard = SDL_AddKeyboard(&keyboard, -1); DirectFB_InitOSKeymap(_this); return 0; error: //FIXME: Cleanup not complete, Free existing displays SDL_DFB_FREE(dispdata); SDL_DFB_FREE(dispdata->modelist); SDL_DFB_RELEASE(layer); SDL_DFB_RELEASE(dfb); return -1; } static void DirectFB_VideoQuit(_THIS) { DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata; SDL_DisplayMode tmode; DFBResult ret; int i; tmode = _this->displays[0].desktop_mode; tmode.format = SDL_PIXELFORMAT_UNKNOWN; DirectFB_SetDisplayMode(_this, &tmode); tmode = _this->displays[0].desktop_mode; DirectFB_SetDisplayMode(_this, &tmode); for (i = 0; i < devdata->numscreens; i++) { DFB_DisplayData *dispdata = (DFB_DisplayData *) _this->displays[i].driverdata; if (dispdata->layer) { SDL_DFB_CHECK(dispdata->layer-> SetCooperativeLevel(dispdata->layer, DLSCL_ADMINISTRATIVE)); SDL_DFB_CHECK(dispdata->layer-> SetCursorOpacity(dispdata->layer, 0x00)); SDL_DFB_CHECK(dispdata->layer-> SetCooperativeLevel(dispdata->layer, DLSCL_SHARED)); } SDL_DFB_RELEASE(dispdata->layer); /* Free video mode list */ if (dispdata->modelist) { SDL_free(dispdata->modelist); dispdata->modelist = NULL; } // Done by core //SDL_free(dispdata); } //SDL_DFB_RELEASE(devdata->eventbuffer); SDL_DFB_RELEASE(devdata->dfb); SDL_DelMouse(devdata->mouse); SDL_DelKeyboard(devdata->keyboard); #if SDL_DIRECTFB_OPENGL DirectFB_GL_UnloadLibrary(_this); #endif devdata->initialized = 0; } static DFBSurfacePixelFormat SDLToDFBPixelFormat(Uint32 format) { switch (format) { case SDL_PIXELFORMAT_INDEX4LSB: return DSPF_ALUT44; case SDL_PIXELFORMAT_INDEX8: return DSPF_LUT8; case SDL_PIXELFORMAT_RGB332: return DSPF_RGB332; case SDL_PIXELFORMAT_RGB555: return DSPF_ARGB1555; case SDL_PIXELFORMAT_ARGB4444: return DSPF_ARGB4444; case SDL_PIXELFORMAT_ARGB1555: return DSPF_ARGB1555; case SDL_PIXELFORMAT_RGB565: return DSPF_RGB16; case SDL_PIXELFORMAT_RGB24: return DSPF_RGB24; case SDL_PIXELFORMAT_RGB888: return DSPF_RGB32; case SDL_PIXELFORMAT_ARGB8888: return DSPF_ARGB; case SDL_PIXELFORMAT_YV12: return DSPF_YV12; /* Planar mode: Y + V + U (3 planes) */ case SDL_PIXELFORMAT_IYUV: return DSPF_I420; /* Planar mode: Y + U + V (3 planes) */ case SDL_PIXELFORMAT_YUY2: return DSPF_YUY2; /* Packed mode: Y0+U0+Y1+V0 (1 plane) */ case SDL_PIXELFORMAT_UYVY: return DSPF_UYVY; /* Packed mode: U0+Y0+V0+Y1 (1 plane) */ case SDL_PIXELFORMAT_YVYU: return DSPF_UNKNOWN; /* Packed mode: Y0+V0+Y1+U0 (1 plane) */ case SDL_PIXELFORMAT_INDEX1LSB: return DSPF_UNKNOWN; case SDL_PIXELFORMAT_INDEX1MSB: return DSPF_UNKNOWN; case SDL_PIXELFORMAT_INDEX4MSB: return DSPF_UNKNOWN; case SDL_PIXELFORMAT_RGB444: return DSPF_UNKNOWN; case SDL_PIXELFORMAT_BGR24: return DSPF_UNKNOWN; case SDL_PIXELFORMAT_BGR888: return DSPF_UNKNOWN; case SDL_PIXELFORMAT_RGBA8888: return DSPF_UNKNOWN; case SDL_PIXELFORMAT_ABGR8888: return DSPF_UNKNOWN; case SDL_PIXELFORMAT_BGRA8888: return DSPF_UNKNOWN; case SDL_PIXELFORMAT_ARGB2101010: return DSPF_UNKNOWN; default: return DSPF_UNKNOWN; } } static void CheckSetDisplayMode(_THIS, DFB_DisplayData * data, SDL_DisplayMode * mode) { DFBDisplayLayerConfig config; DFBDisplayLayerConfigFlags failed; config.width = mode->w; config.height = mode->h; config.pixelformat = SDLToDFBPixelFormat(mode->format); config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT; failed = 0; data->layer->TestConfiguration(data->layer, &config, &failed); if (failed == 0) SDL_AddDisplayMode(_this->current_display, mode); } static void DirectFB_GetDisplayModes(_THIS) { //SDL_DisplayData *data = (SDL_DisplayData *) SDL_CurrentDisplay.driverdata; //SDL_DisplayMode mode; //SDL_AddDisplayMode(_this->current_display, &mode); SDL_DFB_DEVICEDATA(_this); DFB_DisplayData *data = (DFB_DisplayData *) SDL_CurrentDisplay.driverdata; int i; SDL_DisplayMode mode; for (i = 0; i < data->nummodes; ++i) { mode = data->modelist[i]; //mode.format = SDL_PIXELFORMAT_UNKNOWN; mode.format = SDL_PIXELFORMAT_INDEX8; CheckSetDisplayMode(_this, data, &mode); mode.format = SDL_PIXELFORMAT_RGB565; CheckSetDisplayMode(_this, data, &mode); mode.format = SDL_PIXELFORMAT_RGB24; CheckSetDisplayMode(_this, data, &mode); mode.format = SDL_PIXELFORMAT_RGB888; CheckSetDisplayMode(_this, data, &mode); } } int DirectFB_SetDisplayMode(_THIS, SDL_DisplayMode * mode) { SDL_DFB_DEVICEDATA(_this); DFB_DisplayData *data = (DFB_DisplayData *) SDL_CurrentDisplay.driverdata; DFBDisplayLayerConfig config, rconfig; DFBDisplayLayerConfigFlags fail = 0; DFBResult ret; SDL_DFB_CHECKERR(data->layer-> SetCooperativeLevel(data->layer, DLSCL_ADMINISTRATIVE)); SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &config)); config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_BUFFERMODE; if (mode->format != SDL_PIXELFORMAT_UNKNOWN) { config.flags |= DLCONF_PIXELFORMAT; config.pixelformat = SDLToDFBPixelFormat(mode->format); data->pixelformat = config.pixelformat; } config.width = mode->w; config.height = mode->h; config.buffermode = DLBM_BACKVIDEO; //config.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer); data->layer->TestConfiguration(data->layer, &config, &fail); if (fail & (DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT)) { SDL_DFB_DEBUG("Error setting mode %dx%d-%x\n", mode->w, mode->h, mode->format); return -1; } SDL_DFB_DEBUG("Trace\n"); config.flags &= ~fail; SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config)); SDL_DFB_CHECKERR(data->layer-> SetCooperativeLevel(data->layer, DLSCL_ADMINISTRATIVE)); /* Double check */ SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig)); if ((config.width != rconfig.width) || (config.height != rconfig.height) || (config.pixelformat != rconfig.pixelformat)) { SDL_DFB_DEBUG("Error setting mode %dx%d-%x\n", mode->w, mode->h, mode->format); return -1; } return 0; error: return -1; } static int DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp) { return -1; } static int DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp) { return -1; } static int DirectFB_CreateWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_DISPLAYDATA(_this, window); DFB_WindowData *windata; DFBWindowOptions wopts; DFBWindowDescription desc; int ret, x, y; SDL_DFB_DEBUG("Trace x %d y %d w %d h %d\n", window->x, window->y, window->w, window->h); window->driverdata = NULL; SDL_DFB_CALLOC(window->driverdata, 1, sizeof(DFB_WindowData)); windata = (DFB_WindowData *) window->driverdata; SDL_DFB_CHECKERR(devdata->dfb-> SetCooperativeLevel(devdata->dfb, DFSCL_NORMAL)); SDL_DFB_CHECKERR(dispdata->layer-> SetCooperativeLevel(dispdata->layer, DLSCL_ADMINISTRATIVE)); /* Fill the window description. */ if (window->x == SDL_WINDOWPOS_CENTERED) { x = (dispdata->cw - window->w) / 2; } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { x = 0; } else { x = window->x; } if (window->y == SDL_WINDOWPOS_CENTERED) { y = (dispdata->ch - window->h) / 2; } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { y = 0; } else { y = window->y; } if (window->flags & SDL_WINDOW_FULLSCREEN) { x = 0; y = 0; } desc.flags = DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS | DWDESC_PIXELFORMAT | DWDESC_SURFACE_CAPS; if (!(window->flags & SDL_WINDOW_FULLSCREEN) && window->x != SDL_WINDOWPOS_UNDEFINED && window->y != SDL_WINDOWPOS_UNDEFINED) { desc.flags |= DWDESC_POSX | DWDESC_POSY; desc.posx = x; desc.posy = y; } desc.width = window->w; desc.height = window->h; desc.pixelformat = dispdata->pixelformat; desc.caps = 0; //DWCAPS_DOUBLEBUFFER; desc.surface_caps = DSCAPS_DOUBLE | DSCAPS_TRIPLE; //| DSCAPS_PREMULTIPLIED; /* Create the window. */ SDL_DFB_CHECKERR(dispdata->layer-> CreateWindow(dispdata->layer, &desc, &windata->window)); windata->window->GetOptions(windata->window, &wopts); #if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0) if (window->flags & SDL_WINDOW_RESIZABLE) wopts |= DWOP_SCALE; else wopts |= DWOP_KEEP_SIZE; #else wopts |= DWOP_KEEP_SIZE; // if not we will crash ... #endif if (window->flags & SDL_WINDOW_FULLSCREEN) wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE; windata->window->SetOptions(windata->window, wopts); /* Get the window's surface. */ SDL_DFB_CHECKERR(windata->window-> GetSurface(windata->window, &windata->surface)); windata->window->SetOpacity(windata->window, 0xFF); SDL_DFB_CHECKERR(windata->window-> CreateEventBuffer(windata->window, &(windata->eventbuffer))); SDL_DFB_CHECKERR(windata->window-> EnableEvents(windata->window, DWET_POSITION | DWET_SIZE | DWET_CLOSE | DWET_ALL)); if (window->flags & SDL_WINDOW_FULLSCREEN) windata->window->SetStackingClass(windata->window, DWSC_UPPER); /* Make it the top most window. */ windata->window->RaiseToTop(windata->window); windata->window->GetID(windata->window, &windata->windowID); windata->id = window->id; #if SDL_DIRECTFB_OPENGL if (window->flags & SDL_WINDOW_OPENGL) { if (!_this->gl_config.driver_loaded) { /* no driver has been loaded, use default (ourselves) */ if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) { goto error; } } _this->gl_data->gl_active = 1; } #endif /* Add to list ... */ windata->next = devdata->firstwin; windata->opacity = 0xFF; devdata->firstwin = windata; //SDL_DFB_CHECKERR( windata->surface->GetPalette(windata->surface, &windata->palette) ); return 0; error: SDL_DFB_RELEASE(windata->window); SDL_DFB_RELEASE(windata->surface); return -1; } static int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); SDL_Unsupported(); return -1; } static void DirectFB_SetWindowTitle(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); SDL_Unsupported(); //return -1; } static void DirectFB_SetWindowPosition(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); if (!(window->flags & SDL_WINDOW_FULLSCREEN)) windata->window->MoveTo(windata->window, window->x, window->y); } static void DirectFB_SetWindowSize(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); if (!(window->flags & SDL_WINDOW_FULLSCREEN)) windata->window->Resize(windata->window, window->w, window->h); } static void DirectFB_ShowWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); windata->window->SetOpacity(windata->window, windata->opacity); } static void DirectFB_HideWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); windata->window->GetOpacity(windata->window, &windata->opacity); windata->window->SetOpacity(windata->window, 0); } static void DirectFB_RaiseWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); windata->window->Raise(windata->window); } static void DirectFB_MaximizeWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); SDL_Unsupported(); } static void DirectFB_MinimizeWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); SDL_Unsupported(); } static void DirectFB_RestoreWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); SDL_Unsupported(); } static void DirectFB_SetWindowGrab(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); SDL_Unsupported(); } static void DirectFB_DestroyWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); DFB_WindowData *p; SDL_DFB_DEBUG("Trace\n"); SDL_DFB_RELEASE(windata->palette); SDL_DFB_RELEASE(windata->eventbuffer); SDL_DFB_RELEASE(windata->surface); SDL_DFB_RELEASE(windata->window); /* Remove from list ... */ p = devdata->firstwin; while (p && p->next != windata) p = p->next; if (p) p->next = windata->next; else devdata->firstwin = windata->next; SDL_free(windata); } static SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); SDL_Unsupported(); return SDL_FALSE; } #if SDL_DIRECTFB_OPENGL #define OPENGL_REQUIRS_DLOPEN #if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) #include <dlfcn.h> #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL)) #define GL_LoadFunction dlsym #define GL_UnloadObject dlclose #else #define GL_LoadObject SDL_LoadObject #define GL_LoadFunction SDL_LoadFunction #define GL_UnloadObject SDL_UnloadObject #endif static int DirectFB_GL_LoadLibrary(_THIS, const char *path) { SDL_DFB_DEVICEDATA(_this); # void *handle = NULL; SDL_DFB_DEBUG("Loadlibrary : %s\n", path); if (_this->gl_data->gl_active) { SDL_SetError("OpenGL context already created"); return -1; } if (path == NULL) { path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); if (path == NULL) { path = "libGL.so"; } } handle = GL_LoadObject(path); if (handle == NULL) { SDL_DFB_ERR("Library not found: %s\n", path); /* SDL_LoadObject() will call SDL_SetError() for us. */ return -1; } SDL_DFB_DEBUG("Loaded library: %s\n", path); /* Unload the old driver and reset the pointers */ DirectFB_GL_UnloadLibrary(_this); _this->gl_config.dll_handle = handle; _this->gl_config.driver_loaded = 1; if (path) { SDL_strlcpy(_this->gl_config.driver_path, path, SDL_arraysize(_this->gl_config.driver_path)); } else { *_this->gl_config.driver_path = '\0'; } devdata->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish"); devdata->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush"); return 0; } static void DirectFB_GL_UnloadLibrary(_THIS) { SDL_DFB_DEVICEDATA(_this); int ret; if (_this->gl_config.driver_loaded) { ret = GL_UnloadObject(_this->gl_config.dll_handle); if (ret) SDL_DFB_ERR("Error #%d trying to unload library.\n", ret); _this->gl_config.dll_handle = NULL; _this->gl_config.driver_loaded = 0; } } static void * DirectFB_GL_GetProcAddress(_THIS, const char *proc) { SDL_DFB_DEVICEDATA(_this); int ret; void *handle; SDL_DFB_DEBUG("Trace %s\n", proc); handle = _this->gl_config.dll_handle; return GL_LoadFunction(handle, proc); } static SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); int ret; IDirectFBGL *context = NULL; SDL_DFB_DEBUG("Trace\n"); SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface, &context)); SDL_DFB_CHECKERR(context->Unlock(context)); if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) { DirectFB_GL_DeleteContext(_this, context); return NULL; } return context; error: return NULL; } static int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); IDirectFBGL *dfb_context = (IDirectFBGL *) context; int ret; if (dfb_context) { dfb_context->Unlock(dfb_context); SDL_DFB_CHECKERR(dfb_context->Lock(dfb_context)); } if (windata) windata->gl_context = dfb_context; return 0; error: return -1; } static int DirectFB_GL_SetSwapInterval(_THIS, int interval) { SDL_DFB_DEVICEDATA(_this); SDL_Unsupported(); return -1; } static int DirectFB_GL_GetSwapInterval(_THIS) { SDL_DFB_DEVICEDATA(_this); SDL_Unsupported(); return -1; } static void DirectFB_GL_SwapWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); SDL_DFB_DISPLAYDATA(_this, window); int ret; void *p; int pitch; DFBRegion region; region.x1 = 0; region.y1 = 0; region.x2 = window->w; region.y2 = window->h; if (devdata->glFinish) devdata->glFinish(); else if (devdata->glFlush) devdata->glFlush(); SDL_DFB_CHECKERR(windata->gl_context->Unlock(windata->gl_context)); SDL_DFB_CHECKERR(windata->surface-> Flip(windata->surface, ®ion, DSFLIP_ONSYNC)); SDL_DFB_CHECKERR(windata->gl_context->Lock(windata->gl_context)); return; error: return; } static void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context) { IDirectFBGL *dfb_context = (IDirectFBGL *) context; SDL_DFB_DEVICEDATA(_this); dfb_context->Unlock(dfb_context); dfb_context->Release(dfb_context); } #endif