Mercurial > sdl-ios-xcode
diff src/video/directfb/SDL_DirectFB_window.c @ 5202:164f20ba08eb
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.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 05 Feb 2011 16:07:10 -0800 |
parents | b196d2758026 |
children | 58265e606e4e |
line wrap: on
line diff
--- a/src/video/directfb/SDL_DirectFB_window.c Sat Feb 05 16:02:30 2011 -0800 +++ b/src/video/directfb/SDL_DirectFB_window.c Sat Feb 05 16:07:10 2011 -0800 @@ -18,41 +18,49 @@ Sam Lantinga slouken@libsdl.org + + SDL1.3 DirectFB driver by couriersud@arcor.de + */ -#include "SDL_config.h" - -#include "SDL_syswm.h" -#include "../SDL_sysvideo.h" -#include "../../events/SDL_keyboard_c.h" -#include "../../video/SDL_pixels_c.h" #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 @@ } 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 @@ } else { y = window->y; } + if (window->flags & SDL_WINDOW_FULLSCREEN) { x = 0; y = 0; @@ -76,78 +86,103 @@ 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)); } - SDL_DFB_CHECK(windata->window->SetOptions(windata->window, wopts)); + + if (bshaped) { + wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL; + wopts &= ~DWOP_OPAQUE_REGION; + } + + 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 @@ DirectFB_SetWindowPosition(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); + SDL_DFB_DISPLAYDATA(window); int x, y; - if (window->y == 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 { + 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 + } else { y = window->y; - - if (window->x == SDL_WINDOWPOS_UNDEFINED) - x = 0; - else - x = window->x; + } if (window->flags & SDL_WINDOW_FULLSCREEN) { x = 0; y = 0; } 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 @@ { 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 @@ { 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 @@ { 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 @@ DirectFB_RestoreWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); + DFBWindowOptions wopts; - if (windata->is_managed) { - DirectFB_WM_RestoreWindow(_this, window); - } else - SDL_Unsupported(); + /* 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)); + + } void @@ -351,15 +425,15 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ #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: