From b41264936189eb5547daa46ea84ac2265745ee31 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 31 Aug 2008 16:04:32 +0000 Subject: [PATCH] Date: Sun, 31 Aug 2008 17:53:59 +0200 From: Couriersud Subject: Re: Updated DirectFB driver for SDL1.3 attached is a patch which brings the directfb driver in line with current svn. In addition: * driver now is in line with the structure of the X11 driver. This adds a couple of files. * driver now supports relative mouse movements --- src/video/directfb/SDL_DirectFB_events.c | 137 ++- src/video/directfb/SDL_DirectFB_events.h | 1 + src/video/directfb/SDL_DirectFB_modes.c | 507 +++++++++++ src/video/directfb/SDL_DirectFB_modes.h | 57 ++ src/video/directfb/SDL_DirectFB_mouse.c | 81 +- src/video/directfb/SDL_DirectFB_opengl.c | 299 +++++++ src/video/directfb/SDL_DirectFB_opengl.h | 55 ++ src/video/directfb/SDL_DirectFB_render.c | 331 ++++--- src/video/directfb/SDL_DirectFB_video.c | 1019 +--------------------- src/video/directfb/SDL_DirectFB_video.h | 78 +- src/video/directfb/SDL_DirectFB_window.c | 325 +++++++ src/video/directfb/SDL_DirectFB_window.h | 61 ++ 12 files changed, 1705 insertions(+), 1246 deletions(-) create mode 100644 src/video/directfb/SDL_DirectFB_modes.c create mode 100644 src/video/directfb/SDL_DirectFB_modes.h create mode 100644 src/video/directfb/SDL_DirectFB_opengl.c create mode 100644 src/video/directfb/SDL_DirectFB_opengl.h create mode 100644 src/video/directfb/SDL_DirectFB_window.c create mode 100644 src/video/directfb/SDL_DirectFB_window.h diff --git a/src/video/directfb/SDL_DirectFB_events.c b/src/video/directfb/SDL_DirectFB_events.c index 901e3bee0..4eee6976d 100644 --- a/src/video/directfb/SDL_DirectFB_events.c +++ b/src/video/directfb/SDL_DirectFB_events.c @@ -47,22 +47,20 @@ DirectFB_SetContext(_THIS, SDL_WindowID id) #if (DIRECTFB_MAJOR_VERSION >= 1) /* FIXME: does not work on 1.0/1.2 with radeon driver * the approach did work with the matrox driver - * Perhaps make this depending on env var, e.g. SDLDIRECTFB_SWITCHCONTEXT_SUPPORTED + * This has simply no effect. */ - if (getenv("SDLDIRECTFB_SWITCHCONTEXT_SUPPORTED") != NULL) { - SDL_DFB_DEVICEDATA(_this); - SDL_Window *window = SDL_GetWindowFromID(id); - SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; - if (dispdata->vidID >= 0 && dispdata->vidIDinuse) { - IDirectFBDisplayLayer *lay = NULL; - devdata->dfb->GetDisplayLayer(devdata->dfb, dispdata->vidID, - &lay); - if (lay) - lay->SwitchContext(lay, DFB_TRUE); - } - } + SDL_Window *window = SDL_GetWindowFromID(id); + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); + DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; + int ret; + + if (dispdata->vidIDinuse) + SDL_DFB_CHECKERR(dispdata->vidlayer-> + SwitchContext(dispdata->vidlayer, DFB_TRUE)); + + error: + return; #endif } @@ -73,14 +71,24 @@ DirectFB_PumpEventsWindow(_THIS) SDL_DFB_DEVICEDATA(_this); DFB_WindowData *p; DFBWindowEvent evt; + DFBInputEvent ievt; + SDL_WindowID grabbed_window; char text[5]; + grabbed_window = -1; + for (p = devdata->firstwin; p != NULL; p = p->next) { + SDL_Window *w = SDL_GetWindowFromID(p->id); + + if (w->flags & SDL_WINDOW_INPUT_GRABBED) { + grabbed_window = p->id; + } + while (p->eventbuffer->GetEvent(p->eventbuffer, DFB_EVENT(&evt)) == DFB_OK) { SDL_keysym keysym; - if (evt.clazz = DFEC_WINDOW) { + if (evt.clazz == DFEC_WINDOW) { switch (evt.type) { case DWET_BUTTONDOWN: SDL_SendMouseButton(devdata->mouse, SDL_PRESSED, @@ -91,7 +99,9 @@ DirectFB_PumpEventsWindow(_THIS) DirectFB_TranslateButton(evt.button)); break; case DWET_MOTION: - SDL_SendMouseMotion(devdata->mouse, 0, evt.cx, evt.cy); + if (!(w->flags & SDL_WINDOW_INPUT_GRABBED)) + SDL_SendMouseMotion(devdata->mouse, 0, evt.cx, evt.cy, + 0); break; case DWET_KEYDOWN: DirectFB_TranslateKey(_this, &evt, &keysym); @@ -111,18 +121,22 @@ DirectFB_PumpEventsWindow(_THIS) keysym.scancode); break; case DWET_POSITION_SIZE: - SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED, evt.x, - evt.y); - SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED, evt.w, - evt.h); + if (evt.x != w->x || evt.y != w->y) + SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED, + evt.x, evt.y); + if (evt.w != w->w || evt.h != w->h) + SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED, + evt.w, evt.h); break; case DWET_POSITION: - SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED, evt.x, - evt.y); + if (evt.x != w->x || evt.y != w->y) + SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED, + evt.x, evt.y); break; case DWET_SIZE: - SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED, evt.w, - evt.h); + if (evt.w != w->w || evt.h != w->h) + SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED, + evt.w, evt.h); break; case DWET_CLOSE: SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_CLOSE, 0, 0); @@ -139,18 +153,41 @@ DirectFB_PumpEventsWindow(_THIS) SDL_SetKeyboardFocus(devdata->keyboard, 0); break; case DWET_ENTER: - //SDL_DirectFB_ReshowCursor(_this, 0); + /* SDL_DirectFB_ReshowCursor(_this, 0); */ SDL_SetMouseFocus(devdata->mouse, p->id); SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_ENTER, 0, 0); break; case DWET_LEAVE: SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_LEAVE, 0, 0); SDL_SetMouseFocus(devdata->mouse, 0); - //SDL_DirectFB_ReshowCursor(_this, 1); + /* SDL_DirectFB_ReshowCursor(_this, 1); */ break; default: ; } + } else + printf("Event Clazz %d\n", evt.clazz); + + } + } + + /* Now get relative events in case we need them */ + while (devdata->events->GetEvent(devdata->events, + DFB_EVENT(&ievt)) == DFB_OK) { + if (grabbed_window >= 0) { + switch (ievt.type) { + case DIET_AXISMOTION: + if (ievt.flags & DIEF_AXISREL) { + if (ievt.axis == DIAI_X) + SDL_SendMouseMotion(devdata->mouse, 1, ievt.axisrel, + 0, 0); + else if (ievt.axis == DIAI_Y) + SDL_SendMouseMotion(devdata->mouse, 1, 0, + ievt.axisrel, 0); + } + break; + default: + ; } } } @@ -231,9 +268,10 @@ DirectFB_InitOSKeymap(_THIS) keymap[DIKI_META_R - DIKI_UNKNOWN] = SDL_SCANCODE_RGUI; keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; keymap[DIKI_SUPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; - //FIXME:Do we read hyper keys ? - //keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; - //keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; + /* FIXME:Do we read hyper keys ? + * keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; + * keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; + */ keymap[DIKI_TAB - DIKI_UNKNOWN] = SDL_SCANCODE_TAB; keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_RETURN; keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDL_SCANCODE_SPACE; @@ -290,7 +328,7 @@ DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_keysym * keysym) if (evt->key_code >= 0 && evt->key_code < SDL_arraysize(linux_scancode_table)) - keysym->scancode = linux_scancode_table[evt->key_code]; // key_id; + keysym->scancode = linux_scancode_table[evt->key_code]; else keysym->scancode = SDL_SCANCODE_UNKNOWN; @@ -331,7 +369,6 @@ input_device_cb(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, { DFB_DeviceData *devdata = callbackdata; SDL_Keyboard keyboard; - SDL_scancode scancode; SDLKey keymap[SDL_NUM_SCANCODES]; if ((desc.caps & DIDTF_KEYBOARD) && device_id == DIDID_KEYBOARD) { @@ -360,6 +397,16 @@ DirectFB_InitKeyboard(_THIS) EnumInputDevices(devdata->dfb, input_device_cb, devdata)); } +void +DirectFB_QuitKeyboard(_THIS) +{ + SDL_DFB_DEVICEDATA(_this); + int ret; + + SDL_DelKeyboard(devdata->keyboard); + +} + #if 0 /* FIXME: Remove once determined this is not needed in fullscreen mode */ void @@ -383,25 +430,33 @@ DirectFB_PumpEvents(_THIS) switch (evt.type) { case DIET_BUTTONPRESS: posted += SDL_PrivateMouseButton(SDL_PRESSED, - DirectFB_TranslateButton - (evt.button), 0, 0); + DirectFB_TranslateButton(evt. + button), + 0, 0); break; case DIET_BUTTONRELEASE: posted += SDL_PrivateMouseButton(SDL_RELEASED, - DirectFB_TranslateButton - (evt.button), 0, 0); + DirectFB_TranslateButton(evt. + button), + 0, 0); break; case DIET_KEYPRESS: posted += SDL_PrivateKeyboard(SDL_PRESSED, - DirectFB_TranslateKey - (evt.key_id, evt.key_symbol, - mod, &keysym)); + DirectFB_TranslateKey(evt. + key_id, + evt. + key_symbol, + mod, + &keysym)); break; case DIET_KEYRELEASE: posted += SDL_PrivateKeyboard(SDL_RELEASED, - DirectFB_TranslateKey - (evt.key_id, evt.key_symbol, - mod, &keysym)); + DirectFB_TranslateKey(evt. + key_id, + evt. + key_symbol, + mod, + &keysym)); break; case DIET_AXISMOTION: if (evt.flags & DIEF_AXISREL) { diff --git a/src/video/directfb/SDL_DirectFB_events.h b/src/video/directfb/SDL_DirectFB_events.h index e17113d87..f94b694d9 100644 --- a/src/video/directfb/SDL_DirectFB_events.h +++ b/src/video/directfb/SDL_DirectFB_events.h @@ -25,5 +25,6 @@ /* Functions to be exported */ extern void DirectFB_InitKeyboard(_THIS); +extern void DirectFB_QuitKeyboard(_THIS); extern void DirectFB_PumpEventsWindow(_THIS); extern SDLKey DirectFB_GetLayoutKey(_THIS, SDLKey physicalKey); diff --git a/src/video/directfb/SDL_DirectFB_modes.c b/src/video/directfb/SDL_DirectFB_modes.c new file mode 100644 index 000000000..bc33f8145 --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_modes.c @@ -0,0 +1,507 @@ +/* + 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 +*/ +#include "SDL_config.h" + +#include "SDL_DirectFB_video.h" + +#define DFB_MAX_MODES 200 + +struct scn_callback_t +{ + int numscreens; + DFBScreenID screenid[DFB_MAX_SCREENS]; + DFBDisplayLayerID gralayer[DFB_MAX_SCREENS]; + DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS]; + int aux; /* auxiliary integer for callbacks */ +}; + +struct modes_callback_t +{ + int nummodes; + SDL_DisplayMode *modelist; +}; + +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 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 DFBEnumerationResult +EnumModesCallback(int width, int height, int bpp, void *data) +{ + struct modes_callback_t *modedata = (struct modes_callback_t *) data; + SDL_DisplayMode mode; + + mode.w = width; + mode.h = height; + mode.refresh_rate = 0; + mode.driverdata = NULL; + mode.format = SDL_PIXELFORMAT_UNKNOWN; + + if (modedata->nummodes < DFB_MAX_MODES) { + modedata->modelist[modedata->nummodes++] = mode; + } + + SDL_DFB_DEBUG("w %d h %d bpp %d\n", width, height, bpp); + return DFENUM_OK; +} + +static DFBEnumerationResult +cbScreens(DFBScreenID screen_id, DFBScreenDescription desc, + void *callbackdata) +{ + struct scn_callback_t *devdata = (struct scn_callback_t *) callbackdata; + + devdata->screenid[devdata->numscreens++] = screen_id; + return DFENUM_OK; +} + +DFBEnumerationResult +cbLayers(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc, + void *callbackdata) +{ + struct scn_callback_t *devdata = (struct scn_callback_t *) 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 void +CheckSetDisplayMode(_THIS, DFB_DisplayData * data, SDL_DisplayMode * mode) +{ + SDL_DFB_DEVICEDATA(_this); + DFBDisplayLayerConfig config; + DFBDisplayLayerConfigFlags failed; + int ret; + + SDL_DFB_CHECKERR(data->layer-> + SetCooperativeLevel(data->layer, DLSCL_ADMINISTRATIVE)); + config.width = mode->w; + config.height = mode->h; + config.pixelformat = SDLToDFBPixelFormat(mode->format); + config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT; + if (devdata->use_yuv_underlays) { + config.flags |= DLCONF_OPTIONS; + config.options = DLOP_ALPHACHANNEL; + } + failed = 0; + data->layer->TestConfiguration(data->layer, &config, &failed); + SDL_DFB_CHECKERR(data->layer-> + SetCooperativeLevel(data->layer, DLSCL_SHARED)); + if (failed == 0) + SDL_AddDisplayMode(_this->current_display, mode); + else + SDL_DFB_DEBUG("Mode %d x %d not available: %x\n", mode->w, mode->h, + failed); + + return; + error: + return; +} + +void +DirectFB_InitModes(_THIS) +{ + SDL_DFB_DEVICEDATA(_this); + IDirectFBDisplayLayer *layer = NULL; + SDL_VideoDisplay display; + DFB_DisplayData *dispdata; + SDL_DisplayMode mode; +#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23) + DFBCardCapabilities caps; +#else + DFBGraphicsDeviceDescription caps; +#endif + DFBDisplayLayerConfig dlc; + struct scn_callback_t *screencbdata; + + int tcw[DFB_MAX_SCREENS]; + int tch[DFB_MAX_SCREENS]; + int i; + DFBResult ret; + + SDL_DFB_CALLOC(screencbdata, 1, sizeof(*screencbdata)); + + screencbdata->numscreens = 0; + + for (i = 0; i < DFB_MAX_SCREENS; i++) { + screencbdata->gralayer[i] = -1; + screencbdata->vidlayer[i] = -1; + } + + SDL_DFB_CHECKERR(devdata->dfb-> + EnumScreens(devdata->dfb, &cbScreens, screencbdata)); + + for (i = 0; i < screencbdata->numscreens; i++) { + IDirectFBScreen *screen; + + SDL_DFB_CHECKERR(devdata->dfb-> + GetScreen(devdata->dfb, screencbdata->screenid[i], + &screen)); + + screencbdata->aux = i; + SDL_DFB_CHECKERR(screen-> + EnumDisplayLayers(screen, &cbLayers, screencbdata)); +#if (DIRECTFB_MAJOR_VERSION >= 1) + screen->GetSize(screen, &tcw[i], &tch[i]); +#else + /* FIXME: this is only used to center windows + * Should be done otherwise, e.g. get surface from layer + */ + tcw[i] = 800; + tch[i] = 600; +#endif + screen->Release(screen); + } + + /* Query card capabilities */ + + devdata->dfb->GetDeviceDescription(devdata->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 < screencbdata->numscreens; i++) { + SDL_DFB_CHECKERR(devdata->dfb-> + GetDisplayLayer(devdata->dfb, + screencbdata->gralayer[i], &layer)); + + SDL_DFB_CHECKERR(layer-> + SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE)); + layer->EnableCursor(layer, 1); + SDL_DFB_CHECKERR(layer->SetCursorOpacity(layer, 0xC0)); + + if (devdata->use_yuv_underlays) { + dlc.flags = DLCONF_PIXELFORMAT | DLCONF_OPTIONS; + dlc.pixelformat = DSPF_ARGB; + dlc.options = DLOP_ALPHACHANNEL; + + ret = layer->SetConfiguration(layer, &dlc); + if (ret) { + /* try AiRGB if the previous failed */ + dlc.pixelformat = DSPF_AiRGB; + ret = layer->SetConfiguration(layer, &dlc); + } + } + + SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED)); + + /* Query layer configuration to determine the current mode and pixelformat */ + layer->GetConfiguration(layer, &dlc); + + if (DFBToSDLPixelFormat(dlc.pixelformat, &mode.format) != 0) { + SDL_DFB_ERR("Unknown dfb pixelformat %x !\n", dlc.pixelformat); + goto error; + } + + 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 = screencbdata->vidlayer[i]; + dispdata->vidIDinuse = 0; + + SDL_zero(display); + + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = dispdata; + + SDL_AddVideoDisplay(&display); + } + SDL_DFB_FREE(screencbdata); + return; + error: + /* FIXME: Cleanup not complete, Free existing displays */ + SDL_DFB_FREE(dispdata); + SDL_DFB_RELEASE(layer); + return; +} + +void +DirectFB_GetDisplayModes(_THIS) +{ + SDL_DFB_DEVICEDATA(_this); + DFB_DisplayData *dispdata = + (DFB_DisplayData *) SDL_CurrentDisplay.driverdata; + SDL_DisplayMode mode; + struct modes_callback_t data; + int i; + int ret; + + data.nummodes = 0; + /* Enumerate the available fullscreen modes */ + SDL_DFB_CALLOC(data.modelist, DFB_MAX_MODES, sizeof(SDL_DisplayMode)); + SDL_DFB_CHECKERR(devdata->dfb-> + EnumVideoModes(devdata->dfb, EnumModesCallback, &data)); + + for (i = 0; i < data.nummodes; ++i) { + mode = data.modelist[i]; + + mode.format = SDL_PIXELFORMAT_ARGB8888; + CheckSetDisplayMode(_this, dispdata, &mode); + mode.format = SDL_PIXELFORMAT_RGB888; + CheckSetDisplayMode(_this, dispdata, &mode); + mode.format = SDL_PIXELFORMAT_RGB24; + CheckSetDisplayMode(_this, dispdata, &mode); + mode.format = SDL_PIXELFORMAT_RGB565; + CheckSetDisplayMode(_this, dispdata, &mode); + mode.format = SDL_PIXELFORMAT_INDEX8; + CheckSetDisplayMode(_this, dispdata, &mode); + } + SDL_DFB_FREE(data.modelist); + return; + error: + SDL_DFB_FREE(data.modelist); + return; +} + +int +DirectFB_SetDisplayMode(_THIS, SDL_DisplayMode * mode) +{ + /* + * FIXME: video mode switch is currently broken for 1.2.0 + * + */ + + 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; + 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; + + if (devdata->use_yuv_underlays) { + config.flags |= DLCONF_OPTIONS; + config.options = DLOP_ALPHACHANNEL; + } + + data->layer->TestConfiguration(data->layer, &config, &fail); + + if (fail & + (DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_OPTIONS)) + { + SDL_DFB_ERR("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)); + + /* Double check */ + SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig)); + SDL_DFB_CHECKERR(data->layer-> + SetCooperativeLevel(data->layer, DLSCL_SHARED)); + + if ((config.width != rconfig.width) || + (config.height != rconfig.height) || + ((mode->format != SDL_PIXELFORMAT_UNKNOWN) + && (config.pixelformat != rconfig.pixelformat))) { + SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h, + mode->format); + return -1; + } + + data->pixelformat = rconfig.pixelformat; + data->cw = config.width; + data->ch = config.height; + SDL_CurrentDisplay.current_mode = *mode; + + return 0; + error: + return -1; +} + +void +DirectFB_QuitModes(_THIS) +{ + DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata; + SDL_DisplayMode tmode; + DFBResult ret; + int i; + + SDL_SelectVideoDisplay(0); + + SDL_GetDesktopDisplayMode(&tmode); + tmode.format = SDL_PIXELFORMAT_UNKNOWN; + DirectFB_SetDisplayMode(_this, &tmode); + + SDL_GetDesktopDisplayMode(&tmode); + DirectFB_SetDisplayMode(_this, &tmode); + + for (i = 0; i < SDL_GetNumVideoDisplays(); 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); + SDL_DFB_RELEASE(dispdata->vidlayer); + + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_modes.h b/src/video/directfb/SDL_DirectFB_modes.h new file mode 100644 index 000000000..8a61fca6f --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_modes.h @@ -0,0 +1,57 @@ +/* + 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 +*/ +#include "SDL_config.h" + +#ifndef _SDL_directfb_modes_h +#define _SDL_directfb_modes_h + +#include "SDL_DirectFB_video.h" + +#define SDL_DFB_DISPLAYDATA(dev, win) DFB_DisplayData *dispdata = ((win && dev) ? (DFB_DisplayData *) (dev)->displays[(win)->display].driverdata : NULL) + +typedef struct _DFB_DisplayData DFB_DisplayData; +struct _DFB_DisplayData +{ + IDirectFBDisplayLayer *layer; + DFBSurfacePixelFormat pixelformat; + /* FIXME: support for multiple video layer. + * However, I do not know any card supporting + * more than one + */ + DFBDisplayLayerID vidID; + IDirectFBDisplayLayer *vidlayer; + + int vidIDinuse; + + int cw; + int ch; +}; + + +extern void DirectFB_InitModes(_THIS); +extern void DirectFB_GetDisplayModes(_THIS); +extern int DirectFB_SetDisplayMode(_THIS, SDL_DisplayMode * mode); +extern void DirectFB_QuitModes(_THIS); + +#endif /* _SDL_directfb_modes_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_mouse.c b/src/video/directfb/SDL_DirectFB_mouse.c index 1395e593b..5531e2de3 100644 --- a/src/video/directfb/SDL_DirectFB_mouse.c +++ b/src/video/directfb/SDL_DirectFB_mouse.c @@ -22,7 +22,6 @@ #include "SDL_config.h" #include "SDL_DirectFB_video.h" -#include "SDL_DirectFB_mouse.h" #include "../SDL_sysvideo.h" #include "../../events/SDL_mouse_c.h" @@ -49,7 +48,8 @@ DirectFB_InitMouse(_THIS) mouse.FreeCursor = DirectFB_FreeCursor; mouse.WarpMouse = DirectFB_WarpMouse; mouse.FreeMouse = DirectFB_FreeMouse; - devdata->mouse = SDL_AddMouse(&mouse, -1); + mouse.cursor_shown = 1; + devdata->mouse = SDL_AddMouse(&mouse, -1, "Mouse", 0, 0, 1); } void @@ -85,23 +85,21 @@ DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) dsc.height = surface->h; dsc.pixelformat = DSPF_ARGB; - SDL_DFB_CHECKERR(devdata-> - dfb->CreateSurface(devdata->dfb, &dsc, &curdata->surf)); + SDL_DFB_CHECKERR(devdata->dfb-> + CreateSurface(devdata->dfb, &dsc, &curdata->surf)); curdata->hotx = hot_x; curdata->hoty = hot_y; cursor->driverdata = curdata; - SDL_DFB_CHECKERR(curdata-> - surf->Lock(curdata->surf, DSLF_WRITE, (void *) &dest, - &pitch)); + SDL_DFB_CHECKERR(curdata->surf-> + Lock(curdata->surf, DSLF_WRITE, (void *) &dest, &pitch)); - //FIXME: Implies a lot of things, e.g. rgba format for SDL_SURFACE .... + /* Relies on the fact that this is only called with ARGB surface. */ p = surface->pixels; - for (i = 0; i < surface->w * surface->h; i++) - if (p[i] == 0x00000000) - dest[i] = 0x00000000; - else - dest[i] = p[i]; + for (i = 0; i < surface->h; i++) + memcpy((char *) dest + i * pitch, (char *) p + i * surface->pitch, + 4 * surface->w); + curdata->surf->Unlock(curdata->surf); return cursor; error: @@ -113,37 +111,38 @@ static int DirectFB_ShowCursor(SDL_Cursor * cursor) { SDL_DFB_CURSORDATA(cursor); - SDL_VideoDevice *dev = SDL_GetVideoDevice(); - SDL_DFB_DEVICEDATA(dev); -#if 0 - DFB_DisplayData *dispdata = - (DFB_DisplayData *) dev->displays[dev->current_display].driverdata; -#endif DFBResult ret; SDL_WindowID wid; wid = SDL_GetFocusWindow(); - if (!wid) + if (wid < 0) return -1; else { SDL_Window *window = SDL_GetWindowFromID(wid); SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; - DFB_WindowData *windata = (DFB_WindowData *) window->driverdata; - - if (cursor) - SDL_DFB_CHECKERR(windata->window->SetCursorShape(windata->window, - curdata->surf, - curdata->hotx, - curdata->hoty)); - //TODO: Check administrative - SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer, - DLSCL_ADMINISTRATIVE)); - SDL_DFB_CHECKERR(dispdata->layer->SetCursorOpacity(dispdata->layer, - cursor ? 0xC0 : - 0x00)); - SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer, - DLSCL_SHARED)); + + if (display) { + DFB_DisplayData *dispdata = + (DFB_DisplayData *) display->driverdata; + DFB_WindowData *windata = (DFB_WindowData *) window->driverdata; + + if (cursor) + SDL_DFB_CHECKERR(windata->window-> + SetCursorShape(windata->window, + curdata->surf, curdata->hotx, + curdata->hoty)); + + /* fprintf(stdout, "Cursor is %s\n", cursor ? "on" : "off"); */ + SDL_DFB_CHECKERR(dispdata->layer-> + SetCooperativeLevel(dispdata->layer, + DLSCL_ADMINISTRATIVE)); + SDL_DFB_CHECKERR(dispdata->layer-> + SetCursorOpacity(dispdata->layer, + cursor ? 0xC0 : 0x00)); + SDL_DFB_CHECKERR(dispdata->layer-> + SetCooperativeLevel(dispdata->layer, + DLSCL_SHARED)); + } } return 0; @@ -155,8 +154,7 @@ DirectFB_ShowCursor(SDL_Cursor * cursor) static void DirectFB_MoveCursor(SDL_Cursor * cursor) { - SDL_DFB_CURSORDATA(cursor); - /* Do we need to do something here ? */ + } /* Free a window manager cursor */ @@ -182,8 +180,8 @@ DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_WindowID windowID, int x, int y) int cx, cy; SDL_DFB_CHECKERR(windata->window->GetPosition(windata->window, &cx, &cy)); - SDL_DFB_CHECKERR(dispdata-> - layer->WarpCursor(dispdata->layer, cx + x, cy + y)); + SDL_DFB_CHECKERR(dispdata->layer-> + WarpCursor(dispdata->layer, cx + x, cy + y)); error: return; @@ -193,8 +191,7 @@ DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_WindowID windowID, int x, int y) static void DirectFB_FreeMouse(SDL_Mouse * mouse) { - // nothing yet - + /* nothing yet */ } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_opengl.c b/src/video/directfb/SDL_DirectFB_opengl.c new file mode 100644 index 000000000..5be8ae0ef --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_opengl.c @@ -0,0 +1,299 @@ +/* + 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 +*/ +#include "SDL_config.h" + +#include "SDL_DirectFB_video.h" + +#if SDL_DIRECTFB_OPENGL + +struct SDL_GLDriverData +{ + int gl_active; /* to stop switching drivers while we have a valid context */ + int initialized; + DirectFB_GLContext *firstgl; /* linked list */ +}; + +#define OPENGL_REQUIRS_DLOPEN +#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) +#include +#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 void DirectFB_GL_UnloadLibrary(_THIS); + +int +DirectFB_GL_Initialize(_THIS) +{ + if (_this->gl_data) { + return 0; + } + + _this->gl_data = + (struct SDL_GLDriverData *) SDL_calloc(1, + sizeof(struct + SDL_GLDriverData)); + if (!_this->gl_data) { + SDL_OutOfMemory(); + return -1; + } + _this->gl_data->initialized = 0; + + ++_this->gl_data->initialized; + _this->gl_data->firstgl = NULL; + + if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) { + return -1; + } + + /* Initialize extensions */ + /* FIXME needed? + * X11_GL_InitExtensions(_this); + */ + + return 0; +} + +void +DirectFB_GL_Shutdown(_THIS) +{ + if (!_this->gl_data || (--_this->gl_data->initialized > 0)) { + return; + } + + DirectFB_GL_UnloadLibrary(_this); + + SDL_free(_this->gl_data); + _this->gl_data = NULL; +} + +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) +{ + 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; + } +} + +void * +DirectFB_GL_GetProcAddress(_THIS, const char *proc) +{ + void *handle; + + handle = _this->gl_config.dll_handle; + return GL_LoadFunction(handle, proc); +} + +SDL_GLContext +DirectFB_GL_CreateContext(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + DirectFB_GLContext *context; + int ret; + + SDL_DFB_CALLOC(context, 1, sizeof(*context)); + + SDL_DFB_CHECKERR(windata->surface-> + GetGL(windata->surface, &context->context)); + SDL_DFB_CHECKERR(context->context->Unlock(context->context)); + + context->next = _this->gl_data->firstgl; + _this->gl_data->firstgl = context; + + if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) { + DirectFB_GL_DeleteContext(_this, context); + return NULL; + } + + return context; + + error: + return NULL; +} + +int +DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ + SDL_DFB_WINDOWDATA(window); + DirectFB_GLContext *ctx = (DirectFB_GLContext *) context; + DirectFB_GLContext *p; + + int ret; + + for (p = _this->gl_data->firstgl; p; p = p->next) + p->context->Unlock(p->context); + + if (windata) { + int cw, ch; + + windata->gl_context = NULL; + /* Everything is unlocked, check for a resize */ + SDL_DFB_CHECKERR(windata->surface-> + GetSize(windata->surface, &cw, &ch)); + if (cw != window->w || ch != window->h) + SDL_DFB_CHECKERR(windata->window-> + ResizeSurface(windata->window, window->w, + window->h)); + } + + if (ctx != NULL) { + SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context)); + } + + if (windata) + windata->gl_context = ctx; + + return 0; + error: + return -1; +} + +int +DirectFB_GL_SetSwapInterval(_THIS, int interval) +{ + SDL_Unsupported(); + return -1; +} + +int +DirectFB_GL_GetSwapInterval(_THIS) +{ + SDL_Unsupported(); + return -1; +} + +void +DirectFB_GL_SwapWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + int ret; + 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(); + + if (1 || windata->gl_context) { + /* SDL_DFB_CHECKERR(windata->gl_context->context->Unlock(windata->gl_context->context)); */ + SDL_DFB_CHECKERR(windata->surface-> + Flip(windata->surface, ®ion, DSFLIP_ONSYNC)); + /* SDL_DFB_CHECKERR(windata->gl_context->context->Lock(windata->gl_context->context)); */ + + } + + return; + error: + return; +} + +void +DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context) +{ + DirectFB_GLContext *ctx = (DirectFB_GLContext *) context; + DirectFB_GLContext *p; + + ctx->context->Unlock(ctx->context); + ctx->context->Release(ctx->context); + + p = _this->gl_data->firstgl; + while (p && p->next != ctx) + p = p->next; + if (p) + p->next = ctx->next; + else + _this->gl_data->firstgl = ctx->next; + + SDL_DFB_FREE(ctx); + +} + +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_opengl.h b/src/video/directfb/SDL_DirectFB_opengl.h new file mode 100644 index 000000000..9a08575e9 --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_opengl.h @@ -0,0 +1,55 @@ +/* + 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 +*/ +#include "SDL_config.h" + +#ifndef _SDL_directfb_opengl_h +#define _SDL_directfb_opengl_h + +#if SDL_DIRECTFB_OPENGL +#include "SDL_opengl.h" + +typedef struct _DirectFB_GLContext DirectFB_GLContext; +struct _DirectFB_GLContext +{ + IDirectFBGL *context; + DirectFB_GLContext *next; +}; + +/* OpenGL functions */ +extern int DirectFB_GL_Initialize(_THIS); +extern void DirectFB_GL_Shutdown(_THIS); + +extern int DirectFB_GL_LoadLibrary(_THIS, const char *path); +extern void *DirectFB_GL_GetProcAddress(_THIS, const char *proc); +extern SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window); +extern int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, + SDL_GLContext context); +extern int DirectFB_GL_SetSwapInterval(_THIS, int interval); +extern int DirectFB_GL_GetSwapInterval(_THIS); +extern void DirectFB_GL_SwapWindow(_THIS, SDL_Window * window); +extern void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context); + +#endif /* SDL_DIRECTFB_OPENGL */ + +#endif /* _SDL_directfb_opengl_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_render.c b/src/video/directfb/SDL_DirectFB_render.c index 4c04c2938..5a9212c89 100644 --- a/src/video/directfb/SDL_DirectFB_render.c +++ b/src/video/directfb/SDL_DirectFB_render.c @@ -29,11 +29,15 @@ #include "../SDL_rect_c.h" #include "../SDL_yuv_sw_c.h" +/* the following is not yet tested ... */ +#define USE_DISPLAY_PALETTE (0) + /* GDI renderer implementation */ static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags); static int DirectFB_DisplayModeChanged(SDL_Renderer * renderer); +static int DirectFB_ActivateRenderer(SDL_Renderer * renderer); static int DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer, @@ -89,11 +93,12 @@ SDL_RenderDriver DirectFB_RenderDriver = { (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK | SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD | SDL_TEXTUREBLENDMODE_MOD), - (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST), + (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST | + SDL_TEXTURESCALEMODE_SLOW | SDL_TEXTURESCALEMODE_BEST), 14, { - SDL_PIXELFORMAT_INDEX8, SDL_PIXELFORMAT_INDEX4LSB, + SDL_PIXELFORMAT_INDEX8, SDL_PIXELFORMAT_RGB332, SDL_PIXELFORMAT_RGB555, SDL_PIXELFORMAT_RGB565, @@ -115,19 +120,32 @@ typedef struct IDirectFBSurface *surface; DFBSurfaceFlipFlags flipflags; int isyuvdirect; + int size_changed; } DirectFB_RenderData; typedef struct { - IDirectFBDisplayLayer *vidlayer; IDirectFBSurface *surface; Uint32 format; void *pixels; int pitch; IDirectFBPalette *palette; - DFB_DisplayData *display; + SDL_VideoDisplay *display; + SDL_DirtyRectList dirty; +#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2) + DFBSurfaceRenderOptions render_options; +#endif } DirectFB_TextureData; +static __inline__ void +SDLtoDFBRect(const SDL_Rect * sr, DFBRectangle * dr) +{ + dr->x = sr->x; + dr->y = sr->y; + dr->h = sr->h; + dr->w = sr->w; +} + void DirectFB_AddRenderDriver(_THIS) { @@ -136,24 +154,53 @@ DirectFB_AddRenderDriver(_THIS) SDL_AddRenderDriver(i, &DirectFB_RenderDriver); } +static int +DisplayPaletteChanged(void *userdata, SDL_Palette * palette) +{ +#if USE_DISPLAY_PALETTE + DirectFB_RenderData *data = (DirectFB_RenderData *) userdata; + IDirectFBPalette *surfpal; + + int ret; + int i; + int ncolors; + DFBColor entries[256]; + + SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface, &surfpal)); + + /* FIXME: number of colors */ + ncolors = (palette->ncolors < 256 ? palette->ncolors : 256); + + for (i = 0; i < ncolors; ++i) { + entries[i].r = palette->colors[i].r; + entries[i].g = palette->colors[i].g; + entries[i].b = palette->colors[i].b; + entries[i].a = palette->colors[i].unused; + } + SDL_DFB_CHECKERR(surfpal->SetEntries(surfpal, entries, ncolors, 0)); + return 0; + error: +#endif + return -1; +} + + SDL_Renderer * DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_DFB_WINDOWDATA(window); SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - SDL_DFB_DEVICEDATA(display->device); SDL_Renderer *renderer = NULL; DirectFB_RenderData *data = NULL; DFBResult ret; - DFBSurfaceDescription dsc; DFBSurfaceCapabilities scaps; char *p; - int i, n; SDL_DFB_CALLOC(renderer, 1, sizeof(*renderer)); SDL_DFB_CALLOC(data, 1, sizeof(*data)); renderer->DisplayModeChanged = DirectFB_DisplayModeChanged; + renderer->ActivateRenderer = DirectFB_ActivateRenderer; renderer->CreateTexture = DirectFB_CreateTexture; renderer->QueryTexturePixels = DirectFB_QueryTexturePixels; renderer->SetTexturePalette = DirectFB_SetTexturePalette; @@ -179,14 +226,16 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD; data->surface = windata->surface; - data->flipflags = 0; + data->surface->AddRef(data->surface); + + data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT; if (flags & SDL_RENDERER_PRESENTVSYNC) { data->flipflags = DSFLIP_ONSYNC; renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } - data->surface->GetCapabilities(data->surface, &scaps); + SDL_DFB_CHECKERR(data->surface->GetCapabilities(data->surface, &scaps)); if (scaps & DSCAPS_DOUBLE) renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; else if (scaps & DSCAPS_TRIPLE) @@ -194,11 +243,16 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) else renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER; - data->isyuvdirect = 1; /* default is on! */ - p = getenv("SDL_DIRECTFB_YUV_DIRECT"); + data->isyuvdirect = 0; /* default is off! */ + p = getenv(DFBENV_USE_YUV_DIRECT); if (p) data->isyuvdirect = atoi(p); + /* Set up a palette watch on the display palette */ + if (display->palette) { + SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data); + } + return renderer; error: @@ -267,25 +321,37 @@ SDLToDFBPixelFormat(Uint32 format) } static int -DirectFB_DisplayModeChanged(SDL_Renderer * renderer) +DirectFB_ActivateRenderer(SDL_Renderer * renderer) { SDL_DFB_RENDERERDATA(renderer); SDL_Window *window = SDL_GetWindowFromID(renderer->window); SDL_DFB_WINDOWDATA(window); - SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - SDL_DFB_DEVICEDATA(display->device); - DFBResult ret; - DFBSurfaceDescription dsc; - int i, n; - /* - * Nothing to do here - */ + if (renddata->size_changed) { + int cw, ch; + int ret; + + SDL_DFB_CHECKERR(windata->surface-> + GetSize(windata->surface, &cw, &ch)); + if (cw != window->w || ch != window->h) + SDL_DFB_CHECKERR(windata->window-> + ResizeSurface(windata->window, window->w, + window->h)); + } return 0; error: return -1; } +static int +DirectFB_DisplayModeChanged(SDL_Renderer * renderer) +{ + SDL_DFB_RENDERERDATA(renderer); + + renddata->size_changed = SDL_TRUE; + return 0; +} + static int DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) { @@ -301,36 +367,42 @@ DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) if (renddata->isyuvdirect && (dispdata->vidID >= 0) && (!dispdata->vidIDinuse) && SDL_ISPIXELFORMAT_FOURCC(data->format)) { - layconf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT; + layconf.flags = + DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | + DLCONF_SURFACE_CAPS; layconf.width = texture->w; layconf.height = texture->h; layconf.pixelformat = SDLToDFBPixelFormat(data->format); + layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE; SDL_DFB_CHECKERR(devdata->dfb-> GetDisplayLayer(devdata->dfb, dispdata->vidID, - &data->vidlayer)); - SDL_DFB_CHECKERR(data->vidlayer-> - SetCooperativeLevel(data->vidlayer, + &dispdata->vidlayer)); + SDL_DFB_CHECKERR(dispdata->vidlayer-> + SetCooperativeLevel(dispdata->vidlayer, DLSCL_EXCLUSIVE)); - SDL_DFB_CHECKERR(data->vidlayer-> - SetConfiguration(data->vidlayer, &layconf)); - SDL_DFB_CHECKERR(data->vidlayer-> - GetSurface(data->vidlayer, &data->surface)); - //SDL_DFB_CHECKERR(data->vidlayer->GetDescription(data->vidlayer, laydsc)); - dispdata->vidIDinuse = 1; - data->display = dispdata; - SDL_DFB_DEBUG("Created HW YUV surface\n"); + if (devdata->use_yuv_underlays) { + ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1); + if (ret != DFB_OK) + SDL_DFB_DEBUG("Underlay Setlevel not supported\n"); + } + SDL_DFB_CHECKERR(dispdata->vidlayer-> + SetConfiguration(dispdata->vidlayer, &layconf)); + SDL_DFB_CHECKERR(dispdata->vidlayer-> + GetSurface(dispdata->vidlayer, &data->surface)); + dispdata->vidIDinuse = 1; + data->display = display; return 0; } return 1; error: - if (data->vidlayer) { + if (dispdata->vidlayer) { SDL_DFB_RELEASE(data->surface); - SDL_DFB_CHECKERR(data->vidlayer-> - SetCooperativeLevel(data->vidlayer, + SDL_DFB_CHECKERR(dispdata->vidlayer-> + SetCooperativeLevel(dispdata->vidlayer, DLSCL_ADMINISTRATIVE)); - SDL_DFB_RELEASE(data->vidlayer); + SDL_DFB_RELEASE(dispdata->vidlayer); } return 1; } @@ -338,23 +410,18 @@ DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) static int DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - SDL_DFB_RENDERERDATA(renderer); SDL_Window *window = SDL_GetWindowFromID(renderer->window); - SDL_DFB_WINDOWDATA(window); SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); SDL_DFB_DEVICEDATA(display->device); DirectFB_TextureData *data; DFBResult ret; DFBSurfaceDescription dsc; - DFBDisplayLayerDescription laydsc; - DFBDisplayLayerConfig layconf; SDL_DFB_CALLOC(data, 1, sizeof(*data)); texture->driverdata = data; data->format = texture->format; data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format)); - data->vidlayer = NULL; if (DirectFB_AcquireVidLayer(renderer, texture) != 0) { /* fill surface description */ @@ -365,13 +432,15 @@ DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance * No DSCAPS_SYSTEMONLY either - let dfb decide * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8 + * Depends on other settings as well. Let dfb decide. */ dsc.caps = DSCAPS_PREMULTIPLIED; - +#if 0 if (texture->access == SDL_TEXTUREACCESS_STREAMING) dsc.caps |= DSCAPS_SYSTEMONLY; else dsc.caps |= DSCAPS_VIDEOONLY; +#endif /* find the right pixelformat */ @@ -393,6 +462,15 @@ DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } } +#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2) + data->render_options = DSRO_NONE; +#endif + + if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); + SDL_DFB_CALLOC(data->pixels, 1, texture->h * data->pitch); + } + return 0; error: @@ -406,13 +484,16 @@ static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, void **pixels, int *pitch) { - DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; - - /* - * Always fail here so in compat mode SDL_HWSURFACE is set ! - */ + DirectFB_TextureData *texturedata = + (DirectFB_TextureData *) texture->driverdata; - return -1; + if (texturedata->display) { + return -1; + } else { + *pixels = texturedata->pixels; + *pitch = texturedata->pitch; + } + return 0; } static int @@ -420,8 +501,6 @@ DirectFB_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Color * colors, int firstcolor, int ncolors) { - DirectFB_RenderData *renderdata = - (DirectFB_RenderData *) renderer->driverdata; DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; DFBResult ret; @@ -468,6 +547,7 @@ DirectFB_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, colors[i].r = entries[i].r; colors[i].g = entries[i].g; colors[i].b = entries[i].b; + colors->unused = SDL_ALPHA_OPAQUE; } return 0; } else { @@ -510,20 +590,29 @@ DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) { +#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2) + + DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + switch (texture->scaleMode) { case SDL_TEXTURESCALEMODE_NONE: case SDL_TEXTURESCALEMODE_FAST: - return 0; + data->render_options = DSRO_NONE; + break; case SDL_TEXTURESCALEMODE_SLOW: + data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE; + break; case SDL_TEXTURESCALEMODE_BEST: - SDL_Unsupported(); - texture->scaleMode = SDL_TEXTURESCALEMODE_FAST; - return -1; + data->render_options = + DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS; + break; default: SDL_Unsupported(); + data->render_options = DSRO_NONE; texture->scaleMode = SDL_TEXTURESCALEMODE_NONE; return -1; } +#endif return 0; } @@ -532,8 +621,6 @@ DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; - DirectFB_RenderData *renderdata = - (DirectFB_RenderData *) renderer->driverdata; DFBResult ret; Uint8 *dpixels; int dpitch; @@ -566,37 +653,32 @@ DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, int markDirty, void **pixels, int *pitch) { - DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + DirectFB_TextureData *texturedata = + (DirectFB_TextureData *) texture->driverdata; DFBResult ret; - void *fdata; - int fpitch; - - SDL_DFB_CHECKERR(data->surface->Lock(data->surface, - DSLF_WRITE | DSLF_READ, &fdata, - &fpitch)); - data->pixels = fdata; - data->pitch = fpitch; - switch (texture->format) { - case SDL_PIXELFORMAT_YV12: - case SDL_PIXELFORMAT_IYUV: - if (rect - && (rect->x != 0 || rect->y != 0 || rect->w != texture->w - || rect->h != texture->h)) { - SDL_SetError - ("YV12 and IYUV textures only support full surface locks"); - return -1; - } - break; - default: - /* Only one plane, no worries */ - break; + if (markDirty) { + SDL_AddDirtyRect(&texturedata->dirty, rect); } - *pitch = data->pitch; - *pixels = data->pixels; + if (texturedata->display) { + void *fdata; + int fpitch; + SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface, + DSLF_WRITE | DSLF_READ, + &fdata, &fpitch)); + *pitch = fpitch; + *pixels = fdata; + } else { + *pixels = + (void *) ((Uint8 *) texturedata->pixels + + rect->y * texturedata->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = texturedata->pitch; + } return 0; + error: return -1; } @@ -604,17 +686,25 @@ DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, static void DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + DirectFB_TextureData *texturedata = + (DirectFB_TextureData *) texture->driverdata; - data->surface->Unlock(data->surface); - data->pixels = NULL; + if (texturedata->display) { + texturedata->surface->Unlock(texturedata->surface); + texturedata->pixels = NULL; + } } static void DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, const SDL_Rect * rects) { - //TODO: DirtyTexture + DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + int i; + + for (i = 0; i < numrects; ++i) { + SDL_AddDirtyRect(&data->dirty, &rects[i]); + } } static int @@ -643,36 +733,51 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, (DirectFB_TextureData *) texture->driverdata; DFBResult ret; - if (texturedata->vidlayer) { + if (texturedata->display) { int px, py; SDL_Window *window = SDL_GetWindowFromID(renderer->window); - SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); - SDL_DFB_DEVICEDATA(display->device); - DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; SDL_DFB_WINDOWDATA(window); + SDL_VideoDisplay *display = texturedata->display; + DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; - SDL_DFB_CHECKERR(texturedata->vidlayer-> - SetSourceRectangle(texturedata->vidlayer, srcrect->x, + SDL_DFB_CHECKERR(dispdata->vidlayer-> + SetSourceRectangle(dispdata->vidlayer, srcrect->x, srcrect->y, srcrect->w, srcrect->h)); windata->window->GetPosition(windata->window, &px, &py); - SDL_DFB_CHECKERR(texturedata->vidlayer-> - SetScreenRectangle(texturedata->vidlayer, + SDL_DFB_CHECKERR(dispdata->vidlayer-> + SetScreenRectangle(dispdata->vidlayer, px + dstrect->x, py + dstrect->y, dstrect->w, dstrect->h)); } else { DFBRectangle sr, dr; DFBSurfaceBlittingFlags flags = 0; - sr.x = srcrect->x; - sr.y = srcrect->y; - sr.w = srcrect->w; - sr.h = srcrect->h; + if (texturedata->dirty.list) { + SDL_DirtyRect *dirty; + void *pixels; + int bpp = SDL_BYTESPERPIXEL(texture->format); + int pitch = texturedata->pitch; + + for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) { + SDL_Rect *rect = &dirty->rect; + pixels = + (void *) ((Uint8 *) texturedata->pixels + + rect->y * pitch + rect->x * bpp); + DirectFB_UpdateTexture(renderer, texture, rect, + texturedata->pixels, + texturedata->pitch); + } + SDL_ClearDirtyRects(&texturedata->dirty); + } +#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 2) + SDL_DFB_CHECKERR(data->surface->SetRenderOptions(data->surface, + texturedata-> + render_options)); +#endif - dr.x = dstrect->x; - dr.y = dstrect->y; - dr.w = dstrect->w; - dr.h = dstrect->h; + SDLtoDFBRect(srcrect, &sr); + SDLtoDFBRect(dstrect, &dr); if (texture-> modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA)) @@ -695,6 +800,7 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, switch (texture->blendMode) { case SDL_TEXTUREBLENDMODE_NONE: + /**< No blending */ flags |= DSBLIT_NOFX; data->surface->SetSrcBlendFunction(data->surface, DSBF_ONE); data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO); @@ -725,10 +831,11 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, SDL_DFB_CHECKERR(data->surface-> SetBlittingFlags(data->surface, flags)); + if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { SDL_DFB_CHECKERR(data->surface-> - Blit(data->surface, texturedata->surface, &sr, - dr.x, dr.y)); + Blit(data->surface, texturedata->surface, + &sr, dr.x, dr.y)); } else { SDL_DFB_CHECKERR(data->surface-> StretchBlit(data->surface, texturedata->surface, @@ -746,7 +853,6 @@ DirectFB_RenderPresent(SDL_Renderer * renderer) DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; SDL_Window *window = SDL_GetWindowFromID(renderer->window); - SDL_DirtyRect *dirty; DFBRectangle sr; DFBResult ret; @@ -757,7 +863,7 @@ DirectFB_RenderPresent(SDL_Renderer * renderer) /* Send the data to the display */ SDL_DFB_CHECKERR(data->surface-> - Flip(data->surface, NULL, data->flipflags)); + Flip(data->surface, NULL, 0 * data->flipflags)); return; error: @@ -775,11 +881,15 @@ DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) SDL_DFB_RELEASE(data->palette); SDL_DFB_RELEASE(data->surface); if (data->display) { - data->display->vidIDinuse = 0; - data->vidlayer->SetCooperativeLevel(data->vidlayer, - DLSCL_ADMINISTRATIVE); + DFB_DisplayData *dispdata = + (DFB_DisplayData *) data->display->driverdata; + dispdata->vidIDinuse = 0; + dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer, + DLSCL_ADMINISTRATIVE); + SDL_DFB_RELEASE(dispdata->vidlayer); } - SDL_DFB_RELEASE(data->vidlayer); + SDL_FreeDirtyRects(&data->dirty); + SDL_DFB_FREE(data->pixels); SDL_free(data); texture->driverdata = NULL; } @@ -788,10 +898,9 @@ static void DirectFB_DestroyRenderer(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - int i; if (data) { - data->surface = NULL; + SDL_DFB_RELEASE(data->surface); SDL_free(data); } SDL_free(renderer); diff --git a/src/video/directfb/SDL_DirectFB_video.c b/src/video/directfb/SDL_DirectFB_video.c index 57f94f4ef..f56dbde80 100644 --- a/src/video/directfb/SDL_DirectFB_video.c +++ b/src/video/directfb/SDL_DirectFB_video.c @@ -43,59 +43,23 @@ #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; -}; +#include "SDL_DirectFB_render.h" +#include "SDL_DirectFB_mouse.h" /* 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_Available(void); +static SDL_VideoDevice *DirectFB_CreateDevice(int devindex); 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 +VideoBootStrap DirectFB_bootstrap = { + "directfb", "DirectFB", + DirectFB_Available, DirectFB_CreateDevice +}; /* DirectFB driver bootstrap functions */ @@ -119,7 +83,6 @@ DirectFB_CreateDevice(int devindex) /* 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 */ @@ -173,217 +136,28 @@ DirectFB_CreateDevice(int devindex) 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; - int i; + char *stemp; DFBResult ret; - int tcw[DFB_MAX_SCREENS]; - int tch[DFB_MAX_SCREENS]; 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)); -#if (DIRECTFB_MAJOR_VERSION >= 1) - screen->GetSize(screen, &tcw[i], &tch[i]); -#else - /* FIXME: this is only used to center windows - * Should be done otherwise, e.g. get surface from layer - */ - tcw[i] = 800; - tch[i] = 600; -#endif - 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 */ + devdata->use_yuv_underlays = 0; /* default: off */ + stemp = getenv(DFBENV_USE_YUV_UNDERLAY); + if (stemp) + devdata->use_yuv_underlays = atoi(stemp); - dispdata->vidID = devdata->vidlayer[i]; - dispdata->vidIDinuse = 0; - - 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); - } + /* Create global Eventbuffer for axis events */ + SDL_DFB_CHECKERR(dfb-> + CreateInputEventBuffer(dfb, DICAPS_AXES /*DICAPS_ALL */ , + DFB_TRUE, &devdata->events)); devdata->initialized = 1; devdata->dfb = dfb; @@ -391,26 +165,21 @@ DirectFB_VideoInit(_THIS) _this->driverdata = devdata; + DirectFB_InitModes(_this); #if SDL_DIRECTFB_OPENGL - /* Opengl */ - _this->gl_data->gl_active = 0; - _this->gl_data->gl_context = NULL; + DirectFB_GL_Initialize(_this); #endif DirectFB_AddRenderDriver(_this); DirectFB_InitMouse(_this); DirectFB_InitKeyboard(_this); - //devdata->mouse = SDL_AddMouse(&mouse, -1); + 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; } @@ -419,234 +188,22 @@ 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); - } + DirectFB_QuitModes(_this); + DirectFB_QuitKeyboard(_this); + DirectFB_QuitMouse(_this); + SDL_DFB_RELEASE(devdata->events); SDL_DFB_RELEASE(devdata->dfb); - - SDL_DelMouse(devdata->mouse); - SDL_DelKeyboard(devdata->keyboard); + SDL_DFB_FREE(_this->driverdata); #if SDL_DIRECTFB_OPENGL - DirectFB_GL_UnloadLibrary(_this); + DirectFB_GL_Shutdown(_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; - DFB_WindowData *win; - - 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) || - ((mode->format != SDL_PIXELFORMAT_UNKNOWN) - && (config.pixelformat != rconfig.pixelformat))) { - SDL_DFB_DEBUG("Error setting mode %dx%d-%x\n", mode->w, mode->h, - mode->format); - return -1; - } - - data->pixelformat = rconfig.pixelformat; - data->cw = config.width; - data->ch = config.height; - SDL_CurrentDisplay.current_mode = *mode; - - /* - * FIXME: video mode switch is currently broken - * - * DirectFB 1.2.0-rc1 even has a broken cursor after a switch - * The following code needs to be revisited whether it is still - * needed once the switch works again. - */ - - win = devdata->firstwin; - - while (win) { - SDL_DFB_RELEASE(win->surface); - SDL_DFB_CHECKERR(win->window->GetSurface(win->window, &win->surface)); - win = win->next; - } - - - return 0; - error: - return -1; -} - static int DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp) { @@ -658,527 +215,3 @@ 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 (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0) - /* Needed for 1.2 */ - desc.flags |= DWDESC_POSX | DWDESC_POSY; - desc.posx = x; - desc.posy = y; -#else - 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; - } -#endif - - 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); - int x, y; - - if (window->y == SDL_WINDOWPOS_UNDEFINED) - y = 0; - else - y = window->y; - - if (window->x == SDL_WINDOWPOS_UNDEFINED) - x = 0; - else - x = window->x; - - if (window->flags & SDL_WINDOW_FULLSCREEN) { - x = 0; - y = 0; - } - //if (!(window->flags & SDL_WINDOW_FULLSCREEN)) - windata->window->MoveTo(windata->window, x, y); -} - -static void -DirectFB_SetWindowSize(_THIS, SDL_Window * window) -{ - int ret; - SDL_DFB_DEVICEDATA(_this); - SDL_DFB_WINDOWDATA(window); - SDL_DFB_DISPLAYDATA(_this, window); - - if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { - int ch, cw; - - // SDL_DFB_DEBUG("Resize %d %d %d %d\n", cw, ch, window->w, window->h); -#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0) - SDL_DFB_CHECKERR(windata->window-> - ResizeSurface(windata->window, window->w, - window->h)); -#else - SDL_DFB_CHECKERR(windata->window-> - Resize(windata->window, window->w, window->h)); -#endif - SDL_DFB_CHECKERR(windata->window->GetSize(windata->window, &window->w, &window->h)); /* if a window manager should have decided otherwise */ - } - error: - return; -} - -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 -#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 diff --git a/src/video/directfb/SDL_DirectFB_video.h b/src/video/directfb/SDL_DirectFB_video.h index 5cb827027..e0b721b91 100644 --- a/src/video/directfb/SDL_DirectFB_video.h +++ b/src/video/directfb/SDL_DirectFB_video.h @@ -24,9 +24,14 @@ #ifndef _SDL_DirectFB_video_h #define _SDL_DirectFB_video_h +#include "../SDL_sysvideo.h" + #include #include +#include "SDL_mouse.h" + +#define DEBUG 0 #define LOG_CHANNEL stdout #if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23) @@ -42,10 +47,18 @@ #include "SDL_loadso.h" #endif -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" +#include "SDL_DirectFB_events.h" +/* + * #include "SDL_DirectFB_gamma.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" -#define DEBUG 1 +#define DFBENV_USE_YUV_UNDERLAY "SDL_DIRECTFB_YUV_UNDERLAY" +#define DFBENV_USE_YUV_DIRECT "SDL_DIRECTFB_YUV_DIRECT" #define SDL_DFB_RELEASE(x) do { if ( x ) { x->Release(x); x = NULL; } } while (0) #define SDL_DFB_FREE(x) do { if ( x ) { SDL_free(x); x = NULL; } } while (0) @@ -102,50 +115,8 @@ /* Private display data */ #define SDL_DFB_DEVICEDATA(dev) DFB_DeviceData *devdata = (DFB_DeviceData *) ((dev)->driverdata) -#define SDL_DFB_WINDOWDATA(win) DFB_WindowData *windata = ((win) ? (DFB_WindowData *) ((win)->driverdata) : NULL) -#define SDL_DFB_DISPLAYDATA(dev, win) DFB_DisplayData *dispdata = ((win && dev) ? (DFB_DisplayData *) (dev)->displays[(win)->display].driverdata : NULL) - -typedef struct _DFB_DisplayData DFB_DisplayData; #define DFB_MAX_SCREENS 10 -#define DFB_MAX_MODES 50 - -struct _DFB_DisplayData -{ - IDirectFBDisplayLayer *layer; - DFBSurfacePixelFormat pixelformat; - //FIXME: support for multiple layer ... - DFBDisplayLayerID vidID; - - int vidIDinuse; - - int cw; - int ch; - - int nummodes; - SDL_DisplayMode *modelist; - -#if 0 - WMcursor *last_cursor; - WMcursor *blank_cursor; - WMcursor *default_cursor; -#endif -}; - - -typedef struct _DFB_WindowData DFB_WindowData; -struct _DFB_WindowData -{ - IDirectFBSurface *surface; - IDirectFBPalette *palette; - IDirectFBWindow *window; - IDirectFBGL *gl_context; - IDirectFBEventBuffer *eventbuffer; - DFBWindowID windowID; - int id; /* SDL window id */ - DFB_WindowData *next; - Uint8 opacity; -}; typedef struct _DFB_DeviceData DFB_DeviceData; struct _DFB_DeviceData @@ -158,25 +129,14 @@ struct _DFB_DeviceData int kbdgeneric; DFB_WindowData *firstwin; - int numscreens; - DFBScreenID screenid[DFB_MAX_SCREENS]; - DFBDisplayLayerID gralayer[DFB_MAX_SCREENS]; - DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS]; - - int aux; /* auxiliary integer for callbacks */ + int use_yuv_underlays; /* OpenGL */ void (*glFinish) (void); void (*glFlush) (void); -}; -struct SDL_GLDriverData -{ - int gl_active; /* to stop switching drivers while we have a valid context */ - -#if SDL_DIRECTFB_OPENGL - IDirectFBGL *gl_context; -#endif /* SDL_DIRECTFB_OPENGL */ + /* global events */ + IDirectFBEventBuffer *events; }; #endif /* _SDL_DirectFB_video_h */ diff --git a/src/video/directfb/SDL_DirectFB_window.c b/src/video/directfb/SDL_DirectFB_window.c new file mode 100644 index 000000000..c91082f3b --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_window.c @@ -0,0 +1,325 @@ +/* + 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 +*/ +#include "SDL_config.h" + +#include "SDL_syswm.h" +#include "../SDL_sysvideo.h" +#include "../../events/SDL_keyboard_c.h" + +#include "SDL_DirectFB_video.h" + +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_PIXELFORMAT; + /*| DWDESC_CAPS | DWDESC_SURFACE_CAPS */ + +#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0) + /* Needed for 1.2 */ + desc.flags |= DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS; + desc.posx = x; + desc.posy = y; +#else + 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; + } +#endif + + desc.width = window->w; + desc.height = window->h; + desc.pixelformat = dispdata->pixelformat; +#if 0 + desc.caps = 0; + desc.surface_caps = + DSCAPS_DOUBLE | DSCAPS_TRIPLE | DSCAPS_PREMULTIPLIED | + DSCAPS_VIDEOONLY; +#endif + desc.surface_caps = DSCAPS_PREMULTIPLIED; + /* DSCAPS_VIDEOONLY has negative impact on performance */ + + /* 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_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->window->GetSize(windata->window, &window->w, &window->h); + + /* remember parent */ + windata->id = window->id; + + /* Add to list ... */ + + windata->next = devdata->firstwin; + windata->opacity = 0xFF; + devdata->firstwin = windata; + + return 0; + error: + SDL_DFB_RELEASE(windata->window); + SDL_DFB_RELEASE(windata->surface); + return -1; +} + +int +DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +{ + SDL_Unsupported(); + return -1; +} + +void +DirectFB_SetWindowTitle(_THIS, SDL_Window * window) +{ + SDL_Unsupported(); +} + +void +DirectFB_SetWindowPosition(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + int x, y; + + if (window->y == SDL_WINDOWPOS_UNDEFINED) + y = 0; + else + y = window->y; + + if (window->x == SDL_WINDOWPOS_UNDEFINED) + x = 0; + else + x = window->x; + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + x = 0; + y = 0; + } + + windata->window->MoveTo(windata->window, x, y); +} + +void +DirectFB_SetWindowSize(_THIS, SDL_Window * window) +{ + int ret; + SDL_DFB_WINDOWDATA(window); + + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { +#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0) + int cw; + int ch; + + /* Make sure all events are disabled for this operation ! */ + SDL_DFB_CHECKERR(windata->window-> + DisableEvents(windata->window, DWET_ALL)); + + SDL_DFB_CHECKERR(windata->window->GetSize(windata->window, &cw, &ch)); + if (cw != window->w || ch != window->h) + SDL_DFB_CHECKERR(windata->window-> + Resize(windata->window, window->w, window->h)); + SDL_DFB_CHECKERR(windata->window-> + EnableEvents(windata->window, DWET_ALL)); + +#else + SDL_DFB_CHECKERR(windata->window-> + Resize(windata->window, window->w, window->h)); +#endif + SDL_DFB_CHECKERR(windata->window->GetSize(windata->window, &window->w, &window->h)); /* if a window manager should have decided otherwise */ + + SDL_OnWindowResized(window); + } + return; + error: + windata->window->EnableEvents(windata->window, DWET_ALL); + return; +} + +void +DirectFB_ShowWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + + windata->window->SetOpacity(windata->window, windata->opacity); + +} + +void +DirectFB_HideWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + + windata->window->GetOpacity(windata->window, &windata->opacity); + windata->window->SetOpacity(windata->window, 0); +} + +void +DirectFB_RaiseWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + + windata->window->RaiseToTop(windata->window); + windata->window->RequestFocus(windata->window); +} + +void +DirectFB_MaximizeWindow(_THIS, SDL_Window * window) +{ + /* FIXME: Size to Desktop ? */ + + SDL_Unsupported(); +} + +void +DirectFB_MinimizeWindow(_THIS, SDL_Window * window) +{ + /* FIXME: Size to 32x32 ? */ + + SDL_Unsupported(); +} + +void +DirectFB_RestoreWindow(_THIS, SDL_Window * window) +{ + SDL_Unsupported(); +} + +void +DirectFB_SetWindowGrab(_THIS, SDL_Window * window) +{ + SDL_DFB_WINDOWDATA(window); + + if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && + (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + windata->window->GrabPointer(windata->window); + windata->window->GrabKeyboard(windata->window); + } else { + windata->window->UngrabPointer(windata->window); + windata->window->UngrabKeyboard(windata->window); + } +} + +void +DirectFB_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + DFB_WindowData *p; + + SDL_DFB_DEBUG("Trace\n"); + + 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); + return; +} + +SDL_bool +DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo * info) +{ + SDL_Unsupported(); + return SDL_FALSE; +} diff --git a/src/video/directfb/SDL_DirectFB_window.h b/src/video/directfb/SDL_DirectFB_window.h new file mode 100644 index 000000000..ebe921af9 --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_window.h @@ -0,0 +1,61 @@ +/* + 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 +*/ +#include "SDL_config.h" + +#ifndef _SDL_directfb_window_h +#define _SDL_directfb_window_h + +#define SDL_DFB_WINDOWDATA(win) DFB_WindowData *windata = ((win) ? (DFB_WindowData *) ((win)->driverdata) : NULL) + +typedef struct _DFB_WindowData DFB_WindowData; +struct _DFB_WindowData +{ + IDirectFBSurface *surface; + IDirectFBWindow *window; + DirectFB_GLContext *gl_context; + IDirectFBEventBuffer *eventbuffer; + DFBWindowID windowID; + DFB_WindowData *next; + Uint8 opacity; + SDL_WindowID id; +}; + +extern int DirectFB_CreateWindow(_THIS, SDL_Window * window); +extern int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, + const void *data); +extern void DirectFB_SetWindowTitle(_THIS, SDL_Window * window); +extern void DirectFB_SetWindowPosition(_THIS, SDL_Window * window); +extern void DirectFB_SetWindowSize(_THIS, SDL_Window * window); +extern void DirectFB_ShowWindow(_THIS, SDL_Window * window); +extern void DirectFB_HideWindow(_THIS, SDL_Window * window); +extern void DirectFB_RaiseWindow(_THIS, SDL_Window * window); +extern void DirectFB_MaximizeWindow(_THIS, SDL_Window * window); +extern void DirectFB_MinimizeWindow(_THIS, SDL_Window * window); +extern void DirectFB_RestoreWindow(_THIS, SDL_Window * window); +extern void DirectFB_SetWindowGrab(_THIS, SDL_Window * window); +extern void DirectFB_DestroyWindow(_THIS, SDL_Window * window); +extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +#endif /* _SDL_directfb_window_h */ + +/* vi: set ts=4 sw=4 expandtab: */