SDL_GLContext
DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
{
    //SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    DirectFB_GLContext *context;

    SDL_DFB_ALLOC_CLEAR(context, sizeof(DirectFB_GLContext));

    SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface,
                                             &context->context));

    if (!context->context)
        return NULL;

    context->is_locked = 0;
    context->sdl_window = window;
    
    context->next = _this->gl_data->firstgl;
    _this->gl_data->firstgl = context;

    SDL_DFB_CHECK(context->context->Unlock(context->context));

    if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
        DirectFB_GL_DeleteContext(_this, context);
        return NULL;
    }

    return context;

  error:
    return NULL;
}
Example #2
0
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));


}
Example #3
0
void
DirectFB_HideWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    windata->window->GetOpacity(windata->window, &windata->opacity);
    windata->window->SetOpacity(windata->window, 0);
}
Example #4
0
void
DirectFB_ShowWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    windata->window->SetOpacity(windata->window, windata->opacity);

}
void
DirectFB_HideWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
    SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
}
void
DirectFB_RaiseWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
    SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
}
Example #7
0
void
DirectFB_RaiseWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    windata->window->RaiseToTop(windata->window);
    windata->window->RequestFocus(windata->window);
}
Example #8
0
void
DirectFB_RestoreWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    if (windata->is_managed) {
        DirectFB_WM_RestoreWindow(_this, window);
    } else
        SDL_Unsupported();
}
Example #9
0
void
DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    if (windata->is_managed) {
        windata->wm_needs_redraw = 1;
    } else
        SDL_Unsupported();
}
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 */) {
        renddata->size_changed = SDL_FALSE;
    }
}
int
DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
{
    const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f));
    SDL_DFB_WINDOWDATA(window);
    SDL_DFB_CHECKERR(windata->dfbwin->SetOpacity(windata->dfbwin, alpha));
    windata->opacity = alpha;
    return 0;

error:
    return -1;
}
void
DirectFB_AdjustWindowSurface(SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    int adjust = windata->wm_needs_redraw;
    int cw, ch;

    DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);

    SDL_DFB_CHECKERR(windata->
                     window_surface->GetSize(windata->window_surface, &cw,
                                             &ch));
    if (cw != windata->size.w || ch != windata->size.h) {
        adjust = 1;
    }

    if (adjust) {
#if SDL_DIRECTFB_OPENGL
		DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
#endif

#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,
                                                          windata->
                                                          window_surface,
                                                          &windata->client));
#else
        DFBWindowOptions 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->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(SDL_GetVideoDevice(), window);
        
#if SDL_DIRECTFB_OPENGL
		DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
#endif
   }
  error:
    return;
}
void
DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    int x, y;

    x = window->x;
    y = window->y;

    DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
    SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
}
Example #14
0
static int
DirectFB_ActivateRenderer(SDL_Renderer * renderer)
{
    SDL_DFB_RENDERERDATA(renderer);
    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
    SDL_DFB_WINDOWDATA(window);

    if (renddata->size_changed || windata->wm_needs_redraw) {
        DirectFB_AdjustWindowSurface(window);
    }
    return 0;
}
Example #15
0
void
DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    SDL_Surface *surface = NULL;
    DFBResult ret;

    if (icon) {
        SDL_PixelFormat format;
        DFBSurfaceDescription dsc;
        Uint32 *dest;
        Uint32 *p;
        int pitch, i;

        /* Convert the icon to ARGB for modern window managers */
        SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
                       0xFF000000);
        surface = SDL_ConvertSurface(icon, &format, 0);
        if (!surface) {
            return;
        }
        dsc.flags =
            DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
        dsc.caps = DSCAPS_VIDEOONLY;
        dsc.width = surface->w;
        dsc.height = surface->h;
        dsc.pixelformat = DSPF_ARGB;

        SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
                                                     &windata->icon));

        SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
                                             (void *) &dest, &pitch));

        p = surface->pixels;
        for (i = 0; i < surface->h; i++)
            memcpy((char *) dest + i * pitch,
                   (char *) p + i * surface->pitch, 4 * surface->w);

        windata->icon->Unlock(windata->icon);
        SDL_FreeSurface(surface);
    } else {
        SDL_DFB_RELEASE(windata->icon);
    }
    return;
  error:
    if (surface)
        SDL_FreeSurface(surface);
    SDL_DFB_RELEASE(windata->icon);
    return;
}
Example #16
0
void
DirectFB_SetWindowGrab(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
        windata->window->GrabPointer(windata->window);
        windata->window->GrabKeyboard(windata->window);
    } else {
        windata->window->UngrabPointer(windata->window);
        windata->window->UngrabKeyboard(windata->window);
    }
}
Example #17
0
DFBResult
DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch)
{
    SDL_DFB_WINDOWDATA(window);
    IDirectFBWindow *dfbwin = windata->dfbwin;

    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 +
        windata->theme.bottom_size;
    return DFB_OK;
}
void
DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window)
{
    DirectFB_GLContext *p;

    for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
        if (p->sdl_window == window)
        {
            SDL_DFB_WINDOWDATA(window);
            SDL_DFB_CHECK(windata->surface->GetGL(windata->surface,
                                             &p->context));
            if (p->is_locked)
                SDL_DFB_CHECK(p->context->Lock(p->context));
            }
}
void
DirectFB_DestroyWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    DFB_WindowData *p;

    /* Some cleanups */
    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));
  	SDL_DFB_RELEASE(windata->icon);
    SDL_DFB_RELEASE(windata->font);
    SDL_DFB_RELEASE(windata->eventbuffer);
    SDL_DFB_RELEASE(windata->surface);
    SDL_DFB_RELEASE(windata->window_surface);

    SDL_DFB_RELEASE(windata->dfbwin);

    /* Remove from list ... */

    p = devdata->firstwin->driverdata;

    while (p && p->next != window)
        p = (p->next ? p->next->driverdata : NULL);
    if (p)
        p->next = windata->next;
    else
        devdata->firstwin = windata->next;
    SDL_free(windata);
    return;
}
Example #20
0
void
DirectFB_AdjustWindowSurface(SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    int adjust = windata->wm_needs_redraw;
    int cw, ch;
    int ret;

    DirectFB_WM_AdjustWindowLayout(window);

    SDL_DFB_CHECKERR(windata->
                     window_surface->GetSize(windata->window_surface, &cw,
                                             &ch));
    if (cw != windata->size.w || ch != windata->size.h) {
        adjust = 1;
    }

    if (adjust) {
#if DFB_VERSION_ATLEAST(1,2,1)
        SDL_DFB_CHECKERR(windata->window->ResizeSurface(windata->window,
                                                        windata->size.w,
                                                        windata->size.h));
        SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
                                                          windata->
                                                          window_surface,
                                                          &windata->client));
