From 6d95fe9980df9fac954f59443e68f500d082e4ef Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 14 Mar 2011 23:13:33 -0700 Subject: [PATCH] DirectFB driver update Couriersud to Sam the attached patch brings the DirectFB driver back in line with recent SDL 1.3 developments. --- src/video/directfb/SDL_DirectFB_modes.c | 4 +- src/video/directfb/SDL_DirectFB_modes.h | 2 +- src/video/directfb/SDL_DirectFB_mouse.c | 279 +++++++++++++++++------ src/video/directfb/SDL_DirectFB_opengl.c | 1 + src/video/directfb/SDL_DirectFB_render.c | 116 +++++++--- src/video/directfb/SDL_DirectFB_shape.c | 134 +++++++++++ src/video/directfb/SDL_DirectFB_shape.h | 43 ++++ src/video/directfb/SDL_DirectFB_video.c | 32 +-- src/video/directfb/SDL_DirectFB_video.h | 4 +- src/video/directfb/SDL_DirectFB_window.c | 14 ++ src/video/directfb/SDL_DirectFB_window.h | 4 + 11 files changed, 514 insertions(+), 119 deletions(-) create mode 100644 src/video/directfb/SDL_DirectFB_shape.c create mode 100644 src/video/directfb/SDL_DirectFB_shape.h diff --git a/src/video/directfb/SDL_DirectFB_modes.c b/src/video/directfb/SDL_DirectFB_modes.c index 69b836850..0e7b9e6df 100644 --- a/src/video/directfb/SDL_DirectFB_modes.c +++ b/src/video/directfb/SDL_DirectFB_modes.c @@ -386,11 +386,11 @@ DirectFB_QuitModes(_THIS) SDL_VideoDisplay *display = &_this->displays[i]; DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; - SDL_GetDesktopDisplayModeForDisplay(display, &tmode); + SDL_GetDesktopDisplayMode(i, &tmode); tmode.format = SDL_PIXELFORMAT_UNKNOWN; DirectFB_SetDisplayMode(_this, display, &tmode); - SDL_GetDesktopDisplayModeForDisplay(display, &tmode); + SDL_GetDesktopDisplayMode(i, &tmode); DirectFB_SetDisplayMode(_this, display, &tmode); if (dispdata->layer) { diff --git a/src/video/directfb/SDL_DirectFB_modes.h b/src/video/directfb/SDL_DirectFB_modes.h index c77925433..39337ee23 100644 --- a/src/video/directfb/SDL_DirectFB_modes.h +++ b/src/video/directfb/SDL_DirectFB_modes.h @@ -30,7 +30,7 @@ #include "../SDL_sysvideo.h" -#define SDL_DFB_DISPLAYDATA(win) DFB_DisplayData *dispdata = ((win) ? (DFB_DisplayData *) (win)->display->driverdata : NULL) +#define SDL_DFB_DISPLAYDATA(win) DFB_DisplayData *dispdata = ((win) ? (DFB_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata : NULL) typedef struct _DFB_DisplayData DFB_DisplayData; struct _DFB_DisplayData diff --git a/src/video/directfb/SDL_DirectFB_mouse.c b/src/video/directfb/SDL_DirectFB_mouse.c index 44973b7ee..811e0b28c 100644 --- a/src/video/directfb/SDL_DirectFB_mouse.c +++ b/src/video/directfb/SDL_DirectFB_mouse.c @@ -24,92 +24,113 @@ */ #include "SDL_config.h" +#include "SDL_assert.h" #include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_mouse.h" +#include "SDL_DirectFB_modes.h" +#include "SDL_DirectFB_window.h" #include "../SDL_sysvideo.h" #include "../../events/SDL_mouse_c.h" -#if USE_MULTI_API +static SDL_Cursor *DirectFB_CreateDefaultCursor(void); static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y); static int DirectFB_ShowCursor(SDL_Cursor * cursor); static void DirectFB_MoveCursor(SDL_Cursor * cursor); static void DirectFB_FreeCursor(SDL_Cursor * cursor); -static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, - int x, int y); +static void DirectFB_WarpMouse(SDL_Window * window, int x, int y); static void DirectFB_FreeMouse(SDL_Mouse * mouse); -static int id_mask; +static const char *arrow[] = { + /* pixels */ + "X ", + "XX ", + "X.X ", + "X..X ", + "X...X ", + "X....X ", + "X.....X ", + "X......X ", + "X.......X ", + "X........X ", + "X.....XXXXX ", + "X..X..X ", + "X.X X..X ", + "XX X..X ", + "X X..X ", + " X..X ", + " X..X ", + " X..X ", + " XX ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", +}; -static DFBEnumerationResult -EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, - void *callbackdata) +static SDL_Cursor * +DirectFB_CreateDefaultCursor(void) { - DFB_DeviceData *devdata = callbackdata; - - if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) { - SDL_Mouse mouse; + SDL_VideoDevice *dev = SDL_GetVideoDevice(); - SDL_zero(mouse); - mouse.id = device_id; - mouse.CreateCursor = DirectFB_CreateCursor; - mouse.ShowCursor = DirectFB_ShowCursor; - mouse.MoveCursor = DirectFB_MoveCursor; - mouse.FreeCursor = DirectFB_FreeCursor; - mouse.WarpMouse = DirectFB_WarpMouse; - mouse.FreeMouse = DirectFB_FreeMouse; - mouse.cursor_shown = 1; + SDL_DFB_DEVICEDATA(dev); + DFB_CursorData *curdata; + DFBResult ret; + DFBSurfaceDescription dsc; + SDL_Cursor *cursor; + Uint32 *dest; + Uint32 *p; + int pitch, i, j; - SDL_AddMouse(&mouse, desc.name, 0, 0, 1); - devdata->mouse_id[devdata->num_mice++] = device_id; - } - return DFENUM_OK; -} + SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor)); + SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata)); -void -DirectFB_InitMouse(_THIS) -{ - SDL_DFB_DEVICEDATA(_this); + dsc.flags = + DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; + dsc.caps = DSCAPS_VIDEOONLY; + dsc.width = 32; + dsc.height = 32; + dsc.pixelformat = DSPF_ARGB; - devdata->num_mice = 0; - if (devdata->use_linux_input) { - /* try non-core devices first */ - id_mask = 0xF0; - devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata); - if (devdata->num_mice == 0) { - /* try core devices */ - id_mask = 0x0F; - devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata); - } - } - if (devdata->num_mice == 0) { - SDL_Mouse mouse; + SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, + &curdata->surf)); + curdata->hotx = 0; + curdata->hoty = 0; + cursor->driverdata = curdata; - SDL_zero(mouse); - mouse.CreateCursor = DirectFB_CreateCursor; - mouse.ShowCursor = DirectFB_ShowCursor; - mouse.MoveCursor = DirectFB_MoveCursor; - mouse.FreeCursor = DirectFB_FreeCursor; - mouse.WarpMouse = DirectFB_WarpMouse; - mouse.FreeMouse = DirectFB_FreeMouse; - mouse.cursor_shown = 1; + SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE, + (void *) &dest, &pitch)); - SDL_AddMouse(&mouse, "Mouse", 0, 0, 1); - devdata->num_mice = 1; + /* Relies on the fact that this is only called with ARGB surface. */ + for (i = 0; i < 32; i++) + { + for (j = 0; j < 32; j++) + { + switch (arrow[i][j]) + { + case ' ': dest[j] = 0x00000000; break; + case '.': dest[j] = 0xffffffff; break; + case 'X': dest[j] = 0xff000000; break; + } + } + dest += (pitch >> 2); } -} -void -DirectFB_QuitMouse(_THIS) -{ - SDL_DFB_DEVICEDATA(_this); - - if (devdata->use_linux_input) { - SDL_MouseQuit(); - } else { - SDL_DelMouse(0); - } + curdata->surf->Unlock(curdata->surf); + return cursor; + error: + return NULL; } /* Create a cursor from a surface */ @@ -127,8 +148,11 @@ DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) Uint32 *p; int pitch, i; - SDL_DFB_ALLOC_CLEAR(cursor, 1, sizeof(*cursor)); - SDL_DFB_ALLOC_CLEAR(curdata, 1, sizeof(*curdata)); + SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); + SDL_assert(surface->pitch == surface->w * 4); + + SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor)); + SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata)); dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; @@ -146,7 +170,6 @@ DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE, (void *) &dest, &pitch)); - /* Relies on the fact that this is only called with ARGB surface. */ p = surface->pixels; for (i = 0; i < surface->h; i++) memcpy((char *) dest + i * pitch, @@ -178,7 +201,7 @@ DirectFB_ShowCursor(SDL_Cursor * cursor) DFB_WindowData *windata = (DFB_WindowData *) window->driverdata; if (cursor) - SDL_DFB_CHECKERR(windata->window-> + SDL_DFB_CHECKERR(windata->dfbwin-> SetCursorShape(windata->dfbwin, curdata->surf, curdata->hotx, curdata->hoty)); @@ -200,13 +223,6 @@ DirectFB_ShowCursor(SDL_Cursor * cursor) return -1; } -/* This is called when a mouse motion event occurs */ -static void -DirectFB_MoveCursor(SDL_Cursor * cursor) -{ - -} - /* Free a window manager cursor */ static void DirectFB_FreeCursor(SDL_Cursor * cursor) @@ -218,6 +234,110 @@ DirectFB_FreeCursor(SDL_Cursor * cursor) SDL_DFB_FREE(cursor); } +/* Warp the mouse to (x,y) */ +static void +DirectFB_WarpMouse(SDL_Window * window, int x, int y) +{ + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; + DFB_WindowData *windata = (DFB_WindowData *) window->driverdata; + DFBResult ret; + int 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)); + + error: + return; +} + +#if USE_MULTI_API + +static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, + int x, int y); + +static int id_mask; + +static DFBEnumerationResult +EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, + void *callbackdata) +{ + DFB_DeviceData *devdata = callbackdata; + + if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) { + SDL_Mouse mouse; + + SDL_zero(mouse); + mouse.id = device_id; + mouse.CreateCursor = DirectFB_CreateCursor; + mouse.ShowCursor = DirectFB_ShowCursor; + mouse.MoveCursor = DirectFB_MoveCursor; + mouse.FreeCursor = DirectFB_FreeCursor; + mouse.WarpMouse = DirectFB_WarpMouse; + mouse.FreeMouse = DirectFB_FreeMouse; + mouse.cursor_shown = 1; + + SDL_AddMouse(&mouse, desc.name, 0, 0, 1); + devdata->mouse_id[devdata->num_mice++] = device_id; + } + return DFENUM_OK; +} + +void +DirectFB_InitMouse(_THIS) +{ + SDL_DFB_DEVICEDATA(_this); + + devdata->num_mice = 0; + if (devdata->use_linux_input) { + /* try non-core devices first */ + id_mask = 0xF0; + devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata); + if (devdata->num_mice == 0) { + /* try core devices */ + id_mask = 0x0F; + devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata); + } + } + if (devdata->num_mice == 0) { + SDL_Mouse mouse; + + SDL_zero(mouse); + mouse.CreateCursor = DirectFB_CreateCursor; + mouse.ShowCursor = DirectFB_ShowCursor; + mouse.MoveCursor = DirectFB_MoveCursor; + mouse.FreeCursor = DirectFB_FreeCursor; + mouse.WarpMouse = DirectFB_WarpMouse; + mouse.FreeMouse = DirectFB_FreeMouse; + mouse.cursor_shown = 1; + + SDL_AddMouse(&mouse, "Mouse", 0, 0, 1); + devdata->num_mice = 1; + } +} + +void +DirectFB_QuitMouse(_THIS) +{ + SDL_DFB_DEVICEDATA(_this); + + if (devdata->use_linux_input) { + SDL_MouseQuit(); + } else { + SDL_DelMouse(0); + } +} + + +/* This is called when a mouse motion event occurs */ +static void +DirectFB_MoveCursor(SDL_Cursor * cursor) +{ + +} + /* Warp the mouse to (x,y) */ static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y) @@ -251,6 +371,17 @@ DirectFB_InitMouse(_THIS) { SDL_DFB_DEVICEDATA(_this); + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Cursor *cursor; + + mouse->CreateCursor = DirectFB_CreateCursor; + mouse->ShowCursor = DirectFB_ShowCursor; + mouse->WarpMouse = DirectFB_WarpMouse; + mouse->FreeCursor = DirectFB_FreeCursor; + + cursor = DirectFB_CreateDefaultCursor(); + mouse->cursors = mouse->cur_cursor = cursor; + devdata->num_mice = 1; } diff --git a/src/video/directfb/SDL_DirectFB_opengl.c b/src/video/directfb/SDL_DirectFB_opengl.c index c00f69e16..440f8c108 100644 --- a/src/video/directfb/SDL_DirectFB_opengl.c +++ b/src/video/directfb/SDL_DirectFB_opengl.c @@ -26,6 +26,7 @@ #include "SDL_DirectFB_video.h" #if SDL_DIRECTFB_OPENGL + #include "SDL_DirectFB_opengl.h" #include "SDL_DirectFB_window.h" diff --git a/src/video/directfb/SDL_DirectFB_render.c b/src/video/directfb/SDL_DirectFB_render.c index 8ab584cd5..ac9496c1b 100644 --- a/src/video/directfb/SDL_DirectFB_render.c +++ b/src/video/directfb/SDL_DirectFB_render.c @@ -22,10 +22,11 @@ SDL1.3 DirectFB driver by couriersud@arcor.de */ -#include "SDL_DirectFB_video.h" +//#include "SDL_DirectFB_video.h" #include "SDL_DirectFB_window.h" #include "SDL_DirectFB_modes.h" +#include "SDL_syswm.h" #include "SDL_DirectFB_shape.h" #include "../SDL_sysvideo.h" @@ -33,6 +34,21 @@ //#include "../SDL_rect_c.h" //#include "../SDL_yuv_sw_c.h" +#ifndef DFB_VERSION_ATLEAST + +#define DFB_VERSIONNUM(X, Y, Z) \ + ((X)*1000 + (Y)*100 + (Z)) + +#define DFB_COMPILEDVERSION \ + DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION) + +#define DFB_VERSION_ATLEAST(X, Y, Z) \ + (DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z)) + +#define SDL_DFB_CHECK(x) x + +#endif + /* the following is not yet tested ... */ #define USE_DISPLAY_PALETTE (0) @@ -87,7 +103,7 @@ static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, 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); + const SDL_Rect * rects, int count); static int DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, @@ -100,6 +116,9 @@ static int DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * r Uint32 format, void * pixels, int pitch); static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, const void * pixels, int pitch); +static int DirectFB_UpdateViewport(SDL_Renderer * renderer); + +static int PrepareDraw(SDL_Renderer * renderer); #define SDL_DFB_WINDOWSURFACE(win) IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface; @@ -185,11 +204,29 @@ TextureHasAlpha(DirectFB_TextureData * data) #endif } +static inline IDirectFBSurface *get_dfb_surface(SDL_Window *window) +{ + SDL_SysWMinfo wm_info; + SDL_VERSION(&wm_info.version); + SDL_GetWindowWMInfo(window, &wm_info); + + return wm_info.info.dfb.surface; +} + +static inline IDirectFBWindow *get_dfb_window(SDL_Window *window) +{ + SDL_SysWMinfo wm_info; + SDL_VERSION(&wm_info.version); + SDL_GetWindowWMInfo(window, &wm_info); + + return wm_info.info.dfb.window; +} + static void SetBlendMode(DirectFB_RenderData * data, int blendMode, DirectFB_TextureData * source) { - SDL_DFB_WINDOWSURFACE(data->window); + IDirectFBSurface *destsurf = get_dfb_surface(data->window); //FIXME: check for format change if (1 || data->lastBlendMode != blendMode) { @@ -290,17 +327,23 @@ DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) int DirectFB_RenderClear(SDL_Renderer * renderer) { - SDL_DFB_RENDERERDATA(renderer); + DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; + IDirectFBSurface *destsurf = get_dfb_surface(data->window); DirectFB_ActivateRenderer(renderer); + PrepareDraw(renderer); + + destsurf->Clear(destsurf, renderer->r, renderer->g, renderer->b, renderer->a); + + return 0; } SDL_Renderer * DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) { - SDL_DFB_WINDOWDATA(window); + IDirectFBSurface *winsurf = get_dfb_surface(window); SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_Renderer *renderer = NULL; DirectFB_RenderData *data = NULL; @@ -323,6 +366,7 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) 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; @@ -334,6 +378,7 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->DestroyTexture = DirectFB_DestroyTexture; renderer->DestroyRenderer = DirectFB_DestroyRenderer; + renderer->UpdateViewport = DirectFB_UpdateViewport; #if 0 renderer->QueryTexturePixels = DirectFB_QueryTexturePixels; @@ -362,8 +407,7 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) } else data->flipflags |= DSFLIP_ONSYNC; - SDL_DFB_CHECKERR(windata->surface-> - GetCapabilities(windata->surface, &scaps)); + SDL_DFB_CHECKERR(winsurf->GetCapabilities(winsurf, &scaps)); #if 0 if (scaps & DSCAPS_DOUBLE) @@ -378,7 +422,7 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) #if 0 /* Set up a palette watch on the display palette */ - if (display->palette) { + if (display-> palette) { SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data); } #endif @@ -394,12 +438,14 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) static void DirectFB_ActivateRenderer(SDL_Renderer * renderer) { + SDL_DFB_RENDERERDATA(renderer); SDL_Window *window = renderer->window; SDL_DFB_WINDOWDATA(window); - if (renddata->size_changed || windata->wm_needs_redraw) { - DirectFB_AdjustWindowSurface(window); + if (renddata->size_changed /*|| windata->wm_needs_redraw*/) { + //DirectFB_AdjustWindowSurface(window); + renddata->size_changed = SDL_FALSE; } } @@ -839,7 +885,7 @@ static int PrepareDraw(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - SDL_DFB_WINDOWSURFACE(data->window); + IDirectFBSurface *destsurf = get_dfb_surface(data->window); Uint8 r, g, b, a; @@ -875,7 +921,7 @@ static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - SDL_DFB_WINDOWSURFACE(data->window); + IDirectFBSurface *destsurf = get_dfb_surface(data->window); int i; DirectFB_ActivateRenderer(renderer); @@ -892,7 +938,7 @@ static int DirectFB_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - SDL_DFB_WINDOWSURFACE(data->window); + IDirectFBSurface *destsurf = get_dfb_surface(data->window); int i; DirectFB_ActivateRenderer(renderer); @@ -915,7 +961,7 @@ 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); + IDirectFBSurface *destsurf = get_dfb_surface(data->window); int i; DirectFB_ActivateRenderer(renderer); @@ -932,10 +978,10 @@ DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int c } static int -DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) +DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - SDL_DFB_WINDOWSURFACE(data->window); + IDirectFBSurface *destsurf = get_dfb_surface(data->window); int i; DirectFB_ActivateRenderer(renderer); @@ -943,8 +989,8 @@ DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int c PrepareDraw(renderer); for (i=0; iFillRectangle(destsurf, rects[i]->x, rects[i]->y, - rects[i]->w, rects[i]->h)); + SDL_DFB_CHECKERR(destsurf->FillRectangle(destsurf, rects[i].x, rects[i].y, + rects[i].w, rects[i].h)); return 0; error: @@ -956,7 +1002,7 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_Rect * dstrect) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - SDL_DFB_WINDOWSURFACE(data->window); + IDirectFBSurface *destsurf = get_dfb_surface(data->window); DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; Uint8 alpha, r, g, b; @@ -966,6 +1012,7 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, if (texturedata->display) { int px, py; SDL_Window *window = renderer->window; + IDirectFBWindow *dfbwin = get_dfb_window(window); SDL_DFB_WINDOWDATA(window); SDL_VideoDisplay *display = texturedata->display; DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; @@ -975,7 +1022,7 @@ DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, srcrect->x, srcrect->y, srcrect->w, srcrect->h)); - SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin, &px, &py)); + dfbwin->GetPosition(dfbwin, &px, &py); px += windata->client.x; py += windata->client.y; SDL_DFB_CHECKERR(dispdata-> @@ -1129,7 +1176,7 @@ static void DirectFB_DestroyRenderer(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; - SDL_VideoDisplay *display = renderer->SDL_GetDisplayForWindow(window); + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(data->window); #if 0 if (display->palette) { @@ -1143,33 +1190,48 @@ DirectFB_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } +static int +DirectFB_UpdateViewport(SDL_Renderer * renderer) +{ + IDirectFBSurface *winsurf = get_dfb_surface(renderer->window); + DFBRegion dreg; + + dreg.x1 = renderer->viewport.x; + dreg.y1 = renderer->viewport.y; + dreg.x2 = dreg.x1 + renderer->viewport.w - 1; + dreg.y2 = dreg.y1 + renderer->viewport.h - 1; + + winsurf->SetClip(winsurf, &dreg); + return 0; +} + 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; + IDirectFBSurface *winsurf = get_dfb_surface(renderer->window); DirectFB_ActivateRenderer(renderer); - SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format)); + winsurf->GetPixelFormat(winsurf, &dfb_format); sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format); - SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_READ, (void **) &laypixels, &laypitch)); + winsurf->Lock(winsurf, 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)); + winsurf->Unlock(winsurf); return 0; } +#if 0 static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, const void * pixels, int pitch) @@ -1195,6 +1257,6 @@ DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, return 0; } - +#endif /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/directfb/SDL_DirectFB_shape.c b/src/video/directfb/SDL_DirectFB_shape.c new file mode 100644 index 000000000..bca5b7b8b --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_shape.c @@ -0,0 +1,134 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + +*/ + +#include "SDL_assert.h" +#include "SDL_DirectFB_video.h" +#include "SDL_DirectFB_shape.h" +#include "SDL_DirectFB_window.h" + +#include "../SDL_shape_internals.h" + +SDL_Window* +DirectFB_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags) { + return SDL_CreateWindow(title,x,y,w,h,flags /*| SDL_DFB_WINDOW_SHAPED */); +} + +SDL_WindowShaper* +DirectFB_CreateShaper(SDL_Window* window) { + SDL_WindowShaper* result = NULL; + + result = malloc(sizeof(SDL_WindowShaper)); + result->window = window; + result->mode.mode = ShapeModeDefault; + result->mode.parameters.binarizationCutoff = 1; + result->userx = result->usery = 0; + SDL_ShapeData* data = SDL_malloc(sizeof(SDL_ShapeData)); + result->driverdata = data; + data->surface = NULL; + window->shaper = result; + int resized_properly = DirectFB_ResizeWindowShape(window); + SDL_assert(resized_properly == 0); + + return result; +} + +int +DirectFB_ResizeWindowShape(SDL_Window* window) { + SDL_ShapeData* data = window->shaper->driverdata; + SDL_assert(data != NULL); + + if (window->x != -1000) + { + window->shaper->userx = window->x; + window->shaper->usery = window->y; + } + SDL_SetWindowPosition(window,-1000,-1000); + + return 0; +} + +int +DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { + + if(shaper == NULL || shape == NULL || shaper->driverdata == NULL) + return -1; + if(shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode)) + return -2; + if(shape->w != shaper->window->w || shape->h != shaper->window->h) + return -3; + + { + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(shaper->window); + SDL_DFB_DEVICEDATA(display->device); + Uint32 *pixels; + Sint32 pitch; + Uint32 h,w; + Uint8 *src, *bitmap; + DFBSurfaceDescription dsc; + + SDL_ShapeData *data = shaper->driverdata; + + SDL_DFB_RELEASE(data->surface); + + dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS; + dsc.width = shape->w; + dsc.height = shape->h; + dsc.caps = DSCAPS_PREMULTIPLIED; + dsc.pixelformat = DSPF_ARGB; + + SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, &data->surface)); + + /* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */ + SDL_DFB_ALLOC_CLEAR(bitmap, shape->w * shape->h); + SDL_CalculateShapeBitmap(shaper->mode,shape,bitmap,1); + + src = bitmap; + + SDL_DFB_CHECK(data->surface->Lock(data->surface, DSLF_WRITE | DSLF_READ, (void **) &pixels, &pitch)); + + h = shaper->window->h; + while (h--) { + for (w = 0; w < shaper->window->w; w++) { + if (*src) + pixels[w] = 0xFFFFFFFF; + else + pixels[w] = 0; + src++; + + } + pixels += (pitch >> 2); + } + SDL_DFB_CHECK(data->surface->Unlock(data->surface)); + SDL_DFB_FREE(bitmap); + + /* FIXME: Need to call this here - Big ?? */ + DirectFB_WM_RedrawLayout(SDL_GetDisplayForWindow(shaper->window)->device, shaper->window); + } + + return 0; +error: + return -1; +} + diff --git a/src/video/directfb/SDL_DirectFB_shape.h b/src/video/directfb/SDL_DirectFB_shape.h new file mode 100644 index 000000000..2a774cc55 --- /dev/null +++ b/src/video/directfb/SDL_DirectFB_shape.h @@ -0,0 +1,43 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2010 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + +*/ + +#ifndef _SDL_DirectFB_shape_h +#define _SDL_DirectFB_shape_h + +#include + +#include "../SDL_sysvideo.h" +#include "SDL_shape.h" + +typedef struct { + IDirectFBSurface *surface; +} SDL_ShapeData; + +extern SDL_Window* DirectFB_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags); +extern SDL_WindowShaper* DirectFB_CreateShaper(SDL_Window* window); +extern int DirectFB_ResizeWindowShape(SDL_Window* window); +extern int DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode); + +#endif /* _SDL_DirectFB_shape_h */ diff --git a/src/video/directfb/SDL_DirectFB_video.c b/src/video/directfb/SDL_DirectFB_video.c index 63050ef50..062508d39 100644 --- a/src/video/directfb/SDL_DirectFB_video.c +++ b/src/video/directfb/SDL_DirectFB_video.c @@ -133,6 +133,10 @@ DirectFB_CreateDevice(int devindex) device->DestroyWindow = DirectFB_DestroyWindow; device->GetWindowWMInfo = DirectFB_GetWindowWMInfo; + /* Not supported by DFB, for completeness */ + device->SetWindowGammaRamp = DirectFB_SetWindowGammaRamp; + device->GetWindowGammaRamp = DirectFB_GetWindowGammaRamp; + #if SDL_DIRECTFB_OPENGL device->GL_LoadLibrary = DirectFB_GL_LoadLibrary; device->GL_GetProcAddress = DirectFB_GL_GetProcAddress; @@ -168,34 +172,34 @@ DirectFB_DeviceInformation(IDirectFB * dfb) dfb->GetDeviceDescription(dfb, &desc); - 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, + SDL_DFB_LOG( "DirectFB Device Information"); + SDL_DFB_LOG( "==========================="); + SDL_DFB_LOG( "Name: %s", desc.name); + SDL_DFB_LOG( "Vendor: %s", desc.vendor); + SDL_DFB_LOG( "Driver Name: %s", desc.driver.name); + SDL_DFB_LOG( "Driver Vendor: %s", desc.driver.vendor); + SDL_DFB_LOG( "Driver Version: %d.%d", desc.driver.major, desc.driver.minor); - SDL_DFB_LOG( "\nVideo memoory: %d\n", desc.video_memory); + SDL_DFB_LOG( "Video memoory: %d", desc.video_memory); - SDL_DFB_LOG( "\nBlitting flags:\n"); + SDL_DFB_LOG( "Blitting flags:"); for (n = 0; blitting_flags[n].flag; n++) { if (desc.blitting_flags & blitting_flags[n].flag) - SDL_DFB_LOG( " %s\n", blitting_flags[n].name); + SDL_DFB_LOG( " %s", blitting_flags[n].name); } - SDL_DFB_LOG( "\nDrawing flags:\n"); + SDL_DFB_LOG( "Drawing flags:"); for (n = 0; drawing_flags[n].flag; n++) { if (desc.drawing_flags & drawing_flags[n].flag) - SDL_DFB_LOG( " %s\n", drawing_flags[n].name); + SDL_DFB_LOG( " %s", drawing_flags[n].name); } - SDL_DFB_LOG( "\nAcceleration flags:\n"); + SDL_DFB_LOG( "Acceleration flags:"); for (n = 0; acceleration_mask[n].mask; n++) { if (desc.acceleration_mask & acceleration_mask[n].mask) - SDL_DFB_LOG( " %s\n", acceleration_mask[n].name); + SDL_DFB_LOG( " %s", acceleration_mask[n].name); } diff --git a/src/video/directfb/SDL_DirectFB_video.h b/src/video/directfb/SDL_DirectFB_video.h index d165e3920..c1d0199b2 100644 --- a/src/video/directfb/SDL_DirectFB_video.h +++ b/src/video/directfb/SDL_DirectFB_video.h @@ -45,7 +45,9 @@ (DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z)) #if (DFB_VERSION_ATLEAST(1,0,0)) +#ifdef SDL_VIDEO_OPENGL #define SDL_DIRECTFB_OPENGL 1 +#endif #else #error "SDL_DIRECTFB: Please compile against libdirectfb version >= 1.0.0" #endif @@ -93,7 +95,7 @@ #define SDL_DFB_LOG(x...) \ do { \ - fprintf(LOG_CHANNEL, SDL_DFB_CONTEXT); \ + fprintf(LOG_CHANNEL, "%s: ", SDL_DFB_CONTEXT); \ fprintf(LOG_CHANNEL, x ); \ fprintf(LOG_CHANNEL, "\n"); \ } while (0) diff --git a/src/video/directfb/SDL_DirectFB_window.c b/src/video/directfb/SDL_DirectFB_window.c index 97070457d..09a9cb2b9 100644 --- a/src/video/directfb/SDL_DirectFB_window.c +++ b/src/video/directfb/SDL_DirectFB_window.c @@ -489,6 +489,20 @@ DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, } } +int +DirectFB_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) +{ + SDL_Unsupported(); + return -1; +} + +int +DirectFB_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) +{ + SDL_Unsupported(); + return -1; +} + void DirectFB_AdjustWindowSurface(SDL_Window * window) { diff --git a/src/video/directfb/SDL_DirectFB_window.h b/src/video/directfb/SDL_DirectFB_window.h index f66c827af..647cafc26 100644 --- a/src/video/directfb/SDL_DirectFB_window.h +++ b/src/video/directfb/SDL_DirectFB_window.h @@ -78,6 +78,10 @@ extern void DirectFB_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); +extern int DirectFB_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); +extern int DirectFB_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); + + extern void DirectFB_AdjustWindowSurface(SDL_Window * window); #endif /* _SDL_directfb_window_h */