From dbc793798f731d51f610c44ff4de511290190ca9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 11 Aug 2007 21:51:19 +0000 Subject: [PATCH] Date: Sat, 11 Aug 2007 02:03:16 +0200 (CEST) From: couriersud arcor.de To: slouken@libsdl.org Subject: Directfb driver for SDL1.3 Hi, the attachment contains a patch for a SDL1.3 directfb driver. It supports: - Renderer "directfb": Hardware acceleration as supported by the underlying directfb driver. With a radeon X850, testsprite2 runs at 50% to 70% of OpenGL (X11, dri) performance. Also supports hardware accelerated yuv overlays. This must be enabled by sett ing: export SDL_DIRECTFB_YUV_DIRECT=1 - Renderer "opengl" Supports software opengl using mesa opengl (make linux-directfb). Some more information may be found in README.DirectFB There will certainly still be some bugs, and there is some debug code around. When I find some time, I will compile against directfb-0.9.25 as distributed with ubuntu 7.04. The diff also contains a fix for SDL_LockYUVOverlay fixing a bug in *pixels and pitches initialization. Kind regards, couriersud --- README.DirectFB | 45 + src/SDL_compat.c | 8 +- src/video/directfb/SDL_DirectFB_events.c | 258 ++- src/video/directfb/SDL_DirectFB_events.h | 3 +- src/video/directfb/SDL_DirectFB_keys.h | 135 -- src/video/directfb/SDL_DirectFB_mouse.c | 212 ++ ...DL_DirectFB_yuv.h => SDL_DirectFB_mouse.h} | 24 +- src/video/directfb/SDL_DirectFB_render.c | 737 +++++++ src/video/directfb/SDL_DirectFB_render.h | 30 + src/video/directfb/SDL_DirectFB_video.c | 1709 ++++++++--------- src/video/directfb/SDL_DirectFB_video.h | 154 +- src/video/directfb/SDL_DirectFB_yuv.c | 290 --- 12 files changed, 2198 insertions(+), 1407 deletions(-) create mode 100644 README.DirectFB delete mode 100644 src/video/directfb/SDL_DirectFB_keys.h create mode 100644 src/video/directfb/SDL_DirectFB_mouse.c rename src/video/directfb/{SDL_DirectFB_yuv.h => SDL_DirectFB_mouse.h} (58%) create mode 100644 src/video/directfb/SDL_DirectFB_render.c create mode 100644 src/video/directfb/SDL_DirectFB_render.h delete mode 100644 src/video/directfb/SDL_DirectFB_yuv.c diff --git a/README.DirectFB b/README.DirectFB new file mode 100644 index 000000000..a13e98771 --- /dev/null +++ b/README.DirectFB @@ -0,0 +1,45 @@ +SDL on DirectFB + +Supports: + +- Hardware YUV overlays +- OpenGL - software only +- 2D/3D accelerations (depends on directfb driver) + +What you need: + +DirectFB 1.0.0 - required +Kernel-Framebuffer support: required: vesafb, radeonfb .... +Mesa 7.0.x - optional for OpenGL + +As of this writing 20070810 you need to pull Mesa from git and do the following: + +------------------------ +cd mesa +make linux-directfb +make + +echo Installing - pleaser enter sudo pw. + +sudo make install INSTALL_DIR=/usr/local/dfb_GL +cd src/mesa/drivers/directfb +make +sudo make install INSTALL_DIR=/usr/local/dfb_GL +------------------------ + +To run the SDL - testprograms: + +export SDL_VIDEODRIVER=directfb +export LD_LIBRARY_PATH=/usr/local/dfb_GL/lib +export LD_PRELOAD=/usr/local/dfb_GL/libGL.so.7 + +./testgl + +To use hardware accelerated YUV-overlays for YUV-textures, use: + +export SDL_DIRECTFB_YUV_DIRECT=1 + +This is disabled by default. It will only support one concurrent +overlay and may behave strange if not used with SDL_CreateYUvOverlay +from SDLcompat.c. + diff --git a/src/SDL_compat.c b/src/SDL_compat.c index 24251fd91..1d85c3d6a 100644 --- a/src/SDL_compat.c +++ b/src/SDL_compat.c @@ -1440,19 +1440,21 @@ SDL_LockYUVOverlay(SDL_Overlay * overlay) < 0) { return -1; } + overlay->pixels[0] = (Uint8 *) pixels; + overlay->pitches[0] = pitch; switch (overlay->format) { case SDL_YV12_OVERLAY: case SDL_IYUV_OVERLAY: - overlay->pixels[0] = (Uint8 *) pixels; + overlay->pitches[1] = pitch / 2; + overlay->pitches[2] = pitch / 2; overlay->pixels[1] = overlay->pixels[0] + overlay->pitches[0] * overlay->h; overlay->pixels[2] = - overlay->pixels[1] + overlay->pitches[1] * overlay->h; + overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2; break; case SDL_YUY2_OVERLAY: case SDL_UYVY_OVERLAY: case SDL_YVYU_OVERLAY: - overlay->pixels[0] = (Uint8 *) pixels; break; } return 0; diff --git a/src/video/directfb/SDL_DirectFB_events.c b/src/video/directfb/SDL_DirectFB_events.c index e5d7b7553..dc732bf7a 100644 --- a/src/video/directfb/SDL_DirectFB_events.c +++ b/src/video/directfb/SDL_DirectFB_events.c @@ -23,70 +23,97 @@ /* Handle the event stream, converting DirectFB input events into SDL events */ -#include -#include -#include -#include -#include - #include #include "SDL.h" #include "../SDL_sysvideo.h" #include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" -#include "SDL_DirectFB_video.h" #include "SDL_DirectFB_events.h" /* The translation tables from a DirectFB keycode to a SDL keysym */ static SDLKey keymap[256]; -static SDL_keysym *DirectFB_TranslateKey(DFBInputEvent * ev, - SDL_keysym * keysym); -static int DirectFB_TranslateButton(DFBInputEvent * ev); -static int posted = 0; +static SDL_keysym *DirectFB_TranslateKey(DFBInputDeviceKeyIdentifier key_id, + DFBInputDeviceKeySymbol key_symbol, + DFBInputDeviceModifierMask key_mod, + SDL_keysym * keysym); +static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button); void -DirectFB_PumpEvents(_THIS) +DirectFB_PumpEventsWindow(_THIS) { - DFBInputEvent evt; + SDL_DFB_DEVICEDATA(_this); + DFB_WindowData *p; + DFBWindowEvent evt; - while (HIDDEN->eventbuffer->GetEvent(HIDDEN->eventbuffer, - DFB_EVENT(&evt)) == DFB_OK) { - SDL_keysym keysym; + for (p = devdata->firstwin; p != NULL; p = p->next) { + while (p->eventbuffer->GetEvent(p->eventbuffer, + DFB_EVENT(&evt)) == DFB_OK) { + SDL_keysym keysym; - switch (evt.type) { - case DIET_BUTTONPRESS: - posted += SDL_PrivateMouseButton(SDL_PRESSED, - DirectFB_TranslateButton - (&evt), 0, 0); - break; - case DIET_BUTTONRELEASE: - posted += SDL_PrivateMouseButton(SDL_RELEASED, - DirectFB_TranslateButton - (&evt), 0, 0); - break; - case DIET_KEYPRESS: - posted += - SDL_PrivateKeyboard(SDL_PRESSED, - DirectFB_TranslateKey(&evt, &keysym)); - break; - case DIET_KEYRELEASE: - posted += - SDL_PrivateKeyboard(SDL_RELEASED, - DirectFB_TranslateKey(&evt, &keysym)); - break; - case DIET_AXISMOTION: - if (evt.flags & DIEF_AXISREL) { - if (evt.axis == DIAI_X) - posted += SDL_PrivateMouseMotion(0, 1, evt.axisrel, 0); - else if (evt.axis == DIAI_Y) - posted += SDL_PrivateMouseMotion(0, 1, 0, evt.axisrel); + if (evt.clazz = DFEC_WINDOW) { + switch (evt.type) { + case DWET_BUTTONDOWN: + SDL_SendMouseButton(devdata->mouse, SDL_PRESSED, + DirectFB_TranslateButton(evt.button)); + break; + case DWET_BUTTONUP: + SDL_SendMouseButton(devdata->mouse, SDL_RELEASED, + DirectFB_TranslateButton(evt.button)); + break; + case DWET_MOTION: + SDL_SendMouseMotion(devdata->mouse, 0, evt.x, evt.y); + break; + case DWET_KEYDOWN: + DirectFB_TranslateKey(evt.key_id, evt.key_symbol, + evt.modifiers, &keysym); + SDL_SendKeyboardKey(devdata->keyboard, SDL_PRESSED, + keysym.scancode, keysym.sym); + break; + case DWET_KEYUP: + DirectFB_TranslateKey(evt.key_id, evt.key_symbol, + evt.modifiers, &keysym); + SDL_SendKeyboardKey(devdata->keyboard, SDL_RELEASED, + keysym.scancode, keysym.sym); + break; + case DWET_POSITION_SIZE: + SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED, evt.cx, + evt.cy); + SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED, evt.w, + evt.h); + break; + case DWET_POSITION: + SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED, evt.cx, + evt.cy); + break; + case DWET_SIZE: + SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED, evt.w, + evt.h); + break; + case DWET_CLOSE: + SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_CLOSE, 0, 0); + break; + case DWET_GOTFOCUS: + //TODO: Implement for yuv-overlay DirectFB_SwitchOverlayContext(this, evt.window_id); + SDL_SetKeyboardFocus(devdata->keyboard, p->id); + break; + case DWET_LOSTFOCUS: + SDL_SetKeyboardFocus(devdata->keyboard, 0); + break; + case DWET_ENTER: + //SDL_DirectFB_ReshowCursor(_this, 0); + SDL_SetMouseFocus(devdata->mouse, p->id); + break; + case DWET_LEAVE: + SDL_SetMouseFocus(devdata->mouse, 0); + //SDL_DirectFB_ReshowCursor(_this, 1); + break; + default: + ; + } } - break; - default: - ; } } } @@ -177,35 +204,80 @@ DirectFB_InitOSKeymap(_THIS) keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDLK_SCROLLOCK; keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDLK_PRINT; keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDLK_PAUSE; + + keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDLK_KP_EQUALS; + keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDLK_KP_PERIOD; + keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDLK_KP0; + keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDLK_KP1; + keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDLK_KP2; + keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDLK_KP3; + keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDLK_KP4; + keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDLK_KP5; + keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDLK_KP6; + keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDLK_KP7; + keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDLK_KP8; + keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDLK_KP9; keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDLK_KP_DIVIDE; keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDLK_KP_MULTIPLY; keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDLK_KP_MINUS; keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDLK_KP_PLUS; keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDLK_KP_ENTER; -} + keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDLK_BACKQUOTE; /* TLDE */ + keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDLK_MINUS; /* AE11 */ + keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDLK_EQUALS; /* AE12 */ + keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDLK_RIGHTBRACKET; /* AD11 */ + keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDLK_LEFTBRACKET; /* AD12 */ + keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDLK_BACKSLASH; /* BKSL */ + keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDLK_SEMICOLON; /* AC10 */ + keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDLK_QUOTE; /* AC11 */ + keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDLK_COMMA; /* AB08 */ + keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDLK_PERIOD; /* AB09 */ + keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDLK_SLASH; /* AB10 */ + keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDLK_LESS; /* 103rd */ +} static SDL_keysym * -DirectFB_TranslateKey(DFBInputEvent * ev, SDL_keysym * keysym) +DirectFB_TranslateKey(DFBInputDeviceKeyIdentifier key_id, + DFBInputDeviceKeySymbol key_symbol, + DFBInputDeviceModifierMask key_mod, SDL_keysym * keysym) { + SDLMod mod = KMOD_NONE; + + /* + * Set modifier information + */ + + if (key_mod & DIMM_SHIFT) + mod = mod | KMOD_LSHIFT; + if (key_mod & DIMM_CONTROL) + mod = mod | KMOD_LCTRL; + if (key_mod & DIMM_ALT) + mod = mod | KMOD_LALT; + if (key_mod & DIMM_ALTGR) + mod = mod | KMOD_RALT; + if (key_mod & DIMM_META) + mod = mod | KMOD_LMETA; + /* Set the keysym information */ - keysym->scancode = ev->key_id; - keysym->mod = KMOD_NONE; /* FIXME */ + keysym->scancode = key_id; + + keysym->mod = mod; keysym->unicode = - (DFB_KEY_TYPE(ev->key_symbol) == DIKT_UNICODE) ? ev->key_symbol : 0; + (DFB_KEY_TYPE(key_symbol) == DIKT_UNICODE) ? key_symbol : 0; - if (ev->key_symbol > 0 && ev->key_symbol < 128) - keysym->sym = ev->key_symbol; + if (key_symbol > 0 && key_symbol < 255) + keysym->sym = key_symbol; else - keysym->sym = keymap[ev->key_id - DIKI_UNKNOWN]; + keysym->sym = keymap[key_id - DIKI_UNKNOWN]; return keysym; } static int -DirectFB_TranslateButton(DFBInputEvent * ev) +DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button) { - switch (ev->button) { + switch (button) { case DIBI_LEFT: return 1; case DIBI_MIDDLE: @@ -217,4 +289,76 @@ DirectFB_TranslateButton(DFBInputEvent * ev) } } -/* vi: set ts=4 sw=4 expandtab: */ +#if 0 +void +DirectFB_PumpEvents(_THIS) +{ + SDL_DFB_DEVICEDATA(_this); + DFBInputEvent evt; + static last_x = 0, last_y = 0; + + while (devdata->eventbuffer->GetEvent(devdata->eventbuffer, + DFB_EVENT(&evt)) == DFB_OK) { + SDL_keysym keysym; + DFBInputDeviceModifierMask mod; + + if (evt.clazz = DFEC_INPUT) { + if (evt.flags & DIEF_MODIFIERS) + mod = evt.modifiers; + else + mod = 0; + + switch (evt.type) { + case DIET_BUTTONPRESS: + posted += SDL_PrivateMouseButton(SDL_PRESSED, + DirectFB_TranslateButton(evt. + button), + 0, 0); + break; + case DIET_BUTTONRELEASE: + posted += SDL_PrivateMouseButton(SDL_RELEASED, + 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)); + break; + case DIET_KEYRELEASE: + posted += SDL_PrivateKeyboard(SDL_RELEASED, + DirectFB_TranslateKey(evt. + key_id, + evt. + key_symbol, + mod, + &keysym)); + break; + case DIET_AXISMOTION: + if (evt.flags & DIEF_AXISREL) { + if (evt.axis == DIAI_X) + posted += + SDL_PrivateMouseMotion(0, 1, evt.axisrel, 0); + else if (evt.axis == DIAI_Y) + posted += + SDL_PrivateMouseMotion(0, 1, 0, evt.axisrel); + } else if (evt.flags & DIEF_AXISABS) { + if (evt.axis == DIAI_X) + last_x = evt.axisabs; + else if (evt.axis == DIAI_Y) + last_y = evt.axisabs; + posted += SDL_PrivateMouseMotion(0, 0, last_x, last_y); + } + break; + default: + ; + } + } + } +} +#endif diff --git a/src/video/directfb/SDL_DirectFB_events.h b/src/video/directfb/SDL_DirectFB_events.h index 7385db078..e4cf73ddb 100644 --- a/src/video/directfb/SDL_DirectFB_events.h +++ b/src/video/directfb/SDL_DirectFB_events.h @@ -25,5 +25,4 @@ /* Functions to be exported */ extern void DirectFB_InitOSKeymap(_THIS); -extern void DirectFB_PumpEvents(_THIS); -/* vi: set ts=4 sw=4 expandtab: */ +extern void DirectFB_PumpEventsWindow(_THIS); diff --git a/src/video/directfb/SDL_DirectFB_keys.h b/src/video/directfb/SDL_DirectFB_keys.h deleted file mode 100644 index 0137cd743..000000000 --- a/src/video/directfb/SDL_DirectFB_keys.h +++ /dev/null @@ -1,135 +0,0 @@ - -#define SCANCODE_ESCAPE 1 - -#define SCANCODE_1 2 -#define SCANCODE_2 3 -#define SCANCODE_3 4 -#define SCANCODE_4 5 -#define SCANCODE_5 6 -#define SCANCODE_6 7 -#define SCANCODE_7 8 -#define SCANCODE_8 9 -#define SCANCODE_9 10 -#define SCANCODE_0 11 - -#define SCANCODE_MINUS 12 -#define SCANCODE_EQUAL 13 - -#define SCANCODE_BACKSPACE 14 -#define SCANCODE_TAB 15 - -#define SCANCODE_Q 16 -#define SCANCODE_W 17 -#define SCANCODE_E 18 -#define SCANCODE_R 19 -#define SCANCODE_T 20 -#define SCANCODE_Y 21 -#define SCANCODE_U 22 -#define SCANCODE_I 23 -#define SCANCODE_O 24 -#define SCANCODE_P 25 -#define SCANCODE_BRACKET_LEFT 26 -#define SCANCODE_BRACKET_RIGHT 27 - -#define SCANCODE_ENTER 28 - -#define SCANCODE_LEFTCONTROL 29 - -#define SCANCODE_A 30 -#define SCANCODE_S 31 -#define SCANCODE_D 32 -#define SCANCODE_F 33 -#define SCANCODE_G 34 -#define SCANCODE_H 35 -#define SCANCODE_J 36 -#define SCANCODE_K 37 -#define SCANCODE_L 38 -#define SCANCODE_SEMICOLON 39 -#define SCANCODE_APOSTROPHE 40 -#define SCANCODE_GRAVE 41 - -#define SCANCODE_LEFTSHIFT 42 -#define SCANCODE_BACKSLASH 43 - -#define SCANCODE_Z 44 -#define SCANCODE_X 45 -#define SCANCODE_C 46 -#define SCANCODE_V 47 -#define SCANCODE_B 48 -#define SCANCODE_N 49 -#define SCANCODE_M 50 -#define SCANCODE_COMMA 51 -#define SCANCODE_PERIOD 52 -#define SCANCODE_SLASH 53 - -#define SCANCODE_RIGHTSHIFT 54 -#define SCANCODE_KEYPADMULTIPLY 55 - -#define SCANCODE_LEFTALT 56 -#define SCANCODE_SPACE 57 -#define SCANCODE_CAPSLOCK 58 - -#define SCANCODE_F1 59 -#define SCANCODE_F2 60 -#define SCANCODE_F3 61 -#define SCANCODE_F4 62 -#define SCANCODE_F5 63 -#define SCANCODE_F6 64 -#define SCANCODE_F7 65 -#define SCANCODE_F8 66 -#define SCANCODE_F9 67 -#define SCANCODE_F10 68 - -#define SCANCODE_NUMLOCK 69 -#define SCANCODE_SCROLLLOCK 70 - -#define SCANCODE_KEYPAD7 71 -#define SCANCODE_CURSORUPLEFT 71 -#define SCANCODE_KEYPAD8 72 -#define SCANCODE_CURSORUP 72 -#define SCANCODE_KEYPAD9 73 -#define SCANCODE_CURSORUPRIGHT 73 -#define SCANCODE_KEYPADMINUS 74 -#define SCANCODE_KEYPAD4 75 -#define SCANCODE_CURSORLEFT 75 -#define SCANCODE_KEYPAD5 76 -#define SCANCODE_KEYPAD6 77 -#define SCANCODE_CURSORRIGHT 77 -#define SCANCODE_KEYPADPLUS 78 -#define SCANCODE_KEYPAD1 79 -#define SCANCODE_CURSORDOWNLEFT 79 -#define SCANCODE_KEYPAD2 80 -#define SCANCODE_CURSORDOWN 80 -#define SCANCODE_KEYPAD3 81 -#define SCANCODE_CURSORDOWNRIGHT 81 -#define SCANCODE_KEYPAD0 82 -#define SCANCODE_KEYPADPERIOD 83 - -#define SCANCODE_LESS 86 - -#define SCANCODE_F11 87 -#define SCANCODE_F12 88 - -#define SCANCODE_KEYPADENTER 96 -#define SCANCODE_RIGHTCONTROL 97 -#define SCANCODE_CONTROL 97 -#define SCANCODE_KEYPADDIVIDE 98 -#define SCANCODE_PRINTSCREEN 99 -#define SCANCODE_RIGHTALT 100 -#define SCANCODE_BREAK 101 /* Beware: is 119 */ -#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */ - -#define SCANCODE_HOME 102 -#define SCANCODE_CURSORBLOCKUP 90 /* Cursor key block */ -#define SCANCODE_PAGEUP 104 -#define SCANCODE_CURSORBLOCKLEFT 92 /* Cursor key block */ -#define SCANCODE_CURSORBLOCKRIGHT 94 /* Cursor key block */ -#define SCANCODE_END 107 -#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */ -#define SCANCODE_PAGEDOWN 109 -#define SCANCODE_INSERT 110 -#define SCANCODE_REMOVE 111 - -#define SCANCODE_RIGHTWIN 126 -#define SCANCODE_LEFTWIN 125 -/* 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 new file mode 100644 index 000000000..b74effc9b --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_mouse.c @@ -0,0 +1,212 @@ +/* + 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" +#include "SDL_DirectFB_mouse.h" + +#include "../SDL_sysvideo.h" +#include "../../events/SDL_mouse_c.h" + +static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, + int hot_y); +static int DirectFB_ShowCursor(SDL_Cursor * cursor); +static void DirectFB_MoveCursor(SDL_Cursor * cursor); +static void DirectFB_FreeCursor(SDL_Cursor * cursor); +static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_WindowID windowID, + int x, int y); +static void DirectFB_FreeMouse(SDL_Mouse * mouse); + +void +DirectFB_InitMouse(_THIS) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_Mouse mouse; + + SDL_zero(mouse); + mouse.CreateCursor = DirectFB_CreateCursor; + mouse.ShowCursor = DirectFB_ShowCursor; + mouse.MoveCursor = DirectFB_MoveCursor; + mouse.FreeCursor = DirectFB_FreeCursor; + mouse.WarpMouse = DirectFB_WarpMouse; + mouse.FreeMouse = DirectFB_FreeMouse; + devdata->mouse = SDL_AddMouse(&mouse, -1); +} + +void +DirectFB_QuitMouse(_THIS) +{ + SDL_DFB_DEVICEDATA(_this); + + SDL_DelMouse(devdata->mouse); +} + +/* Create a cursor from a surface */ +static SDL_Cursor * +DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +{ + SDL_VideoDevice *dev = SDL_GetVideoDevice(); + + SDL_DFB_DEVICEDATA(dev); + DFB_CursorData *curdata; + DFBResult ret; + DFBSurfaceDescription dsc; + SDL_Cursor *cursor; + Uint32 *dest; + Uint32 *p; + int pitch, i; + + SDL_DFB_CALLOC(cursor, 1, sizeof(*cursor)); + SDL_DFB_CALLOC(curdata, 1, sizeof(*curdata)); + + dsc.flags = + DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; + dsc.caps = DSCAPS_NONE; //DSCAPS_SYSTEMONLY; + dsc.width = surface->w; + dsc.height = surface->h; + dsc.pixelformat = DSPF_ARGB; + + 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)); + + //FIXME: Implies a lot of things, e.g. rgba format for SDL_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]; + //memcpy(dest, surface->pixels, surface->w * surface->h * 4); + curdata->surf->Unlock(curdata->surf); + return cursor; + error: + return NULL; +} + +/* Show the specified cursor, or hide if cursor is NULL */ +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) + 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; + SDL_DFB_CHECKERR(windata->window-> + SetCursorShape(windata->window, curdata->surf, + curdata->hotx, curdata->hoty)); + //FIXME: This is somehow a directfb issue + SDL_DFB_CHECKERR(dispdata->layer-> + SetCooperativeLevel(dispdata->layer, + DLSCL_ADMINISTRATIVE)); + SDL_DFB_CHECKERR(dispdata->layer-> + SetCursorOpacity(dispdata->layer, 0xC0)); + SDL_DFB_CHECKERR(dispdata->layer-> + SetCooperativeLevel(dispdata->layer, DLSCL_SHARED)); + } +#if 0 + //TODO: Check administrative + SDL_DFB_CHECKERR(dispdata->layer-> + SetCooperativeLevel(dispdata->layer, + DLSCL_ADMINISTRATIVE)); + SDL_DFB_CHECKERR(dispdata->layer-> + SetCursorShape(dispdata->layer, curdata->surf, + curdata->hotx, curdata->hoty)); + SDL_DFB_CHECKERR(dispdata->layer-> + SetCursorOpacity(dispdata->layer, 0xC0)); + SDL_DFB_CHECKERR(dispdata->layer-> + SetCooperativeLevel(dispdata->layer, DLSCL_SHARED)); + +#endif + + return 0; + error: + return -1; +} + +/* This is called when a mouse motion event occurs */ +static void +DirectFB_MoveCursor(SDL_Cursor * cursor) +{ + SDL_DFB_CURSORDATA(cursor); + /* Do we need to do something here ? */ +} + +/* Free a window manager cursor */ +static void +DirectFB_FreeCursor(SDL_Cursor * cursor) +{ + SDL_DFB_CURSORDATA(cursor); + + SDL_DFB_RELEASE(curdata->surf); + SDL_DFB_FREE(cursor->driverdata); + SDL_DFB_FREE(cursor); +} + +/* Warp the mouse to (x,y) */ +static void +DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_WindowID windowID, int x, int y) +{ +// SDL_DFB_CURSORDATA(cursor); + SDL_Window *window = SDL_GetWindowFromID(windowID); + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); + DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; + DFB_WindowData *windata = (DFB_WindowData *) window->driverdata; + DFBResult ret; + 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)); + + error: + return; +} + +/* Free the mouse when it's time */ +static void +DirectFB_FreeMouse(SDL_Mouse * mouse) +{ + // nothing yet + +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_yuv.h b/src/video/directfb/SDL_DirectFB_mouse.h similarity index 58% rename from src/video/directfb/SDL_DirectFB_yuv.h rename to src/video/directfb/SDL_DirectFB_mouse.h index a2098a07d..c423d2c36 100644 --- a/src/video/directfb/SDL_DirectFB_yuv.h +++ b/src/video/directfb/SDL_DirectFB_mouse.h @@ -21,21 +21,23 @@ */ #include "SDL_config.h" -/* This is the DirectFB implementation of YUV video overlays */ +#ifndef _SDL_DirectFB_mouse_h +#define _SDL_DirectFB_mouse_h -#include "SDL_video.h" -#include "SDL_DirectFB_video.h" +typedef struct _DFB_CursorData DFB_CursorData; -extern SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height, - Uint32 format, - SDL_Surface * display); +struct _DFB_CursorData +{ + IDirectFBSurface *surf; + int hotx; + int hoty; +}; -extern int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay * overlay); +#define SDL_DFB_CURSORDATA(curs) DFB_CursorData *curdata = (DFB_CursorData *) ((curs)->driverdata) -extern void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay); +extern void DirectFB_InitMouse(_THIS); +extern void DirectFB_QuitMouse(_THIS); -extern int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, - SDL_Rect * src, SDL_Rect * dst); +#endif /* _SDL_DirectFB_mouse_h */ -extern void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay * overlay); /* 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 new file mode 100644 index 000000000..4b36e81de --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_render.c @@ -0,0 +1,737 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org + + SDL1.3 implementation by couriersud@arcor.de + +*/ +#include "SDL_config.h" + +#include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_render.h" +#include "../SDL_rect_c.h" +#include "../SDL_yuv_sw_c.h" + +/* GDI renderer implementation */ + +static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window, + Uint32 flags); +static int DirectFB_DisplayModeChanged(SDL_Renderer * renderer); +static int DirectFB_CreateTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer, + SDL_Texture * texture, void **pixels, + int *pitch); +static int DirectFB_SetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Color * colors, + int firstcolor, int ncolors); +static int DirectFB_GetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, + SDL_Color * colors, int firstcolor, + int ncolors); +static int DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DirectFB_SetTextureColorMod(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, + SDL_Texture * texture); +static int DirectFB_UpdateTexture(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch); +static int DirectFB_LockTexture(SDL_Renderer * renderer, + SDL_Texture * texture, const SDL_Rect * rect, + int markDirty, void **pixels, int *pitch); +static void DirectFB_UnlockTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void DirectFB_DirtyTexture(SDL_Renderer * renderer, + SDL_Texture * texture, int numrects, + const SDL_Rect * rects); +static int DirectFB_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, + Uint8 b, Uint8 a, const SDL_Rect * rect); +static int DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); +static void DirectFB_RenderPresent(SDL_Renderer * renderer); +static void DirectFB_DestroyTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void DirectFB_DestroyRenderer(SDL_Renderer * renderer); + +SDL_RenderDriver DirectFB_RenderDriver = { + DirectFB_CreateRenderer, + { + "directfb", + (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY | + SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 | + SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED), + (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR | + SDL_TEXTUREMODULATE_ALPHA), + (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK | + SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_MOD), + (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST), + 14, + { + SDL_PIXELFORMAT_INDEX8, + SDL_PIXELFORMAT_INDEX4LSB, + SDL_PIXELFORMAT_RGB332, + SDL_PIXELFORMAT_RGB555, + SDL_PIXELFORMAT_RGB565, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ARGB4444, + SDL_PIXELFORMAT_ARGB1555, + SDL_PIXELFORMAT_RGB24, + SDL_PIXELFORMAT_YV12, + SDL_PIXELFORMAT_IYUV, + SDL_PIXELFORMAT_YUY2, + SDL_PIXELFORMAT_UYVY}, + 0, + 0} +}; + +typedef struct +{ + IDirectFBSurface *surface; + DFBSurfaceFlipFlags flipflags; + int isyuvdirect; +} DirectFB_RenderData; + +typedef struct +{ + IDirectFBDisplayLayer *vidlayer; + IDirectFBSurface *surface; + Uint32 format; + void *pixels; + int pitch; + IDirectFBPalette *palette; +} DirectFB_TextureData; + +static void +UpdateYUVTextureData(SDL_Texture * texture) +{ + /* + * Not needed - directfb supports yuv surfaces + */ +} + +void +DirectFB_AddRenderDriver(_THIS) +{ + int i; + for (i = 0; i < _this->num_displays; i++) + SDL_AddRenderDriver(i, &DirectFB_RenderDriver); +} + +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->CreateTexture = DirectFB_CreateTexture; + renderer->QueryTexturePixels = DirectFB_QueryTexturePixels; + renderer->SetTexturePalette = DirectFB_SetTexturePalette; + renderer->GetTexturePalette = DirectFB_GetTexturePalette; + renderer->SetTextureAlphaMod = DirectFB_SetTextureAlphaMod; + renderer->SetTextureColorMod = DirectFB_SetTextureColorMod; + renderer->SetTextureBlendMode = DirectFB_SetTextureBlendMode; + renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode; + renderer->UpdateTexture = DirectFB_UpdateTexture; + renderer->LockTexture = DirectFB_LockTexture; + renderer->UnlockTexture = DirectFB_UnlockTexture; + renderer->DirtyTexture = DirectFB_DirtyTexture; + renderer->RenderFill = DirectFB_RenderFill; + renderer->RenderCopy = DirectFB_RenderCopy; + renderer->RenderPresent = DirectFB_RenderPresent; + renderer->DestroyTexture = DirectFB_DestroyTexture; + renderer->DestroyRenderer = DirectFB_DestroyRenderer; + renderer->info = DirectFB_RenderDriver.info; + renderer->window = window->id; // SDL window id + renderer->driverdata = data; + + renderer->info.flags = + SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD; + + data->surface = windata->surface; + data->flipflags = 0; + + if (flags & SDL_RENDERER_PRESENTVSYNC) { + data->flipflags = DSFLIP_ONSYNC; + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } + + data->surface->GetCapabilities(data->surface, &scaps); + if (scaps & DSCAPS_DOUBLE) + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; + else if (scaps & DSCAPS_TRIPLE) + renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; + else + renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER; + + data->isyuvdirect = 0; + p = getenv("SDL_DIRECTFB_YUV_DIRECT"); + if (p) + data->isyuvdirect = atoi(p); + + return renderer; + + error: + SDL_DFB_FREE(renderer); + SDL_DFB_FREE(data); + return NULL; +} + +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 int +DirectFB_DisplayModeChanged(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 + */ + return 0; + error: + return -1; +} + +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); + DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; + 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 (renddata->isyuvdirect && (dispdata->vidID >= 0) + && SDL_ISPIXELFORMAT_FOURCC(data->format)) { + SDL_DFB_CHECKERR(devdata->dfb-> + GetDisplayLayer(devdata->dfb, dispdata->vidID, + &data->vidlayer)); + layconf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT; + layconf.width = texture->w; + layconf.height = texture->h; + layconf.pixelformat = SDLToDFBPixelFormat(data->format); + + SDL_DFB_CHECKERR(data->vidlayer-> + SetCooperativeLevel(data->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)); + SDL_DFB_DEBUG("Created HW YUV surface\n"); + } + if (!data->vidlayer) { + /* fill surface description */ + dsc.flags = + DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; + dsc.width = texture->w; + dsc.height = texture->h; + /* Never use DSCAPS_VIDEOONLY here. It kills performance + * No DSCAPS_SYSTEMONLY either - let dfb decide + */ + dsc.caps = 0; //DSCAPS_PREMULTIPLIED; + + /* find the right pixelformat */ + + dsc.pixelformat = SDLToDFBPixelFormat(data->format); + if (dsc.pixelformat == DSPF_UNKNOWN) { + SDL_SetError("Unknown pixel format %d\n", data->format); + goto error; + } + + data->pixels = NULL; + + /* Create the surface */ + SDL_DFB_CHECKERR(devdata->dfb-> + CreateSurface(devdata->dfb, &dsc, &data->surface)); + if (SDL_ISPIXELFORMAT_INDEXED(data->format) + && !SDL_ISPIXELFORMAT_FOURCC(data->format)) { + SDL_DFB_CHECKERR(data->surface-> + GetPalette(data->surface, &data->palette)); + } + + } + return 0; + + error: + SDL_DFB_RELEASE(data->palette); + SDL_DFB_RELEASE(data->surface); + SDL_DFB_FREE(texture->driverdata); + return -1; +} + +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 ! + */ + + return -1; +} + +static int +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; + + if (SDL_ISPIXELFORMAT_INDEXED(data->format) + && !SDL_ISPIXELFORMAT_FOURCC(data->format)) { + DFBColor entries[256]; + int i; + + for (i = 0; i < ncolors; ++i) { + entries[i].r = colors[i].r; + entries[i].g = colors[i].g; + entries[i].b = colors[i].b; + entries[i].a = 0xFF; + } + SDL_DFB_CHECKERR(data->palette-> + SetEntries(data->palette, entries, ncolors, + firstcolor)); + return 0; + } else { + SDL_SetError("YUV textures don't have a palette"); + return -1; + } + error: + return -1; +} + +static int +DirectFB_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + SDL_Color * colors, int firstcolor, int ncolors) +{ + DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + DFBResult ret; + + if (SDL_ISPIXELFORMAT_INDEXED(data->format) + && !SDL_ISPIXELFORMAT_FOURCC(data->format)) { + DFBColor entries[256]; + int i; + + SDL_DFB_CHECKERR(data->palette-> + GetEntries(data->palette, entries, ncolors, + firstcolor)); + + for (i = 0; i < ncolors; ++i) { + colors[i].r = entries[i].r; + colors[i].g = entries[i].g; + colors[i].b = entries[i].b; + } + return 0; + } else { + SDL_SetError("YUV textures don't have a palette"); + return -1; + } + error: + return -1; +} + +static int +DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + return 0; +} + +static int +DirectFB_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + return 0; +} + +static int +DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) +{ + switch (texture->blendMode) { + case SDL_TEXTUREBLENDMODE_NONE: + case SDL_TEXTUREBLENDMODE_MASK: + case SDL_TEXTUREBLENDMODE_BLEND: + case SDL_TEXTUREBLENDMODE_MOD: + return 0; + default: + SDL_Unsupported(); + texture->blendMode = SDL_TEXTUREBLENDMODE_NONE; + return -1; + } +} + +static int +DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) +{ + switch (texture->scaleMode) { + case SDL_TEXTURESCALEMODE_NONE: + case SDL_TEXTURESCALEMODE_FAST: + return 0; + case SDL_TEXTURESCALEMODE_SLOW: + case SDL_TEXTURESCALEMODE_BEST: + SDL_Unsupported(); + texture->scaleMode = SDL_TEXTURESCALEMODE_FAST; + return -1; + default: + SDL_Unsupported(); + texture->scaleMode = SDL_TEXTURESCALEMODE_NONE; + return -1; + } + return 0; +} + +static int +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; + + if (data->pixels) { + Uint8 *src, *dst; + int row; + size_t length; + + src = (Uint8 *) pixels; + dst = + (Uint8 *) data->pixels + rect->y * data->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format); + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += data->pitch; + } + } else { + SDL_SetError("FIXME: Update without lock!\n"); + return -1; + } + return 0; +} + +static int +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; + 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; + } + + *pitch = data->pitch; + *pixels = data->pixels; + + return 0; + error: + return -1; +} + +static void +DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + + data->surface->Unlock(data->surface); + data->pixels = NULL; +} + +static void +DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, + int numrects, const SDL_Rect * rects) +{ + //TODO: DirtyTexture +} + +static int +DirectFB_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, + Uint8 a, const SDL_Rect * rect) +{ + DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; + DFBResult ret; + + SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, r, g, b, a)); + SDL_DFB_CHECKERR(data->surface-> + FillRectangle(data->surface, rect->x, rect->y, rect->w, + rect->h)); + + return 0; + error: + return -1; +} + +static int +DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect) +{ + DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; + DirectFB_TextureData *texturedata = + (DirectFB_TextureData *) texture->driverdata; + DFBResult ret; + + if (texturedata->vidlayer) { + 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_DFB_CHECKERR(texturedata->vidlayer-> + SetSourceRectangle(texturedata->vidlayer, srcrect->x, + srcrect->y, srcrect->w, + srcrect->h)); + windata->window->GetPosition(windata->window, &px, &py); + SDL_DFB_CHECKERR(texturedata->vidlayer-> + SetScreenRectangle(texturedata->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; + + dr.x = dstrect->x; + dr.y = dstrect->y; + dr.w = dstrect->w; + dr.h = dstrect->h; + + if (texture-> + modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA)) + { + u8 alpha = 0xFF; + if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) + alpha = texture->a; + if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) + SDL_DFB_CHECKERR(data->surface-> + SetColor(data->surface, texture->r, + texture->g, texture->b, alpha)); + else + SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF, + 0xFF, 0xFF, alpha)); + // Only works together .... + flags |= DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR; + } + + if (texture-> + blendMode & (SDL_TEXTUREBLENDMODE_MASK | + SDL_TEXTUREBLENDMODE_BLEND)) { + flags |= DSBLIT_BLEND_ALPHACHANNEL; + } else { + flags |= DSBLIT_NOFX; + } + 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)); + } else { + SDL_DFB_CHECKERR(data->surface-> + StretchBlit(data->surface, texturedata->surface, + &sr, &dr)); + } + } + return 0; + error: + return -1; +} + +static void +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; + + sr.x = 0; + sr.y = 0; + sr.w = window->w; + sr.h = window->h; + + /* Send the data to the display */ + SDL_DFB_CHECKERR(data->surface-> + Flip(data->surface, NULL, data->flipflags)); + + return; + error: + return; +} + +static void +DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + + if (!data) { + return; + } + SDL_DFB_RELEASE(data->palette); + SDL_DFB_RELEASE(data->surface); + SDL_DFB_RELEASE(data->vidlayer); + SDL_free(data); + texture->driverdata = NULL; +} + +static void +DirectFB_DestroyRenderer(SDL_Renderer * renderer) +{ + DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; + int i; + + if (data) { + data->surface = NULL; + SDL_free(data); + } + SDL_free(renderer); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_render.h b/src/video/directfb/SDL_DirectFB_render.h new file mode 100644 index 000000000..e0321437d --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_render.h @@ -0,0 +1,30 @@ +/* + 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" + +/* SDL surface based renderer implementation */ + +#define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL) + +extern void DirectFB_AddRenderDriver(_THIS); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_video.c b/src/video/directfb/SDL_DirectFB_video.c index 1722790aa..e29fdc4cd 100644 --- a/src/video/directfb/SDL_DirectFB_video.c +++ b/src/video/directfb/SDL_DirectFB_video.c @@ -19,10 +19,16 @@ Sam Lantinga slouken@libsdl.org - MGA CRTC2 support by Thomas Jarosch - tomj@simonv.com - CRTC2 support is inspired by mplayer's dfbmga driver - written by Ville Syrj�� + SDL1.3 implementation by couriersud@arcor.de + */ + +/* TODO: Various + * Add Mouse support from 1.2 directfb driver + * - Interface is defined in SDL_Mouse.c.h + * - Default Cursor automatically created + */ + #include "SDL_config.h" /* DirectFB video driver implementation. @@ -42,44 +48,6 @@ #include "../../events/SDL_events_c.h" #include "SDL_DirectFB_video.h" #include "SDL_DirectFB_events.h" -#include "SDL_DirectFB_yuv.h" - -/* The implementation dependent data for the window manager cursor */ -struct WMcursor -{ - int unused; -}; - - -/* Initialization/Query functions */ -static int DirectFB_VideoInit(_THIS, SDL_PixelFormat * vformat); -static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat * format, - Uint32 flags); -static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface * current, - int width, int height, int bpp, - Uint32 flags); -static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, - SDL_Color * colors); -static void DirectFB_VideoQuit(_THIS); - -/* Hardware surface functions */ -static int DirectFB_AllocHWSurface(_THIS, SDL_Surface * surface); -static int DirectFB_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect, - Uint32 color); -static int DirectFB_LockHWSurface(_THIS, SDL_Surface * surface); -static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface * surface); -static void DirectFB_FreeHWSurface(_THIS, SDL_Surface * surface); -static int DirectFB_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst); -static int DirectFB_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect); -static int DirectFB_SetHWColorKey(_THIS, SDL_Surface * surface, Uint32 key); -static int DirectFB_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha); -static int DirectFB_FlipHWSurface(_THIS, SDL_Surface * surface); -static int DirectFB_ShowWMCursor(_THIS, WMcursor * cursor); - -/* Various screen update functions available */ -static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect * rects); -static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect * rects); /* This is the rect EnumModes2 uses */ struct DirectFBEnumRect @@ -88,8 +56,51 @@ struct DirectFBEnumRect struct DirectFBEnumRect *next; }; -static struct DirectFBEnumRect *enumlist = NULL; +struct DirectFB_GLContext +{ + IDirectFBGL *context; +}; + +/* Initialization/Query functions */ +static int DirectFB_VideoInit(_THIS); +static void DirectFB_VideoQuit(_THIS); + +static int DirectFB_CreateWindow(_THIS, SDL_Window * window); +static int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, + const void *data); +static void DirectFB_SetWindowTitle(_THIS, SDL_Window * window); +static void DirectFB_SetWindowPosition(_THIS, SDL_Window * window); +static void DirectFB_SetWindowSize(_THIS, SDL_Window * window); +static void DirectFB_ShowWindow(_THIS, SDL_Window * window); +static void DirectFB_HideWindow(_THIS, SDL_Window * window); +static void DirectFB_RaiseWindow(_THIS, SDL_Window * window); +static void DirectFB_MaximizeWindow(_THIS, SDL_Window * window); +static void DirectFB_MinimizeWindow(_THIS, SDL_Window * window); +static void DirectFB_RestoreWindow(_THIS, SDL_Window * window); +static void DirectFB_SetWindowGrab(_THIS, SDL_Window * window); +static void DirectFB_DestroyWindow(_THIS, SDL_Window * window); +static SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +static void DirectFB_GetDisplayModes(_THIS); +static int DirectFB_SetDisplayMode(_THIS, SDL_DisplayMode * mode); + +static int DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp); +static int DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp); + +#if SDL_DIRECTFB_OPENGL +static int DirectFB_GL_LoadLibrary(_THIS, const char *path); +static void DirectFB_GL_UnloadLibrary(_THIS); +static void *DirectFB_GL_GetProcAddress(_THIS, const char *proc); +static SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window); +static int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, + SDL_GLContext context); +static int DirectFB_GL_SetSwapInterval(_THIS, int interval); +static int DirectFB_GL_GetSwapInterval(_THIS); +static void DirectFB_GL_SwapWindow(_THIS, SDL_Window * window); +static void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context); +#endif /* DirectFB driver bootstrap functions */ @@ -102,7 +113,7 @@ DirectFB_Available(void) static void DirectFB_DeleteDevice(SDL_VideoDevice * device) { - SDL_free(device->hidden); + SDL_free(device->driverdata); SDL_free(device); } @@ -112,50 +123,60 @@ DirectFB_CreateDevice(int devindex) SDL_VideoDevice *device; /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice)); - if (device) { - SDL_memset(device, 0, (sizeof *device)); - device->hidden = (struct SDL_PrivateVideoData *) - malloc(sizeof(*device->hidden)); - } - if (device == NULL || device->hidden == NULL) { - SDL_OutOfMemory(); - if (device) { - free(device); - } - return (0); - } - SDL_memset(device->hidden, 0, sizeof(*device->hidden)); + SDL_DFB_CALLOC(device, 1, sizeof(SDL_VideoDevice)); + SDL_DFB_CALLOC(device->gl_data, 1, sizeof(*device->gl_data)); + + /* Set the function pointers */ /* Set the function pointers */ device->VideoInit = DirectFB_VideoInit; - device->ListModes = DirectFB_ListModes; - device->SetVideoMode = DirectFB_SetVideoMode; - device->SetColors = DirectFB_SetColors; - device->UpdateRects = NULL; - device->CreateYUVOverlay = DirectFB_CreateYUVOverlay; device->VideoQuit = DirectFB_VideoQuit; - device->AllocHWSurface = DirectFB_AllocHWSurface; - device->CheckHWBlit = DirectFB_CheckHWBlit; - device->FillHWRect = DirectFB_FillHWRect; - device->SetHWColorKey = DirectFB_SetHWColorKey; - device->SetHWAlpha = DirectFB_SetHWAlpha; - device->LockHWSurface = DirectFB_LockHWSurface; - device->UnlockHWSurface = DirectFB_UnlockHWSurface; - device->FlipHWSurface = DirectFB_FlipHWSurface; - device->FreeHWSurface = DirectFB_FreeHWSurface; - device->ShowWMCursor = DirectFB_ShowWMCursor; - device->SetCaption = NULL; - device->SetIcon = NULL; - device->IconifyWindow = NULL; - device->GrabInput = NULL; - device->GetWMInfo = NULL; - device->InitOSKeymap = DirectFB_InitOSKeymap; - device->PumpEvents = DirectFB_PumpEvents; + device->GetDisplayModes = DirectFB_GetDisplayModes; + device->SetDisplayMode = DirectFB_SetDisplayMode; +#if 0 + device->SetDisplayGammaRamp = DirectFB_SetDisplayGammaRamp; + device->GetDisplayGammaRamp = DirectFB_GetDisplayGammaRamp; +#else + device->SetDisplayGammaRamp = NULL; + device->GetDisplayGammaRamp = NULL; +#endif + device->PumpEvents = DirectFB_PumpEventsWindow; + + device->CreateWindow = DirectFB_CreateWindow; + device->CreateWindowFrom = DirectFB_CreateWindowFrom; + device->SetWindowTitle = DirectFB_SetWindowTitle; + device->SetWindowPosition = DirectFB_SetWindowPosition; + device->SetWindowSize = DirectFB_SetWindowSize; + device->ShowWindow = DirectFB_ShowWindow; + device->HideWindow = DirectFB_HideWindow; + device->RaiseWindow = DirectFB_RaiseWindow; + device->MaximizeWindow = DirectFB_MaximizeWindow; + device->MinimizeWindow = DirectFB_MinimizeWindow; + device->RestoreWindow = DirectFB_RestoreWindow; + device->SetWindowGrab = DirectFB_SetWindowGrab; + device->DestroyWindow = DirectFB_DestroyWindow; + device->GetWindowWMInfo = DirectFB_GetWindowWMInfo; + +#if SDL_DIRECTFB_OPENGL + device->GL_LoadLibrary = DirectFB_GL_LoadLibrary; + device->GL_GetProcAddress = DirectFB_GL_GetProcAddress; + device->GL_MakeCurrent = DirectFB_GL_MakeCurrent; + + device->GL_CreateContext = DirectFB_GL_CreateContext; + device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval; + device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval; + device->GL_SwapWindow = DirectFB_GL_SwapWindow; + device->GL_DeleteContext = DirectFB_GL_DeleteContext; + +#endif device->free = DirectFB_DeleteDevice; return device; + error: + if (device) + free(device); + return (0); } VideoBootStrap DirectFB_bootstrap = { @@ -163,214 +184,107 @@ VideoBootStrap DirectFB_bootstrap = { DirectFB_Available, DirectFB_CreateDevice }; -static DFBSurfacePixelFormat -GetFormatForBpp(int bpp, IDirectFBDisplayLayer * layer) -{ - DFBDisplayLayerConfig dlc; - int bytes = (bpp + 7) / 8; - - layer->GetConfiguration(layer, &dlc); - - if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1) - return dlc.pixelformat; - - switch (bytes) { - case 1: - return DSPF_LUT8; - case 2: - return DSPF_RGB16; - case 3: - return DSPF_RGB24; - case 4: - return DSPF_RGB32; - } - - return DSPF_UNKNOWN; -} - static DFBEnumerationResult EnumModesCallback(int width, int height, int bpp, void *data) { - SDL_VideoDevice *this = (SDL_VideoDevice *) data; - struct DirectFBEnumRect *enumrect; - - HIDDEN->nummodes++; - - if (enumlist && enumlist->r.w == width && enumlist->r.h == height) - return DFENUM_OK; - - enumrect = SDL_calloc(1, sizeof(struct DirectFBEnumRect)); - if (!enumrect) { - SDL_OutOfMemory(); - return DFENUM_CANCEL; + 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; } - enumrect->r.w = (Uint16) width; - enumrect->r.h = (Uint16) height; - enumrect->next = enumlist; - - enumlist = enumrect; - + SDL_DFB_DEBUG("w %d h %d bpp %d\n", width, height, bpp); return DFENUM_OK; } -struct private_hwdata -{ - IDirectFBSurface *surface; - IDirectFBPalette *palette; -}; - -void -SetDirectFBerror(const char *function, DFBResult code) -{ - const char *error = DirectFBErrorString(code); - - if (error) - SDL_SetError("%s: %s", function, error); - else - SDL_SetError("Unknown error code from %s", function); -} - -static DFBSurfacePixelFormat -SDLToDFBPixelFormat(SDL_PixelFormat * format) -{ - if (format->Rmask && format->Gmask && format->Bmask) { - switch (format->BitsPerPixel) { - case 8: - return DSPF_LUT8; - - case 16: - if (format->Rmask == 0xF800 && - format->Gmask == 0x07E0 && format->Bmask == 0x001F) - return DSPF_RGB16; - /* fall through */ - - case 15: - if (format->Rmask == 0x7C00 && - format->Gmask == 0x03E0 && format->Bmask == 0x001F) - return DSPF_ARGB1555; - break; - - case 24: - if (format->Rmask == 0xFF0000 && - format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF) - return DSPF_RGB24; - break; - - case 32: - if (format->Rmask == 0xFF0000 && - format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF) { - if (format->Amask == 0xFF000000) - return DSPF_ARGB; - else - return DSPF_RGB32; - } - break; - } - } else { - switch (format->BitsPerPixel) { - case 8: - return DSPF_LUT8; - case 15: - return DSPF_ARGB1555; - case 16: - return DSPF_RGB16; - case 24: - return DSPF_RGB24; - case 32: - return DSPF_RGB32; - } - } - - return DSPF_UNKNOWN; -} - -static SDL_Palette * -AllocatePalette(int size) -{ - SDL_Palette *palette; - SDL_Color *colors; - - palette = SDL_calloc(1, sizeof(SDL_Palette)); - if (!palette) { - SDL_OutOfMemory(); - return NULL; - } - - colors = SDL_calloc(size, sizeof(SDL_Color)); - if (!colors) { - SDL_OutOfMemory(); - return NULL; - } - - palette->ncolors = size; - palette->colors = colors; - - return palette; -} - static int -DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat, - SDL_PixelFormat * format) +DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat, Uint32 * fmt) { - format->Amask = format->Rmask = format->Gmask = format->Bmask = 0; - format->BitsPerPixel = format->BytesPerPixel = 0; - switch (pixelformat) { - case DSPF_A8: - format->Amask = 0x000000FF; + case DSPF_ALUT44: + *fmt = SDL_PIXELFORMAT_INDEX4LSB; break; - - case DSPF_ARGB1555: - format->Rmask = 0x00007C00; - format->Gmask = 0x000003E0; - format->Bmask = 0x0000001F; + 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: - format->Rmask = 0x0000F800; - format->Gmask = 0x000007E0; - format->Bmask = 0x0000001F; + *fmt = SDL_PIXELFORMAT_RGB565; break; - - case DSPF_ARGB: - format->Amask = 0; /* apps don't seem to like that: 0xFF000000; */ - /* fall through */ case DSPF_RGB24: + *fmt = SDL_PIXELFORMAT_RGB24; + break; case DSPF_RGB32: - format->Rmask = 0x00FF0000; - format->Gmask = 0x0000FF00; - format->Bmask = 0x000000FF; + *fmt = SDL_PIXELFORMAT_RGB888; break; - - case DSPF_LUT8: - format->Rmask = 0x000000FF; - format->Gmask = 0x000000FF; - format->Bmask = 0x000000FF; - - if (!format->palette) - format->palette = AllocatePalette(256); + 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: - fprintf(stderr, - "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n", - pixelformat); return -1; } + return 0; +} - format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8; - format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat); +static DFBEnumerationResult +cbScreens(DFBScreenID screen_id, DFBScreenDescription desc, + void *callbackdata) +{ + DFB_DeviceData *devdata = (DFB_DeviceData *) callbackdata; - return 0; + 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; +} -int -DirectFB_VideoInit(_THIS, SDL_PixelFormat * vformat) +static int +DirectFB_VideoInit(_THIS) { - int i; - DFBResult ret; #if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23) DFBCardCapabilities caps; #else @@ -380,801 +294,816 @@ DirectFB_VideoInit(_THIS, SDL_PixelFormat * vformat) struct DirectFBEnumRect *rect; IDirectFB *dfb = NULL; IDirectFBDisplayLayer *layer = NULL; - IDirectFBEventBuffer *events = NULL; - - HIDDEN->c2layer = NULL, HIDDEN->c2frame = NULL; - HIDDEN->enable_mga_crtc2 = 0; - HIDDEN->mga_crtc2_stretch_overscan = 1; - ret = DirectFBInit(NULL, NULL); - if (ret) { - SetDirectFBerror("DirectFBInit", ret); - goto error; - } + SDL_VideoDisplay display; + DFB_DisplayData *dispdata; + DFB_DeviceData *devdata; + SDL_DisplayMode mode; + SDL_Keyboard keyboard; + int i; + DFBResult ret; + int tcw[DFB_MAX_SCREENS]; + int tch[DFB_MAX_SCREENS]; - ret = DirectFBCreate(&dfb); - if (ret) { - SetDirectFBerror("DirectFBCreate", ret); - goto error; - } + SDL_zero(keyboard); - ret = dfb->GetDisplayLayer(dfb, DLID_PRIMARY, &layer); - if (ret) { - SetDirectFBerror("dfb->GetDisplayLayer", ret); - goto error; - } + SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL)); + SDL_DFB_CHECKERR(DirectFBCreate(&dfb)); - ret = dfb->CreateInputEventBuffer(dfb, DICAPS_ALL, DFB_FALSE, &events); - if (ret) { - SetDirectFBerror("dfb->CreateEventBuffer", ret); - goto error; + 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; - layer->EnableCursor(layer, 1); + SDL_DFB_CHECKERR(dfb->GetScreen(dfb, devdata->screenid[i], &screen)); - /* Query layer configuration to determine the current mode and pixelformat */ - layer->GetConfiguration(layer, &dlc); + devdata->aux = i; + SDL_DFB_CHECKERR(screen-> + EnumDisplayLayers(screen, &cbLayers, devdata)); + screen->GetSize(screen, &tcw[i], &tch[i]); + screen->Release(screen); + } - /* If current format is not supported use LUT8 as the default */ - if (DFBToSDLPixelFormat(dlc.pixelformat, vformat)) - DFBToSDLPixelFormat(DSPF_LUT8, vformat); + /* Query card capabilities */ - /* Enumerate the available fullscreen modes */ - ret = dfb->EnumVideoModes(dfb, EnumModesCallback, this); - if (ret) { - SetDirectFBerror("dfb->EnumVideoModes", ret); - goto error; - } + dfb->GetDeviceDescription(dfb, &caps); - HIDDEN->modelist = SDL_calloc(HIDDEN->nummodes + 1, sizeof(SDL_Rect *)); - if (!HIDDEN->modelist) { - SDL_OutOfMemory(); - goto error; - } + 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, rect = enumlist; rect; ++i, rect = rect->next) { - HIDDEN->modelist[i] = &rect->r; - } + 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) ); - HIDDEN->modelist[i] = NULL; + 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); - /* Query card capabilities to get the video memory size */ -#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23) - dfb->GetCardCapabilities(dfb, &caps); -#else - dfb->GetDeviceDescription(dfb, &caps); -#endif + DFBToSDLPixelFormat(dlc.pixelformat, &mode.format); - this->info.wm_available = 1; - this->info.hw_available = 1; - this->info.blit_hw = 1; - this->info.blit_hw_CC = 1; - this->info.blit_hw_A = 1; - this->info.blit_fill = 1; - this->info.video_mem = caps.video_memory / 1024; - this->info.current_w = dlc.width; - this->info.current_h = dlc.height; - - HIDDEN->initialized = 1; - HIDDEN->dfb = dfb; - HIDDEN->layer = layer; - HIDDEN->eventbuffer = events; - - if (SDL_getenv("SDL_DIRECTFB_MGA_CRTC2") != NULL) - HIDDEN->enable_mga_crtc2 = 1; - - if (HIDDEN->enable_mga_crtc2) { - DFBDisplayLayerConfig dlc; - DFBDisplayLayerConfigFlags failed; - - ret = dfb->GetDisplayLayer(dfb, 2, &HIDDEN->c2layer); - if (ret) { - SetDirectFBerror("dfb->GetDisplayLayer(CRTC2)", ret); - goto error; - } + mode.w = dlc.width; + mode.h = dlc.height; + mode.refresh_rate = 0; + mode.driverdata = NULL; - ret = - HIDDEN->layer->SetCooperativeLevel(HIDDEN->layer, - DLSCL_EXCLUSIVE); - if (ret) { - SetDirectFBerror - ("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret); - goto error; - } + SDL_DFB_CALLOC(dispdata, 1, sizeof(*dispdata)); - ret = - HIDDEN->c2layer->SetCooperativeLevel(HIDDEN->c2layer, - DLSCL_EXCLUSIVE); - if (ret) { - SetDirectFBerror - ("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret); - goto error; - } + dispdata->layer = layer; + dispdata->pixelformat = dlc.pixelformat; + dispdata->cw = tcw[i]; + dispdata->ch = tch[i]; - HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0x0); + /* YUV - Video layer */ - /* Init the surface here as it got a fixed size */ - dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; - dlc.buffermode = DLBM_BACKVIDEO; - dlc.pixelformat = DSPF_RGB32; + dispdata->vidID = devdata->vidlayer[i]; - ret = - HIDDEN->c2layer->TestConfiguration(HIDDEN->c2layer, &dlc, - &failed); - if (ret) { - SetDirectFBerror("c2layer->TestConfiguration", ret); - goto error; - } + SDL_zero(display); - ret = HIDDEN->c2layer->SetConfiguration(HIDDEN->c2layer, &dlc); - if (ret) { - SetDirectFBerror("c2layer->SetConfiguration", ret); - goto error; - } + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = dispdata; - ret = HIDDEN->c2layer->GetSurface(HIDDEN->c2layer, &HIDDEN->c2frame); - if (ret) { - SetDirectFBerror("c2layer->GetSurface", ret); - goto error; - } + /* Enumerate the available fullscreen modes */ + SDL_DFB_CALLOC(dispdata->modelist, DFB_MAX_MODES, + sizeof(SDL_DisplayMode)); + SDL_DFB_CHECKERR(dfb-> + EnumVideoModes(dfb, EnumModesCallback, &display)); - HIDDEN->c2framesize.x = 0; - HIDDEN->c2framesize.y = 0; - HIDDEN->c2frame->GetSize(HIDDEN->c2frame, &HIDDEN->c2framesize.w, - &HIDDEN->c2framesize.h); - - HIDDEN->c2frame->SetBlittingFlags(HIDDEN->c2frame, DSBLIT_NOFX); - HIDDEN->c2frame->SetColor(HIDDEN->c2frame, 0, 0, 0, 0xff); - - /* Clear CRTC2 */ - HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff); - HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0); - HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff); - HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0); - HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff); - - HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0xFF); - - /* Check if overscan is possibly set */ - if (SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN") != NULL) { - float overscan = 0; - if (SDL_sscanf - (SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN"), "%f", - &overscan) == 1) - if (overscan > 0 && overscan < 2) - HIDDEN->mga_crtc2_stretch_overscan = overscan; - } -#ifdef DIRECTFB_CRTC2_DEBUG - printf("CRTC2 overscan: %f\n", HIDDEN->mga_crtc2_stretch_overscan); -#endif + SDL_AddVideoDisplay(&display); } - return 0; + devdata->initialized = 1; + devdata->dfb = dfb; + devdata->firstwin = NULL; - error: - if (events) - events->Release(events); + _this->driverdata = devdata; - if (HIDDEN->c2frame) - HIDDEN->c2frame->Release(HIDDEN->c2frame); - if (HIDDEN->c2layer) - HIDDEN->c2layer->Release(HIDDEN->c2layer); +#if SDL_DIRECTFB_OPENGL + /* Opengl */ + _this->gl_data->gl_active = 0; + _this->gl_data->gl_context = NULL; +#endif - if (layer) - layer->Release(layer); + DirectFB_AddRenderDriver(_this); + DirectFB_InitMouse(_this); + //devdata->mouse = SDL_AddMouse(&mouse, -1); + devdata->keyboard = SDL_AddKeyboard(&keyboard, -1); + DirectFB_InitOSKeymap(_this); - if (dfb) - dfb->Release(dfb); + return 0; - return -1; -} -static SDL_Rect ** -DirectFB_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags) -{ - if (flags & SDL_FULLSCREEN) - return HIDDEN->modelist; - else if (SDLToDFBPixelFormat(format) != DSPF_UNKNOWN) - return (SDL_Rect **) - 1; - - return NULL; + error: + //FIXME: Cleanup not complete, Free existing displays + SDL_DFB_FREE(dispdata); + SDL_DFB_FREE(dispdata->modelist); + SDL_DFB_RELEASE(layer); + SDL_DFB_RELEASE(dfb); + return -1; } -static SDL_Surface * -DirectFB_SetVideoMode(_THIS, SDL_Surface * current, int width, int height, - int bpp, Uint32 flags) +static void +DirectFB_VideoQuit(_THIS) { + DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata; + SDL_DisplayMode tmode; DFBResult ret; - DFBSurfaceDescription dsc; - DFBSurfacePixelFormat pixelformat; - IDirectFBSurface *surface; - - fprintf(stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n", - width, height, bpp, flags); - - flags |= SDL_FULLSCREEN; - - /* Release previous primary surface */ - if (current->hwdata && current->hwdata->surface) { - current->hwdata->surface->Release(current->hwdata->surface); - current->hwdata->surface = NULL; - - /* And its palette if present */ - if (current->hwdata->palette) { - current->hwdata->palette->Release(current->hwdata->palette); - current->hwdata->palette = NULL; - } - } else if (!current->hwdata) { - /* Allocate the hardware acceleration data */ - current->hwdata = - (struct private_hwdata *) SDL_calloc(1, sizeof(*current->hwdata)); - if (!current->hwdata) { - SDL_OutOfMemory(); - return NULL; - } - } + int i; - /* Set cooperative level depending on flag SDL_FULLSCREEN */ - if (flags & SDL_FULLSCREEN) { - ret = HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_FULLSCREEN); - if (ret && !HIDDEN->enable_mga_crtc2) { - DirectFBError("dfb->SetCooperativeLevel", ret); - flags &= ~SDL_FULLSCREEN; - } - } else - HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_NORMAL); - - /* Set video mode */ - ret = HIDDEN->dfb->SetVideoMode(HIDDEN->dfb, width, height, bpp); - if (ret) { - if (flags & SDL_FULLSCREEN) { - flags &= ~SDL_FULLSCREEN; - HIDDEN->dfb->SetCooperativeLevel(HIDDEN->dfb, DFSCL_NORMAL); - ret = HIDDEN->dfb->SetVideoMode(HIDDEN->dfb, width, height, bpp); + 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); - if (ret) { - SetDirectFBerror("dfb->SetVideoMode", ret); - return NULL; + /* Free video mode list */ + if (dispdata->modelist) { + SDL_free(dispdata->modelist); + dispdata->modelist = NULL; } + // Done by core + //SDL_free(dispdata); } - /* Create primary surface */ - dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT; - dsc.caps = - DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0); - dsc.pixelformat = GetFormatForBpp(bpp, HIDDEN->layer); - - ret = HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc, &surface); - if (ret && (flags & SDL_DOUBLEBUF)) { - /* Try without double buffering */ - dsc.caps &= ~DSCAPS_FLIPPING; - ret = HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc, &surface); - } - if (ret) { - SetDirectFBerror("dfb->CreateSurface", ret); - return NULL; - } + //SDL_DFB_RELEASE(devdata->eventbuffer); - current->w = width; - current->h = height; - current->flags = SDL_HWSURFACE | SDL_PREALLOC; + SDL_DFB_RELEASE(devdata->dfb); - if (flags & SDL_FULLSCREEN) { - current->flags |= SDL_FULLSCREEN; - this->UpdateRects = DirectFB_DirectUpdate; - } else - this->UpdateRects = DirectFB_WindowedUpdate; + SDL_DelMouse(devdata->mouse); + SDL_DelKeyboard(devdata->keyboard); - if (dsc.caps & DSCAPS_FLIPPING) - current->flags |= SDL_DOUBLEBUF; - - surface->GetPixelFormat(surface, &pixelformat); +#if SDL_DIRECTFB_OPENGL + DirectFB_GL_UnloadLibrary(_this); +#endif - DFBToSDLPixelFormat(pixelformat, current->format); + devdata->initialized = 0; +} - /* Get the surface palette (if supported) */ - if (DFB_PIXELFORMAT_IS_INDEXED(pixelformat)) { - surface->GetPalette(surface, ¤t->hwdata->palette); - current->flags |= SDL_HWPALETTE; +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; } +} - current->hwdata->surface = surface; - - /* MGA CRTC2 stuff */ - if (HIDDEN->enable_mga_crtc2) { - /* no stretching if c2ssize == c2framesize */ - HIDDEN->c2ssize.x = 0, HIDDEN->c2ssize.y = 0; - HIDDEN->c2ssize.w = width; - HIDDEN->c2ssize.h = height; - - HIDDEN->c2dsize.x = 0, HIDDEN->c2dsize.y = 0; - HIDDEN->c2dsize.w = width; - HIDDEN->c2dsize.h = height; - - HIDDEN->mga_crtc2_stretch = 0; - - if (SDL_getenv("SDL_DIRECTFB_MGA_STRETCH") != NULL) { - /* Normally assume a picture aspect ratio of 4:3 */ - int zoom_aspect_x = 4, zoom_aspect_y = 3, i, j; - - for (i = 1; i < 20; i++) { - for (j = 1; j < 10; j++) { - if ((float) width / (float) i * (float) j == height) { - zoom_aspect_x = i; - zoom_aspect_y = j; - - /* break the loop */ - i = 21; - break; - } - } - } - -#ifdef DIRECTFB_CRTC2_DEBUG - printf - ("Source resolution: X: %d, Y: %d, Aspect ratio: %d:%d\n", - width, height, zoom_aspect_x, zoom_aspect_y); - printf("CRTC2 resolution: X: %d, Y: %d\n", - HIDDEN->c2framesize.w, HIDDEN->c2framesize.h); -#endif - - /* don't stretch only slightly smaller/larger images */ - if ((float) width < (float) HIDDEN->c2framesize.w * 0.95 - || (float) height < (float) HIDDEN->c2framesize.h * 0.95) { - while ((float) HIDDEN->c2dsize.w < - (float) HIDDEN->c2framesize.w * - HIDDEN->mga_crtc2_stretch_overscan - && (float) HIDDEN->c2dsize.h < - (float) HIDDEN->c2framesize.h * - HIDDEN->mga_crtc2_stretch_overscan) { - HIDDEN->c2dsize.w += zoom_aspect_x; - HIDDEN->c2dsize.h += zoom_aspect_y; - } - - /* one step down */ - HIDDEN->c2dsize.w -= zoom_aspect_x; - HIDDEN->c2dsize.h -= zoom_aspect_y; - -#ifdef DIRECTFB_CRTC2_DEBUG - printf("Stretched resolution: X: %d, Y: %d\n", - HIDDEN->c2dsize.w, HIDDEN->c2dsize.h); -#endif +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); - HIDDEN->mga_crtc2_stretch = 1; - } else if ((float) width > (float) HIDDEN->c2framesize.w * 0.95 - || (float) height > - (float) HIDDEN->c2framesize.h * 0.95) { - while ((float) HIDDEN->c2dsize.w > - (float) HIDDEN->c2framesize.w * - HIDDEN->mga_crtc2_stretch_overscan - || (float) HIDDEN->c2dsize.h > - (float) HIDDEN->c2framesize.h * - HIDDEN->mga_crtc2_stretch_overscan) { - HIDDEN->c2dsize.w -= zoom_aspect_x; - HIDDEN->c2dsize.h -= zoom_aspect_y; - } - -#ifdef DIRECTFB_CRTC2_DEBUG - printf("Down-Stretched resolution: X: %d, Y: %d\n", - HIDDEN->c2dsize.w, HIDDEN->c2dsize.h); -#endif +} - HIDDEN->mga_crtc2_stretch = 1; - } else { -#ifdef DIRECTFB_CRTC2_DEBUG - printf("Not stretching image\n"); -#endif - } +static void +DirectFB_GetDisplayModes(_THIS) +{ + //SDL_DisplayData *data = (SDL_DisplayData *) SDL_CurrentDisplay.driverdata; + //SDL_DisplayMode mode; + //SDL_AddDisplayMode(_this->current_display, &mode); - /* Panning */ - if (HIDDEN->c2framesize.w > HIDDEN->c2dsize.w) - HIDDEN->c2dsize.x = - (HIDDEN->c2framesize.w - HIDDEN->c2dsize.w) / 2; - else - HIDDEN->c2dsize.x = - (HIDDEN->c2dsize.w - HIDDEN->c2framesize.w) / 2; - - if (HIDDEN->c2framesize.h > HIDDEN->c2dsize.h) - HIDDEN->c2dsize.y = - (HIDDEN->c2framesize.h - HIDDEN->c2dsize.h) / 2; - else - HIDDEN->c2dsize.y = - (HIDDEN->c2dsize.h - HIDDEN->c2framesize.h) / 2; - -#ifdef DIRECTFB_CRTC2_DEBUG - printf("CRTC2 position X: %d, Y: %d\n", HIDDEN->c2dsize.x, - HIDDEN->c2dsize.y); -#endif - } + 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); } - - return current; } -static int -DirectFB_AllocHWSurface(_THIS, SDL_Surface * surface) +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; - DFBSurfaceDescription dsc; - /* fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n", - surface->w, surface->h, surface->format->BitsPerPixel, surface->flags); */ + SDL_DFB_CHECKERR(data->layer-> + SetCooperativeLevel(data->layer, DLSCL_ADMINISTRATIVE)); - if (surface->w < 8 || surface->h < 8) - return -1; + 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; - /* fill surface description */ - dsc.flags = - DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; - dsc.width = surface->w; - dsc.height = surface->h; - dsc.caps = (surface->flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0; + config.buffermode = DLBM_BACKVIDEO; - /* find the right pixelformat */ - dsc.pixelformat = SDLToDFBPixelFormat(surface->format); - if (dsc.pixelformat == DSPF_UNKNOWN) - return -1; + //config.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer); - /* Allocate the hardware acceleration data */ - surface->hwdata = - (struct private_hwdata *) SDL_calloc(1, sizeof(*surface->hwdata)); - if (surface->hwdata == NULL) { - SDL_OutOfMemory(); + 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; } - - /* Create the surface */ - ret = - HIDDEN->dfb->CreateSurface(HIDDEN->dfb, &dsc, - &surface->hwdata->surface); - if (ret) { - SetDirectFBerror("dfb->CreateSurface", ret); - free(surface->hwdata); - surface->hwdata = NULL; + SDL_DFB_DEBUG("Trace\n"); + config.flags &= ~fail; + SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config)); + SDL_DFB_CHECKERR(data->layer-> + SetCooperativeLevel(data->layer, DLSCL_ADMINISTRATIVE)); + + /* Double check */ + SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig)); + + if ((config.width != rconfig.width) || + (config.height != rconfig.height) || + (config.pixelformat != rconfig.pixelformat)) { + SDL_DFB_DEBUG("Error setting mode %dx%d-%x\n", mode->w, mode->h, + mode->format); return -1; } - surface->flags |= SDL_HWSURFACE | SDL_PREALLOC; - return 0; + error: + return -1; } -static void -DirectFB_FreeHWSurface(_THIS, SDL_Surface * surface) +static int +DirectFB_SetDisplayGammaRamp(_THIS, Uint16 * ramp) { - if (surface->hwdata && HIDDEN->initialized) { - surface->hwdata->surface->Release(surface->hwdata->surface); - free(surface->hwdata); - surface->hwdata = NULL; - } + return -1; } static int -DirectFB_CheckHWBlit(_THIS, SDL_Surface * src, SDL_Surface * dst) +DirectFB_GetDisplayGammaRamp(_THIS, Uint16 * ramp) { - /* fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n", - src->hwdata, dst->hwdata); */ - - if (!src->hwdata || !dst->hwdata) - return 0; - - src->flags |= SDL_HWACCEL; - src->map->hw_blit = DirectFB_HWAccelBlit; - - return 1; + return -1; } static int -DirectFB_HWAccelBlit(SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) +DirectFB_CreateWindow(_THIS, SDL_Window * window) { - DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; + 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; + } - DFBRectangle sr = { srcrect->x, srcrect->y, srcrect->w, srcrect->h }; - DFBRectangle dr = { dstrect->x, dstrect->y, dstrect->w, dstrect->h }; + desc.flags = + DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_CAPS | DWDESC_PIXELFORMAT; + desc.flags |= DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS; + desc.posx = x; + desc.posy = y; + desc.width = window->w; + desc.height = window->h; - IDirectFBSurface *surface = dst->hwdata->surface; + desc.pixelformat = dispdata->pixelformat; - if (src->flags & SDL_SRCCOLORKEY) { - flags |= DSBLIT_SRC_COLORKEY; - DirectFB_SetHWColorKey(NULL, src, src->format->colorkey); - } + desc.caps = 0; //DWCAPS_DOUBLEBUFFER; + desc.surface_caps = DSCAPS_DOUBLE | DSCAPS_TRIPLE; //| DSCAPS_PREMULTIPLIED; - if (src->flags & SDL_SRCALPHA) { - flags |= DSBLIT_BLEND_COLORALPHA; - surface->SetColor(surface, 0xff, 0xff, 0xff, src->format->alpha); - } + /* Create the window. */ + SDL_DFB_CHECKERR(dispdata->layer-> + CreateWindow(dispdata->layer, &desc, &windata->window)); - surface->SetBlittingFlags(surface, flags); + windata->window->GetOptions(windata->window, &wopts); +#if (DIRECTFB_MAJOR_VERSION == 1) && (DIRECTFB_MINOR_VERSION >= 0) - if (sr.w == dr.w && sr.h == dr.h) - surface->Blit(surface, src->hwdata->surface, &sr, dr.x, dr.y); + if (window->flags & SDL_WINDOW_RESIZABLE) + wopts |= DWOP_SCALE; else - surface->StretchBlit(surface, src->hwdata->surface, &sr, &dr); + 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_FillHWRect(_THIS, SDL_Surface * dst, SDL_Rect * dstrect, - Uint32 color) +DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { - SDL_PixelFormat *fmt = dst->format; - IDirectFBSurface *surface = dst->hwdata->surface; - - /* ugly */ - surface->SetColor(surface, - (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss), - (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss), - (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift), - 0xFF); - surface->FillRectangle(surface, dstrect->x, dstrect->y, dstrect->w, - dstrect->h); + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); - return 0; + SDL_Unsupported(); + return -1; } -static int -DirectFB_SetHWColorKey(_THIS, SDL_Surface * src, Uint32 key) +static void +DirectFB_SetWindowTitle(_THIS, SDL_Window * window) { - SDL_PixelFormat *fmt = src->format; - IDirectFBSurface *surface = src->hwdata->surface; + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); - if (fmt->BitsPerPixel == 8) - surface->SetSrcColorKeyIndex(surface, key); - else - /* ugly */ - surface->SetSrcColorKey(surface, - (key & fmt->Rmask) >> (fmt->Rshift - - fmt->Rloss), - (key & fmt->Gmask) >> (fmt->Gshift - - fmt->Gloss), - (key & fmt->Bmask) << (fmt->Bloss - - fmt->Bshift)); + SDL_Unsupported(); + //return -1; - return 0; } - -static int -DirectFB_SetHWAlpha(_THIS, SDL_Surface * surface, Uint8 alpha) +static void +DirectFB_SetWindowPosition(_THIS, SDL_Window * window) { - return 0; -} + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); -static int -DirectFB_FlipHWSurface(_THIS, SDL_Surface * surface) -{ - if (HIDDEN->enable_mga_crtc2) { - int rtn = - surface->hwdata->surface->Flip(surface->hwdata->surface, NULL, - 0); - if (HIDDEN->mga_crtc2_stretch) - HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, - surface->hwdata->surface, - &HIDDEN->c2ssize, &HIDDEN->c2dsize); - else - HIDDEN->c2frame->Blit(HIDDEN->c2frame, - surface->hwdata->surface, NULL, - HIDDEN->c2dsize.x, HIDDEN->c2dsize.y); - - HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC); - return rtn; - } else - return surface->hwdata->surface->Flip(surface->hwdata->surface, NULL, - DSFLIP_WAITFORSYNC); + windata->window->MoveTo(windata->window, window->x, window->y); } -static int -DirectFB_LockHWSurface(_THIS, SDL_Surface * surface) +static void +DirectFB_SetWindowSize(_THIS, SDL_Window * window) { - DFBResult ret; - void *data; - int pitch; + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); - ret = surface->hwdata->surface->Lock(surface->hwdata->surface, - DSLF_WRITE, &data, &pitch); - if (ret) { - SetDirectFBerror("surface->Lock", ret); - return -1; - } + windata->window->Resize(windata->window, window->w, window->h); - surface->pixels = data; - surface->pitch = pitch; +} +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); - return 0; } static void -DirectFB_UnlockHWSurface(_THIS, SDL_Surface * surface) +DirectFB_HideWindow(_THIS, SDL_Window * window) { - surface->hwdata->surface->Unlock(surface->hwdata->surface); - surface->pixels = NULL; -} + 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_DirectUpdate(_THIS, int numrects, SDL_Rect * rects) +DirectFB_RaiseWindow(_THIS, SDL_Window * window) { - if (HIDDEN->enable_mga_crtc2) { - if (HIDDEN->mga_crtc2_stretch) - HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, - this->screen->hwdata->surface, - &HIDDEN->c2ssize, &HIDDEN->c2dsize); - else - HIDDEN->c2frame->Blit(HIDDEN->c2frame, - this->screen->hwdata->surface, NULL, - HIDDEN->c2dsize.x, HIDDEN->c2dsize.y); - - HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC); - } + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); + + windata->window->Raise(windata->window); + } static void -DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect * rects) +DirectFB_MaximizeWindow(_THIS, SDL_Window * window) { - DFBRegion region; - int i; - int region_valid = 0; - IDirectFBSurface *surface = this->screen->hwdata->surface; + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); - for (i = 0; i < numrects; ++i) { - int x2, y2; + SDL_Unsupported(); - if (!rects[i].w) /* Clipped? */ - continue; +} +static void +DirectFB_MinimizeWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); - x2 = rects[i].x + rects[i].w - 1; - y2 = rects[i].y + rects[i].h - 1; + SDL_Unsupported(); - if (region_valid) { - if (rects[i].x < region.x1) - region.x1 = rects[i].x; +} - if (rects[i].y < region.y1) - region.y1 = rects[i].y; +static void +DirectFB_RestoreWindow(_THIS, SDL_Window * window) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); - if (x2 > region.x2) - region.x2 = x2; + SDL_Unsupported(); - if (y2 > region.y2) - region.y2 = y2; - } else { - region.x1 = rects[i].x; - region.y1 = rects[i].y; - region.x2 = x2; - region.y2 = y2; +} +static void +DirectFB_SetWindowGrab(_THIS, SDL_Window * window) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); - region_valid = 1; - } - } + SDL_Unsupported(); - if (region_valid) { - if (HIDDEN->enable_mga_crtc2) { - if (HIDDEN->mga_crtc2_stretch) - HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, surface, - &HIDDEN->c2ssize, - &HIDDEN->c2dsize); - else - HIDDEN->c2frame->Blit(HIDDEN->c2frame, surface, NULL, - HIDDEN->c2dsize.x, HIDDEN->c2dsize.y); - - HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC); - } else - surface->Flip(surface, ®ion, DSFLIP_WAITFORSYNC); - } } -int -DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors) +static void +DirectFB_DestroyWindow(_THIS, SDL_Window * window) { - IDirectFBPalette *palette = this->screen->hwdata->palette; + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(_this, window); + DFB_WindowData *p; - if (!palette) - return 0; + SDL_DFB_DEBUG("Trace\n"); - if (firstcolor > 255) - return 0; + SDL_DFB_RELEASE(windata->palette); + SDL_DFB_RELEASE(windata->eventbuffer); + SDL_DFB_RELEASE(windata->surface); + SDL_DFB_RELEASE(windata->window); - if (firstcolor + ncolors > 256) - ncolors = 256 - firstcolor; + /* Remove from list ... */ - if (ncolors > 0) { - int i; - DFBColor entries[ncolors]; + 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); - for (i = 0; i < ncolors; i++) { - entries[i].a = 0xff; - entries[i].r = colors[i].r; - entries[i].g = colors[i].g; - entries[i].b = colors[i].b; - } + SDL_Unsupported(); + return SDL_FALSE; +} - palette->SetEntries(palette, entries, ncolors, firstcolor); - } +#if SDL_DIRECTFB_OPENGL - return 1; -} +#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 -void -DirectFB_VideoQuit(_THIS) +static int +DirectFB_GL_LoadLibrary(_THIS, const char *path) { - struct DirectFBEnumRect *rect = enumlist; + SDL_DFB_DEVICEDATA(_this); +# + void *handle = NULL; - if (this->screen && this->screen->hwdata) { - IDirectFBSurface *surface = this->screen->hwdata->surface; - IDirectFBPalette *palette = this->screen->hwdata->palette; + SDL_DFB_DEBUG("Loadlibrary : %s\n", path); - if (palette) - palette->Release(palette); + if (_this->gl_data->gl_active) { + SDL_SetError("OpenGL context already created"); + return -1; + } - if (surface) - surface->Release(surface); - this->screen->hwdata->surface = NULL; - this->screen->hwdata->palette = NULL; + if (path == NULL) { + path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); + if (path == NULL) { + path = "libGL.so"; + } } - if (HIDDEN->c2frame) { - HIDDEN->c2frame->Release(HIDDEN->c2frame); - HIDDEN->c2frame = NULL; + 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; } - if (HIDDEN->eventbuffer) { - HIDDEN->eventbuffer->Release(HIDDEN->eventbuffer); - HIDDEN->eventbuffer = NULL; - } + SDL_DFB_DEBUG("Loaded library: %s\n", path); - if (HIDDEN->c2layer) { - HIDDEN->c2layer->Release(HIDDEN->c2layer); - HIDDEN->c2layer = NULL; - } + /* Unload the old driver and reset the pointers */ + DirectFB_GL_UnloadLibrary(_this); - if (HIDDEN->layer) { - HIDDEN->layer->Release(HIDDEN->layer); - HIDDEN->layer = NULL; + _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'; } - if (HIDDEN->dfb) { - HIDDEN->dfb->Release(HIDDEN->dfb); - HIDDEN->dfb = NULL; + 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; - /* Free video mode list */ - if (HIDDEN->modelist) { - free(HIDDEN->modelist); - HIDDEN->modelist = NULL; + 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; } - /* Free mode enumeration list */ - while (rect) { - struct DirectFBEnumRect *next = rect->next; - free(rect); - rect = next; + 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)); } - enumlist = NULL; + if (windata) + windata->gl_context = dfb_context; - HIDDEN->initialized = 0; + return 0; + error: + return -1; } +static int +DirectFB_GL_SetSwapInterval(_THIS, int interval) +{ + SDL_DFB_DEVICEDATA(_this); + + SDL_Unsupported(); + return -1; -int -DirectFB_ShowWMCursor(_THIS, WMcursor * cursor) +} + +static int +DirectFB_GL_GetSwapInterval(_THIS) { - /* We can only hide or show the default cursor */ - if (cursor == NULL) { - HIDDEN->layer->SetCursorOpacity(HIDDEN->layer, 0x00); - } else { - HIDDEN->layer->SetCursorOpacity(HIDDEN->layer, 0xFF); - } - return 1; + SDL_DFB_DEVICEDATA(_this); + + SDL_Unsupported(); + return -1; + } -void -DirectFB_FinalQuit(void) +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); } -/* vi: set ts=4 sw=4 expandtab: */ +#endif diff --git a/src/video/directfb/SDL_DirectFB_video.h b/src/video/directfb/SDL_DirectFB_video.h index 1a3607d19..1d28845a0 100644 --- a/src/video/directfb/SDL_DirectFB_video.h +++ b/src/video/directfb/SDL_DirectFB_video.h @@ -25,39 +25,155 @@ #define _SDL_DirectFB_video_h #include +#include + +#define LOG_CHANNEL stdout + +#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23) +#error "SDL_DIRECTFB: Please compile against libdirectfb version >=0.9.24" +#endif + +#if (DIRECTFB_MAJOR_VERSION >= 1) && (DIRECTFB_MINOR_VERSION >= 0) && (DIRECTFB_MICRO_VERSION >= 0 ) +#define SDL_DIRECTFB_OPENGL 1 +#include +#endif + +#if SDL_DIRECTFB_OPENGL +#include "SDL_loadso.h" +#endif #include "SDL_mouse.h" #include "../SDL_sysvideo.h" -#define _THIS SDL_VideoDevice *this +#define DEBUG 1 + +#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) +#define SDL_DFB_UNLOCK(x) do { if ( x ) { x->Unlock(x); } } while (0) + +#if DEBUG +#define SDL_DFB_DEBUG(x...) do { fprintf(LOG_CHANNEL, "%s:", __FUNCTION__); fprintf(LOG_CHANNEL, x); } while (0) +#define SDL_DFB_DEBUGC(x...) do { fprintf(LOG_CHANNEL, x); } while (0) +#else +#define SDL_DFB_DEBUG(x...) do { } while (0) +#define SDL_DFB_DEBUGC(x...) do { } while (0) +#endif + +#define SDL_DFB_CONTEXT "SDL_DirectFB" + +#define SDL_DFB_ERR(x...) \ + do { \ + fprintf(LOG_CHANNEL, "%s: %s <%d>:\n\t", \ + SDL_DFB_CONTEXT, __FILE__, __LINE__ ); \ + fprintf(LOG_CHANNEL, x ); \ + } while (0) + +#define SDL_DFB_CHECK(x...) \ + do { \ + ret = x; \ + if (ret != DFB_OK) { \ + fprintf(LOG_CHANNEL, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ + SDL_SetError( #x, DirectFBErrorString (ret) ); \ + } \ + } while (0) + +#define SDL_DFB_CHECKERR(x...) \ + do { \ + ret = x; \ + if (ret != DFB_OK) { \ + fprintf(LOG_CHANNEL, "%s <%d>:\n", __FILE__, __LINE__ ); \ + fprintf(LOG_CHANNEL, "\t%s\n", #x ); \ + fprintf(LOG_CHANNEL, "\t%s\n", DirectFBErrorString (ret) ); \ + SDL_SetError( #x, DirectFBErrorString (ret) ); \ + goto error; \ + } \ + } while (0) + +#define SDL_DFB_CALLOC(r, n, s) \ + do { \ + r = SDL_calloc (n, s); \ + if (!(r)) { \ + fprintf( LOG_CHANNEL, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ + SDL_OutOfMemory(); \ + goto error; \ + } \ + } while (0) /* Private display data */ -struct SDL_PrivateVideoData +#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; + DFBDisplayLayerID vidID; + + 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; + u8 opacity; +}; + +typedef struct _DFB_DeviceData DFB_DeviceData; +struct _DFB_DeviceData { int initialized; IDirectFB *dfb; - IDirectFBDisplayLayer *layer; - IDirectFBEventBuffer *eventbuffer; + int mouse; + int keyboard; + DFB_WindowData *firstwin; - int nummodes; - SDL_Rect **modelist; - - /* MGA CRTC2 support */ - int enable_mga_crtc2; - int mga_crtc2_stretch; - float mga_crtc2_stretch_overscan; - IDirectFBDisplayLayer *c2layer; - IDirectFBSurface *c2frame; - DFBRectangle c2ssize; /* Real screen size */ - DFBRectangle c2dsize; /* Stretched screen size */ - DFBRectangle c2framesize; /* CRTC2 screen size */ + int numscreens; + DFBScreenID screenid[DFB_MAX_SCREENS]; + DFBDisplayLayerID gralayer[DFB_MAX_SCREENS]; + DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS]; + + // auxiliary integer for callbacks + int aux; + + // OpenGL + void (*glFinish) (void); + void (*glFlush) (void); }; -#define HIDDEN (this->hidden) +struct SDL_GLDriverData +{ + int gl_active; /* to stop switching drivers while we have a valid context */ -void SetDirectFBerror(const char *function, DFBResult code); +#if SDL_DIRECTFB_OPENGL + IDirectFBGL *gl_context; +#endif /* SDL_DIRECTFB_OPENGL */ +}; #endif /* _SDL_DirectFB_video_h */ -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_yuv.c b/src/video/directfb/SDL_DirectFB_yuv.c deleted file mode 100644 index 1f2d5fb49..000000000 --- a/src/video/directfb/SDL_DirectFB_yuv.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - 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" - -/* This is the DirectFB implementation of YUV video overlays */ - -#include "SDL_video.h" -#include "SDL_DirectFB_yuv.h" -#include "../SDL_yuvfuncs.h" - - -/* The functions used to manipulate software video overlays */ -static struct private_yuvhwfuncs directfb_yuvfuncs = { - DirectFB_LockYUVOverlay, - DirectFB_UnlockYUVOverlay, - DirectFB_DisplayYUVOverlay, - DirectFB_FreeYUVOverlay -}; - -struct private_yuvhwdata -{ - DFBDisplayLayerID layer_id; - - IDirectFBDisplayLayer *layer; - IDirectFBSurface *surface; - - /* These are just so we don't have to allocate them separately */ - Uint16 pitches[3]; - Uint8 *planes[3]; -}; - -static DFBEnumerationResult -enum_layers_callback(DFBDisplayLayerID id, - DFBDisplayLayerDescription desc, void *data) -{ - struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data; - - /* we don't want the primary */ - if (id == DLID_PRIMARY) - return DFENUM_OK; - - /* take the one with a surface for video */ - if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO)) { - hwdata->layer_id = id; - - return DFENUM_CANCEL; - } - - return DFENUM_OK; -} - - -static DFBResult -CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata, - int width, int height, Uint32 format) -{ - DFBResult ret; - IDirectFB *dfb = HIDDEN->dfb; - IDirectFBDisplayLayer *layer; - DFBDisplayLayerConfig conf; - - ret = dfb->EnumDisplayLayers(dfb, enum_layers_callback, hwdata); - if (ret) { - SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret); - return ret; - } - - if (!hwdata->layer_id) - return DFB_UNSUPPORTED; - - ret = dfb->GetDisplayLayer(dfb, hwdata->layer_id, &layer); - if (ret) { - SetDirectFBerror("IDirectFB::GetDisplayLayer", ret); - return ret; - } - - conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT; - conf.width = width; - conf.height = height; - - switch (format) { - case SDL_YV12_OVERLAY: - conf.pixelformat = DSPF_YV12; - break; - case SDL_IYUV_OVERLAY: - conf.pixelformat = DSPF_I420; - break; - case SDL_YUY2_OVERLAY: - conf.pixelformat = DSPF_YUY2; - break; - case SDL_UYVY_OVERLAY: - conf.pixelformat = DSPF_UYVY; - break; - default: - fprintf(stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n", - format); - break; - } - - /* Need to set coop level or newer DirectFB versions will fail here. */ - ret = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE); - if (ret) { - SetDirectFBError - ("IDirectFBDisplayLayer::SetCooperativeLevel() failed", ret); - layer->Release(layer); - return ret; - } - - ret = layer->SetConfiguration(layer, &conf); - if (ret) { - SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret); - layer->Release(layer); - return ret; - } - - ret = layer->GetSurface(layer, &hwdata->surface); - if (ret) { - SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret); - layer->Release(layer); - return ret; - } - - hwdata->layer = layer; - - return DFB_OK; -} - -SDL_Overlay * -DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, - SDL_Surface * display) -{ - SDL_Overlay *overlay; - struct private_yuvhwdata *hwdata; - - /* Create the overlay structure */ - overlay = SDL_calloc(1, sizeof(SDL_Overlay)); - if (!overlay) { - SDL_OutOfMemory(); - return NULL; - } - - /* Fill in the basic members */ - overlay->format = format; - overlay->w = width; - overlay->h = height; - - /* Set up the YUV surface function structure */ - overlay->hwfuncs = &directfb_yuvfuncs; - - /* Create the pixel data and lookup tables */ - hwdata = SDL_calloc(1, sizeof(struct private_yuvhwdata)); - overlay->hwdata = hwdata; - if (!hwdata) { - SDL_OutOfMemory(); - SDL_FreeYUVOverlay(overlay); - return NULL; - } - - if (CreateYUVSurface(this, hwdata, width, height, format)) { - SDL_FreeYUVOverlay(overlay); - return NULL; - } - - overlay->hw_overlay = 1; - - /* Set up the plane pointers */ - overlay->pitches = hwdata->pitches; - overlay->pixels = hwdata->planes; - switch (format) { - case SDL_YV12_OVERLAY: - case SDL_IYUV_OVERLAY: - overlay->planes = 3; - break; - default: - overlay->planes = 1; - break; - } - - /* We're all done.. */ - return overlay; -} - -int -DirectFB_LockYUVOverlay(_THIS, SDL_Overlay * overlay) -{ - DFBResult ret; - void *data; - int pitch; - IDirectFBSurface *surface = overlay->hwdata->surface; - - ret = surface->Lock(surface, DSLF_READ | DSLF_WRITE, &data, &pitch); - if (ret) { - SetDirectFBerror("IDirectFBSurface::Lock", ret); - return -1; - } - - /* Find the pitch and offset values for the overlay */ - overlay->pitches[0] = (Uint16) pitch; - overlay->pixels[0] = (Uint8 *) data; - - switch (overlay->format) { - case SDL_YV12_OVERLAY: - case SDL_IYUV_OVERLAY: - /* Add the two extra planes */ - overlay->pitches[1] = overlay->pitches[0] / 2; - overlay->pitches[2] = overlay->pitches[0] / 2; - overlay->pixels[1] = - overlay->pixels[0] + overlay->pitches[0] * overlay->h; - overlay->pixels[2] = - overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2; - break; - default: - /* Only one plane, no worries */ - break; - } - - return 0; -} - -void -DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay) -{ - IDirectFBSurface *surface = overlay->hwdata->surface; - - overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL; - - surface->Unlock(surface); -} - -int -DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src, - SDL_Rect * dst) -{ - DFBResult ret; - DFBDisplayLayerConfig conf; - IDirectFBDisplayLayer *primary = HIDDEN->layer; - IDirectFBDisplayLayer *layer = overlay->hwdata->layer; - - primary->GetConfiguration(primary, &conf); - - ret = layer->SetScreenLocation(layer, - dst->x / (float) conf.width, - dst->y / (float) conf.height, - dst->w / (float) conf.width, - dst->h / (float) conf.height); - if (ret) { - SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret); - return -1; - } - - return 0; -} - -void -DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay * overlay) -{ - struct private_yuvhwdata *hwdata; - - hwdata = overlay->hwdata; - if (hwdata) { - if (hwdata->surface) - hwdata->surface->Release(hwdata->surface); - - if (hwdata->layer) - hwdata->layer->Release(hwdata->layer); - - free(hwdata); - } -} - -/* vi: set ts=4 sw=4 expandtab: */