SDL_DirectFB_video.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:21k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

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