#else
        DFBWindowOptions opts;

        SDL_DFB_CHECKERR(windata->window->GetOptions(windata->window, &opts));
        /* recreate subsurface */
        SDL_DFB_RELEASE(windata->surface);

        if (opts & DWOP_SCALE)
            SDL_DFB_CHECKERR(windata->window->ResizeSurface(windata->window,
                                                            windata->size.w,
                                                            windata->size.h));
        SDL_DFB_CHECKERR(windata->window_surface->
                         GetSubSurface(windata->window_surface,
                                       &windata->client, &windata->surface));
#endif
        DirectFB_WM_RedrawLayout(window);
    }
  error:
    return;
}
Example #21
0
static void
DirectFB_RenderPresent(SDL_Renderer * renderer)
{
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
    SDL_Window *window = SDL_GetWindowFromID(renderer->window);
    SDL_DFB_WINDOWDATA(window);

    DFBRectangle sr;
    DFBResult ret;

    sr.x = 0;
    sr.y = 0;
    sr.w = window->w;
    sr.h = window->h;

    /* Send the data to the display */
    SDL_DFB_CHECK(windata->window_surface->Flip(windata->window_surface, NULL,
                                                data->flipflags));
}
SDL_bool
DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
                         struct SDL_SysWMinfo * info)
{
    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;
    }
}
Example #23
0
SDL_bool
DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
                         struct SDL_SysWMinfo * info)
{
    const Uint32 version = ((((Uint32) info->version.major) * 1000000) +
                            (((Uint32) info->version.minor) * 10000) +
                            (((Uint32) info->version.patch)));

    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);

    /* Before 2.0.6, it was possible to build an SDL with DirectFB support
       (SDL_SysWMinfo will be large enough to hold DirectFB info), but build
       your app against SDL headers that didn't have DirectFB support
       (SDL_SysWMinfo could be smaller than DirectFB needs. This would lead
       to an app properly using SDL_GetWindowWMInfo() but we'd accidentally
       overflow memory on the stack or heap. To protect against this, we've
       padded out the struct unconditionally in the headers and DirectFB will
       just return an error for older apps using this function. Those apps
       will need to be recompiled against newer headers or not use DirectFB,
       maybe by forcing SDL_VIDEODRIVER=x11. */
    if (version < 2000006) {
        info->subsystem = SDL_SYSWM_UNKNOWN;
        SDL_SetError("Version must be 2.0.6 or newer");
        return SDL_FALSE;
    }

    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",
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
        return SDL_FALSE;
    }
}
void
DirectFB_SetWindowGrab(_THIS, SDL_Window * window)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);

    if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
        if (gwindata != NULL)
        {
		    SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
		    SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
        }
        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->dfbwin->UngrabPointer(windata->dfbwin));
        SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
        devdata->grabbed_window = NULL;
    }
}
Example #25
0
void
DirectFB_SetWindowSize(_THIS, SDL_Window * window)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    int ret;

    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,
                                                        DWET_ALL));

        SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));

        if (cw != window->w || ch != window->h) {

            DirectFB_WM_AdjustWindowLayout(window);
            SDL_DFB_CHECKERR(windata->window->Resize(windata->window,
                                                     windata->size.w,
                                                     windata->size.h));
        }

        SDL_DFB_CHECKERR(windata->window->EnableEvents(windata->window,
                                                       DWET_ALL));

        SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
                         (_this, window, &window->w, &window->h));

        SDL_OnWindowResized(window);
    }
    return;
  error:
    windata->window->EnableEvents(windata->window, DWET_ALL);
    return;
}
void
DirectFB_SetWindowSize(_THIS, SDL_Window * window)
{
    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->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->dfbwin->Resize(windata->dfbwin,
                                                     windata->size.w,
                                                     windata->size.h));
        }

        SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
                     (_this, window, &window->w, &window->h));
        DirectFB_AdjustWindowSurface(window);

        SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
                                                       DWET_ALL));

    }
    return;
  error:
    SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
    return;
}
Example #27
0
void
DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
{
    //SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    DFBRegion region;
    DirectFB_GLContext *p;

    region.x1 = 0;
    region.y1 = 0;
    region.x2 = window->w;
    region.y2 = window->h;

#if 0
    if (devdata->glFinish)
        devdata->glFinish();
    else if (devdata->glFlush)
        devdata->glFlush();
#endif

  	for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
        if (p->sdl_window == window && p->is_locked)
        {
            SDL_DFB_CHECKERR(p->context->Unlock(p->context));
            p->is_locked = 0;
        }            

    SDL_DFB_CHECKERR(windata->window_surface->Flip(windata->window_surface,NULL,  DSFLIP_PIPELINE |DSFLIP_BLIT | DSFLIP_ONSYNC ));

    //if (windata->gl_context) {
        //SDL_DFB_CHECKERR(windata->surface->Flip(windata->surface,NULL, DSFLIP_ONSYNC)); 
        //SDL_DFB_CHECKERR(windata->gl_context->context->Lock(windata->gl_context->context));
    //}

    return;
  error:
    return;
}
void
DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    DFBWindowOptions wopts;

    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));
}
Example #29
0
void
DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    int x, y;

    if (window->y == SDL_WINDOWPOS_UNDEFINED)
        y = 0;
    else
        y = window->y;

    if (window->x == SDL_WINDOWPOS_UNDEFINED)
        x = 0;
    else
        x = window->x;

    if (window->flags & SDL_WINDOW_FULLSCREEN) {
        x = 0;
        y = 0;
    }
    DirectFB_WM_AdjustWindowLayout(window);
    windata->window->MoveTo(windata->window, x, y);
}
static int
DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
                    const SDL_Rect * srcrect, const SDL_FRect * dstrect)
{
    DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
    IDirectFBSurface *destsurf = data->target;
    DirectFB_TextureData *texturedata =
        (DirectFB_TextureData *) texture->driverdata;
    Uint8 alpha, r, g, b;
    DFBRegion clip_region;
    DFBRectangle sr, dr;

    DirectFB_ActivateRenderer(renderer);

    SDLtoDFBRect(srcrect, &sr);
    SDLtoDFBRect_Float(dstrect, &dr);

    destsurf->GetClip(destsurf, &clip_region);
    dr.x += clip_region.x1;
    dr.y += clip_region.y1;

    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;

        SDL_DFB_CHECKERR(dispdata->
                         vidlayer->SetSourceRectangle(dispdata->vidlayer,
                                                      sr.x, sr.y, sr.w, sr.h));
        dfbwin->GetPosition(dfbwin, &px, &py);
        px += windata->client.x;
        py += windata->client.y;
        SDL_DFB_CHECKERR(dispdata->
                         vidlayer->SetScreenRectangle(dispdata->vidlayer,
                                                      px + dr.x,
                                                      py + dr.y,
                                                      dr.w,
                                                      dr.h));
    } else {
        DFBSurfaceBlittingFlags flags = 0;

#if 0
        if (texturedata->dirty.list) {
            SDL_DirtyRect *dirty;
            void *pixels;
            int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
            int pitch = texturedata->pitch;

            for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
                SDL_Rect *rect = &dirty->rect;
                pixels =
                    (void *) ((Uint8 *) texturedata->pixels +
                              rect->y * pitch + rect->x * bpp);
                DirectFB_UpdateTexture(renderer, texture, rect,
                                       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);
        }

        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, r, g, b, alpha));

        /* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */

        SetBlendMode(data, texture->blendMode, texturedata);

        SDL_DFB_CHECKERR(destsurf->SetBlittingFlags(destsurf,
                                                    data->blitFlags | flags));

#if (DFB_VERSION_ATLEAST(1,2,0))
        SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf,
                                                    texturedata->
                                                    render_options));
#endif

        if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
            SDL_DFB_CHECKERR(destsurf->Blit(destsurf,
                                            texturedata->surface,
                                            &sr, dr.x, dr.y));
        } else {
            SDL_DFB_CHECKERR(destsurf->StretchBlit(destsurf,
                                                   texturedata->surface,
                                                   &sr, &dr));
        }
    }
    return 0;
  error:
    return -1;
}