src/video/directfb/SDL_DirectFB_video.c
author Sam Lantinga
Thu, 20 Dec 2001 22:46:09 +0000
changeset 259 80b647695abd
parent 252 e8157fcb3114
child 286 3ea69fd0b095
permissions -rw-r--r--
*** empty log message ***
     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   IDirectFBInputBuffer  *inputbuffer;
   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->CreateInputBuffer (dfb, DICAPS_BUTTONS | DICAPS_AXIS | DICAPS_KEYS,
   333                                 &inputbuffer);
   334   if (ret)
   335     {
   336       SetDirectFBerror ("dfb->CreateInputBuffer", ret);
   337       layer->Release (layer);
   338       dfb->Release (dfb);
   339       return -1;
   340     }
   341   
   342   layer->EnableCursor (layer, 1);
   343 
   344   /* Query layer configuration to determine the current mode and pixelformat */
   345   layer->GetConfiguration (layer, &dlc);
   346 
   347   if (DFBToSDLPixelFormat (dlc.pixelformat, vformat))
   348     {
   349       SDL_SetError ("Unsupported pixelformat");
   350       layer->Release (layer);
   351       dfb->Release (dfb);
   352       return -1;
   353     }
   354 
   355   /* Enumerate the available fullscreen modes */
   356   for ( i=0; i<NUM_MODELISTS; ++i )
   357     enumlists[i] = NULL;
   358 
   359   ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this);
   360   if (ret)
   361     {
   362       SetDirectFBerror ("dfb->EnumVideoModes", ret);
   363       layer->Release (layer);
   364       dfb->Release (dfb);
   365       return(-1);
   366     }
   367   for ( i=0; i<NUM_MODELISTS; ++i )
   368     {
   369       struct DirectFBEnumRect *rect;
   370       HIDDEN->SDL_modelist[i] = (SDL_Rect **) malloc
   371         ((HIDDEN->SDL_nummodes[i]+1)*sizeof(SDL_Rect *));
   372       if ( HIDDEN->SDL_modelist[i] == NULL )
   373         {
   374           SDL_OutOfMemory();
   375           return(-1);
   376         }
   377       for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next )
   378         {
   379           HIDDEN->SDL_modelist[i][j]=(SDL_Rect *)rect;
   380         }
   381       HIDDEN->SDL_modelist[i][j] = NULL;
   382     }
   383 
   384   /* Query card capabilities to get the video memory size */
   385   dfb->GetCardCapabilities (dfb, &caps);
   386 
   387   this->info.wm_available = 1;
   388   this->info.hw_available = 1;
   389   this->info.blit_hw      = 1;
   390   this->info.blit_hw_CC   = 1;
   391   this->info.blit_hw_A    = 1;
   392   this->info.blit_fill    = 1;
   393   this->info.video_mem    = caps.video_memory / 1024;
   394 
   395   HIDDEN->initialized = 1;
   396   HIDDEN->dfb         = dfb;
   397   HIDDEN->layer       = layer;
   398   HIDDEN->inputbuffer = inputbuffer;
   399 
   400   return 0;
   401 }
   402 
   403 static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
   404 {
   405   if (flags & SDL_FULLSCREEN)
   406     return HIDDEN->SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1];
   407   else
   408     if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN)
   409       return (SDL_Rect**) -1;
   410 
   411   return NULL;
   412 }
   413 
   414 SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
   415 {
   416   DFBResult             ret;
   417   DFBSurfaceDescription dsc;
   418   DFBSurfacePixelFormat pixelformat;
   419 
   420   fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
   421            width, height, bpp, flags);
   422 
   423   flags |= SDL_FULLSCREEN;
   424 
   425   /* Release previous primary surface */
   426   if (current->hwdata && current->hwdata->surface)
   427     {
   428       current->hwdata->surface->Release (current->hwdata->surface);
   429       current->hwdata->surface = NULL;
   430     }
   431   else if (!current->hwdata)
   432     {
   433       /* Allocate the hardware acceleration data */
   434       current->hwdata = (struct private_hwdata *) malloc (sizeof(*current->hwdata));
   435       if (!current->hwdata)
   436         {
   437           SDL_OutOfMemory();
   438           return NULL;
   439 	}
   440       memset (current->hwdata, 0, sizeof(*current->hwdata));
   441     }
   442 
   443   /* Set cooperative level depending on flag SDL_FULLSCREEN */
   444   if (flags & SDL_FULLSCREEN)
   445     {
   446       ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN);
   447       if (ret)
   448         {
   449           DirectFBError ("dfb->SetCooperativeLevel", ret);
   450           flags &= ~SDL_FULLSCREEN;
   451         }
   452     }
   453   else
   454     HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
   455 
   456   /* Set video mode */
   457   ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
   458   if (ret)
   459     {
   460       if (flags & SDL_FULLSCREEN)
   461         {
   462           flags &= ~SDL_FULLSCREEN;
   463           HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
   464           ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
   465         }
   466 
   467       if (ret)
   468         {
   469           SetDirectFBerror ("dfb->SetVideoMode", ret);
   470           return NULL;
   471         }
   472     }
   473 
   474   /* Create primary surface */
   475   dsc.flags = DSDESC_CAPS;
   476   dsc.caps  = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
   477 
   478   ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface);
   479   if (ret && (flags & SDL_DOUBLEBUF))
   480     {
   481       /* Try without double buffering */
   482       dsc.caps &= ~DSCAPS_FLIPPING;
   483       ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface);
   484     }
   485   if (ret)
   486     {
   487       SetDirectFBerror ("dfb->CreateSurface", ret);
   488       current->hwdata->surface = NULL;
   489       return NULL;
   490     }
   491 
   492   current->w     = width;
   493   current->h     = height;
   494   current->flags = SDL_HWSURFACE | SDL_PREALLOC;
   495 
   496   if (flags & SDL_FULLSCREEN)
   497     {
   498       current->flags |= SDL_FULLSCREEN;
   499       this->UpdateRects = DirectFB_DirectUpdate;
   500     }
   501   else
   502     this->UpdateRects = DirectFB_WindowedUpdate;
   503 
   504   if (dsc.caps & DSCAPS_FLIPPING)
   505     current->flags |= SDL_DOUBLEBUF;
   506 
   507   current->hwdata->surface->GetPixelFormat (current->hwdata->surface, &pixelformat);
   508   DFBToSDLPixelFormat (pixelformat, current->format);
   509 
   510   return current;
   511 }
   512 
   513 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface)
   514 {
   515   DFBResult             ret;
   516   DFBSurfaceDescription dsc;
   517 
   518   /*  fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n",
   519       surface->w, surface->h, surface->format->BitsPerPixel, surface->flags);*/
   520 
   521   if (surface->w < 8 || surface->h < 8)
   522     return -1;
   523 
   524   /* fill surface description */
   525   dsc.flags  = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   526   dsc.width  = surface->w;
   527   dsc.height = surface->h;
   528   dsc.caps   = surface->flags & SDL_DOUBLEBUF ? DSCAPS_FLIPPING : 0;
   529 
   530   /* find the right pixelformat */
   531   dsc.pixelformat = SDLToDFBPixelFormat (surface->format);
   532   if (dsc.pixelformat == DSPF_UNKNOWN)
   533     return -1;
   534 
   535   /* Allocate the hardware acceleration data */
   536   surface->hwdata = (struct private_hwdata *) malloc (sizeof(*surface->hwdata));
   537   if (surface->hwdata == NULL)
   538     {
   539       SDL_OutOfMemory();
   540       return -1;
   541     }
   542 
   543   /* Create the surface */
   544   ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface->hwdata->surface);
   545   if (ret)
   546     {
   547       SetDirectFBerror ("dfb->CreateSurface", ret);
   548       free (surface->hwdata);
   549       surface->hwdata = NULL;
   550       return -1;
   551     }
   552 
   553   surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
   554 
   555   return 0;
   556 }
   557 
   558 static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface)
   559 {
   560   if (surface->hwdata && HIDDEN->initialized)
   561     {
   562       surface->hwdata->surface->Release (surface->hwdata->surface);
   563       free (surface->hwdata);
   564       surface->hwdata = NULL;
   565     }
   566 }
   567 
   568 static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
   569 {
   570   /*  fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
   571       src->hwdata, dst->hwdata);*/
   572 
   573   if (!src->hwdata || !dst->hwdata)
   574     return 0;
   575 
   576   src->flags |= SDL_HWACCEL;
   577   src->map->hw_blit = DirectFB_HWAccelBlit;
   578 
   579   return 1;
   580 }
   581 
   582 static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
   583                                 SDL_Surface *dst, SDL_Rect *dstrect)
   584 {
   585   DFBRectangle             sr, dr;
   586   IDirectFBSurface        *surface;
   587   DFBSurfaceBlittingFlags  flags = DSBLIT_NOFX;
   588 
   589   sr.x = srcrect->x;
   590   sr.y = srcrect->y;
   591   sr.w = srcrect->w;
   592   sr.h = srcrect->h;
   593 
   594   dr.x = dstrect->x;
   595   dr.y = dstrect->y;
   596   dr.w = dstrect->w;
   597   dr.h = dstrect->h;
   598 
   599   surface = dst->hwdata->surface;
   600 
   601   if (src->flags & SDL_SRCCOLORKEY)
   602     {
   603       flags |= DSBLIT_SRC_COLORKEY;
   604       DirectFB_SetHWColorKey (NULL, src, src->format->colorkey);
   605     }
   606 
   607   if (src->flags & SDL_SRCALPHA)
   608     {
   609       flags |= DSBLIT_BLEND_COLORALPHA;
   610       surface->SetColor (surface, 0xff, 0xff, 0xff, src->format->alpha);
   611     }
   612 
   613   surface->SetBlittingFlags (surface, flags);
   614 
   615   if (sr.w == dr.w && sr.h == dr.h)
   616     surface->Blit (surface, src->hwdata->surface, &sr, dr.x, dr.y);
   617   else
   618     surface->StretchBlit (surface, src->hwdata->surface, &sr, &dr);
   619 
   620   return 0;
   621 }
   622 
   623 static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
   624 {
   625   SDL_PixelFormat  *fmt     = dst->format;
   626   IDirectFBSurface *surface = dst->hwdata->surface;
   627 
   628   /* ugly */
   629   surface->SetColor (surface,
   630                      (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
   631                      (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
   632                      (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift), 0xFF);
   633   surface->FillRectangle (surface, dstrect->x, dstrect->y, dstrect->w, dstrect->h);
   634 
   635   return 0;
   636 }
   637 
   638 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *src, Uint32 key)
   639 {
   640   SDL_PixelFormat  *fmt     = src->format;
   641   IDirectFBSurface *surface = src->hwdata->surface;
   642 
   643   /* ugly */
   644   surface->SetSrcColorKey (surface,
   645                            (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
   646                            (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
   647                            (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift));
   648 
   649   return 0;
   650 }
   651 
   652 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha)
   653 {
   654   return 0;
   655 }
   656 
   657 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface)
   658 {
   659   return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, DSFLIP_WAITFORSYNC);
   660 }
   661 
   662 static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface)
   663 {
   664   DFBResult  ret;
   665   void      *data;
   666   int        pitch;
   667 
   668   ret = surface->hwdata->surface->Lock (surface->hwdata->surface,
   669                                         DSLF_WRITE, &data, &pitch);
   670   if (ret)
   671     {
   672       SetDirectFBerror ("surface->Lock", ret);
   673       return -1;
   674     }
   675 
   676   surface->pixels = data;
   677   surface->pitch  = pitch;
   678 
   679   return 0;
   680 }
   681 
   682 static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface)
   683 {
   684   surface->hwdata->surface->Unlock (surface->hwdata->surface);
   685   surface->pixels = NULL;
   686 }
   687 
   688 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
   689 {
   690 }
   691 
   692 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects)
   693 {
   694   IDirectFBSurface *surface = this->screen->hwdata->surface;
   695   DFBRegion region = { rects->x, rects->y,
   696                        rects->x + rects->w - 1,
   697                        rects->y + rects->h - 1 };
   698 
   699   while (--numrects)
   700     {
   701       int x2, y2;
   702 
   703       rects++;
   704 
   705       if (rects->x < region.x1)
   706         region.x1 = rects->x;
   707 
   708       if (rects->y < region.y1)
   709         region.y1 = rects->y;
   710 
   711       x2 = rects->x + rects->w - 1;
   712       y2 = rects->y + rects->h - 1;
   713 
   714       if (x2 > region.x2)
   715         region.x2 = x2;
   716 
   717       if (y2 > region.y2)
   718         region.y2 = y2;
   719     }
   720 
   721   surface->Flip (surface, &region, DSFLIP_WAITFORSYNC);
   722 }
   723 
   724 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   725 {
   726   fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n");
   727   return 0;
   728 }
   729 	
   730 void DirectFB_VideoQuit(_THIS)
   731 {
   732   int i, j;
   733 
   734   HIDDEN->inputbuffer->Release (HIDDEN->inputbuffer);
   735   HIDDEN->layer->Release (HIDDEN->layer);
   736   HIDDEN->dfb->Release (HIDDEN->dfb);
   737 
   738   /* Free video mode lists */
   739   for ( i=0; i<NUM_MODELISTS; ++i )
   740     {
   741       if ( HIDDEN->SDL_modelist[i] != NULL )
   742         {
   743           for ( j=0; HIDDEN->SDL_modelist[i][j]; ++j )
   744             free(HIDDEN->SDL_modelist[i][j]);
   745           free(HIDDEN->SDL_modelist[i]);
   746           HIDDEN->SDL_modelist[i] = NULL;
   747         }
   748     }
   749 
   750   HIDDEN->initialized = 0;
   751 }
   752 
   753 void DirectFB_FinalQuit(void) 
   754 {
   755 }