From 8938cbf2a03704a76bea6d034b473962734080aa Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 5 Feb 2011 16:07:10 -0800 Subject: [PATCH] Updated the DirectFB support, from Couriersud attached is a working directfb driver diff which works with the current changes. There are a number of changes around it as well, e.g. configure.in. The directfb renderdriver right now still depends on a some "includes" from src/video/directfb. That's why it is not yet moved to the new render folder. --- README.DirectFB | 4 +- configure.in | 9 +- include/SDL_config.h.in | 1 + include/SDL_syswm.h | 2 +- src/render/SDL_render.c | 3 + src/render/SDL_sysrender.h | 3 + src/video/directfb/SDL_DirectFB_WM.c | 169 +++--- src/video/directfb/SDL_DirectFB_WM.h | 8 +- src/video/directfb/SDL_DirectFB_dyn.c | 7 +- src/video/directfb/SDL_DirectFB_dyn.h | 4 +- src/video/directfb/SDL_DirectFB_events.c | 285 +++++----- src/video/directfb/SDL_DirectFB_events.h | 12 +- src/video/directfb/SDL_DirectFB_modes.c | 162 ++---- src/video/directfb/SDL_DirectFB_modes.h | 26 +- src/video/directfb/SDL_DirectFB_mouse.c | 13 +- src/video/directfb/SDL_DirectFB_mouse.h | 13 +- src/video/directfb/SDL_DirectFB_opengl.c | 16 +- src/video/directfb/SDL_DirectFB_opengl.h | 16 +- src/video/directfb/SDL_DirectFB_render.c | 650 +++++++++++++++++------ src/video/directfb/SDL_DirectFB_render.h | 9 +- src/video/directfb/SDL_DirectFB_video.c | 224 ++++++-- src/video/directfb/SDL_DirectFB_video.h | 157 +++--- src/video/directfb/SDL_DirectFB_window.c | 263 ++++++--- src/video/directfb/SDL_DirectFB_window.h | 43 +- 24 files changed, 1330 insertions(+), 769 deletions(-) diff --git a/README.DirectFB b/README.DirectFB index f63eadaff..68988136b 100644 --- a/README.DirectFB +++ b/README.DirectFB @@ -71,9 +71,9 @@ works at least on all directfb supported platforms. As of this writing 20100802 you need to pull Mesa from git and do the following: ------------------------ -git checkout 2c9fdaf7292423c157fc79b5ce43f0f199dd753a -cd mesa git clone git://anongit.freedesktop.org/git/mesa/mesa +cd mesa +git checkout 2c9fdaf7292423c157fc79b5ce43f0f199dd753a ------------------------ Edit configs/linux-directfb so that the Directories-section looks like diff --git a/configure.in b/configure.in index 6f05d533b..f0d3ac58e 100644 --- a/configure.in +++ b/configure.in @@ -1312,8 +1312,7 @@ AC_HELP_STRING([--enable-video-directfb], [use DirectFB video driver [[default=n video_directfb=no DIRECTFB_REQUIRED_VERSION=1.0.0 - - AC_PATH_PROG(DIRECTFBCONFIG, directfb-config, no) + AC_PATH_PROGS(DIRECTFBCONFIG, directfb-config, no, [$prefix/bin:$PATH]) if test x$DIRECTFBCONFIG = xno; then AC_PATH_PROG(PKG_CONFIG, pkg-config, no) if test x$PKG_CONFIG != xno; then @@ -1353,13 +1352,15 @@ AC_HELP_STRING([--enable-directfb-shared], [dynamically load directfb support [[ , enable_directfb_shared=yes) AC_DEFINE(SDL_VIDEO_DRIVER_DIRECTFB) + AC_DEFINE(SDL_VIDEO_RENDER_DIRECTFB) SOURCES="$SOURCES $srcdir/src/video/directfb/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $DIRECTFB_CFLAGS" AC_MSG_CHECKING(for directfb dynamic loading support) directfb_shared=no - directfb_lib=[`find_lib "libdirectfb.so.*" "$DIRECTFB_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] - + directfb_lib=[`find_lib "libdirectfb.so.*" "$DIRECTFB_LIBS"`] + # | sed 's/.*\/\(.*\)/\1/; q'`] +AC_MSG_WARN("directfb $directfb_lib") if test x$have_loadso != xyes && \ test x$enable_directfb_shared = xyes; then AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic directfb loading]) diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 7ac87b9cf..70b540fc2 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -279,6 +279,7 @@ #undef SDL_VIDEO_RENDER_D3D #undef SDL_VIDEO_RENDER_OGL #undef SDL_VIDEO_RENDER_OGL_ES +#undef SDL_VIDEO_RENDER_DIRECTFB /* Enable OpenGL support */ #undef SDL_VIDEO_OPENGL diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index 62647511a..0f1adf227 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -77,7 +77,7 @@ struct SDL_SysWMinfo; #endif /* defined(SDL_VIDEO_DRIVER_X11) */ #if defined(SDL_VIDEO_DRIVER_DIRECTFB) -#include +#include #endif #if defined(SDL_VIDEO_DRIVER_COCOA) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 020198fcb..66d5e6e2f 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -52,6 +52,9 @@ static const SDL_RenderDriver *render_drivers[] = { #endif #if SDL_VIDEO_RENDER_OGL_ES &GL_ES_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_DIRECTFB + &DirectFB_RenderDriver, #endif &SW_RenderDriver }; diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h index f4e2d8854..33e514d1b 100644 --- a/src/render/SDL_sysrender.h +++ b/src/render/SDL_sysrender.h @@ -127,6 +127,9 @@ extern SDL_RenderDriver GL_RenderDriver; #if SDL_VIDEO_RENDER_OGL_ES extern SDL_RenderDriver GL_ES_RenderDriver; #endif +#if SDL_VIDEO_RENDER_DIRECTFB +extern SDL_RenderDriver DirectFB_RenderDriver; +#endif extern SDL_RenderDriver SW_RenderDriver; #endif /* _SDL_sysrender_h */ diff --git a/src/video/directfb/SDL_DirectFB_WM.c b/src/video/directfb/SDL_DirectFB_WM.c index 101a8e06a..36b959559 100644 --- a/src/video/directfb/SDL_DirectFB_WM.c +++ b/src/video/directfb/SDL_DirectFB_WM.c @@ -18,14 +18,13 @@ Sam Lantinga slouken@libsdl.org -*/ -#include "SDL_config.h" -//#include "SDL_syswm.h" -//#include "../SDL_sysvideo.h" -//#include "../../events/SDL_keyboard_c.h" + SDL1.3 DirectFB driver by couriersud@arcor.de + +*/ #include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_window.h" #include "../../events/SDL_windowevents_c.h" @@ -127,6 +126,11 @@ DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window) if (!windata->is_managed || (window->flags & SDL_WINDOW_FULLSCREEN)) return; + SDL_DFB_CHECK(s->SetSrcBlendFunction(s, DSBF_ONE)); + SDL_DFB_CHECK(s->SetDstBlendFunction(s, DSBF_ZERO)); + SDL_DFB_CHECK(s->SetDrawingFlags(s, DSDRAW_NOFX)); + SDL_DFB_CHECK(s->SetBlittingFlags(s, DSBLIT_NOFX)); + LoadFont(_this, window); //s->SetDrawingFlags(s, DSDRAW_BLEND); s->SetColor(s, COLOR_EXPAND(t->frame_color)); @@ -181,8 +185,10 @@ DFBResult DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch) { SDL_DFB_WINDOWDATA(window); + IDirectFBWindow *dfbwin = windata->dfbwin; - SDL_DFB_CHECK(windata->window->GetSize(windata->window, cw, ch)); + SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, cw, ch)); + dfbwin->GetSize(dfbwin, cw, ch); *cw -= windata->theme.left_size + windata->theme.right_size; *ch -= windata->theme.top_size + windata->theme.caption_size + @@ -197,6 +203,9 @@ DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h) if (!windata->is_managed) windata->theme = theme_none; + else if (flags & SDL_WINDOW_BORDERLESS) + //desc.caps |= DWCAPS_NODECORATION;) + windata->theme = theme_none; else if (flags & SDL_WINDOW_FULLSCREEN) { windata->theme = theme_none; } else if (flags & SDL_WINDOW_MAXIMIZED) { @@ -220,37 +229,6 @@ DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h) windata->theme.caption_size + windata->theme.bottom_size; } -void -DirectFB_WM_MaximizeWindow(_THIS, SDL_Window * window) -{ - SDL_DFB_WINDOWDATA(window); - SDL_VideoDisplay *display = window->display; - - SDL_DFB_CHECK(windata->window->GetPosition(windata->window, - &windata->restore.x, &windata->restore.y)); - SDL_DFB_CHECK(windata->window->GetSize(windata->window, &windata->restore.w, - &windata->restore.h)); - - DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ; - - SDL_DFB_CHECK(windata->window->MoveTo(windata->window, 0, 0)); - SDL_DFB_CHECK(windata->window->Resize(windata->window, - display->current_mode.w, display->current_mode.h)); -} - -void -DirectFB_WM_RestoreWindow(_THIS, SDL_Window * window) -{ - SDL_DFB_WINDOWDATA(window); - - DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED), - windata->restore.w, windata->restore.h); - - SDL_DFB_CHECK(windata->window->Resize(windata->window, windata->restore.w, - windata->restore.h)); - SDL_DFB_CHECK(windata->window->MoveTo(windata->window, windata->restore.x, - windata->restore.y)); -} enum { @@ -307,20 +285,20 @@ WMPos(DFB_WindowData * p, int x, int y) return pos; } -static int wm_grab; -static int wm_lastx; -static int wm_lasty; - int DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL); + IDirectFBWindow *dfbwin = windata->dfbwin; + DFBWindowOptions wopts; if (!windata->is_managed) return 0; + SDL_DFB_CHECK(dfbwin->GetOptions(dfbwin, &wopts)); + switch (evt->type) { case DWET_BUTTONDOWN: if (evt->buttons & DIBM_LEFT) { @@ -329,59 +307,99 @@ DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) case WM_POS_NONE: return 0; case WM_POS_CLOSE: - wm_grab = WM_POS_NONE; + windata->wm_grab = WM_POS_NONE; SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0, 0); return 1; case WM_POS_MAX: - wm_grab = WM_POS_NONE; - if (window->flags & SDL_WINDOW_MAXIMIZED) { - SDL_RestoreWindow(window); - } else { - SDL_MaximizeWindow(window); - } + windata->wm_grab = WM_POS_NONE; + if (window->flags & SDL_WINDOW_MAXIMIZED) { + SDL_RestoreWindow(window); + } else { + SDL_MaximizeWindow(window); + } return 1; case WM_POS_CAPTION: - DirectFB_RaiseWindow(_this, window); + if (!(wopts & DWOP_KEEP_STACKING)) { + DirectFB_RaiseWindow(_this, window); + } + if (window->flags & SDL_WINDOW_MAXIMIZED) + return 1; /* fall through */ default: - wm_grab = pos; + windata->wm_grab = pos; if (gwindata != NULL) - SDL_DFB_CHECK(gwindata->window->UngrabPointer(gwindata->window)); - SDL_DFB_CHECK(windata->window->GrabPointer(windata->window)); - wm_lastx = evt->cx; - wm_lasty = evt->cy; + SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin)); + SDL_DFB_CHECK(dfbwin->GrabPointer(dfbwin)); + windata->wm_lastx = evt->cx; + windata->wm_lasty = evt->cy; } } return 1; case DWET_BUTTONUP: + if (!windata->wm_grab) + return 0; + if (!(evt->buttons & DIBM_LEFT)) { + if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) { + int dx = evt->cx - windata->wm_lastx; + int dy = evt->cy - windata->wm_lasty; + + if (!(wopts & DWOP_KEEP_SIZE)) { + int cw, ch; + if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM) + dx = 0; + else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT) + dy = 0; + SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch)); + + /* necessary to trigger an event - ugly*/ + SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL)); + SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx + 1, ch + dy)); + SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL)); + + SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy)); + } + } + SDL_DFB_CHECK(dfbwin->UngrabPointer(dfbwin)); + if (gwindata != NULL) + SDL_DFB_CHECK(gwindata->dfbwin->GrabPointer(gwindata->dfbwin)); + windata->wm_grab = WM_POS_NONE; + return 1; + } break; case DWET_MOTION: - if (!wm_grab) + if (!windata->wm_grab) return 0; if (evt->buttons & DIBM_LEFT) { - int dx = evt->cx - wm_lastx; - int dy = evt->cy - wm_lasty; - int cw, ch; - - if (wm_grab & WM_POS_CAPTION) - SDL_DFB_CHECK(windata->window->Move(windata->window, dx, dy)); - if (wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) { - if ((wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM) - dx = 0; - else if ((wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT) - dy = 0; - SDL_DFB_CHECK(windata->window->GetSize(windata->window, &cw, &ch)); - SDL_DFB_CHECK(windata->window->Resize(windata->window, cw + dx, ch + dy)); + int dx = evt->cx - windata->wm_lastx; + int dy = evt->cy - windata->wm_lasty; + + if (windata->wm_grab & WM_POS_CAPTION) { + if (!(wopts & DWOP_KEEP_POSITION)) + SDL_DFB_CHECK(dfbwin->Move(dfbwin, dx, dy)); } - wm_lastx = evt->cx; - wm_lasty = evt->cy; - return 1; + if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) { + if (!(wopts & DWOP_KEEP_SIZE)) { + int cw, ch; + + /* Make sure all events are disabled for this operation ! */ + SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL)); + + if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM) + dx = 0; + else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT) + dy = 0; + + SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch)); + SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy)); + + SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL)); + } + } + windata->wm_lastx = evt->cx; + windata->wm_lasty = evt->cy; + return 1; } - SDL_DFB_CHECK(windata->window->UngrabPointer(windata->window)); - if (gwindata != NULL) - SDL_DFB_CHECK(gwindata->window->GrabPointer(gwindata->window)); - wm_grab = WM_POS_NONE; break; case DWET_KEYDOWN: break; @@ -392,3 +410,4 @@ DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) } return 0; } + diff --git a/src/video/directfb/SDL_DirectFB_WM.h b/src/video/directfb/SDL_DirectFB_WM.h index f04d0ce31..7682a4d55 100644 --- a/src/video/directfb/SDL_DirectFB_WM.h +++ b/src/video/directfb/SDL_DirectFB_WM.h @@ -18,12 +18,16 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" #ifndef _SDL_directfb_wm_h #define _SDL_directfb_wm_h +#include "SDL_DirectFB_video.h" + typedef struct _DFB_Theme DFB_Theme; struct _DFB_Theme { @@ -42,8 +46,6 @@ struct _DFB_Theme }; extern void DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h); -extern void DirectFB_WM_MaximizeWindow(_THIS, SDL_Window * window); -extern void DirectFB_WM_RestoreWindow(_THIS, SDL_Window * window); extern void DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window); extern int DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, diff --git a/src/video/directfb/SDL_DirectFB_dyn.c b/src/video/directfb/SDL_DirectFB_dyn.c index 3706186eb..e6ef55920 100644 --- a/src/video/directfb/SDL_DirectFB_dyn.c +++ b/src/video/directfb/SDL_DirectFB_dyn.c @@ -18,7 +18,11 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ + #include "SDL_config.h" #include "SDL_DirectFB_video.h" @@ -41,6 +45,7 @@ static struct _SDL_DirectFB_Symbols #define DFB_SYM(ret, name, args, al, func) ret name args { func SDL_DirectFB_Symbols.name al ; } DFB_SYMS #undef DFB_SYM + static void *handle = NULL; int @@ -55,7 +60,7 @@ SDL_DirectFB_LoadLibrary(void) #define DFB_SYM(ret, name, args, al, func) if (!(SDL_DirectFB_Symbols.name = SDL_LoadFunction(handle, # name))) retval = 0; DFB_SYMS #undef DFB_SYM - if (! + if (! (SDL_DirectFB_Symbols.directfb_major_version = SDL_LoadFunction(handle, "directfb_major_version"))) retval = 0; diff --git a/src/video/directfb/SDL_DirectFB_dyn.h b/src/video/directfb/SDL_DirectFB_dyn.h index 8569ab965..b0f2c4250 100644 --- a/src/video/directfb/SDL_DirectFB_dyn.h +++ b/src/video/directfb/SDL_DirectFB_dyn.h @@ -18,6 +18,9 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ #ifndef _SDL_DirectFB_dyn_h @@ -33,7 +36,6 @@ DFB_SYM(DFBResult, DirectFBCreate, (IDirectFB **interface), (interface), return) \ DFB_SYM(const char *, DirectFBCheckVersion, (unsigned int required_major, unsigned int required_minor, unsigned int required_micro), \ (required_major, required_minor, required_micro), return) -// #define SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC "/usr/lib/libdirectfb-1.2.so.0" int SDL_DirectFB_LoadLibrary(void); void SDL_DirectFB_UnLoadLibrary(void); diff --git a/src/video/directfb/SDL_DirectFB_events.c b/src/video/directfb/SDL_DirectFB_events.c index e994249bc..123597898 100644 --- a/src/video/directfb/SDL_DirectFB_events.c +++ b/src/video/directfb/SDL_DirectFB_events.c @@ -18,17 +18,26 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" /* Handle the event stream, converting DirectFB input events into SDL events */ -#include +#include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_window.h" +#include "SDL_DirectFB_modes.h" -#include "../SDL_sysvideo.h" -#include "../../events/SDL_events_c.h" +#include "SDL_syswm.h" + +#include "../../events/SDL_mouse_c.h" #include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_windowevents_c.h" +#include "../../events/SDL_events_c.h" #include "../../events/scancodes_linux.h" +#include "../../events/scancodes_xfree86.h" + #include "SDL_DirectFB_events.h" #if USE_MULTI_API @@ -52,36 +61,36 @@ struct _cb_data }; /* The translation tables from a DirectFB keycode to a SDL keysym */ -static SDLKey oskeymap[256]; +static SDL_ScanCode oskeymap[256]; static SDL_KeySym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_KeySym * keysym); -static SDL_KeySym *DirectFB_TranslateKeyInputEvent(_THIS, int index, - DFBInputEvent * evt, +static SDL_KeySym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt, SDL_KeySym * keysym); -static void DirectFB_InitOSKeymap(_THIS, SDLKey * keypmap, int numkeys); +static void DirectFB_InitOSKeymap(_THIS, SDL_ScanCode * keypmap, int numkeys); static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button); -static void -DirectFB_SetContext(_THIS, SDL_Window *window) +static void UnicodeToUtf8( Uint16 w , char *utf8buf) { -#if (DFB_VERSION_ATLEAST(1,0,0)) - /* FIXME: does not work on 1.0/1.2 with radeon driver - * the approach did work with the matrox driver - * This has simply no effect. - */ - - SDL_VideoDisplay *display = window->display; - DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; - - /* FIXME: should we handle the error */ - if (dispdata->vidIDinuse) - SDL_DFB_CHECK(dispdata->vidlayer->SwitchContext(dispdata->vidlayer, - DFB_TRUE)); -#endif - + unsigned char *utf8s = (unsigned char *) utf8buf; + + if ( w < 0x0080 ) { + utf8s[0] = ( unsigned char ) w; + utf8s[1] = 0; + } + else if ( w < 0x0800 ) { + utf8s[0] = 0xc0 | (( w ) >> 6 ); + utf8s[1] = 0x80 | (( w ) & 0x3f ); + utf8s[2] = 0; + } + else { + utf8s[0] = 0xe0 | (( w ) >> 12 ); + utf8s[1] = 0x80 | (( ( w ) >> 6 ) & 0x3f ); + utf8s[2] = 0x80 | (( w ) & 0x3f ); + utf8s[3] = 0; + } } static void @@ -163,21 +172,21 @@ ClientXY(DFB_WindowData * p, int *x, int *y) } static void -ProcessWindowEvent(_THIS, DFB_WindowData * p, Uint32 flags, - DFBWindowEvent * evt) +ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt) { SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(sdlwin); SDL_KeySym keysym; - char text[5]; + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; if (evt->clazz == DFEC_WINDOW) { switch (evt->type) { case DWET_BUTTONDOWN: - if (ClientXY(p, &evt->x, &evt->y)) { + if (ClientXY(windata, &evt->x, &evt->y)) { if (!devdata->use_linux_input) { - SDL_SendMouseMotion_ex(p->sdl_window, devdata->mouse_id[0], 0, evt->x, + SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x, evt->y, 0); - SDL_SendMouseButton_ex(p->sdl_window, devdata->mouse_id[0], + SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0], SDL_PRESSED, DirectFB_TranslateButton (evt->button)); @@ -187,11 +196,11 @@ ProcessWindowEvent(_THIS, DFB_WindowData * p, Uint32 flags, } break; case DWET_BUTTONUP: - if (ClientXY(p, &evt->x, &evt->y)) { + if (ClientXY(windata, &evt->x, &evt->y)) { if (!devdata->use_linux_input) { - SDL_SendMouseMotion_ex(p->sdl_window, devdata->mouse_id[0], 0, evt->x, + SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x, evt->y, 0); - SDL_SendMouseButton_ex(p->sdl_window, devdata->mouse_id[0], + SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0], SDL_RELEASED, DirectFB_TranslateButton (evt->button)); @@ -201,11 +210,10 @@ ProcessWindowEvent(_THIS, DFB_WindowData * p, Uint32 flags, } break; case DWET_MOTION: - if (ClientXY(p, &evt->x, &evt->y)) { - SDL_Window *window = p->sdl_window; + if (ClientXY(windata, &evt->x, &evt->y)) { if (!devdata->use_linux_input) { - if (!(flags & SDL_WINDOW_INPUT_GRABBED)) - SDL_SendMouseMotion_ex(p->sdl_window, devdata->mouse_id[0], 0, + if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED)) + SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x, evt->y, 0); } else { /* relative movements are not exact! @@ -217,18 +225,19 @@ ProcessWindowEvent(_THIS, DFB_WindowData * p, Uint32 flags, cnt = 0; } } - if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) - SDL_SendWindowEvent(p->sdl_window, SDL_WINDOWEVENT_ENTER, 0, + if (!(sdlwin->flags & SDL_WINDOW_MOUSE_FOCUS)) + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, 0); } break; case DWET_KEYDOWN: if (!devdata->use_linux_input) { DirectFB_TranslateKey(_this, evt, &keysym); + //printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); SDL_SendKeyboardKey_ex(0, SDL_PRESSED, keysym.scancode); if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { - SDL_memcpy(text, &keysym.unicode, 4); - text[4] = 0; + SDL_zero(text); + UnicodeToUtf8(keysym.unicode, text); if (*text) { SDL_SendKeyboardText_ex(0, text); } @@ -242,49 +251,49 @@ ProcessWindowEvent(_THIS, DFB_WindowData * p, Uint32 flags, } break; case DWET_POSITION: - if (ClientXY(p, &evt->x, &evt->y)) { - SDL_SendWindowEvent(p->sdl_window, SDL_WINDOWEVENT_MOVED, + if (ClientXY(windata, &evt->x, &evt->y)) { + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED, evt->x, evt->y); } break; case DWET_POSITION_SIZE: - if (ClientXY(p, &evt->x, &evt->y)) { - SDL_SendWindowEvent(p->sdl_window, SDL_WINDOWEVENT_MOVED, + if (ClientXY(windata, &evt->x, &evt->y)) { + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED, evt->x, evt->y); } /* fall throught */ case DWET_SIZE: // FIXME: what about < 0 - evt->w -= (p->theme.right_size + p->theme.left_size); + evt->w -= (windata->theme.right_size + windata->theme.left_size); evt->h -= - (p->theme.top_size + p->theme.bottom_size + - p->theme.caption_size); - SDL_SendWindowEvent(p->sdl_window, SDL_WINDOWEVENT_RESIZED, + (windata->theme.top_size + windata->theme.bottom_size + + windata->theme.caption_size); + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED, evt->w, evt->h); break; case DWET_CLOSE: - SDL_SendWindowEvent(p->sdl_window, SDL_WINDOWEVENT_CLOSE, 0, 0); + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_CLOSE, 0, 0); break; case DWET_GOTFOCUS: - DirectFB_SetContext(_this, p->sdl_window); - FocusAllKeyboards(_this, p->sdl_window); - SDL_SendWindowEvent(p->sdl_window, SDL_WINDOWEVENT_FOCUS_GAINED, + DirectFB_SetContext(_this, sdlwin); + FocusAllKeyboards(_this, sdlwin); + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0); break; case DWET_LOSTFOCUS: - SDL_SendWindowEvent(p->sdl_window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); FocusAllKeyboards(_this, 0); break; case DWET_ENTER: /* SDL_DirectFB_ReshowCursor(_this, 0); */ - FocusAllMice(_this, p->sdl_window); + FocusAllMice(_this, sdlwin); // FIXME: when do we really enter ? - if (ClientXY(p, &evt->x, &evt->y)) + if (ClientXY(windata, &evt->x, &evt->y)) MotionAllMice(_this, evt->x, evt->y); - SDL_SendWindowEvent(p->sdl_window, SDL_WINDOWEVENT_ENTER, 0, 0); + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, 0); break; case DWET_LEAVE: - SDL_SendWindowEvent(p->sdl_window, SDL_WINDOWEVENT_LEAVE, 0, 0); + SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_LEAVE, 0, 0); FocusAllMice(_this, 0); /* SDL_DirectFB_ReshowCursor(_this, 1); */ break; @@ -301,7 +310,7 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) SDL_DFB_DEVICEDATA(_this); SDL_KeySym keysym; int kbd_idx; - char text[5]; + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; if (!devdata->use_linux_input) { if (ievt->type == DIET_AXISMOTION) { @@ -336,7 +345,7 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) (DFB_WindowData *) window->driverdata; int x, y; - windata->window->GetPosition(windata->window, &x, &y); + windata->dfbwin->GetPosition(windata->dfbwin, &x, &y); SDL_SendMouseMotion_ex(window, ievt->device_id, 0, last_x - (x + windata->client.x), @@ -358,11 +367,12 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) break; case DIET_KEYPRESS: kbd_idx = KbdIndex(_this, ievt->device_id); - DirectFB_TranslateKeyInputEvent(_this, kbd_idx, ievt, &keysym); + DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym); + //printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); SDL_SendKeyboardKey_ex(kbd_idx, SDL_PRESSED, keysym.scancode); if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { - SDL_memcpy(text, &keysym.unicode, 4); - text[4] = 0; + SDL_zero(text); + UnicodeToUtf8(keysym.unicode, text); if (*text) { SDL_SendKeyboardText_ex(kbd_idx, text); } @@ -370,7 +380,7 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) break; case DIET_KEYRELEASE: kbd_idx = KbdIndex(_this, ievt->device_id); - DirectFB_TranslateKeyInputEvent(_this, kbd_idx, ievt, &keysym); + DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym); SDL_SendKeyboardKey_ex(kbd_idx, SDL_RELEASED, keysym.scancode); break; case DIET_BUTTONPRESS: @@ -399,29 +409,46 @@ void DirectFB_PumpEventsWindow(_THIS) { SDL_DFB_DEVICEDATA(_this); - DFB_WindowData *p; DFBInputEvent ievt; + SDL_Window *w; - for (p = devdata->firstwin; p != NULL; p = p->next) { + for (w = devdata->firstwin; w != NULL; w = w->next) { + SDL_DFB_WINDOWDATA(w); DFBWindowEvent evt; - SDL_Window *w = p->sdl_window; - while (p->eventbuffer->GetEvent(p->eventbuffer, + while (windata->eventbuffer->GetEvent(windata->eventbuffer, DFB_EVENT(&evt)) == DFB_OK) { - if (!DirectFB_WM_ProcessEvent(_this, w, &evt)) - ProcessWindowEvent(_this, p, w->flags, &evt); + if (!DirectFB_WM_ProcessEvent(_this, w, &evt)) { + /* Send a SDL_SYSWMEVENT if the application wants them */ + if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { + SDL_SysWMmsg wmmsg; + SDL_VERSION(&wmmsg.version); + wmmsg.subsystem = SDL_SYSWM_DIRECTFB; + wmmsg.msg.dfb.event.window = evt; + SDL_SendSysWMEvent(&wmmsg); + } + ProcessWindowEvent(_this, w, &evt); + } } } /* Now get relative events in case we need them */ while (devdata->events->GetEvent(devdata->events, DFB_EVENT(&ievt)) == DFB_OK) { + + if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { + SDL_SysWMmsg wmmsg; + SDL_VERSION(&wmmsg.version); + wmmsg.subsystem = SDL_SYSWM_DIRECTFB; + wmmsg.msg.dfb.event.input = ievt; + SDL_SendSysWMEvent(&wmmsg); + } ProcessInputEvent(_this, &ievt); } } void -DirectFB_InitOSKeymap(_THIS, SDLKey * keymap, int numkeys) +DirectFB_InitOSKeymap(_THIS, SDL_ScanCode * keymap, int numkeys) { int i; @@ -552,15 +579,17 @@ static SDL_KeySym * DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_KeySym * keysym) { SDL_DFB_DEVICEDATA(_this); + int kbd_idx = 0; /* Window events lag the device source KbdIndex(_this, evt->device_id); */ + DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx]; - if (evt->key_code >= 0 && - evt->key_code < SDL_arraysize(linux_scancode_table)) - keysym->scancode = linux_scancode_table[evt->key_code]; - else - keysym->scancode = SDL_SCANCODE_UNKNOWN; + keysym->scancode = SDL_SCANCODE_UNKNOWN; + + if (kbd->map && evt->key_code >= kbd->map_adjust && + evt->key_code < kbd->map_size + kbd->map_adjust) + keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust]; if (keysym->scancode == SDL_SCANCODE_UNKNOWN || - devdata->keyboard[0].is_generic) { + devdata->keyboard[kbd_idx].is_generic) { if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap)) keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN]; else @@ -577,19 +606,20 @@ DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_KeySym * keysym) } static SDL_KeySym * -DirectFB_TranslateKeyInputEvent(_THIS, int index, DFBInputEvent * evt, +DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt, SDL_KeySym * keysym) { SDL_DFB_DEVICEDATA(_this); + int kbd_idx = KbdIndex(_this, evt->device_id); + DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx]; - if (evt->key_code >= 0 && - evt->key_code < SDL_arraysize(linux_scancode_table)) - keysym->scancode = linux_scancode_table[evt->key_code]; - else - keysym->scancode = SDL_SCANCODE_UNKNOWN; + keysym->scancode = SDL_SCANCODE_UNKNOWN; - if (keysym->scancode == SDL_SCANCODE_UNKNOWN || - devdata->keyboard[index].is_generic) { + if (kbd->map && evt->key_code >= kbd->map_adjust && + evt->key_code < kbd->map_size + kbd->map_adjust) + keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust]; + + if (keysym->scancode == SDL_SCANCODE_UNKNOWN || devdata->keyboard[kbd_idx].is_generic) { if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap)) keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN]; else @@ -652,8 +682,18 @@ EnumKeyboards(DFBInputDeviceID device_id, devdata->keyboard[devdata->num_keyboard].id = device_id; devdata->keyboard[devdata->num_keyboard].is_generic = 0; if (!strncmp("X11", desc.name, 3)) - devdata->keyboard[devdata->num_keyboard].is_generic = 1; + { + devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2; + devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2); + devdata->keyboard[devdata->num_keyboard].map_adjust = 8; + } else { + devdata->keyboard[devdata->num_keyboard].map = linux_scancode_table; + devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(linux_scancode_table); + devdata->keyboard[devdata->num_keyboard].map_adjust = 0; + } + SDL_DFB_LOG("Keyboard %d - %s\n", device_id, desc.name); + SDL_GetDefaultKeymap(keymap); #if USE_MULTI_API SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES); @@ -707,74 +747,3 @@ DirectFB_QuitKeyboard(_THIS) } -#if 0 -/* FIXME: Remove once determined this is not needed in fullscreen mode */ -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 641313667..be953ea1a 100644 --- a/src/video/directfb/SDL_DirectFB_events.h +++ b/src/video/directfb/SDL_DirectFB_events.h @@ -18,13 +18,19 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" -#include "SDL_DirectFB_video.h" +#ifndef _SDL_DirectFB_events_h +#define _SDL_DirectFB_events_h + +#include "../SDL_sysvideo.h" /* Functions to be exported */ extern void DirectFB_InitKeyboard(_THIS); extern void DirectFB_QuitKeyboard(_THIS); extern void DirectFB_PumpEventsWindow(_THIS); -extern SDLKey DirectFB_GetLayoutKey(_THIS, SDLKey physicalKey); + +#endif diff --git a/src/video/directfb/SDL_DirectFB_modes.c b/src/video/directfb/SDL_DirectFB_modes.c index bb336c7cd..221a034ef 100644 --- a/src/video/directfb/SDL_DirectFB_modes.c +++ b/src/video/directfb/SDL_DirectFB_modes.c @@ -18,14 +18,17 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" #include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_modes.h" #define DFB_MAX_MODES 200 -struct scn_callback_t +struct screen_callback_t { int numscreens; DFBScreenID screenid[DFB_MAX_SCREENS]; @@ -40,103 +43,6 @@ struct modes_callback_t SDL_DisplayMode *modelist; }; -static const struct { - DFBSurfacePixelFormat dfb; - Uint32 sdl; -} pixelformat_tab[] = -{ - { DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 }, /* 8 bit LUT (8 bit color and alpha lookup from palette) */ - { DSPF_RGB332, SDL_PIXELFORMAT_RGB332 }, /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */ - { DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 }, /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */ - { DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 }, /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */ - { DSPF_RGB16, SDL_PIXELFORMAT_RGB565 }, /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */ - { DSPF_RGB24, SDL_PIXELFORMAT_RGB24 }, /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */ - { DSPF_RGB32, SDL_PIXELFORMAT_RGB888 }, /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */ - { DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 }, /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */ - { DSPF_RGB444, SDL_PIXELFORMAT_RGB444 }, /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */ - { DSPF_YV12, SDL_PIXELFORMAT_YV12 }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */ - { DSPF_I420,SDL_PIXELFORMAT_IYUV }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */ - { DSPF_YUY2, SDL_PIXELFORMAT_YUY2 }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */ - { DSPF_UYVY, SDL_PIXELFORMAT_UYVY }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */ - { DSPF_RGB555, SDL_PIXELFORMAT_RGB555 }, /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */ - -#if (DFB_VERSION_ATLEAST(1,2,0)) - { DSPF_BGR555, SDL_PIXELFORMAT_BGR555 }, /* 16 bit BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */ -#else - { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR555 }, -#endif - - /* Pfff ... nonmatching formats follow */ - - { DSPF_ALUT44, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit ALUT (1 byte, alpha 4@4, color lookup 4@0) */ - { DSPF_A8, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit alpha (1 byte, alpha 8@0), e.g. anti-aliased glyphs */ - { DSPF_AiRGB, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */ - { DSPF_A1, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */ - { DSPF_NV12, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CbCr [15:0] plane) */ - { DSPF_NV16, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit YUV (8 bit Y plane followed by one 16 bit half width CbCr [15:0] plane) */ - { DSPF_ARGB2554, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */ - { DSPF_NV21, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CrCb [15:0] plane) */ - { DSPF_AYUV, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */ - { DSPF_A4, SDL_PIXELFORMAT_UNKNOWN }, /* 4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */ - { DSPF_ARGB1666, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (3 byte/ alpha 1@18, red 6@16, green 6@6, blue 6@0) */ - { DSPF_ARGB6666, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit alpha (3 byte/ alpha 6@18, red 6@16, green 6@6, blue 6@0) */ - { DSPF_RGB18, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit RGB (3 byte/ red 6@16, green 6@6, blue 6@0) */ - { DSPF_LUT2, SDL_PIXELFORMAT_UNKNOWN }, /* 2 bit LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */ - -#if (DFB_VERSION_ATLEAST(1,3,0)) - { DSPF_RGBA4444, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 4@12, green 4@8, blue 4@4, alpha 4@0) */ -#endif - -#if (DFB_VERSION_ATLEAST(1,4,0)) - { DSPF_RGBA5551, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 5@11, green 5@6, blue 5@1, alpha 1@0) */ - { DSPF_YUV444P, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit full YUV planar (8 bit Y plane followed by an 8 bit Cb and an 8 bit Cr plane) */ - { DSPF_ARGB8565, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit ARGB (3 byte, alpha 8@16, red 5@11, green 6@5, blue 5@0) */ - { DSPF_AVYU, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AVYU 4:4:4 (4 byte, alpha 8@24, Cr 8@16, Y 8@8, Cb 8@0) */ - { DSPF_VYU, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit VYU 4:4:4 (3 byte, Cr 8@16, Y 8@8, Cb 8@0) */ -#endif - - { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1MSB }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4LSB }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4MSB }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR24 }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR888 }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_RGBA8888 }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR8888 }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGRA8888 }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_ARGB2101010 }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR4444 }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR1555 }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR565 }, - { DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU }, /**< Packed mode: Y0+V0+Y1+U0 (1 pla */ -}; - -static Uint32 -DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat) -{ - int i; - - for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++) - if (pixelformat_tab[i].dfb == pixelformat) - { - return pixelformat_tab[i].sdl; - } - return SDL_PIXELFORMAT_UNKNOWN; -} - -static DFBSurfacePixelFormat -SDLToDFBPixelFormat(Uint32 format) -{ - int i; - - for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++) - if (pixelformat_tab[i].sdl == format) - { - return pixelformat_tab[i].dfb; - } - return DSPF_UNKNOWN; -} - static DFBEnumerationResult EnumModesCallback(int width, int height, int bpp, void *data) { @@ -157,20 +63,20 @@ EnumModesCallback(int width, int height, int bpp, void *data) } static DFBEnumerationResult -cbScreens(DFBScreenID screen_id, DFBScreenDescription desc, +EnumScreensCallback(DFBScreenID screen_id, DFBScreenDescription desc, void *callbackdata) { - struct scn_callback_t *devdata = (struct scn_callback_t *) callbackdata; + struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata; devdata->screenid[devdata->numscreens++] = screen_id; return DFENUM_OK; } -DFBEnumerationResult -cbLayers(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc, +static DFBEnumerationResult +EnumLayersCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc, void *callbackdata) { - struct scn_callback_t *devdata = (struct scn_callback_t *) callbackdata; + struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata; if (desc.caps & DLCAPS_SURFACE) { if ((desc.type & DLTF_GRAPHICS) && (desc.type & DLTF_VIDEO)) { @@ -195,7 +101,7 @@ CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, S DLSCL_ADMINISTRATIVE)); config.width = mode->w; config.height = mode->h; - config.pixelformat = SDLToDFBPixelFormat(mode->format); + config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format); config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT; if (devdata->use_yuv_underlays) { config.flags |= DLCONF_OPTIONS; @@ -206,7 +112,10 @@ CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, S SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer, DLSCL_SHARED)); if (failed == 0) + { SDL_AddDisplayMode(display, mode); + SDL_DFB_LOG("Mode %d x %d Added\n", mode->w, mode->h); + } else SDL_DFB_ERR("Mode %d x %d not available: %x\n", mode->w, mode->h, failed); @@ -216,6 +125,26 @@ CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, S return; } + +void +DirectFB_SetContext(_THIS, SDL_Window *window) +{ +#if (DFB_VERSION_ATLEAST(1,0,0)) + /* FIXME: does not work on 1.0/1.2 with radeon driver + * the approach did work with the matrox driver + * This has simply no effect. + */ + + SDL_VideoDisplay *display = window->display; + DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; + + /* FIXME: should we handle the error */ + if (dispdata->vidIDinuse) + SDL_DFB_CHECK(dispdata->vidlayer->SwitchContext(dispdata->vidlayer, + DFB_TRUE)); +#endif +} + void DirectFB_InitModes(_THIS) { @@ -226,14 +155,14 @@ DirectFB_InitModes(_THIS) SDL_DisplayMode mode; DFBGraphicsDeviceDescription caps; DFBDisplayLayerConfig dlc; - struct scn_callback_t *screencbdata; + struct screen_callback_t *screencbdata; int tcw[DFB_MAX_SCREENS]; int tch[DFB_MAX_SCREENS]; int i; DFBResult ret; - SDL_DFB_CALLOC(screencbdata, 1, sizeof(*screencbdata)); + SDL_DFB_ALLOC_CLEAR(screencbdata, sizeof(*screencbdata)); screencbdata->numscreens = 0; @@ -242,7 +171,7 @@ DirectFB_InitModes(_THIS) screencbdata->vidlayer[i] = -1; } - SDL_DFB_CHECKERR(devdata->dfb->EnumScreens(devdata->dfb, &cbScreens, + SDL_DFB_CHECKERR(devdata->dfb->EnumScreens(devdata->dfb, &EnumScreensCallback, screencbdata)); for (i = 0; i < screencbdata->numscreens; i++) { @@ -253,9 +182,10 @@ DirectFB_InitModes(_THIS) [i], &screen)); screencbdata->aux = i; - SDL_DFB_CHECKERR(screen->EnumDisplayLayers(screen, &cbLayers, + SDL_DFB_CHECKERR(screen->EnumDisplayLayers(screen, &EnumLayersCallback, screencbdata)); screen->GetSize(screen, &tcw[i], &tch[i]); + screen->Release(screen); } @@ -263,10 +193,6 @@ DirectFB_InitModes(_THIS) devdata->dfb->GetDeviceDescription(devdata->dfb, &caps); - SDL_DFB_DEBUG("SDL directfb video driver - %s %s\n", __DATE__, __TIME__); - SDL_DFB_DEBUG("Using %s (%s) driver.\n", caps.name, caps.vendor); - SDL_DFB_DEBUG("Found %d screens\n", screencbdata->numscreens); - for (i = 0; i < screencbdata->numscreens; i++) { SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb, screencbdata->gralayer @@ -282,7 +208,7 @@ DirectFB_InitModes(_THIS) dlc.pixelformat = DSPF_ARGB; dlc.options = DLOP_ALPHACHANNEL; - ret = SDL_DFB_CHECK(layer->SetConfiguration(layer, &dlc)); + ret = layer->SetConfiguration(layer, &dlc); if (ret != DFB_OK) { /* try AiRGB if the previous failed */ dlc.pixelformat = DSPF_AiRGB; @@ -294,7 +220,7 @@ DirectFB_InitModes(_THIS) dlc.flags = DLCONF_ALL; SDL_DFB_CHECKERR(layer->GetConfiguration(layer, &dlc)); - mode.format = DFBToSDLPixelFormat(dlc.pixelformat); + mode.format = DirectFB_DFBToSDLPixelFormat(dlc.pixelformat); if (mode.format == SDL_PIXELFORMAT_UNKNOWN) { SDL_DFB_ERR("Unknown dfb pixelformat %x !\n", dlc.pixelformat); @@ -306,7 +232,7 @@ DirectFB_InitModes(_THIS) mode.refresh_rate = 0; mode.driverdata = NULL; - SDL_DFB_CALLOC(dispdata, 1, sizeof(*dispdata)); + SDL_DFB_ALLOC_CLEAR(dispdata, sizeof(*dispdata)); dispdata->layer = layer; dispdata->pixelformat = dlc.pixelformat; @@ -399,7 +325,7 @@ DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mod config.flags = DLCONF_WIDTH | DLCONF_HEIGHT; if (mode->format != SDL_PIXELFORMAT_UNKNOWN) { config.flags |= DLCONF_PIXELFORMAT; - config.pixelformat = SDLToDFBPixelFormat(mode->format); + config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format); data->pixelformat = config.pixelformat; } config.width = mode->w; @@ -420,7 +346,6 @@ DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mod return -1; } - SDL_DFB_DEBUG("Trace\n"); config.flags &= ~fail; SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config)); #if (DFB_VERSION_ATLEAST(1,2,0)) @@ -454,7 +379,6 @@ DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mod void DirectFB_QuitModes(_THIS) { - //DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata; SDL_DisplayMode tmode; int i; diff --git a/src/video/directfb/SDL_DirectFB_modes.h b/src/video/directfb/SDL_DirectFB_modes.h index 6f5dbf9e6..2ccffe863 100644 --- a/src/video/directfb/SDL_DirectFB_modes.h +++ b/src/video/directfb/SDL_DirectFB_modes.h @@ -18,32 +18,36 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" #ifndef _SDL_directfb_modes_h #define _SDL_directfb_modes_h -#include "SDL_DirectFB_video.h" +#include + +#include "../SDL_sysvideo.h" -#define SDL_DFB_DISPLAYDATA(dev, win) DFB_DisplayData *dispdata = ((win && dev) ? (DFB_DisplayData *) (win)->display->driverdata : NULL) +#define SDL_DFB_DISPLAYDATA(win) DFB_DisplayData *dispdata = ((win) ? (DFB_DisplayData *) (win)->display->driverdata : NULL) typedef struct _DFB_DisplayData DFB_DisplayData; struct _DFB_DisplayData { - IDirectFBDisplayLayer *layer; - DFBSurfacePixelFormat pixelformat; + IDirectFBDisplayLayer *layer; + DFBSurfacePixelFormat pixelformat; /* FIXME: support for multiple video layer. * However, I do not know any card supporting * more than one */ - DFBDisplayLayerID vidID; - IDirectFBDisplayLayer *vidlayer; + DFBDisplayLayerID vidID; + IDirectFBDisplayLayer *vidlayer; - int vidIDinuse; + int vidIDinuse; - int cw; - int ch; + int cw; + int ch; }; @@ -52,6 +56,8 @@ extern void DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display); extern int DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); extern void DirectFB_QuitModes(_THIS); +extern void DirectFB_SetContext(_THIS, SDL_Window *window); + #endif /* _SDL_directfb_modes_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_mouse.c b/src/video/directfb/SDL_DirectFB_mouse.c index be0315b03..0e887b8e7 100644 --- a/src/video/directfb/SDL_DirectFB_mouse.c +++ b/src/video/directfb/SDL_DirectFB_mouse.c @@ -18,7 +18,11 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ + #include "SDL_config.h" #include "SDL_DirectFB_video.h" @@ -123,8 +127,8 @@ DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) Uint32 *p; int pitch, i; - SDL_DFB_CALLOC(cursor, 1, sizeof(*cursor)); - SDL_DFB_CALLOC(curdata, 1, sizeof(*curdata)); + SDL_DFB_ALLOC_CLEAR(cursor, 1, sizeof(*cursor)); + SDL_DFB_ALLOC_CLEAR(curdata, 1, sizeof(*curdata)); dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; @@ -175,7 +179,7 @@ DirectFB_ShowCursor(SDL_Cursor * cursor) if (cursor) SDL_DFB_CHECKERR(windata->window-> - SetCursorShape(windata->window, + SetCursorShape(windata->dfbwin, curdata->surf, curdata->hotx, curdata->hoty)); @@ -224,7 +228,7 @@ DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y) DFBResult ret; int cx, cy; - SDL_DFB_CHECKERR(windata->window->GetPosition(windata->window, &cx, &cy)); + SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy)); SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer, cx + x + windata->client.x, cy + y + windata->client.y)); @@ -253,7 +257,6 @@ DirectFB_InitMouse(_THIS) void DirectFB_QuitMouse(_THIS) { - //SDL_DFB_DEVICEDATA(_this); } diff --git a/src/video/directfb/SDL_DirectFB_mouse.h b/src/video/directfb/SDL_DirectFB_mouse.h index f04da53dc..1f882a185 100644 --- a/src/video/directfb/SDL_DirectFB_mouse.h +++ b/src/video/directfb/SDL_DirectFB_mouse.h @@ -18,19 +18,24 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" #ifndef _SDL_DirectFB_mouse_h #define _SDL_DirectFB_mouse_h -typedef struct _DFB_CursorData DFB_CursorData; +#include +#include "../SDL_sysvideo.h" + +typedef struct _DFB_CursorData DFB_CursorData; struct _DFB_CursorData { IDirectFBSurface *surf; - int hotx; - int hoty; + int hotx; + int hoty; }; #define SDL_DFB_CURSORDATA(curs) DFB_CursorData *curdata = (DFB_CursorData *) ((curs) ? (curs)->driverdata : NULL) diff --git a/src/video/directfb/SDL_DirectFB_opengl.c b/src/video/directfb/SDL_DirectFB_opengl.c index 22c642275..faa0aa227 100644 --- a/src/video/directfb/SDL_DirectFB_opengl.c +++ b/src/video/directfb/SDL_DirectFB_opengl.c @@ -13,16 +13,26 @@ 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 + 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 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" #include "SDL_DirectFB_video.h" +#if SDL_DIRECTFB_OPENGL +#include "SDL_DirectFB_opengl.h" +#include "SDL_DirectFB_window.h" + +#include +#include "SDL_loadso.h" +#endif + #if SDL_DIRECTFB_OPENGL struct SDL_GLDriverData @@ -177,7 +187,7 @@ DirectFB_GL_CreateContext(_THIS, SDL_Window * window) SDL_DFB_WINDOWDATA(window); DirectFB_GLContext *context; - SDL_DFB_CALLOC(context, 1, sizeof(DirectFB_GLContext)); + SDL_DFB_ALLOC_CLEAR(context, sizeof(DirectFB_GLContext)); SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface, &context->context)); diff --git a/src/video/directfb/SDL_DirectFB_opengl.h b/src/video/directfb/SDL_DirectFB_opengl.h index 9757df42c..e43730d80 100644 --- a/src/video/directfb/SDL_DirectFB_opengl.h +++ b/src/video/directfb/SDL_DirectFB_opengl.h @@ -18,23 +18,29 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" + #ifndef _SDL_directfb_opengl_h #define _SDL_directfb_opengl_h +#include "SDL_DirectFB_video.h" + #if SDL_DIRECTFB_OPENGL + #include "SDL_opengl.h" typedef struct _DirectFB_GLContext DirectFB_GLContext; struct _DirectFB_GLContext { - IDirectFBGL *context; - DirectFB_GLContext *next; + IDirectFBGL *context; + DirectFB_GLContext *next; - SDL_Window *sdl_window; - int is_locked; + SDL_Window *sdl_window; + int is_locked; }; /* OpenGL functions */ diff --git a/src/video/directfb/SDL_DirectFB_render.c b/src/video/directfb/SDL_DirectFB_render.c index 8918ef56a..dd928ffcf 100644 --- a/src/video/directfb/SDL_DirectFB_render.c +++ b/src/video/directfb/SDL_DirectFB_render.c @@ -18,47 +18,74 @@ Sam Lantinga slouken@libsdl.org - - SDL1.3 implementation by couriersud@arcor.de - -*/ -#include "SDL_config.h" + SDL1.3 DirectFB driver by couriersud@arcor.de + +*/ #include "SDL_DirectFB_video.h" -#include "SDL_DirectFB_render.h" -#include "../SDL_yuv_sw_c.h" +#include "SDL_DirectFB_window.h" +#include "SDL_DirectFB_modes.h" + +#include "SDL_DirectFB_shape.h" + +#include "../SDL_sysvideo.h" +#include "../../render/SDL_sysrender.h" +//#include "../SDL_rect_c.h" +//#include "../SDL_yuv_sw_c.h" /* the following is not yet tested ... */ #define USE_DISPLAY_PALETTE (0) + +#define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL) + + /* GDI renderer implementation */ static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags); -static int DirectFB_DisplayModeChanged(SDL_Renderer * renderer); -static int DirectFB_ActivateRenderer(SDL_Renderer * renderer); +static void DirectFB_ActivateRenderer(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, + const SDL_Rect * rect, 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_SetDrawBlendMode(SDL_Renderer * renderer); static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, int count); static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count); +static int DirectFB_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect ** rects, int count); static int DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count); static int DirectFB_RenderCopy(SDL_Renderer * renderer, @@ -69,6 +96,11 @@ static void DirectFB_RenderPresent(SDL_Renderer * renderer); static void DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); static void DirectFB_DestroyRenderer(SDL_Renderer * renderer); +static int DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch); +static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, const void * pixels, int pitch); + #define SDL_DFB_WINDOWSURFACE(win) IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface; @@ -77,20 +109,16 @@ SDL_RenderDriver DirectFB_RenderDriver = { { "directfb", (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED), - 12, + /* (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR | + SDL_TEXTUREMODULATE_ALPHA), + (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | + SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD), + (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST | + SDL_SCALEMODE_SLOW | SDL_SCALEMODE_BEST),*/ + 0, { - 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}, + /* formats filled in later */ + }, 0, 0} }; @@ -99,7 +127,6 @@ typedef struct { SDL_Window *window; DFBSurfaceFlipFlags flipflags; - int isyuvdirect; int size_changed; int lastBlendMode; DFBSurfaceBlittingFlags blitFlags; @@ -112,8 +139,11 @@ typedef struct Uint32 format; void *pixels; int pitch; - SDL_VideoDisplay *display; - SDL_DirtyRectList dirty; + IDirectFBPalette *palette; + int isDirty; + + SDL_VideoDisplay *display; /* only for yuv textures */ + #if (DFB_VERSION_ATLEAST(1,2,0)) DFBSurfaceRenderOptions render_options; #endif @@ -135,7 +165,12 @@ TextureHasAlpha(DirectFB_TextureData * data) /* Drawing primitive ? */ if (!data) return 0; + + return (DFB_PIXELFORMAT_HAS_ALPHA(DirectFB_SDLToDFBPixelFormat(data->format)) ? 1 : 0); +#if 0 switch (data->format) { + case SDL_PIXELFORMAT_INDEX4LSB: + case SDL_PIXELFORMAT_INDEX4MSB: case SDL_PIXELFORMAT_ARGB4444: case SDL_PIXELFORMAT_ARGB1555: case SDL_PIXELFORMAT_ARGB8888: @@ -143,10 +178,11 @@ TextureHasAlpha(DirectFB_TextureData * data) case SDL_PIXELFORMAT_ABGR8888: case SDL_PIXELFORMAT_BGRA8888: case SDL_PIXELFORMAT_ARGB2101010: - return 1; + return 1; default: return 0; } +#endif } static void @@ -165,6 +201,14 @@ SetBlendMode(DirectFB_RenderData * data, int blendMode, SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE)); SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO)); break; +#if 0 + case SDL_BLENDMODE_MASK: + data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL; + data->drawFlags = DSDRAW_BLEND; + SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA)); + SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA)); + break; +#endif case SDL_BLENDMODE_BLEND: data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL; data->drawFlags = DSDRAW_BLEND; @@ -182,20 +226,75 @@ SetBlendMode(DirectFB_RenderData * data, int blendMode, else SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE)); SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ONE)); + break; + case SDL_BLENDMODE_MOD: + data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL; + data->drawFlags = DSDRAW_BLEND; + //SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_DESTCOLOR)); + //SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO)); + //data->glBlendFunc(GL_ZERO, GL_SRC_COLOR); + SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ZERO)); + SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_SRCCOLOR)); + break; } data->lastBlendMode = blendMode; } } -void -DirectFB_AddRenderDriver(_THIS) +static int +DisplayPaletteChanged(void *userdata, SDL_Palette * palette) { +#if USE_DISPLAY_PALETTE + DirectFB_RenderData *data = (DirectFB_RenderData *) userdata; + SDL_DFB_WINDOWSURFACE(data->window); + IDirectFBPalette *surfpal; + int i; + int ncolors; + DFBColor entries[256]; + + SDL_DFB_CHECKERR(destsurf->GetPalette(destsurf, &surfpal)); - for (i = 0; i < _this->num_displays; ++i) { - SDL_AddRenderDriver(&_this->displays[i], &DirectFB_RenderDriver); + /* FIXME: number of colors */ + ncolors = (palette->ncolors < 256 ? palette->ncolors : 256); + + for (i = 0; i < ncolors; ++i) { + entries[i].r = palette->colors[i].r; + entries[i].g = palette->colors[i].g; + entries[i].b = palette->colors[i].b; + entries[i].a = palette->colors[i].unused; } + SDL_DFB_CHECKERR(surfpal->SetEntries(surfpal, entries, ncolors, 0)); + return 0; + error: +#else + SDL_Unsupported(); +#endif + return -1; +} + +static void +DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +{ + SDL_DFB_RENDERERDATA(renderer); + + if (event->event == SDL_WINDOWEVENT_RESIZED) { + /* Rebind the context to the window area and update matrices */ + //SDL_CurrentContext = NULL; + //data->updateSize = SDL_TRUE; + renddata->size_changed = SDL_TRUE; + } +} + +int +DirectFB_RenderClear(SDL_Renderer * renderer) +{ + SDL_DFB_RENDERERDATA(renderer); + + DirectFB_ActivateRenderer(renderer); + + return 0; } SDL_Renderer * @@ -205,35 +304,53 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) SDL_VideoDisplay *display = window->display; SDL_Renderer *renderer = NULL; DirectFB_RenderData *data = NULL; - char *p; + DFBSurfaceCapabilities scaps; + //char *p; - SDL_DFB_CALLOC(renderer, 1, sizeof(*renderer)); - SDL_DFB_CALLOC(data, 1, sizeof(*data)); + SDL_DFB_ALLOC_CLEAR(renderer, sizeof(*renderer)); + SDL_DFB_ALLOC_CLEAR(data, sizeof(*data)); - renderer->DisplayModeChanged = DirectFB_DisplayModeChanged; - renderer->ActivateRenderer = DirectFB_ActivateRenderer; + renderer->WindowEvent = DirectFB_WindowEvent; renderer->CreateTexture = DirectFB_CreateTexture; - renderer->QueryTexturePixels = DirectFB_QueryTexturePixels; + renderer->SetTextureAlphaMod = DirectFB_SetTextureAlphaMod; + renderer->SetTextureColorMod = DirectFB_SetTextureColorMod; + renderer->SetTextureBlendMode = DirectFB_SetTextureBlendMode; renderer->UpdateTexture = DirectFB_UpdateTexture; renderer->LockTexture = DirectFB_LockTexture; + renderer->RenderClear = DirectFB_RenderClear; renderer->UnlockTexture = DirectFB_UnlockTexture; - renderer->DirtyTexture = DirectFB_DirtyTexture; renderer->RenderDrawPoints = DirectFB_RenderDrawPoints; renderer->RenderDrawLines = DirectFB_RenderDrawLines; + /* SetDrawColor - no needed */ renderer->RenderFillRects = DirectFB_RenderFillRects; /* RenderDrawEllipse - no reference implementation yet */ /* RenderFillEllipse - no reference implementation yet */ renderer->RenderCopy = DirectFB_RenderCopy; renderer->RenderPresent = DirectFB_RenderPresent; - /* RenderReadPixels is difficult to implement */ - /* RenderWritePixels is difficult to implement */ + + /* FIXME: Yet to be tested */ + renderer->RenderReadPixels = DirectFB_RenderReadPixels; + //renderer->RenderWritePixels = DirectFB_RenderWritePixels; + renderer->DestroyTexture = DirectFB_DestroyTexture; renderer->DestroyRenderer = DirectFB_DestroyRenderer; + +#if 0 + renderer->QueryTexturePixels = DirectFB_QueryTexturePixels; + renderer->SetTexturePalette = DirectFB_SetTexturePalette; + renderer->GetTexturePalette = DirectFB_GetTexturePalette; + renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode; + renderer->DirtyTexture = DirectFB_DirtyTexture; + renderer->SetDrawBlendMode = DirectFB_SetDrawBlendMode; + renderer->RenderDrawRects = DirectFB_RenderDrawRects; +#endif + renderer->info = DirectFB_RenderDriver.info; renderer->window = window; /* SDL window */ renderer->driverdata = data; - renderer->info.flags = SDL_RENDERER_ACCELERATED; + renderer->info.flags = + SDL_RENDERER_ACCELERATED; data->window = window; @@ -245,10 +362,26 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) } else data->flipflags |= DSFLIP_ONSYNC; - data->isyuvdirect = 0; /* default is off! */ - p = SDL_getenv(DFBENV_USE_YUV_DIRECT); - if (p) - data->isyuvdirect = atoi(p); + SDL_DFB_CHECKERR(windata->surface-> + GetCapabilities(windata->surface, &scaps)); + +#if 0 + 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; +#endif + + DirectFB_SetSupportedPixelFormats(&renderer->info); + +#if 0 + /* Set up a palette watch on the display palette */ + if (display->palette) { + SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data); + } +#endif return renderer; @@ -258,58 +391,7 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) return NULL; } -static DFBSurfacePixelFormat -SDLToDFBPixelFormat(Uint32 format) -{ - switch (format) { - 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) */ -#if (DFB_VERSION_ATLEAST(1,2,0)) - case SDL_PIXELFORMAT_RGB444: - return DSPF_RGB444; -#endif - 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 +static void DirectFB_ActivateRenderer(SDL_Renderer * renderer) { SDL_DFB_RENDERERDATA(renderer); @@ -317,24 +399,15 @@ DirectFB_ActivateRenderer(SDL_Renderer * renderer) SDL_DFB_WINDOWDATA(window); if (renddata->size_changed || windata->wm_needs_redraw) { -// DirectFB_AdjustWindowSurface(window); + DirectFB_AdjustWindowSurface(window); } - return 0; } -static int -DirectFB_DisplayModeChanged(SDL_Renderer * renderer) -{ - SDL_DFB_RENDERERDATA(renderer); - - renddata->size_changed = SDL_TRUE; - return 0; -} static int DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) { - SDL_DFB_RENDERERDATA(renderer); + //SDL_DFB_RENDERERDATA(renderer); SDL_Window *window = renderer->window; SDL_VideoDisplay *display = window->display; SDL_DFB_DEVICEDATA(display->device); @@ -343,7 +416,7 @@ DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) DFBDisplayLayerConfig layconf; DFBResult ret; - if (renddata->isyuvdirect && (dispdata->vidID >= 0) + if (devdata->use_yuv_direct && (dispdata->vidID >= 0) && (!dispdata->vidIDinuse) && SDL_ISPIXELFORMAT_FOURCC(data->format)) { layconf.flags = @@ -351,7 +424,7 @@ DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) DLCONF_SURFACE_CAPS; layconf.width = texture->w; layconf.height = texture->h; - layconf.pixelformat = SDLToDFBPixelFormat(data->format); + layconf.pixelformat = DirectFB_SDLToDFBPixelFormat(data->format); layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE; SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb, @@ -362,7 +435,7 @@ DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) DLSCL_EXCLUSIVE)); if (devdata->use_yuv_underlays) { - ret = SDL_DFB_CHECK(dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1)); + ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1); if (ret != DFB_OK) SDL_DFB_DEBUG("Underlay Setlevel not supported\n"); } @@ -398,11 +471,13 @@ DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) DFBSurfaceDescription dsc; DFBSurfacePixelFormat pixelformat; - SDL_DFB_CALLOC(data, 1, sizeof(*data)); + DirectFB_ActivateRenderer(renderer); + + SDL_DFB_ALLOC_CLEAR(data, sizeof(*data)); texture->driverdata = data; /* find the right pixelformat */ - pixelformat = SDLToDFBPixelFormat(texture->format); + pixelformat = DirectFB_SDLToDFBPixelFormat(texture->format); if (pixelformat == DSPF_UNKNOWN) { SDL_SetError("Unknown pixel format %d\n", data->format); goto error; @@ -417,6 +492,12 @@ DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; dsc.width = texture->w; dsc.height = texture->h; + if(texture->format == SDL_PIXELFORMAT_YV12 || + texture->format == SDL_PIXELFORMAT_IYUV) { + /* dfb has problems with odd sizes -make them even internally */ + dsc.width += (dsc.width % 2); + dsc.height += (dsc.height % 2); + } /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance * No DSCAPS_SYSTEMONLY either - let dfb decide * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8 @@ -436,18 +517,33 @@ DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) /* 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)) { +#if 1 + SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface, &data->palette)); +#else + /* DFB has issues with blitting LUT8 surfaces. + * Creating a new palette does not help. + */ + DFBPaletteDescription pal_desc; + pal_desc.flags = DPDESC_SIZE; // | DPDESC_ENTRIES + pal_desc.size = 256; + SDL_DFB_CHECKERR(devdata->dfb->CreatePalette(devdata->dfb, &pal_desc,&data->palette)); + SDL_DFB_CHECKERR(data->surface->SetPalette(data->surface, data->palette)); +#endif + } + } #if (DFB_VERSION_ATLEAST(1,2,0)) data->render_options = DSRO_NONE; #endif - if (texture->access == SDL_TEXTUREACCESS_STREAMING) { /* 3 plane YUVs return 1 bpp, but we need more space for other planes */ if(texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { - SDL_DFB_CALLOC(data->pixels, 1, (texture->h * data->pitch * 3 + texture->h * data->pitch * 3 % 2) / 2); + SDL_DFB_ALLOC_CLEAR(data->pixels, (texture->h * data->pitch + ((texture->h + texture->h % 2) * (data->pitch + data->pitch % 2) * 2) / 4)); } else { - SDL_DFB_CALLOC(data->pixels, 1, texture->h * data->pitch); + SDL_DFB_ALLOC_CLEAR(data->pixels, texture->h * data->pitch); } } @@ -476,6 +572,116 @@ DirectFB_QueryTexturePixels(SDL_Renderer * renderer, return 0; } +static int +DirectFB_SetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, + int ncolors) +{ + DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + if (SDL_ISPIXELFORMAT_INDEXED(data->format) + && !SDL_ISPIXELFORMAT_FOURCC(data->format)) { + DFBColor entries[256]; + int i; + + if (ncolors > 256) + ncolors = 256; + + 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; + + 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; + colors->unused = SDL_ALPHA_OPAQUE; + } + 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_BLENDMODE_NONE: + //case SDL_BLENDMODE_MASK: + case SDL_BLENDMODE_BLEND: + case SDL_BLENDMODE_ADD: + case SDL_BLENDMODE_MOD: + return 0; + default: + SDL_Unsupported(); + texture->blendMode = SDL_BLENDMODE_NONE; + return -1; + } +} + +static int +DirectFB_SetDrawBlendMode(SDL_Renderer * renderer) +{ + switch (renderer->blendMode) { + case SDL_BLENDMODE_NONE: + //case SDL_BLENDMODE_MASK: + case SDL_BLENDMODE_BLEND: + case SDL_BLENDMODE_ADD: + case SDL_BLENDMODE_MOD: + return 0; + default: + SDL_Unsupported(); + renderer->blendMode = SDL_BLENDMODE_NONE; + return -1; + } +} + +#if 0 static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) { @@ -504,6 +710,7 @@ DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) #endif return 0; } +#endif static int DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, @@ -515,9 +722,16 @@ DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, Uint8 *src, *dst; int row; size_t length; - int bpp = DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format)); + int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format)); // FIXME: SDL_BYTESPERPIXEL(texture->format) broken for yuv yv12 3 planes + DirectFB_ActivateRenderer(renderer); + + if ((texture->format == SDL_PIXELFORMAT_YV12) || + (texture->format == SDL_PIXELFORMAT_IYUV)) { + bpp = 1; + } + SDL_DFB_CHECKERR(data->surface->Lock(data->surface, DSLF_WRITE | DSLF_READ, ((void **) &dpixels), &dpitch)); @@ -530,24 +744,25 @@ DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, dst += dpitch; } /* copy other planes for 3 plane formats */ - if (texture->format == SDL_PIXELFORMAT_YV12 || - texture->format == SDL_PIXELFORMAT_IYUV) { + if ((texture->format == SDL_PIXELFORMAT_YV12) || + (texture->format == SDL_PIXELFORMAT_IYUV)) { src = (Uint8 *) pixels + texture->h * pitch; dst = (Uint8 *) dpixels + texture->h * dpitch + rect->y * dpitch / 4 + rect->x * bpp / 2; - for (row = 0; row < rect->h / 2; ++row) { + for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) { SDL_memcpy(dst, src, length / 2); src += pitch / 2; dst += dpitch / 2; } src = (Uint8 *) pixels + texture->h * pitch + texture->h * pitch / 4; dst = (Uint8 *) dpixels + texture->h * dpitch + texture->h * dpitch / 4 + rect->y * dpitch / 4 + rect->x * bpp / 2; - for (row = 0; row < rect->h / 2; ++row) { + for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) { SDL_memcpy(dst, src, length / 2); src += pitch / 2; dst += dpitch / 2; } } SDL_DFB_CHECKERR(data->surface->Unlock(data->surface)); + data->isDirty = 0; return 0; error: return 1; @@ -556,15 +771,18 @@ DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, static int DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, int markDirty, - void **pixels, int *pitch) + const SDL_Rect * rect, void **pixels, int *pitch) { DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; + DirectFB_ActivateRenderer(renderer); + +#if 0 if (markDirty) { SDL_AddDirtyRect(&texturedata->dirty, rect); } +#endif if (texturedata->display) { void *fdata; @@ -579,8 +797,9 @@ DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, *pixels = (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch + - rect->x * DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format))); + rect->x * DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format))); *pitch = texturedata->pitch; + texturedata->isDirty = 1; } return 0; @@ -594,12 +813,15 @@ DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; + DirectFB_ActivateRenderer(renderer); + if (texturedata->display) { SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface)); texturedata->pixels = NULL; } } +#if 0 static void DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, const SDL_Rect * rects) @@ -611,6 +833,7 @@ DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, SDL_AddDirtyRect(&data->dirty, &rects[i]); } } +#endif static int PrepareDraw(SDL_Renderer * renderer) @@ -630,9 +853,11 @@ PrepareDraw(SDL_Renderer * renderer) switch (renderer->blendMode) { case SDL_BLENDMODE_NONE: + //case SDL_BLENDMODE_MASK: case SDL_BLENDMODE_BLEND: break; case SDL_BLENDMODE_ADD: + case SDL_BLENDMODE_MOD: r = ((int) r * (int) a) / 255; g = ((int) g * (int) a) / 255; b = ((int) b * (int) a) / 255; @@ -653,6 +878,8 @@ static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer, SDL_DFB_WINDOWSURFACE(data->window); int i; + DirectFB_ActivateRenderer(renderer); + PrepareDraw(renderer); for (i=0; i < count; i++) SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, points[i].x, points[i].y, points[i].x, points[i].y)); @@ -668,6 +895,8 @@ static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, SDL_DFB_WINDOWSURFACE(data->window); int i; + DirectFB_ActivateRenderer(renderer); + PrepareDraw(renderer); /* Use antialiasing when available */ #if (DFB_VERSION_ATLEAST(1,2,0)) @@ -682,6 +911,26 @@ static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, return -1; } +static int +DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) +{ + DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; + SDL_DFB_WINDOWSURFACE(data->window); + int i; + + DirectFB_ActivateRenderer(renderer); + + PrepareDraw(renderer); + + for (i=0; iDrawRectangle(destsurf, rects[i]->x, rects[i]->y, + rects[i]->w, rects[i]->h)); + + return 0; + error: + return -1; +} + static int DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) { @@ -689,6 +938,8 @@ DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int c SDL_DFB_WINDOWSURFACE(data->window); int i; + DirectFB_ActivateRenderer(renderer); + PrepareDraw(renderer); for (i=0; iwindow); DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; - Uint8 alpha = 0xFF; + Uint8 alpha, r, g, b; + + DirectFB_ActivateRenderer(renderer); if (texturedata->display) { int px, py; @@ -722,7 +975,7 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, srcrect->x, srcrect->y, srcrect->w, srcrect->h)); - SDL_DFB_CHECK(windata->window->GetPosition(windata->window, &px, &py)); + SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin, &px, &py)); px += windata->client.x; py += windata->client.y; SDL_DFB_CHECKERR(dispdata-> @@ -735,10 +988,11 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, DFBRectangle sr, dr; DFBSurfaceBlittingFlags flags = 0; +#if 0 if (texturedata->dirty.list) { SDL_DirtyRect *dirty; void *pixels; - int bpp = DFB_BYTES_PER_PIXEL(SDLToDFBPixelFormat(texture->format)); + int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format)); int pitch = texturedata->pitch; for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) { @@ -747,38 +1001,43 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, (void *) ((Uint8 *) texturedata->pixels + rect->y * pitch + rect->x * bpp); DirectFB_UpdateTexture(renderer, texture, rect, - texturedata->pixels, + pixels, texturedata->pitch); } SDL_ClearDirtyRects(&texturedata->dirty); } +#endif + if (texturedata->isDirty) + { + SDL_Rect rect; + + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + + DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch); + } SDLtoDFBRect(srcrect, &sr); SDLtoDFBRect(dstrect, &dr); + alpha = r = g = b = 0xff; + if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA){ + alpha = texture->a; + flags |= DSBLIT_BLEND_COLORALPHA; + } + + if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { + r = texture->r; + g = texture->g; + b = texture->b; + flags |= DSBLIT_COLORIZE; + } SDL_DFB_CHECKERR(destsurf-> - SetColor(destsurf, 0xFF, 0xFF, 0xFF, 0xFF)); - if (texture-> - modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA)) - { - if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) { - alpha = texture->a; - SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, 0xFF, 0xFF, - 0xFF, alpha)); - } - if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) { + SetColor(destsurf, r, g, b, alpha)); - SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, - texture->r, - texture->g, - texture->b, alpha)); - flags |= DSBLIT_COLORIZE; - } - if (alpha < 0xFF) - flags |= DSBLIT_SRC_PREMULTCOLOR; - } else - SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, 0xFF, 0xFF, - 0xFF, 0xFF)); + // ???? flags |= DSBLIT_SRC_PREMULTCOLOR; SetBlendMode(data, texture->blendMode, texturedata); @@ -812,13 +1071,27 @@ DirectFB_RenderPresent(SDL_Renderer * renderer) DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; SDL_DFB_WINDOWDATA(window); - - DFBRectangle sr; - - sr.x = 0; - sr.y = 0; - sr.w = window->w; - sr.h = window->h; + SDL_ShapeData *shape_data = (window->shaper ? window->shaper->driverdata : NULL); + + DirectFB_ActivateRenderer(renderer); + + if (shape_data && shape_data->surface) { + /* saturate the window surface alpha channel */ + SDL_DFB_CHECK(windata->window_surface->SetSrcBlendFunction(windata->window_surface, DSBF_ONE)); + SDL_DFB_CHECK(windata->window_surface->SetDstBlendFunction(windata->window_surface, DSBF_ONE)); + SDL_DFB_CHECK(windata->window_surface->SetDrawingFlags(windata->window_surface, DSDRAW_BLEND)); + SDL_DFB_CHECK(windata->window_surface->SetColor(windata->window_surface, 0, 0, 0, 0xff)); + SDL_DFB_CHECK(windata->window_surface->FillRectangle(windata->window_surface, 0,0, windata->size.w, windata->size.h)); + + /* blit the mask */ + SDL_DFB_CHECK(windata->surface->SetSrcBlendFunction(windata->surface, DSBF_DESTCOLOR)); + SDL_DFB_CHECK(windata->surface->SetDstBlendFunction(windata->surface, DSBF_ZERO)); + SDL_DFB_CHECK(windata->surface->SetBlittingFlags(windata->surface, DSBLIT_BLEND_ALPHACHANNEL)); +#if (DFB_VERSION_ATLEAST(1,2,0)) + SDL_DFB_CHECK(windata->surface->SetRenderOptions(windata->surface, DSRO_NONE)); +#endif + SDL_DFB_CHECK(windata->surface->Blit(windata->surface, shape_data->surface, NULL, 0, 0)); + } /* Send the data to the display */ SDL_DFB_CHECK(windata->window_surface->Flip(windata->window_surface, NULL, @@ -830,9 +1103,12 @@ DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + DirectFB_ActivateRenderer(renderer); + if (!data) { return; } + //SDL_FreeDirtyRects(&data->dirty); SDL_DFB_RELEASE(data->palette); SDL_DFB_RELEASE(data->surface); if (data->display) { @@ -844,7 +1120,6 @@ DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) DLSCL_ADMINISTRATIVE)); SDL_DFB_RELEASE(dispdata->vidlayer); } - SDL_FreeDirtyRects(&data->dirty); SDL_DFB_FREE(data->pixels); SDL_free(data); texture->driverdata = NULL; @@ -854,6 +1129,13 @@ static void DirectFB_DestroyRenderer(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; + SDL_VideoDisplay *display = renderer->window->display; + +#if 0 + if (display->palette) { + SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, data); + } +#endif if (data) { SDL_free(data); @@ -861,4 +1143,58 @@ DirectFB_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } +static int +DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, void * pixels, int pitch) +{ + SDL_Window *window = renderer->window; + SDL_DFB_WINDOWDATA(window); + Uint32 sdl_format; + void * laypixels; + int laypitch; + DFBSurfacePixelFormat dfb_format; + + DirectFB_ActivateRenderer(renderer); + + SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format)); + sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format); + SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_READ, (void **) &laypixels, &laypitch)); + + laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) ); + SDL_ConvertPixels(rect->w, rect->h, + sdl_format, laypixels, laypitch, + format, pixels, pitch); + + SDL_DFB_CHECK(windata->surface->Unlock(windata->surface)); + + return 0; +} + +static int +DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 format, const void * pixels, int pitch) +{ + SDL_Window *window = renderer->window; + SDL_DFB_WINDOWDATA(window); + Uint32 sdl_format; + void * laypixels; + int laypitch; + DFBSurfacePixelFormat dfb_format; + + SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format)); + sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format); + + SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_WRITE, (void **) &laypixels, &laypitch)); + + laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) ); + SDL_ConvertPixels(rect->w, rect->h, + format, pixels, pitch, + sdl_format, laypixels, laypitch); + + SDL_DFB_CHECK(windata->surface->Unlock(windata->surface)); + + return 0; +} + + /* 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 index 0b4851a91..47f252d13 100644 --- a/src/video/directfb/SDL_DirectFB_render.h +++ b/src/video/directfb/SDL_DirectFB_render.h @@ -18,13 +18,12 @@ Sam Lantinga slouken@libsdl.org -*/ -#include "SDL_config.h" -/* SDL surface based renderer implementation */ + SDL1.3 DirectFB driver by couriersud@arcor.de + +*/ -#define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL) -extern void DirectFB_AddRenderDriver(_THIS); +/* SDL surface based renderer implementation */ /* 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 117b5442d..e602e944c 100644 --- a/src/video/directfb/SDL_DirectFB_video.c +++ b/src/video/directfb/SDL_DirectFB_video.c @@ -19,10 +19,23 @@ Sam Lantinga slouken@libsdl.org - SDL1.3 implementation by couriersud@arcor.de + SDL1.3 DirectFB driver by couriersud@arcor.de */ +#include "SDL_DirectFB_video.h" + +#include "SDL_DirectFB_events.h" +/* + * #include "SDL_DirectFB_gamma.h" + * #include "SDL_DirectFB_keyboard.h" + */ +#include "SDL_DirectFB_modes.h" +#include "SDL_DirectFB_mouse.h" +#include "SDL_DirectFB_opengl.h" +#include "SDL_DirectFB_window.h" +#include "SDL_DirectFB_WM.h" + #include "SDL_config.h" @@ -46,6 +59,8 @@ #include "SDL_DirectFB_events.h" #include "SDL_DirectFB_render.h" #include "SDL_DirectFB_mouse.h" +#include "SDL_DirectFB_shape.h" + #include "SDL_DirectFB_dyn.h" @@ -61,6 +76,10 @@ VideoBootStrap DirectFB_bootstrap = { DirectFB_Available, DirectFB_CreateDevice }; +static const DirectFBSurfaceDrawingFlagsNames(drawing_flags); +static const DirectFBSurfaceBlittingFlagsNames(blitting_flags); +static const DirectFBAccelerationMaskNames(acceleration_mask); + /* DirectFB driver bootstrap functions */ static int @@ -89,7 +108,7 @@ DirectFB_CreateDevice(int devindex) return NULL; /* Initialize all variables that we clean on shutdown */ - SDL_DFB_CALLOC(device, 1, sizeof(SDL_VideoDevice)); + SDL_DFB_ALLOC_CLEAR(device, sizeof(SDL_VideoDevice)); /* Set the function pointers */ @@ -128,8 +147,13 @@ DirectFB_CreateDevice(int devindex) #endif + /* Shaped window support */ + device->shape_driver.CreateShaper = DirectFB_CreateShaper; + device->shape_driver.SetWindowShape = DirectFB_SetWindowShape; + device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape; + device->free = DirectFB_DeleteDevice; - fprintf(LOG_CHANNEL, "Device setup %p!!\n", device->ShowWindow); + return device; error: if (device) @@ -137,10 +161,6 @@ DirectFB_CreateDevice(int devindex) return (0); } -static const DirectFBSurfaceDrawingFlagsNames(drawing_flags); -static const DirectFBSurfaceBlittingFlagsNames(blitting_flags); -static const DirectFBAccelerationMaskNames(acceleration_mask); - static void DirectFB_DeviceInformation(IDirectFB * dfb) { @@ -149,59 +169,64 @@ DirectFB_DeviceInformation(IDirectFB * dfb) dfb->GetDeviceDescription(dfb, &desc); - fprintf(LOG_CHANNEL, "DirectFB Device Information\n"); - fprintf(LOG_CHANNEL, "===========================\n"); - fprintf(LOG_CHANNEL, "Name: %s\n", desc.name); - fprintf(LOG_CHANNEL, "Vendor: %s\n", desc.vendor); - fprintf(LOG_CHANNEL, "Driver Name: %s\n", desc.driver.name); - fprintf(LOG_CHANNEL, "Driver Vendor: %s\n", desc.driver.vendor); - fprintf(LOG_CHANNEL, "Driver Version: %d.%d\n", desc.driver.major, + SDL_DFB_LOG( "DirectFB Device Information\n"); + SDL_DFB_LOG( "===========================\n"); + SDL_DFB_LOG( "Name: %s\n", desc.name); + SDL_DFB_LOG( "Vendor: %s\n", desc.vendor); + SDL_DFB_LOG( "Driver Name: %s\n", desc.driver.name); + SDL_DFB_LOG( "Driver Vendor: %s\n", desc.driver.vendor); + SDL_DFB_LOG( "Driver Version: %d.%d\n", desc.driver.major, desc.driver.minor); - fprintf(LOG_CHANNEL, "\nVideo memoory: %d\n", desc.video_memory); + SDL_DFB_LOG( "\nVideo memoory: %d\n", desc.video_memory); - fprintf(LOG_CHANNEL, "\nBlitting flags:\n"); + SDL_DFB_LOG( "\nBlitting flags:\n"); for (n = 0; blitting_flags[n].flag; n++) { if (desc.blitting_flags & blitting_flags[n].flag) - fprintf(LOG_CHANNEL, " %s\n", blitting_flags[n].name); + SDL_DFB_LOG( " %s\n", blitting_flags[n].name); } - fprintf(LOG_CHANNEL, "\nDrawing flags:\n"); + SDL_DFB_LOG( "\nDrawing flags:\n"); for (n = 0; drawing_flags[n].flag; n++) { if (desc.drawing_flags & drawing_flags[n].flag) - fprintf(LOG_CHANNEL, " %s\n", drawing_flags[n].name); + SDL_DFB_LOG( " %s\n", drawing_flags[n].name); } - fprintf(LOG_CHANNEL, "\nAcceleration flags:\n"); + SDL_DFB_LOG( "\nAcceleration flags:\n"); for (n = 0; acceleration_mask[n].mask; n++) { if (desc.acceleration_mask & acceleration_mask[n].mask) - fprintf(LOG_CHANNEL, " %s\n", acceleration_mask[n].name); + SDL_DFB_LOG( " %s\n", acceleration_mask[n].name); } } +static int readBoolEnv(const char *env_name, int def_val) +{ + char *stemp; + + stemp = SDL_getenv(env_name); + if (stemp) + return atoi(stemp); + else + return def_val; +} + static int DirectFB_VideoInit(_THIS) { IDirectFB *dfb = NULL; DFB_DeviceData *devdata = NULL; - char *stemp; DFBResult ret; - SDL_DFB_CALLOC(devdata, 1, sizeof(*devdata)); + SDL_DFB_ALLOC_CLEAR(devdata, sizeof(*devdata)); SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL)); /* avoid switching to the framebuffer when we * are running X11 */ - stemp = SDL_getenv(DFBENV_USE_X11_CHECK); - if (stemp) - ret = atoi(stemp); - else - ret = 1; - + ret = readBoolEnv(DFBENV_USE_X11_CHECK , 1); if (ret) { if (SDL_getenv("DISPLAY")) DirectFBSetOption("system", "x11"); @@ -210,22 +235,20 @@ DirectFB_VideoInit(_THIS) } /* FIXME: Reenable as default once multi kbd/mouse interface is sorted out */ - devdata->use_linux_input = 0; /* default: on */ - stemp = SDL_getenv(DFBENV_USE_LINUX_INPUT); - if (stemp) - devdata->use_linux_input = atoi(stemp); + devdata->use_linux_input = readBoolEnv(DFBENV_USE_LINUX_INPUT, 0); /* default: on */ if (!devdata->use_linux_input) + { + SDL_DFB_LOG("Disabling linxu input\n"); DirectFBSetOption("disable-module", "linux_input"); - + } + SDL_DFB_CHECKERR(DirectFBCreate(&dfb)); DirectFB_DeviceInformation(dfb); - devdata->use_yuv_underlays = 0; /* default: off */ - stemp = SDL_getenv(DFBENV_USE_YUV_UNDERLAY); - if (stemp) - devdata->use_yuv_underlays = atoi(stemp); - + + devdata->use_yuv_underlays = readBoolEnv(DFBENV_USE_YUV_UNDERLAY, 0); /* default: off */ + devdata->use_yuv_direct = readBoolEnv(DFBENV_USE_YUV_DIRECT, 0); /* default is off! */ /* Create global Eventbuffer for axis events */ if (devdata->use_linux_input) { @@ -239,14 +262,10 @@ DirectFB_VideoInit(_THIS) &devdata->events)); } - devdata->initialized = 1; - /* simple window manager support */ - stemp = SDL_getenv(DFBENV_USE_WM); - if (stemp) - devdata->has_own_wm = atoi(stemp); - else - devdata->has_own_wm = 0; + devdata->has_own_wm = readBoolEnv(DFBENV_USE_WM, 0); + + devdata->initialized = 1; devdata->dfb = dfb; devdata->firstwin = NULL; @@ -260,7 +279,6 @@ DirectFB_VideoInit(_THIS) DirectFB_GL_Initialize(_this); #endif - DirectFB_AddRenderDriver(_this); DirectFB_InitMouse(_this); DirectFB_InitKeyboard(_this); @@ -282,6 +300,7 @@ DirectFB_VideoQuit(_THIS) DirectFB_QuitKeyboard(_this); DirectFB_QuitMouse(_this); + devdata->events->Reset(devdata->events); SDL_DFB_RELEASE(devdata->events); SDL_DFB_RELEASE(devdata->dfb); @@ -291,3 +310,114 @@ DirectFB_VideoQuit(_THIS) devdata->initialized = 0; } + +/* DirectFB driver general support functions */ + +static const struct { + DFBSurfacePixelFormat dfb; + Uint32 sdl; +} pixelformat_tab[] = +{ + { DSPF_RGB32, SDL_PIXELFORMAT_RGB888 }, /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */ + { DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 }, /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */ + { DSPF_RGB16, SDL_PIXELFORMAT_RGB565 }, /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */ + { DSPF_RGB332, SDL_PIXELFORMAT_RGB332 }, /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */ + { DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 }, /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */ + { DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 }, /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */ + { DSPF_RGB24, SDL_PIXELFORMAT_RGB24 }, /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */ + { DSPF_RGB444, SDL_PIXELFORMAT_RGB444 }, /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */ + { DSPF_YV12, SDL_PIXELFORMAT_YV12 }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */ + { DSPF_I420,SDL_PIXELFORMAT_IYUV }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */ + { DSPF_YUY2, SDL_PIXELFORMAT_YUY2 }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */ + { DSPF_UYVY, SDL_PIXELFORMAT_UYVY }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */ + { DSPF_RGB555, SDL_PIXELFORMAT_RGB555 }, /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */ +#if (ENABLE_LUT8) + { DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 }, /* 8 bit LUT (8 bit color and alpha lookup from palette) */ +#endif + +#if (DFB_VERSION_ATLEAST(1,2,0)) + { DSPF_BGR555, SDL_PIXELFORMAT_BGR555 }, /* 16 bit BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */ +#else + { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR555 }, +#endif + + /* Pfff ... nonmatching formats follow */ + + { DSPF_ALUT44, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit ALUT (1 byte, alpha 4@4, color lookup 4@0) */ + { DSPF_A8, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit alpha (1 byte, alpha 8@0), e.g. anti-aliased glyphs */ + { DSPF_AiRGB, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */ + { DSPF_A1, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */ + { DSPF_NV12, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CbCr [15:0] plane) */ + { DSPF_NV16, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit YUV (8 bit Y plane followed by one 16 bit half width CbCr [15:0] plane) */ + { DSPF_ARGB2554, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */ + { DSPF_NV21, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CrCb [15:0] plane) */ + { DSPF_AYUV, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */ + { DSPF_A4, SDL_PIXELFORMAT_UNKNOWN }, /* 4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */ + { DSPF_ARGB1666, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (3 byte/ alpha 1@18, red 6@16, green 6@6, blue 6@0) */ + { DSPF_ARGB6666, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit alpha (3 byte/ alpha 6@18, red 6@16, green 6@6, blue 6@0) */ + { DSPF_RGB18, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit RGB (3 byte/ red 6@16, green 6@6, blue 6@0) */ + { DSPF_LUT2, SDL_PIXELFORMAT_UNKNOWN }, /* 2 bit LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */ + +#if (DFB_VERSION_ATLEAST(1,3,0)) + { DSPF_RGBA4444, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 4@12, green 4@8, blue 4@4, alpha 4@0) */ +#endif + +#if (DFB_VERSION_ATLEAST(1,4,3)) + { DSPF_RGBA5551, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 5@11, green 5@6, blue 5@1, alpha 1@0) */ + { DSPF_YUV444P, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit full YUV planar (8 bit Y plane followed by an 8 bit Cb and an 8 bit Cr plane) */ + { DSPF_ARGB8565, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit ARGB (3 byte, alpha 8@16, red 5@11, green 6@5, blue 5@0) */ + { DSPF_AVYU, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AVYU 4:4:4 (4 byte, alpha 8@24, Cr 8@16, Y 8@8, Cb 8@0) */ + { DSPF_VYU, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit VYU 4:4:4 (3 byte, Cr 8@16, Y 8@8, Cb 8@0) */ +#endif + + { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1MSB }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4LSB }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4MSB }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR24 }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR888 }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_RGBA8888 }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR8888 }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGRA8888 }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_ARGB2101010 }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR4444 }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR1555 }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR565 }, + { DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU }, /**< Packed mode: Y0+V0+Y1+U0 (1 pla */ +}; + +Uint32 +DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat) +{ + int i; + + for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++) + if (pixelformat_tab[i].dfb == pixelformat) + { + return pixelformat_tab[i].sdl; + } + return SDL_PIXELFORMAT_UNKNOWN; +} + +DFBSurfacePixelFormat +DirectFB_SDLToDFBPixelFormat(Uint32 format) +{ + int i; + + for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++) + if (pixelformat_tab[i].sdl == format) + { + return pixelformat_tab[i].dfb; + } + return DSPF_UNKNOWN; +} + +void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo* ri) +{ + int i, j; + + for (i=0, j=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++) + if (pixelformat_tab[i].sdl != SDL_PIXELFORMAT_UNKNOWN) + ri->texture_formats[j++] = pixelformat_tab[i].sdl; + ri->num_texture_formats = j; +} diff --git a/src/video/directfb/SDL_DirectFB_video.h b/src/video/directfb/SDL_DirectFB_video.h index 6c5732cb7..fed1b7856 100644 --- a/src/video/directfb/SDL_DirectFB_video.h +++ b/src/video/directfb/SDL_DirectFB_video.h @@ -18,28 +18,22 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ + #include "SDL_config.h" #ifndef _SDL_DirectFB_video_h #define _SDL_DirectFB_video_h -#include "../SDL_sysvideo.h" - #include #include -#include "SDL_mouse.h" - - -/* Set below to 1 to compile with (old) multi mice/keyboard api. Code left in - * in case we see this again ... - */ - -#define USE_MULTI_API (0) - -#define DEBUG 1 -#define LOG_CHANNEL stdout +#include "../SDL_sysvideo.h" +#include "SDL_scancode.h" +#include "SDL_render.h" #define DFB_VERSIONNUM(X, Y, Z) \ ((X)*1000 + (Y)*100 + (Z)) @@ -52,25 +46,29 @@ #if (DFB_VERSION_ATLEAST(1,0,0)) #define SDL_DIRECTFB_OPENGL 1 -#include #else #error "SDL_DIRECTFB: Please compile against libdirectfb version >= 1.0.0" #endif -#if SDL_DIRECTFB_OPENGL -#include "SDL_loadso.h" -#endif +/* Set below to 1 to compile with (old) multi mice/keyboard api. Code left in + * in case we see this again ... + */ -#include "SDL_DirectFB_events.h" -/* - * #include "SDL_DirectFB_gamma.h" - * #include "SDL_DirectFB_keyboard.h" +#define USE_MULTI_API (0) + +/* Support for LUT8/INDEX8 pixel format. + * This is broken in DirectFB 1.4.3. It works in 1.4.0 and 1.4.5 + * occurred. */ -#include "SDL_DirectFB_modes.h" -#include "SDL_DirectFB_mouse.h" -#include "SDL_DirectFB_opengl.h" -#include "SDL_DirectFB_window.h" -#include "SDL_DirectFB_WM.h" + +#if (DFB_COMPILEDVERSION == DFB_VERSIONNUM(1, 4, 3)) +#define ENABLE_LUT8 (0) +#else +#define ENABLE_LUT8 (1) +#endif + +#define DIRECTFB_DEBUG 1 +#define LOG_CHANNEL stdout #define DFBENV_USE_YUV_UNDERLAY "SDL_DIRECTFB_YUV_UNDERLAY" /* Default: off */ #define DFBENV_USE_YUV_DIRECT "SDL_DIRECTFB_YUV_DIRECT" /* Default: off */ @@ -82,76 +80,103 @@ #define SDL_DFB_FREE(x) do { if ( (x) != NULL ) { SDL_free(x); x = NULL; } } while (0) #define SDL_DFB_UNLOCK(x) do { if ( (x) != NULL ) { x->Unlock(x); } } while (0) -#if DEBUG -/* FIXME: do something with DEBUG */ -#endif - #define SDL_DFB_CONTEXT "SDL_DirectFB" -static inline DFBResult sdl_dfb_check(DFBResult ret, const char *src_file, int src_line, const char *src_code) { +#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) + +#if (DIRECTFB_DEBUG) + +#define SDL_DFB_LOG(x...) \ + do { \ + fprintf(LOG_CHANNEL, SDL_DFB_CONTEXT); \ + fprintf(LOG_CHANNEL, x ); \ + fprintf(LOG_CHANNEL, "\n"); \ + } while (0) + +#define SDL_DFB_DEBUG(x...) SDL_DFB_ERR( x ) + +static inline DFBResult sdl_dfb_check(DFBResult ret, const char *src_file, int src_line) { if (ret != DFB_OK) { - fprintf(LOG_CHANNEL, "%s <%d>:\n\t", src_file, src_line ); - fprintf(LOG_CHANNEL, "\t%s\n", src_code ); - fprintf(LOG_CHANNEL, "\t%s\n", DirectFBErrorString (ret) ); - SDL_SetError( src_code, DirectFBErrorString (ret) ); + SDL_DFB_LOG("%s (%d):%s", src_file, src_line, DirectFBErrorString (ret) ); + SDL_SetError("%s:%s", SDL_DFB_CONTEXT, DirectFBErrorString (ret) ); } return ret; } -#define SDL_DFB_CHECK(x...) sdl_dfb_check( x, __FILE__, __LINE__, #x ) +#define SDL_DFB_CHECK(x...) do { sdl_dfb_check( x, __FILE__, __LINE__); } while (0) +#define SDL_DFB_CHECKERR(x...) do { if ( sdl_dfb_check( x, __FILE__, __LINE__) != DFB_OK ) goto error; } while (0) -#define SDL_DFB_CHECKERR(x...) if ( sdl_dfb_check( x, __FILE__, __LINE__, #x ) != DFB_OK ) goto error +#else -#define SDL_DFB_DEBUG(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...) x +#define SDL_DFB_CHECKERR(x...) do { if (x != DFB_OK ) goto error; } while (0) +#define SDL_DFB_LOG(x...) do {} while (0) +#define SDL_DFB_DEBUG(x...) do {} while (0) + +#endif -#define SDL_DFB_ERR(x...) SDL_DFB_DEBUG( x ) #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; \ - } \ + do { \ + r = SDL_calloc (n, s); \ + if (!(r)) { \ + SDL_DFB_ERR("Out of memory"); \ + SDL_OutOfMemory(); \ + goto error; \ + } \ } while (0) +#define SDL_DFB_ALLOC_CLEAR(r, s) SDL_DFB_CALLOC(r, 1, s) + /* Private display data */ #define SDL_DFB_DEVICEDATA(dev) DFB_DeviceData *devdata = (dev ? (DFB_DeviceData *) ((dev)->driverdata) : NULL) #define DFB_MAX_SCREENS 10 +typedef struct _DFB_KeyboardData DFB_KeyboardData; +struct _DFB_KeyboardData +{ + const SDL_ScanCode *map; /* keyboard scancode map */ + int map_size; /* size of map */ + int map_adjust; /* index adjust */ + int is_generic; /* generic keyboard */ + int id; +}; + typedef struct _DFB_DeviceData DFB_DeviceData; struct _DFB_DeviceData { int initialized; - IDirectFB *dfb; - int num_mice; - int mouse_id[0x100]; - int num_keyboard; - struct - { - int is_generic; - int id; - } keyboard[10]; - DFB_WindowData *firstwin; - - int use_yuv_underlays; - int use_linux_input; - int has_own_wm; + IDirectFB *dfb; + int num_mice; + int mouse_id[0x100]; + int num_keyboard; + DFB_KeyboardData keyboard[10]; + SDL_Window *firstwin; + + int use_yuv_underlays; + int use_yuv_direct; + int use_linux_input; + int has_own_wm; + /* window grab */ - SDL_Window *grabbed_window; + SDL_Window *grabbed_window; /* global events */ IDirectFBEventBuffer *events; }; +Uint32 DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat); +DFBSurfacePixelFormat DirectFB_SDLToDFBPixelFormat(Uint32 format); +void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo *ri); + + #endif /* _SDL_DirectFB_video_h */ diff --git a/src/video/directfb/SDL_DirectFB_window.c b/src/video/directfb/SDL_DirectFB_window.c index 1dd2eeb18..f4fcb15a9 100644 --- a/src/video/directfb/SDL_DirectFB_window.c +++ b/src/video/directfb/SDL_DirectFB_window.c @@ -18,41 +18,49 @@ Sam Lantinga slouken@libsdl.org -*/ -#include "SDL_config.h" -#include "SDL_syswm.h" -#include "../SDL_sysvideo.h" -#include "../../events/SDL_keyboard_c.h" -#include "../../video/SDL_pixels_c.h" + SDL1.3 DirectFB driver by couriersud@arcor.de + +*/ #include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_modes.h" +#include "SDL_DirectFB_window.h" +#include "SDL_DirectFB_shape.h" + #if SDL_DIRECTFB_OPENGL #include "SDL_DirectFB_opengl.h" #endif -static void DirectFB_AdjustWindowSurface(_THIS, SDL_Window * window); +#include "SDL_syswm.h" + +#include "../SDL_pixels_c.h" int DirectFB_CreateWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); - SDL_DFB_DISPLAYDATA(_this, window); + SDL_DFB_DISPLAYDATA(window); DFB_WindowData *windata = NULL; DFBWindowOptions wopts; DFBWindowDescription desc; int x, y; + int bshaped = 0; - SDL_DFB_CALLOC(window->driverdata, 1, sizeof(DFB_WindowData)); + SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData)); windata = (DFB_WindowData *) window->driverdata; windata->is_managed = devdata->has_own_wm; - +#if 1 SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb, DFSCL_NORMAL)); SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer, DLSCL_ADMINISTRATIVE)); - +#endif + /* FIXME ... ughh, ugly */ + if (window->x == -1000 && window->y == -1000) + bshaped = 1; + /* Fill the window description. */ if (window->x == SDL_WINDOWPOS_CENTERED) { x = (dispdata->cw - window->w) / 2; @@ -61,6 +69,7 @@ DirectFB_CreateWindow(_THIS, SDL_Window * window) } else { x = window->x; } + if (window->y == SDL_WINDOWPOS_CENTERED) { y = (dispdata->ch - window->h) / 2; } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { @@ -68,6 +77,7 @@ DirectFB_CreateWindow(_THIS, SDL_Window * window) } else { y = window->y; } + if (window->flags & SDL_WINDOW_FULLSCREEN) { x = 0; y = 0; @@ -76,78 +86,103 @@ DirectFB_CreateWindow(_THIS, SDL_Window * window) DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); /* Create Window */ + desc.caps = 0; desc.flags = - DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_PIXELFORMAT | DWDESC_POSX - | DWDESC_POSY | DWDESC_SURFACE_CAPS; + DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS; + + if (bshaped) { + desc.flags |= DWDESC_CAPS; + desc.caps |= DWCAPS_ALPHACHANNEL; + } + else + { + desc.flags |= DWDESC_PIXELFORMAT; + } + + if (!(window->flags & SDL_WINDOW_BORDERLESS)) + desc.caps |= DWCAPS_NODECORATION; + desc.posx = x; desc.posy = y; desc.width = windata->size.w; desc.height = windata->size.h; desc.pixelformat = dispdata->pixelformat; desc.surface_caps = DSCAPS_PREMULTIPLIED; - + /* Create the window. */ SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc, - &windata->window)); + &windata->dfbwin)); /* Set Options */ - SDL_DFB_CHECK(windata->window->GetOptions(windata->window, &wopts)); + SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts)); - if (window->flags & SDL_WINDOW_RESIZABLE) - wopts |= DWOP_SCALE; - else + /* explicit rescaling of surface */ + wopts |= DWOP_SCALE; + if (window->flags & SDL_WINDOW_RESIZABLE) { + wopts &= ~DWOP_KEEP_SIZE; + } + else { wopts |= DWOP_KEEP_SIZE; + } if (window->flags & SDL_WINDOW_FULLSCREEN) { wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE; - SDL_DFB_CHECK(windata->window->SetStackingClass(windata->window, DWSC_UPPER)); + SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER)); + } + + if (bshaped) { + wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL; + wopts &= ~DWOP_OPAQUE_REGION; } - SDL_DFB_CHECK(windata->window->SetOptions(windata->window, wopts)); + + SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); /* See what we got */ - SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize + SDL_DFB_CHECK(DirectFB_WM_GetClientSize (_this, window, &window->w, &window->h)); /* Get the window's surface. */ - SDL_DFB_CHECKERR(windata->window->GetSurface(windata->window, + SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin, &windata->window_surface)); + /* And get a subsurface for rendering */ SDL_DFB_CHECKERR(windata->window_surface-> GetSubSurface(windata->window_surface, &windata->client, &windata->surface)); - SDL_DFB_CHECK(windata->window->SetOpacity(windata->window, 0xFF)); + SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF)); /* Create Eventbuffer */ - SDL_DFB_CHECKERR(windata->window->CreateEventBuffer(windata->window, + + SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin, &windata-> eventbuffer)); - SDL_DFB_CHECKERR(windata->window-> - EnableEvents(windata->window, DWET_ALL)); + SDL_DFB_CHECKERR(windata->dfbwin-> + EnableEvents(windata->dfbwin, DWET_ALL)); /* Create a font */ /* FIXME: once during Video_Init */ windata->font = NULL; /* Make it the top most window. */ - SDL_DFB_CHECK(windata->window->RaiseToTop(windata->window)); + SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin)); /* remember parent */ - windata->sdl_window = window; + //windata->sdlwin = window; /* Add to list ... */ windata->next = devdata->firstwin; windata->opacity = 0xFF; - devdata->firstwin = windata; + devdata->firstwin = window; /* Draw Frame */ DirectFB_WM_RedrawLayout(_this, window); return 0; error: - SDL_DFB_RELEASE(windata->window); - SDL_DFB_RELEASE(windata->surface); + SDL_DFB_RELEASE(windata->surface); + SDL_DFB_RELEASE(windata->dfbwin); return -1; } @@ -226,61 +261,69 @@ void DirectFB_SetWindowPosition(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(window); int x, y; - if (window->y == SDL_WINDOWPOS_UNDEFINED) - y = 0; - else - y = window->y; - - if (window->x == SDL_WINDOWPOS_UNDEFINED) + if (window->x == SDL_WINDOWPOS_CENTERED) { + x = (dispdata->cw - window->w) / 2; + } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { x = 0; - else + } else { x = window->x; + } + + if (window->y == SDL_WINDOWPOS_CENTERED) { + y = (dispdata->ch - window->h) / 2; + } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { + y = 0; + } else { + y = window->y; + } if (window->flags & SDL_WINDOW_FULLSCREEN) { x = 0; y = 0; } DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); - SDL_DFB_CHECK(windata->window->MoveTo(windata->window, x, y)); + SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y)); } void DirectFB_SetWindowSize(_THIS, SDL_Window * window) { - //SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); + if(SDL_IsShapedWindow(window)) + DirectFB_ResizeWindowShape(window); + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { int cw; int ch; /* Make sure all events are disabled for this operation ! */ - SDL_DFB_CHECKERR(windata->window->DisableEvents(windata->window, + SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin, DWET_ALL)); - SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch)); if (cw != window->w || ch != window->h) { DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h); - SDL_DFB_CHECKERR(windata->window->Resize(windata->window, + SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin, windata->size.w, windata->size.h)); } SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize (_this, window, &window->w, &window->h)); - DirectFB_AdjustWindowSurface(_this, window); + DirectFB_AdjustWindowSurface(window); - SDL_DFB_CHECKERR(windata->window->EnableEvents(windata->window, + SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL)); } return; error: - SDL_DFB_CHECK(windata->window->EnableEvents(windata->window, DWET_ALL)); + SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL)); return; } @@ -289,7 +332,7 @@ DirectFB_ShowWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); - SDL_DFB_CHECK(windata->window->SetOpacity(windata->window, windata->opacity)); + SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity)); } @@ -298,8 +341,8 @@ DirectFB_HideWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); - SDL_DFB_CHECK(windata->window->GetOpacity(windata->window, &windata->opacity)); - SDL_DFB_CHECK(windata->window->SetOpacity(windata->window, 0)); + SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity)); + SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0)); } void @@ -307,19 +350,32 @@ DirectFB_RaiseWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); - SDL_DFB_CHECK(windata->window->RaiseToTop(windata->window)); - SDL_DFB_CHECK(windata->window->RequestFocus(windata->window)); + SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin)); + SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin)); } void DirectFB_MaximizeWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); + SDL_VideoDisplay *display = window->display; + DFBWindowOptions wopts; - if (windata->is_managed) { - DirectFB_WM_MaximizeWindow(_this, window); - } else - SDL_Unsupported(); + SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin, + &windata->restore.x, &windata->restore.y)); + SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w, + &windata->restore.h)); + + DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ; + + SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0)); + SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, + display->current_mode.w, display->current_mode.h)); + + /* Set Options */ + SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts)); + wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION; + SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); } void @@ -334,11 +390,29 @@ void DirectFB_RestoreWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); + DFBWindowOptions wopts; + + /* Set Options */ + SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts)); + wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION); + SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); + + /* Window layout */ + DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED), + windata->restore.w, windata->restore.h); + SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w, + windata->restore.h)); + SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x, + windata->restore.y)); + + if (!(window->flags & SDL_WINDOW_RESIZABLE)) + wopts |= DWOP_KEEP_SIZE; + + if (window->flags & SDL_WINDOW_FULLSCREEN) + wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE; + SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); + - if (windata->is_managed) { - DirectFB_WM_RestoreWindow(_this, window); - } else - SDL_Unsupported(); } void @@ -351,15 +425,15 @@ DirectFB_SetWindowGrab(_THIS, SDL_Window * window) if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) { if (gwindata != NULL) { - SDL_DFB_CHECK(gwindata->window->UngrabPointer(gwindata->window)); - SDL_DFB_CHECK(gwindata->window->UngrabKeyboard(gwindata->window)); + SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin)); + SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin)); } - SDL_DFB_CHECK(windata->window->GrabPointer(windata->window)); - SDL_DFB_CHECK(windata->window->GrabKeyboard(windata->window)); + SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin)); + SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin)); devdata->grabbed_window = window; } else { - SDL_DFB_CHECK(windata->window->UngrabPointer(windata->window)); - SDL_DFB_CHECK(windata->window->UngrabKeyboard(windata->window)); + SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin)); + SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); devdata->grabbed_window = NULL; } } @@ -372,13 +446,22 @@ DirectFB_DestroyWindow(_THIS, SDL_Window * window) DFB_WindowData *p; /* Some cleanups */ - SDL_DFB_CHECK(windata->window->UngrabPointer(windata->window)); - SDL_DFB_CHECK(windata->window->UngrabKeyboard(windata->window)); + SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin)); + SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); #if SDL_DIRECTFB_OPENGL DirectFB_GL_DestroyWindowContexts(_this, window); #endif + if (window->shaper) + { + SDL_ShapeData *data = window->shaper->driverdata; + SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface)); + SDL_DFB_RELEASE(data->surface); + SDL_DFB_FREE(data); + SDL_DFB_FREE(window->shaper); + } + SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL)); SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface)); SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface)); @@ -388,13 +471,14 @@ DirectFB_DestroyWindow(_THIS, SDL_Window * window) SDL_DFB_RELEASE(windata->surface); SDL_DFB_RELEASE(windata->window_surface); - SDL_DFB_RELEASE(windata->window); + SDL_DFB_RELEASE(windata->dfbwin); /* Remove from list ... */ - p = devdata->firstwin; - while (p && p->next != windata) - p = p->next; + p = devdata->firstwin->driverdata; + + while (p && p->next != window) + p = (p->next ? p->next->driverdata : NULL); if (p) p->next = windata->next; else @@ -407,12 +491,25 @@ SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo * info) { - SDL_Unsupported(); - return SDL_FALSE; + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + + if (info->version.major == SDL_MAJOR_VERSION && + info->version.minor == SDL_MINOR_VERSION) { + info->subsystem = SDL_SYSWM_DIRECTFB; + info->info.dfb.dfb = devdata->dfb; + info->info.dfb.window = windata->dfbwin; + info->info.dfb.surface = windata->surface; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d.%d\n", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return SDL_FALSE; + } } -static void -DirectFB_AdjustWindowSurface(_THIS, SDL_Window * window) +void +DirectFB_AdjustWindowSurface(SDL_Window * window) { SDL_DFB_WINDOWDATA(window); int adjust = windata->wm_needs_redraw; @@ -429,11 +526,11 @@ DirectFB_AdjustWindowSurface(_THIS, SDL_Window * window) if (adjust) { #if SDL_DIRECTFB_OPENGL - DirectFB_GL_FreeWindowContexts(_this, window); + DirectFB_GL_FreeWindowContexts(window->display->device, window); #endif -#if DFB_VERSION_ATLEAST(1,2,1) - SDL_DFB_CHECKERR(windata->window->ResizeSurface(windata->window, +#if (DFB_VERSION_ATLEAST(1,2,1)) + SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin, windata->size.w, windata->size.h)); SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface, @@ -443,22 +540,22 @@ DirectFB_AdjustWindowSurface(_THIS, SDL_Window * window) #else DFBWindowOptions opts; - SDL_DFB_CHECKERR(windata->window->GetOptions(windata->window, &opts)); + SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts)); /* recreate subsurface */ SDL_DFB_RELEASE(windata->surface); if (opts & DWOP_SCALE) - SDL_DFB_CHECKERR(windata->window->ResizeSurface(windata->window, + SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin, windata->size.w, windata->size.h)); SDL_DFB_CHECKERR(windata->window_surface-> GetSubSurface(windata->window_surface, &windata->client, &windata->surface)); #endif - DirectFB_WM_RedrawLayout(_this, window); + DirectFB_WM_RedrawLayout(window->display->device, window); #if SDL_DIRECTFB_OPENGL - DirectFB_GL_ReAllocWindowContexts(_this, window); + DirectFB_GL_ReAllocWindowContexts(window->display->device, window); #endif } error: diff --git a/src/video/directfb/SDL_DirectFB_window.h b/src/video/directfb/SDL_DirectFB_window.h index e94ab8c3b..4090bada3 100644 --- a/src/video/directfb/SDL_DirectFB_window.h +++ b/src/video/directfb/SDL_DirectFB_window.h @@ -18,12 +18,15 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" #ifndef _SDL_directfb_window_h #define _SDL_directfb_window_h +#include "SDL_DirectFB_video.h" #include "SDL_DirectFB_WM.h" #define SDL_DFB_WINDOWDATA(win) DFB_WindowData *windata = ((win) ? (DFB_WindowData *) ((win)->driverdata) : NULL) @@ -31,22 +34,28 @@ typedef struct _DFB_WindowData DFB_WindowData; struct _DFB_WindowData { - IDirectFBSurface *surface; - IDirectFBSurface *window_surface; /* only used with has_own_wm */ - IDirectFBWindow *window; - IDirectFBEventBuffer *eventbuffer; - SDL_Window *sdl_window; - DFB_WindowData *next; - Uint8 opacity; - DFBRectangle client; - DFBDimension size; + IDirectFBSurface *window_surface; /* window surface */ + IDirectFBSurface *surface; /* client drawing surface */ + IDirectFBWindow *dfbwin; + IDirectFBEventBuffer *eventbuffer; + //SDL_Window *sdlwin; + SDL_Window *next; + Uint8 opacity; + DFBRectangle client; + DFBDimension size; + DFBRectangle restore; + /* WM extras */ - DFBRectangle restore; - int is_managed; - int wm_needs_redraw; - IDirectFBSurface *icon; - IDirectFBFont *font; - DFB_Theme theme; + int is_managed; + int wm_needs_redraw; + IDirectFBSurface *icon; + IDirectFBFont *font; + DFB_Theme theme; + + /* WM moving and sizing */ + int wm_grab; + int wm_lastx; + int wm_lasty; }; extern int DirectFB_CreateWindow(_THIS, SDL_Window * window); @@ -69,7 +78,7 @@ extern void DirectFB_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); -//extern void DirectFB_AdjustWindowSurface(_THIS, SDL_Window * window); +extern void DirectFB_AdjustWindowSurface(SDL_Window * window); #endif /* _SDL_directfb_window_h */