src/video/directfb/SDL_DirectFB_video.c
author Sam Lantinga
Tue, 26 Feb 2002 14:38:53 +0000
changeset 286 3ea69fd0b095
parent 259 80b647695abd
child 297 f6ffac90895c
permissions -rw-r--r--
Updated for DirectFB 0.9.9
     1 /*
     2 	SDL - Simple DirectMedia Layer
     3 	Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     4 
     5 	This library is free software; you can redistribute it and/or
     6 	modify it under the terms of the GNU Library General Public
     7 	License as published by the Free Software Foundation; either
     8 	version 2 of the License, or (at your option) any later version.
     9 
    10 	This library is distributed in the hope that it will be useful,
    11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
    12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13 	Library General Public License for more details.
    14 
    15 	You should have received a copy of the GNU Library General Public
    16 	License along with this library; if not, write to the Free
    17 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19 	Sam Lantinga
    20 	slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 /* DirectFB video driver implementation.
    29 */
    30 
    31 #include <stdlib.h>
    32 #include <stdio.h>
    33 #include <fcntl.h>
    34 #include <unistd.h>
    35 #include <sys/mman.h>
    36 
    37 #include <directfb.h>
    38 
    39 #include "SDL.h"
    40 #include "SDL_error.h"
    41 #include "SDL_video.h"
    42 #include "SDL_mouse.h"
    43 #include "SDL_sysvideo.h"
    44 #include "SDL_pixels_c.h"
    45 #include "SDL_events_c.h"
    46 #include "SDL_DirectFB_video.h"
    47 #include "SDL_DirectFB_events.h"
    48 
    49 
    50 /* Initialization/Query functions */
    51 static int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat);
    52 static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
    53 static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
    54 static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors,
    55 			 SDL_Color *colors);
    56 static void DirectFB_VideoQuit(_THIS);
    57 
    58 /* Hardware surface functions */
    59 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface);
    60 static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
    61 static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface);
    62 static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface);
    63 static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface);
    64 static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
    65 static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
    66                                 SDL_Surface *dst, SDL_Rect *dstrect);
    67 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);
    68 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha);
    69 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface);
    70 
    71 /* Various screen update functions available */
    72 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
    73 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects);
    74 
    75 /* This is the rect EnumModes2 uses */
    76 struct DirectFBEnumRect {
    77 	SDL_Rect r;
    78 	struct DirectFBEnumRect* next;
    79 };
    80 
    81 static struct DirectFBEnumRect *enumlists[NUM_MODELISTS];
    82 
    83 
    84 /* DirectFB driver bootstrap functions */
    85 
    86 static int DirectFB_Available(void)
    87 {
    88   return 1;
    89 }
    90 
    91 static void DirectFB_DeleteDevice(SDL_VideoDevice *device)
    92 {
    93   free(device->hidden);
    94   free(device);
    95 }
    96 
    97 static SDL_VideoDevice *DirectFB_CreateDevice(int devindex)
    98 {
    99   SDL_VideoDevice *device;
   100 
   101   /* Initialize all variables that we clean on shutdown */
   102   device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
   103   if (device)
   104     {
   105       memset (device, 0, (sizeof *device));
   106       device->hidden = (struct SDL_PrivateVideoData *) malloc (sizeof (*device->hidden));
   107     }
   108   if (device == NULL  ||  device->hidden == NULL)
   109     {
   110       SDL_OutOfMemory();
   111       if (device)
   112         {
   113           free (device);
   114         }
   115       return(0);
   116     }
   117   memset (device->hidden, 0, sizeof (*device->hidden));
   118 
   119   /* Set the function pointers */
   120   device->VideoInit = DirectFB_VideoInit;
   121   device->ListModes = DirectFB_ListModes;
   122   device->SetVideoMode = DirectFB_SetVideoMode;
   123   device->SetColors = DirectFB_SetColors;
   124   device->UpdateRects = NULL;
   125   device->VideoQuit = DirectFB_VideoQuit;
   126   device->AllocHWSurface = DirectFB_AllocHWSurface;
   127   device->CheckHWBlit = DirectFB_CheckHWBlit;
   128   device->FillHWRect = DirectFB_FillHWRect;
   129   device->SetHWColorKey = DirectFB_SetHWColorKey;
   130   device->SetHWAlpha = DirectFB_SetHWAlpha;
   131   device->LockHWSurface = DirectFB_LockHWSurface;
   132   device->UnlockHWSurface = DirectFB_UnlockHWSurface;
   133   device->FlipHWSurface = DirectFB_FlipHWSurface;
   134   device->FreeHWSurface = DirectFB_FreeHWSurface;
   135   device->SetCaption = NULL;
   136   device->SetIcon = NULL;
   137   device->IconifyWindow = NULL;
   138   device->GrabInput = NULL;
   139   device->GetWMInfo = NULL;
   140   device->InitOSKeymap = DirectFB_InitOSKeymap;
   141   device->PumpEvents = DirectFB_PumpEvents;
   142 
   143   device->free = DirectFB_DeleteDevice;
   144 
   145   return device;
   146 }
   147 
   148 VideoBootStrap DirectFB_bootstrap = {
   149   "directfb", "DirectFB",
   150   DirectFB_Available, DirectFB_CreateDevice
   151 };
   152 
   153 static DFBEnumerationResult EnumModesCallback (unsigned int  width,
   154                                                unsigned int  height,
   155                                                unsigned int  bpp,
   156                                                void         *data)
   157 {
   158   SDL_VideoDevice *this = (SDL_VideoDevice *)data;
   159   struct DirectFBEnumRect *enumrect;
   160 
   161   switch (bpp)
   162     {
   163     case 8:
   164     case 15:
   165     case 16:
   166     case 24:
   167     case 32:
   168       bpp /= 8; --bpp;
   169       ++HIDDEN->SDL_nummodes[bpp];
   170       enumrect = (struct DirectFBEnumRect*)malloc(sizeof(struct DirectFBEnumRect));
   171       if ( !enumrect )
   172         {
   173           SDL_OutOfMemory();
   174           return DFENUM_CANCEL;
   175         }
   176       enumrect->r.x = 0;
   177       enumrect->r.y = 0;
   178       enumrect->r.w = width;
   179       enumrect->r.h = height;
   180       enumrect->next = enumlists[bpp];
   181       enumlists[bpp] = enumrect;
   182       break;
   183     }
   184 
   185   return DFENUM_OK;
   186 }
   187 
   188 struct private_hwdata {
   189   IDirectFBSurface *surface;
   190 };
   191 
   192 void SetDirectFBerror (const char *function, DFBResult code)
   193 {
   194   const char *error = DirectFBErrorString (code);
   195 
   196   if (error)
   197     SDL_SetError("%s: %s", function, error);
   198   else
   199     SDL_SetError("Unknown error code from %s", function);
   200 }
   201 
   202 static DFBSurfacePixelFormat SDLToDFBPixelFormat (SDL_PixelFormat *format)
   203 {
   204   if (format->Rmask && format->Gmask && format->Bmask)
   205     {
   206       switch (format->BitsPerPixel)
   207         {
   208         case 16:
   209           if (format->Rmask == 0xF800 &&
   210               format->Gmask == 0x07E0 &&
   211               format->Bmask == 0x001F)
   212             return DSPF_RGB16;
   213           /* fall through */
   214           
   215         case 15:
   216           if (format->Rmask == 0x7C00 &&
   217               format->Gmask == 0x03E0 &&
   218               format->Bmask == 0x001F)
   219             return DSPF_RGB15;
   220           break;
   221           
   222         case 24:
   223           if (format->Rmask == 0xFF0000 &&
   224               format->Gmask == 0x00FF00 &&
   225               format->Bmask == 0x0000FF)
   226             return DSPF_RGB24;
   227           break;
   228           
   229         case 32:
   230           if (format->Rmask == 0xFF0000 &&
   231               format->Gmask == 0x00FF00 &&
   232               format->Bmask == 0x0000FF)
   233             {
   234               if (format->Amask == 0xFF000000)
   235                 return DSPF_ARGB;
   236               else
   237                 return DSPF_RGB32;
   238             }
   239           break;
   240         }
   241     }
   242   else
   243     {
   244       switch (format->BitsPerPixel)
   245 	{
   246 	case 15:
   247 	  return DSPF_RGB15;
   248 	case 16:
   249 	  return DSPF_RGB16;
   250 	case 24:
   251 	  return DSPF_RGB24;
   252 	case 32:
   253 	  return DSPF_RGB32;
   254 	}
   255     }
   256 
   257   return DSPF_UNKNOWN;
   258 }
   259 
   260 static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat, SDL_PixelFormat *format)
   261 {
   262   format->BitsPerPixel = 0;
   263   format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
   264 
   265   switch (pixelformat)
   266     {
   267     case DSPF_A8:
   268       format->Amask = 0x000000FF;
   269       break;
   270     case DSPF_RGB15:
   271       format->Rmask = 0x00007C00;
   272       format->Gmask = 0x000003E0;
   273       format->Bmask = 0x0000001F;
   274       break;
   275     case DSPF_RGB16:
   276       format->Rmask = 0x0000F800;
   277       format->Gmask = 0x000007E0;
   278       format->Bmask = 0x0000001F;
   279       break;
   280     case DSPF_ARGB:
   281       format->Amask = 0xFF000000;
   282       /* fall through */
   283     case DSPF_RGB24:
   284     case DSPF_RGB32:
   285       format->Rmask = 0x00FF0000;
   286       format->Gmask = 0x0000FF00;
   287       format->Bmask = 0x000000FF;
   288       break;
   289     default:
   290       return -1;
   291     }
   292 
   293   format->BitsPerPixel = DFB_BITS_PER_PIXEL(pixelformat);
   294 
   295   return 0;
   296 }
   297 
   298 
   299 int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat)
   300 {
   301   int                    i, j;
   302   DFBResult              ret;
   303   IDirectFB             *dfb;
   304   DFBCardCapabilities    caps;
   305   IDirectFBDisplayLayer *layer;
   306   DFBDisplayLayerConfig  dlc;
   307   IDirectFBEventBuffer  *eventbuffer;
   308 
   309 
   310   ret = DirectFBInit (NULL, NULL);
   311   if (ret)
   312     {
   313       SetDirectFBerror ("DirectFBInit", ret);
   314       return -1;
   315     }
   316 
   317   ret = DirectFBCreate (&dfb);
   318   if (ret)
   319     {
   320       SetDirectFBerror ("DirectFBCreate", ret);
   321       return -1;
   322     }
   323 
   324   ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer);
   325   if (ret)
   326     {
   327       SetDirectFBerror ("dfb->GetDisplayLayer", ret);
   328       dfb->Release (dfb);
   329       return -1;
   330     }
   331 
   332   ret = dfb->CreateEventBuffer (dfb, DICAPS_ALL, &eventbuffer);
   333   if (ret)
   334     {
   335       SetDirectFBerror ("dfb->CreateEventBuffer", ret);
   336       layer->Release (layer);
   337       dfb->Release (dfb);
   338       return -1;
   339     }
   340   
   341   layer->EnableCursor (layer, 1);
   342 
   343   /* Query layer configuration to determine the current mode and pixelformat */
   344   layer->GetConfiguration (layer, &dlc);
   345 
   346   if (DFBToSDLPixelFormat (dlc.pixelformat, vformat))
   347     {
   348       SDL_SetError ("Unsupported pixelformat");
   349       layer->Release (layer);
   350       dfb->Release (dfb);
   351       return -1;
   352     }
   353 
   354   /* Enumerate the available fullscreen modes */
   355   for ( i=0; i<NUM_MODELISTS; ++i )
   356     enumlists[i] = NULL;
   357 
   358   ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this);
   359   if (ret)
   360     {
   361       SetDirectFBerror ("dfb->EnumVideoModes", ret);
   362       layer->Release (layer);
   363       dfb->Release (dfb);
   364       return(-1);
   365     }
   366   for ( i=0; i<NUM_MODELISTS; ++i )
   367     {
   368       struct DirectFBEnumRect *rect;
   369       HIDDEN->SDL_modelist[i] = (SDL_Rect **) malloc
   370         ((HIDDEN->SDL_nummodes[i]+1)*sizeof(SDL_Rect *));
   371       if ( HIDDEN->SDL_modelist[i] == NULL )
   372         {
   373           SDL_OutOfMemory();
   374           return(-1);
   375         }
   376       for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next )
   377         {
   378           HIDDEN->SDL_modelist[i][j]=(SDL_Rect *)rect;
   379         }
   380       HIDDEN->SDL_modelist[i][j] = NULL;
   381     }
   382 
   383   /* Query card capabilities to get the video memory size */
   384   dfb->GetCardCapabilities (dfb, &caps);
   385 
   386   this->info.wm_available = 1;
   387   this->info.hw_available = 1;
   388   this->info.blit_hw      = 1;
   389   this->info.blit_hw_CC   = 1;
   390   this->info.blit_hw_A    = 1;
   391   this->info.blit_fill    = 1;
   392   this->info.video_mem    = caps.video_memory / 1024;
   393 
   394   HIDDEN->initialized = 1;
   395   HIDDEN->dfb         = dfb;
   396   HIDDEN->layer       = layer;
   397   HIDDEN->eventbuffer = eventbuffer;
   398 
   399   return 0;
   400 }
   401 
   402 static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
   403 {
   404   if (flags & SDL_FULLSCREEN)
   405     return HIDDEN->SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1];
   406   else
   407     if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN)
   408       return (SDL_Rect**) -1;
   409 
   410   return NULL;
   411 }
   412 
   413 SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
   414 {
   415   DFBResult             ret;
   416   DFBSurfaceDescription dsc;
   417   DFBSurfacePixelFormat pixelformat;
   418 
   419   fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
   420            width, height, bpp, flags);
   421 
   422   flags |= SDL_FULLSCREEN;
   423 
   424   /* Release previous primary surface */
   425   if (current->hwdata && current->hwdata->surface)
   426     {
   427       current->hwdata->surface->Release (current->hwdata->surface);
   428       current->hwdata->surface = NULL;
   429     }
   430   else if (!current->hwdata)
   431     {
   432       /* Allocate the hardware acceleration data */
   433       current->hwdata = (struct private_hwdata *) malloc (sizeof(*current->hwdata));
   434       if (!current->hwdata)
   435         {
   436           SDL_OutOfMemory();
   437           return NULL;
   438 	}
   439       memset (current->hwdata, 0, sizeof(*current->hwdata));
   440     }
   441 
   442   /* Set cooperative level depending on flag SDL_FULLSCREEN */
   443   if (flags & SDL_FULLSCREEN)
   444     {
   445       ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN);
   446       if (ret)
   447         {
   448           DirectFBError ("dfb->SetCooperativeLevel", ret);
   449           flags &= ~SDL_FULLSCREEN;
   450         }
   451     }
   452   else
   453     HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
   454 
   455   /* Set video mode */
   456   ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
   457   if (ret)
   458     {
   459       if (flags & SDL_FULLSCREEN)
   460         {
   461           flags &= ~SDL_FULLSCREEN;
   462           HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
   463           ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
   464         }
   465 
   466       if (ret)
   467         {
   468           SetDirectFBerror ("dfb->SetVideoMode", ret);
   469           return NULL;
   470         }
   471     }
   472 
   473   /* Create primary surface */
   474   dsc.flags = DSDESC_CAPS;
   475   dsc.caps  = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
   476 
   477   ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface);
   478   if (ret && (flags & SDL_DOUBLEBUF))
   479     {
   480       /* Try without double buffering */
   481       dsc.caps &= ~DSCAPS_FLIPPING;
   482       ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface);
   483     }
   484   if (ret)
   485     {
   486       SetDirectFBerror ("dfb->CreateSurface", ret);
   487       current->hwdata->surface = NULL;
   488       return NULL;
   489     }
   490 
   491   current->w     = width;
   492   current->h     = height;
   493   current->flags = SDL_HWSURFACE | SDL_PREALLOC;
   494 
   495   if (flags & SDL_FULLSCREEN)
   496     {
   497       current->flags |= SDL_FULLSCREEN;
   498       this->UpdateRects = DirectFB_DirectUpdate;
   499     }
   500   else
   501     this->UpdateRects = DirectFB_WindowedUpdate;
   502 
   503   if (dsc.caps & DSCAPS_FLIPPING)
   504     current->flags |= SDL_DOUBLEBUF;
   505 
   506   current->hwdata->surface->GetPixelFormat (current->hwdata->surface, &pixelformat);
   507   DFBToSDLPixelFormat (pixelformat, current->format);
   508 
   509   return current;
   510 }
   511 
   512 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface)
   513 {
   514   DFBResult             ret;
   515   DFBSurfaceDescription dsc;
   516 
   517   /*  fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n",
   518       surface->w, surface->h, surface->format->BitsPerPixel, surface->flags);*/
   519 
   520   if (surface->w < 8 || surface->h < 8)
   521     return -1;
   522 
   523   /* fill surface description */
   524   dsc.flags  = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   525   dsc.width  = surface->w;
   526   dsc.height = surface->h;
   527   dsc.caps   = surface->flags & SDL_DOUBLEBUF ? DSCAPS_FLIPPING : 0;
   528 
   529   /* find the right pixelformat */
   530   dsc.pixelformat = SDLToDFBPixelFormat (surface->format);
   531   if (dsc.pixelformat == DSPF_UNKNOWN)
   532     return -1;
   533 
   534   /* Allocate the hardware acceleration data */
   535   surface->hwdata = (struct private_hwdata *) malloc (sizeof(*surface->hwdata));
   536   if (surface->hwdata == NULL)
   537     {
   538       SDL_OutOfMemory();
   539       return -1;
   540     }
   541 
   542   /* Create the surface */
   543   ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface->hwdata->surface);
   544   if (ret)
   545     {
   546       SetDirectFBerror ("dfb->CreateSurface", ret);
   547       free (surface->hwdata);
   548       surface->hwdata = NULL;
   549       return -1;
   550     }
   551 
   552   surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
   553 
   554   return 0;
   555 }
   556 
   557 static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface)
   558 {
   559   if (surface->hwdata && HIDDEN->initialized)
   560     {
   561       surface->hwdata->surface->Release (surface->hwdata->surface);
   562       free (surface->hwdata);
   563       surface->hwdata = NULL;
   564     }
   565 }
   566 
   567 static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
   568 {
   569   /*  fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
   570       src->hwdata, dst->hwdata);*/
   571 
   572   if (!src->hwdata || !dst->hwdata)
   573     return 0;
   574 
   575   src->flags |= SDL_HWACCEL;
   576   src->map->hw_blit = DirectFB_HWAccelBlit;
   577 
   578   return 1;
   579 }
   580 
   581 static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
   582                                 SDL_Surface *dst, SDL_Rect *dstrect)
   583 {
   584   DFBRectangle             sr, dr;
   585   IDirectFBSurface        *surface;
   586   DFBSurfaceBlittingFlags  flags = DSBLIT_NOFX;
   587 
   588   sr.x = srcrect->x;
   589   sr.y = srcrect->y;
   590   sr.w = srcrect->w;
   591   sr.h = srcrect->h;
   592 
   593   dr.x = dstrect->x;
   594   dr.y = dstrect->y;
   595   dr.w = dstrect->w;
   596   dr.h = dstrect->h;
   597 
   598   surface = dst->hwdata->surface;
   599 
   600   if (src->flags & SDL_SRCCOLORKEY)
   601     {
   602       flags |= DSBLIT_SRC_COLORKEY;
   603       DirectFB_SetHWColorKey (NULL, src, src->format->colorkey);
   604     }
   605 
   606   if (src->flags & SDL_SRCALPHA)
   607     {
   608       flags |= DSBLIT_BLEND_COLORALPHA;
   609       surface->SetColor (surface, 0xff, 0xff, 0xff, src->format->alpha);
   610     }
   611 
   612   surface->SetBlittingFlags (surface, flags);
   613 
   614   if (sr.w == dr.w && sr.h == dr.h)
   615     surface->Blit (surface, src->hwdata->surface, &sr, dr.x, dr.y);
   616   else
   617     surface->StretchBlit (surface, src->hwdata->surface, &sr, &dr);
   618 
   619   return 0;
   620 }
   621 
   622 static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
   623 {
   624   SDL_PixelFormat  *fmt     = dst->format;
   625   IDirectFBSurface *surface = dst->hwdata->surface;
   626 
   627   /* ugly */
   628   surface->SetColor (surface,
   629                      (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
   630                      (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
   631                      (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift), 0xFF);
   632   surface->FillRectangle (surface, dstrect->x, dstrect->y, dstrect->w, dstrect->h);
   633 
   634   return 0;
   635 }
   636 
   637 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *src, Uint32 key)
   638 {
   639   SDL_PixelFormat  *fmt     = src->format;
   640   IDirectFBSurface *surface = src->hwdata->surface;
   641 
   642   /* ugly */
   643   surface->SetSrcColorKey (surface,
   644                            (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
   645                            (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
   646                            (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift));
   647 
   648   return 0;
   649 }
   650 
   651 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha)
   652 {
   653   return 0;
   654 }
   655 
   656 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface)
   657 {
   658   return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, DSFLIP_WAITFORSYNC);
   659 }
   660 
   661 static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface)
   662 {
   663   DFBResult  ret;
   664   void      *data;
   665   int        pitch;
   666 
   667   ret = surface->hwdata->surface->Lock (surface->hwdata->surface,
   668                                         DSLF_WRITE, &data, &pitch);
   669   if (ret)
   670     {
   671       SetDirectFBerror ("surface->Lock", ret);
   672       return -1;
   673     }
   674 
   675   surface->pixels = data;
   676   surface->pitch  = pitch;
   677 
   678   return 0;
   679 }
   680 
   681 static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface)
   682 {
   683   surface->hwdata->surface->Unlock (surface->hwdata->surface);
   684   surface->pixels = NULL;
   685 }
   686 
   687 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
   688 {
   689 }
   690 
   691 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects)
   692 {
   693   DFBRegion         region;
   694   int               i;
   695   int               region_valid = 0;
   696   IDirectFBSurface *surface = this->screen->hwdata->surface;
   697 
   698   for (i=0; i<numrects; ++i)
   699     {
   700       int x2, y2;
   701 
   702       if ( ! rects[i].w ) /* Clipped? */
   703         continue;
   704 
   705       x2 = rects[i].x + rects[i].w - 1;
   706       y2 = rects[i].y + rects[i].h - 1;
   707 
   708       if (region_valid)
   709         {
   710           if (rects[i].x < region.x1)
   711             region.x1 = rects[i].x;
   712 
   713           if (rects[i].y < region.y1)
   714             region.y1 = rects[i].y;
   715 
   716           if (x2 > region.x2)
   717             region.x2 = x2;
   718 
   719           if (y2 > region.y2)
   720             region.y2 = y2;
   721         }
   722       else
   723         {
   724             region.x1 = rects[i].x;
   725             region.y1 = rects[i].y;
   726             region.x2 = x2;
   727             region.y2 = y2;
   728 
   729             region_valid = 1;
   730         }
   731     }
   732 
   733   if (region_valid)
   734     surface->Flip (surface, &region, DSFLIP_WAITFORSYNC);
   735 }
   736 
   737 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   738 {
   739   fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n");
   740   return 0;
   741 }
   742 	
   743 void DirectFB_VideoQuit(_THIS)
   744 {
   745   int i, j;
   746 
   747   HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
   748   HIDDEN->layer->Release (HIDDEN->layer);
   749   HIDDEN->dfb->Release (HIDDEN->dfb);
   750 
   751   /* Free video mode lists */
   752   for ( i=0; i<NUM_MODELISTS; ++i )
   753     {
   754       if ( HIDDEN->SDL_modelist[i] != NULL )
   755         {
   756           for ( j=0; HIDDEN->SDL_modelist[i][j]; ++j )
   757             free(HIDDEN->SDL_modelist[i][j]);
   758           free(HIDDEN->SDL_modelist[i]);
   759           HIDDEN->SDL_modelist[i] = NULL;
   760         }
   761     }
   762 
   763   HIDDEN->initialized = 0;
   764 }
   765 
   766 void DirectFB_FinalQuit(void) 
   767 {
   768 }