src/video/directfb/SDL_DirectFB_video.c
author Sam Lantinga
Mon, 27 Dec 2004 20:03:53 +0000
changeset 1018 012af0b7e8e6
parent 893 8762a202f121
child 1029 f87f87efd45a
permissions -rw-r--r--
Date: Fri, 24 Dec 2004 23:32:06 -0500
From: Mike Frysinger
Subject: [SDL] minor fix for gcc-2.x building

in src/video/directfb/SDL_DirectFB_video.c, some variables are not declared at
the beginning of scope ... newer gcc's will accept this, but gcc-2.x does not

find attached a simple patch by Matt Taylor to resolve this
http://bugs.gentoo.org/show_bug.cgi?id=75392
     1 /*
     2 	SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 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 	MGA CRTC2 support by Thomas Jarosch - tomj@simonv.com
    23 	CRTC2 support is inspired by mplayer's dfbmga driver
    24 	written by Ville Syrj��<syrjala@sci.fi>
    25 */
    26 
    27 #ifdef SAVE_RCSID
    28 static char rcsid =
    29  "@(#) $Id$";
    30 #endif
    31 
    32 /* DirectFB video driver implementation.
    33 */
    34 
    35 #include <stdlib.h>
    36 #include <string.h>
    37 #include <stdio.h>
    38 #include <fcntl.h>
    39 #include <unistd.h>
    40 #include <sys/mman.h>
    41 
    42 #include <directfb.h>
    43 
    44 #include "SDL.h"
    45 #include "SDL_error.h"
    46 #include "SDL_video.h"
    47 #include "SDL_mouse.h"
    48 #include "SDL_sysvideo.h"
    49 #include "SDL_pixels_c.h"
    50 #include "SDL_events_c.h"
    51 #include "SDL_DirectFB_video.h"
    52 #include "SDL_DirectFB_events.h"
    53 #include "SDL_DirectFB_yuv.h"
    54 
    55 /* The implementation dependent data for the window manager cursor */
    56 struct WMcursor {
    57 	int unused;
    58 };
    59 
    60 
    61 /* Initialization/Query functions */
    62 static int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat);
    63 static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
    64 static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
    65 static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors,
    66 			 SDL_Color *colors);
    67 static void DirectFB_VideoQuit(_THIS);
    68 
    69 /* Hardware surface functions */
    70 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface);
    71 static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
    72 static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface);
    73 static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface);
    74 static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface);
    75 static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
    76 static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
    77                                 SDL_Surface *dst, SDL_Rect *dstrect);
    78 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);
    79 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha);
    80 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface);
    81 static int DirectFB_ShowWMCursor(_THIS, WMcursor *cursor);
    82 
    83 /* Various screen update functions available */
    84 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
    85 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects);
    86 
    87 /* This is the rect EnumModes2 uses */
    88 struct DirectFBEnumRect {
    89 	SDL_Rect r;
    90 	struct DirectFBEnumRect* next;
    91 };
    92 
    93 static struct DirectFBEnumRect *enumlist = NULL;
    94 
    95 
    96 /* DirectFB driver bootstrap functions */
    97 
    98 static int DirectFB_Available(void)
    99 {
   100   return 1;
   101 }
   102 
   103 static void DirectFB_DeleteDevice(SDL_VideoDevice *device)
   104 {
   105   free(device->hidden);
   106   free(device);
   107 }
   108 
   109 static SDL_VideoDevice *DirectFB_CreateDevice(int devindex)
   110 {
   111   SDL_VideoDevice *device;
   112 
   113   /* Initialize all variables that we clean on shutdown */
   114   device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
   115   if (device)
   116     {
   117       memset (device, 0, (sizeof *device));
   118       device->hidden = (struct SDL_PrivateVideoData *) malloc (sizeof (*device->hidden));
   119     }
   120   if (device == NULL  ||  device->hidden == NULL)
   121     {
   122       SDL_OutOfMemory();
   123       if (device)
   124         {
   125           free (device);
   126         }
   127       return(0);
   128     }
   129   memset (device->hidden, 0, sizeof (*device->hidden));
   130 
   131   /* Set the function pointers */
   132   device->VideoInit = DirectFB_VideoInit;
   133   device->ListModes = DirectFB_ListModes;
   134   device->SetVideoMode = DirectFB_SetVideoMode;
   135   device->SetColors = DirectFB_SetColors;
   136   device->UpdateRects = NULL;
   137   device->CreateYUVOverlay = DirectFB_CreateYUVOverlay;
   138   device->VideoQuit = DirectFB_VideoQuit;
   139   device->AllocHWSurface = DirectFB_AllocHWSurface;
   140   device->CheckHWBlit = DirectFB_CheckHWBlit;
   141   device->FillHWRect = DirectFB_FillHWRect;
   142   device->SetHWColorKey = DirectFB_SetHWColorKey;
   143   device->SetHWAlpha = DirectFB_SetHWAlpha;
   144   device->LockHWSurface = DirectFB_LockHWSurface;
   145   device->UnlockHWSurface = DirectFB_UnlockHWSurface;
   146   device->FlipHWSurface = DirectFB_FlipHWSurface;
   147   device->FreeHWSurface = DirectFB_FreeHWSurface;
   148   device->ShowWMCursor = DirectFB_ShowWMCursor;
   149   device->SetCaption = NULL;
   150   device->SetIcon = NULL;
   151   device->IconifyWindow = NULL;
   152   device->GrabInput = NULL;
   153   device->GetWMInfo = NULL;
   154   device->InitOSKeymap = DirectFB_InitOSKeymap;
   155   device->PumpEvents = DirectFB_PumpEvents;
   156 
   157   device->free = DirectFB_DeleteDevice;
   158 
   159   return device;
   160 }
   161 
   162 VideoBootStrap DirectFB_bootstrap = {
   163   "directfb", "DirectFB",
   164   DirectFB_Available, DirectFB_CreateDevice
   165 };
   166 
   167 static DFBSurfacePixelFormat GetFormatForBpp (int bpp, IDirectFBDisplayLayer *layer)
   168 {
   169   DFBDisplayLayerConfig dlc;
   170   int                   bytes = (bpp + 7) / 8;
   171 
   172   layer->GetConfiguration (layer, &dlc);
   173 
   174   if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1)
   175     return dlc.pixelformat;
   176 
   177   switch (bytes)
   178     {
   179     case 1:
   180       return DSPF_LUT8;
   181     case 2:
   182       return DSPF_RGB16;
   183     case 3:
   184       return DSPF_RGB24;
   185     case 4:
   186       return DSPF_RGB32;
   187     }
   188 
   189   return DSPF_UNKNOWN;
   190 }
   191 
   192 static DFBEnumerationResult EnumModesCallback (int  width,
   193                                                int  height,
   194                                                int  bpp,
   195                                                void *data)
   196 {
   197   SDL_VideoDevice *this = (SDL_VideoDevice *)data;
   198   struct DirectFBEnumRect *enumrect;
   199 
   200   HIDDEN->nummodes++;
   201 
   202   enumrect = calloc(1, sizeof(struct DirectFBEnumRect));
   203   if (!enumrect)
   204     {
   205       SDL_OutOfMemory();
   206       return DFENUM_CANCEL;
   207     }
   208 
   209   enumrect->r.w  = (Uint16)width;
   210   enumrect->r.h  = (Uint16)height;
   211   enumrect->next = enumlist;
   212 
   213   enumlist = enumrect;
   214 
   215   return DFENUM_OK;
   216 }
   217 
   218 struct private_hwdata {
   219   IDirectFBSurface *surface;
   220   IDirectFBPalette *palette;
   221 };
   222 
   223 void SetDirectFBerror (const char *function, DFBResult code)
   224 {
   225   const char *error = DirectFBErrorString (code);
   226 
   227   if (error)
   228     SDL_SetError("%s: %s", function, error);
   229   else
   230     SDL_SetError("Unknown error code from %s", function);
   231 }
   232 
   233 static DFBSurfacePixelFormat SDLToDFBPixelFormat (SDL_PixelFormat *format)
   234 {
   235   if (format->Rmask && format->Gmask && format->Bmask)
   236     {
   237       switch (format->BitsPerPixel)
   238         {
   239         case 8:
   240           return DSPF_LUT8;
   241           
   242         case 16:
   243           if (format->Rmask == 0xF800 &&
   244               format->Gmask == 0x07E0 &&
   245               format->Bmask == 0x001F)
   246             return DSPF_RGB16;
   247           /* fall through */
   248           
   249         case 15:
   250           if (format->Rmask == 0x7C00 &&
   251               format->Gmask == 0x03E0 &&
   252               format->Bmask == 0x001F)
   253             return DSPF_ARGB1555;
   254           break;
   255           
   256         case 24:
   257           if (format->Rmask == 0xFF0000 &&
   258               format->Gmask == 0x00FF00 &&
   259               format->Bmask == 0x0000FF)
   260             return DSPF_RGB24;
   261           break;
   262 
   263         case 32:
   264           if (format->Rmask == 0xFF0000 &&
   265               format->Gmask == 0x00FF00 &&
   266               format->Bmask == 0x0000FF)
   267             {
   268               if (format->Amask == 0xFF000000)
   269                 return DSPF_ARGB;
   270               else
   271                 return DSPF_RGB32;
   272             }
   273           break;
   274         }
   275     }
   276   else
   277     {
   278       switch (format->BitsPerPixel)
   279 	{
   280         case 8:
   281           return DSPF_LUT8;
   282 	case 15:
   283 	  return DSPF_ARGB1555;
   284 	case 16:
   285 	  return DSPF_RGB16;
   286 	case 24:
   287 	  return DSPF_RGB24;
   288 	case 32:
   289 	  return DSPF_RGB32;
   290 	}
   291     }
   292 
   293   return DSPF_UNKNOWN;
   294 }
   295 
   296 static SDL_Palette *AllocatePalette(int size)
   297 {
   298   SDL_Palette *palette;
   299   SDL_Color   *colors;
   300 
   301   palette = calloc (1, sizeof(SDL_Palette));
   302   if (!palette)
   303     {
   304       SDL_OutOfMemory();
   305       return NULL;
   306     }
   307 
   308   colors = calloc (size, sizeof(SDL_Color));
   309   if (!colors)
   310     {
   311       SDL_OutOfMemory();
   312       return NULL;
   313     }
   314 
   315   palette->ncolors = size;
   316   palette->colors  = colors;
   317 
   318   return palette;
   319 }
   320 
   321 static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat, SDL_PixelFormat *format)
   322 {
   323   format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
   324   format->BitsPerPixel = format->BytesPerPixel = 0;
   325 
   326   switch (pixelformat)
   327     {
   328     case DSPF_A8:
   329       format->Amask = 0x000000FF;
   330       break;
   331 
   332     case DSPF_ARGB1555:
   333       format->Rmask = 0x00007C00;
   334       format->Gmask = 0x000003E0;
   335       format->Bmask = 0x0000001F;
   336       break;
   337 
   338     case DSPF_RGB16:
   339       format->Rmask = 0x0000F800;
   340       format->Gmask = 0x000007E0;
   341       format->Bmask = 0x0000001F;
   342       break;
   343 
   344     case DSPF_ARGB:
   345       format->Amask = 0; /* apps don't seem to like that:  0xFF000000; */
   346       /* fall through */
   347     case DSPF_RGB24:
   348     case DSPF_RGB32:
   349       format->Rmask = 0x00FF0000;
   350       format->Gmask = 0x0000FF00;
   351       format->Bmask = 0x000000FF;
   352       break;
   353 
   354     case DSPF_LUT8:
   355       format->Rmask = 0x000000FF;
   356       format->Gmask = 0x000000FF;
   357       format->Bmask = 0x000000FF;
   358 
   359       if (!format->palette)
   360         format->palette = AllocatePalette(256);
   361       break;
   362 
   363     default:
   364       fprintf (stderr, "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n", pixelformat);
   365       return -1;
   366     }
   367 
   368   format->BitsPerPixel  = DFB_BYTES_PER_PIXEL(pixelformat) * 8;
   369   format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat);
   370 
   371   return 0;
   372 }
   373 
   374 
   375 int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat)
   376 {
   377   int                      i;
   378   DFBResult                ret;
   379   DFBCardCapabilities      caps;
   380   DFBDisplayLayerConfig    dlc;
   381   struct DirectFBEnumRect *rect;
   382   IDirectFB               *dfb    = NULL;
   383   IDirectFBDisplayLayer   *layer  = NULL;
   384   IDirectFBEventBuffer    *events = NULL;
   385 
   386   HIDDEN->c2layer = NULL, HIDDEN->c2frame = NULL;
   387   HIDDEN->enable_mga_crtc2 = 0;
   388   HIDDEN->mga_crtc2_stretch_overscan = 1;
   389 
   390   ret = DirectFBInit (NULL, NULL);
   391   if (ret)
   392     {
   393       SetDirectFBerror ("DirectFBInit", ret);
   394       goto error;
   395     }
   396 
   397   ret = DirectFBCreate (&dfb);
   398   if (ret)
   399     {
   400       SetDirectFBerror ("DirectFBCreate", ret);
   401       goto error;
   402     }
   403 
   404   ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer);
   405   if (ret)
   406     {
   407       SetDirectFBerror ("dfb->GetDisplayLayer", ret);
   408       goto error;
   409     }
   410 
   411   ret = dfb->CreateInputEventBuffer (dfb, DICAPS_ALL, DFB_FALSE, &events);
   412   if (ret)
   413     {
   414       SetDirectFBerror ("dfb->CreateEventBuffer", ret);
   415       goto error;
   416     }
   417   
   418   layer->EnableCursor (layer, 1);
   419 
   420   /* Query layer configuration to determine the current mode and pixelformat */
   421   layer->GetConfiguration (layer, &dlc);
   422 
   423   /* If current format is not supported use LUT8 as the default */
   424   if (DFBToSDLPixelFormat (dlc.pixelformat, vformat))
   425     DFBToSDLPixelFormat (DSPF_LUT8, vformat);
   426 
   427   /* Enumerate the available fullscreen modes */
   428   ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this);
   429   if (ret)
   430     {
   431       SetDirectFBerror ("dfb->EnumVideoModes", ret);
   432       goto error;
   433     }
   434 
   435   HIDDEN->modelist = calloc (HIDDEN->nummodes + 1, sizeof(SDL_Rect *));
   436   if (!HIDDEN->modelist)
   437     {
   438       SDL_OutOfMemory();
   439       goto error;
   440     }
   441 
   442   for (i = 0, rect = enumlist; rect; ++i, rect = rect->next )
   443     {
   444       HIDDEN->modelist[i] = &rect->r;
   445     }
   446 
   447   HIDDEN->modelist[i] = NULL;
   448 
   449 
   450   /* Query card capabilities to get the video memory size */
   451   dfb->GetCardCapabilities (dfb, &caps);
   452 
   453   this->info.wm_available = 1;
   454   this->info.hw_available = 1;
   455   this->info.blit_hw      = 1;
   456   this->info.blit_hw_CC   = 1;
   457   this->info.blit_hw_A    = 1;
   458   this->info.blit_fill    = 1;
   459   this->info.video_mem    = caps.video_memory / 1024;
   460 
   461   HIDDEN->initialized = 1;
   462   HIDDEN->dfb         = dfb;
   463   HIDDEN->layer       = layer;
   464   HIDDEN->eventbuffer = events;
   465 
   466   if (getenv("SDL_DIRECTFB_MGA_CRTC2") != NULL)
   467     HIDDEN->enable_mga_crtc2 = 1;
   468   
   469   if (HIDDEN->enable_mga_crtc2)
   470     {
   471       DFBDisplayLayerConfig      dlc;
   472       DFBDisplayLayerConfigFlags failed;
   473 
   474       ret = dfb->GetDisplayLayer (dfb, 2, &HIDDEN->c2layer);
   475       if (ret)
   476         {
   477           SetDirectFBerror ("dfb->GetDisplayLayer(CRTC2)", ret);
   478           goto error;
   479         }
   480 
   481       ret = HIDDEN->layer->SetCooperativeLevel(HIDDEN->layer, DLSCL_EXCLUSIVE);
   482       if (ret)
   483         {
   484           SetDirectFBerror ("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
   485           goto error;
   486         }
   487  
   488       ret = HIDDEN->c2layer->SetCooperativeLevel(HIDDEN->c2layer, DLSCL_EXCLUSIVE);
   489       if (ret)
   490         {
   491           SetDirectFBerror ("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
   492           goto error;
   493         }
   494 
   495       HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0x0);
   496 
   497       /* Init the surface here as it got a fixed size */
   498       dlc.flags      = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
   499       dlc.buffermode = DLBM_BACKVIDEO;
   500       dlc.options    = DLOP_FLICKER_FILTERING;
   501       dlc.pixelformat = DSPF_RGB32;
   502       
   503       ret = HIDDEN->c2layer->TestConfiguration( HIDDEN->c2layer, &dlc, &failed );
   504       if (ret)
   505         {
   506           SetDirectFBerror ("c2layer->TestConfiguration", ret);
   507           goto error;
   508         }
   509     
   510       ret = HIDDEN->c2layer->SetConfiguration( HIDDEN->c2layer, &dlc );
   511       if (ret)
   512         {
   513           SetDirectFBerror ("c2layer->SetConfiguration", ret);
   514           goto error;
   515         }
   516     
   517       ret = HIDDEN->c2layer->GetSurface( HIDDEN->c2layer, &HIDDEN->c2frame );
   518       if (ret)
   519         {
   520           SetDirectFBerror ("c2layer->GetSurface", ret);
   521           goto error;
   522         }
   523 
   524       HIDDEN->c2framesize.x = 0;
   525       HIDDEN->c2framesize.y = 0;
   526       HIDDEN->c2frame->GetSize( HIDDEN->c2frame, &HIDDEN->c2framesize.w, &HIDDEN->c2framesize.h);
   527 
   528       HIDDEN->c2frame->SetBlittingFlags( HIDDEN->c2frame, DSBLIT_NOFX );
   529       HIDDEN->c2frame->SetColor( HIDDEN->c2frame, 0, 0, 0, 0xff );
   530     
   531       /* Clear CRTC2 */
   532       HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff );
   533       HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0 );
   534       HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff );
   535       HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0 );
   536       HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff );
   537 
   538       HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0xFF );
   539     
   540       /* Check if overscan is possibly set */
   541       if (getenv("SDL_DIRECTFB_MGA_OVERSCAN") != NULL)
   542         {
   543 	    float overscan = 0;
   544 	    if (sscanf(getenv("SDL_DIRECTFB_MGA_OVERSCAN"), "%f", &overscan) == 1)
   545                if (overscan > 0 && overscan < 2)
   546 		  HIDDEN->mga_crtc2_stretch_overscan = overscan;
   547 	}
   548 
   549       #ifdef DIRECTFB_CRTC2_DEBUG
   550       printf("CRTC2 overscan: %f\n", HIDDEN->mga_crtc2_stretch_overscan);
   551       #endif
   552     }
   553 
   554   return 0;
   555 
   556  error:
   557   if (events)
   558     events->Release (events);
   559   
   560   if (HIDDEN->c2frame)
   561     HIDDEN->c2frame->Release (HIDDEN->c2frame);
   562 
   563   if (HIDDEN->c2layer)
   564     HIDDEN->c2layer->Release (HIDDEN->c2layer);
   565 
   566   if (layer)
   567     layer->Release (layer);
   568 
   569   if (dfb)
   570     dfb->Release (dfb);
   571 
   572   return -1;
   573 }
   574 
   575 static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
   576 {
   577   if (flags & SDL_FULLSCREEN)
   578     return HIDDEN->modelist;
   579   else
   580     if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN)
   581       return (SDL_Rect**) -1;
   582 
   583   return NULL;
   584 }
   585 
   586 static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
   587 {
   588   DFBResult              ret;
   589   DFBSurfaceDescription  dsc;
   590   DFBSurfacePixelFormat  pixelformat;
   591   IDirectFBSurface      *surface;
   592 
   593   fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
   594            width, height, bpp, flags);
   595 
   596   flags |= SDL_FULLSCREEN;
   597 
   598   /* Release previous primary surface */
   599   if (current->hwdata && current->hwdata->surface)
   600     {
   601       current->hwdata->surface->Release (current->hwdata->surface);
   602       current->hwdata->surface = NULL;
   603 
   604       /* And its palette if present */
   605       if (current->hwdata->palette)
   606         {
   607           current->hwdata->palette->Release (current->hwdata->palette);
   608           current->hwdata->palette = NULL;
   609         }
   610     }
   611   else if (!current->hwdata)
   612     {
   613       /* Allocate the hardware acceleration data */
   614       current->hwdata = (struct private_hwdata *) calloc (1, sizeof(*current->hwdata));
   615       if (!current->hwdata)
   616         {
   617           SDL_OutOfMemory();
   618           return NULL;
   619 	}
   620     }
   621 
   622   /* Set cooperative level depending on flag SDL_FULLSCREEN */
   623   if (flags & SDL_FULLSCREEN)
   624     {
   625       ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN);
   626       if (ret && !HIDDEN->enable_mga_crtc2)
   627         {
   628           DirectFBError ("dfb->SetCooperativeLevel", ret);
   629           flags &= ~SDL_FULLSCREEN;
   630         }
   631     }
   632   else
   633     HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
   634 
   635   /* Set video mode */
   636   ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
   637   if (ret)
   638     {
   639       if (flags & SDL_FULLSCREEN)
   640         {
   641           flags &= ~SDL_FULLSCREEN;
   642           HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
   643           ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
   644         }
   645 
   646       if (ret)
   647         {
   648           SetDirectFBerror ("dfb->SetVideoMode", ret);
   649           return NULL;
   650         }
   651     }
   652 
   653   /* Create primary surface */
   654   dsc.flags       = DSDESC_CAPS | DSDESC_PIXELFORMAT;
   655   dsc.caps        = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
   656   dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer);
   657 
   658   ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface);
   659   if (ret && (flags & SDL_DOUBLEBUF))
   660     {
   661       /* Try without double buffering */
   662       dsc.caps &= ~DSCAPS_FLIPPING;
   663       ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface);
   664     }
   665   if (ret)
   666     {
   667       SetDirectFBerror ("dfb->CreateSurface", ret);
   668       return NULL;
   669     }
   670 
   671   current->w     = width;
   672   current->h     = height;
   673   current->flags = SDL_HWSURFACE | SDL_PREALLOC;
   674 
   675   if (flags & SDL_FULLSCREEN)
   676     {
   677       current->flags |= SDL_FULLSCREEN;
   678       this->UpdateRects = DirectFB_DirectUpdate;
   679     }
   680   else
   681     this->UpdateRects = DirectFB_WindowedUpdate;
   682 
   683   if (dsc.caps & DSCAPS_FLIPPING)
   684     current->flags |= SDL_DOUBLEBUF;
   685 
   686   surface->GetPixelFormat (surface, &pixelformat);
   687 
   688   DFBToSDLPixelFormat (pixelformat, current->format);
   689 
   690   /* Get the surface palette (if supported) */
   691   if (DFB_PIXELFORMAT_IS_INDEXED( pixelformat ))
   692     {
   693       surface->GetPalette (surface, &current->hwdata->palette);
   694 
   695       current->flags |= SDL_HWPALETTE;
   696     }
   697 
   698   current->hwdata->surface = surface;
   699 
   700   /* MGA CRTC2 stuff */
   701   if (HIDDEN->enable_mga_crtc2)
   702     {
   703       /* no stretching if c2ssize == c2framesize */
   704       HIDDEN->c2ssize.x = 0, HIDDEN->c2ssize.y = 0;
   705       HIDDEN->c2ssize.w = width;
   706       HIDDEN->c2ssize.h = height;
   707 
   708       HIDDEN->c2dsize.x = 0, HIDDEN->c2dsize.y = 0;
   709       HIDDEN->c2dsize.w = width;
   710       HIDDEN->c2dsize.h = height;
   711 
   712       HIDDEN->mga_crtc2_stretch = 0;
   713 
   714       if (getenv("SDL_DIRECTFB_MGA_STRETCH") != NULL)
   715         {
   716 	    /* Normally assume a picture aspect ratio of 4:3 */
   717 	    int zoom_aspect_x = 4, zoom_aspect_y = 3, i, j;
   718 
   719 	    for (i = 1; i < 20; i++)
   720 	      {
   721 		for (j = 1; j < 10; j++)
   722 		  {
   723 		    if ((float)width/(float)i*(float)j == height) 
   724 		      {
   725 			zoom_aspect_x = i;
   726 			zoom_aspect_y = j;
   727 			
   728 			/* break the loop */
   729 			i = 21;
   730 			break;
   731 		      }
   732 		  }
   733 	      }
   734 	
   735             #ifdef DIRECTFB_CRTC2_DEBUG
   736             printf("Source resolution: X: %d, Y: %d, Aspect ratio: %d:%d\n", width, height, zoom_aspect_x, zoom_aspect_y);
   737             printf("CRTC2 resolution: X: %d, Y: %d\n", HIDDEN->c2framesize.w, HIDDEN->c2framesize.h);
   738             #endif
   739 	
   740           /* don't stretch only slightly smaller/larger images */
   741           if ((float)width < (float)HIDDEN->c2framesize.w*0.95 || (float)height < (float)HIDDEN->c2framesize.h*0.95)
   742             {
   743               while ((float)HIDDEN->c2dsize.w < (float)HIDDEN->c2framesize.w*HIDDEN->mga_crtc2_stretch_overscan && (float)HIDDEN->c2dsize.h < (float)HIDDEN->c2framesize.h*HIDDEN->mga_crtc2_stretch_overscan)
   744                 {
   745                    HIDDEN->c2dsize.w+=zoom_aspect_x;
   746                    HIDDEN->c2dsize.h+=zoom_aspect_y;
   747                 }
   748 
   749               /* one step down */
   750                 HIDDEN->c2dsize.w-=zoom_aspect_x;
   751                 HIDDEN->c2dsize.h-=zoom_aspect_y;
   752 
   753               #ifdef DIRECTFB_CRTC2_DEBUG
   754               printf("Stretched resolution: X: %d, Y: %d\n", HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
   755               #endif
   756 
   757               HIDDEN->mga_crtc2_stretch = 1;
   758             } 
   759           else if ((float)width > (float)HIDDEN->c2framesize.w*0.95 || (float)height > (float)HIDDEN->c2framesize.h*0.95)
   760             {
   761                while ((float)HIDDEN->c2dsize.w > (float)HIDDEN->c2framesize.w*HIDDEN->mga_crtc2_stretch_overscan || (float)HIDDEN->c2dsize.h > (float)HIDDEN->c2framesize.h*HIDDEN->mga_crtc2_stretch_overscan)
   762                 {
   763               HIDDEN->c2dsize.w-=zoom_aspect_x;
   764               HIDDEN->c2dsize.h-=zoom_aspect_y;
   765                 }
   766               
   767               #ifdef DIRECTFB_CRTC2_DEBUG
   768               printf("Down-Stretched resolution: X: %d, Y: %d\n", HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
   769               #endif
   770 
   771               HIDDEN->mga_crtc2_stretch = 1;
   772              } else {
   773           #ifdef DIRECTFB_CRTC2_DEBUG
   774           printf("Not stretching image\n");
   775           #endif
   776         }
   777 
   778       /* Panning */
   779       if (HIDDEN->c2framesize.w > HIDDEN->c2dsize.w)
   780         HIDDEN->c2dsize.x = (HIDDEN->c2framesize.w - HIDDEN->c2dsize.w)  / 2;
   781       else
   782         HIDDEN->c2dsize.x = (HIDDEN->c2dsize.w - HIDDEN->c2framesize.w)  / 2;
   783 
   784       if (HIDDEN->c2framesize.h > HIDDEN->c2dsize.h)
   785         HIDDEN->c2dsize.y = (HIDDEN->c2framesize.h - HIDDEN->c2dsize.h)  / 2;
   786       else
   787         HIDDEN->c2dsize.y = (HIDDEN->c2dsize.h - HIDDEN->c2framesize.h)  / 2;
   788 
   789       #ifdef DIRECTFB_CRTC2_DEBUG
   790     printf("CRTC2 position X: %d, Y: %d\n", HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
   791       #endif
   792    }
   793   }
   794 
   795   return current;
   796 }
   797 
   798 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface)
   799 {
   800   DFBResult             ret;
   801   DFBSurfaceDescription dsc;
   802 
   803   /*  fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n",
   804       surface->w, surface->h, surface->format->BitsPerPixel, surface->flags);*/
   805 
   806   if (surface->w < 8 || surface->h < 8)
   807     return -1;
   808 
   809   /* fill surface description */
   810   dsc.flags  = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   811   dsc.width  = surface->w;
   812   dsc.height = surface->h;
   813   dsc.caps   = (surface->flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0;
   814 
   815   /* find the right pixelformat */
   816   dsc.pixelformat = SDLToDFBPixelFormat (surface->format);
   817   if (dsc.pixelformat == DSPF_UNKNOWN)
   818     return -1;
   819 
   820   /* Allocate the hardware acceleration data */
   821   surface->hwdata = (struct private_hwdata *) calloc (1, sizeof(*surface->hwdata));
   822   if (surface->hwdata == NULL)
   823     {
   824       SDL_OutOfMemory();
   825       return -1;
   826     }
   827 
   828   /* Create the surface */
   829   ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface->hwdata->surface);
   830   if (ret)
   831     {
   832       SetDirectFBerror ("dfb->CreateSurface", ret);
   833       free (surface->hwdata);
   834       surface->hwdata = NULL;
   835       return -1;
   836     }
   837 
   838   surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
   839 
   840   return 0;
   841 }
   842 
   843 static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface)
   844 {
   845   if (surface->hwdata && HIDDEN->initialized)
   846     {
   847       surface->hwdata->surface->Release (surface->hwdata->surface);
   848       free (surface->hwdata);
   849       surface->hwdata = NULL;
   850     }
   851 }
   852 
   853 static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
   854 {
   855   /*  fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
   856       src->hwdata, dst->hwdata);*/
   857 
   858   if (!src->hwdata || !dst->hwdata)
   859     return 0;
   860 
   861   src->flags |= SDL_HWACCEL;
   862   src->map->hw_blit = DirectFB_HWAccelBlit;
   863 
   864   return 1;
   865 }
   866 
   867 static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
   868                                 SDL_Surface *dst, SDL_Rect *dstrect)
   869 {
   870   DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
   871 
   872   DFBRectangle sr = { srcrect->x, srcrect->y, srcrect->w, srcrect->h };
   873   DFBRectangle dr = { dstrect->x, dstrect->y, dstrect->w, dstrect->h };
   874 
   875   IDirectFBSurface *surface = dst->hwdata->surface;
   876 
   877   if (src->flags & SDL_SRCCOLORKEY)
   878     {
   879       flags |= DSBLIT_SRC_COLORKEY;
   880       DirectFB_SetHWColorKey (NULL, src, src->format->colorkey);
   881     }
   882 
   883   if (src->flags & SDL_SRCALPHA)
   884     {
   885       flags |= DSBLIT_BLEND_COLORALPHA;
   886       surface->SetColor (surface, 0xff, 0xff, 0xff, src->format->alpha);
   887     }
   888 
   889   surface->SetBlittingFlags (surface, flags);
   890 
   891   if (sr.w == dr.w && sr.h == dr.h)
   892     surface->Blit (surface, src->hwdata->surface, &sr, dr.x, dr.y);
   893   else
   894     surface->StretchBlit (surface, src->hwdata->surface, &sr, &dr);
   895 
   896   return 0;
   897 }
   898 
   899 static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
   900 {
   901   SDL_PixelFormat  *fmt     = dst->format;
   902   IDirectFBSurface *surface = dst->hwdata->surface;
   903 
   904   /* ugly */
   905   surface->SetColor (surface,
   906                      (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
   907                      (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
   908                      (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift), 0xFF);
   909   surface->FillRectangle (surface, dstrect->x, dstrect->y, dstrect->w, dstrect->h);
   910 
   911   return 0;
   912 }
   913 
   914 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *src, Uint32 key)
   915 {
   916   SDL_PixelFormat  *fmt     = src->format;
   917   IDirectFBSurface *surface = src->hwdata->surface;
   918 
   919   if (fmt->BitsPerPixel == 8)
   920     surface->SetSrcColorKeyIndex (surface, key);
   921   else
   922     /* ugly */
   923     surface->SetSrcColorKey (surface,
   924                              (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
   925                              (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
   926                              (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift));
   927 
   928   return 0;
   929 }
   930 
   931 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha)
   932 {
   933   return 0;
   934 }
   935 
   936 static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface)
   937 {
   938   if (HIDDEN->enable_mga_crtc2)
   939     {
   940        int rtn = surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, 0);
   941        if (HIDDEN->mga_crtc2_stretch)
   942          HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, surface->hwdata->surface, &HIDDEN->c2ssize, &HIDDEN->c2dsize);
   943        else
   944          HIDDEN->c2frame->Blit(HIDDEN->c2frame, surface->hwdata->surface, NULL, HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
   945      
   946        HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
   947        return rtn;
   948     } 
   949   else 
   950      return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, DSFLIP_WAITFORSYNC);
   951 }
   952 
   953 static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface)
   954 {
   955   DFBResult  ret;
   956   void      *data;
   957   int        pitch;
   958 
   959   ret = surface->hwdata->surface->Lock (surface->hwdata->surface,
   960                                         DSLF_WRITE, &data, &pitch);
   961   if (ret)
   962     {
   963       SetDirectFBerror ("surface->Lock", ret);
   964       return -1;
   965     }
   966 
   967   surface->pixels = data;
   968   surface->pitch  = pitch;
   969 
   970   return 0;
   971 }
   972 
   973 static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface)
   974 {
   975   surface->hwdata->surface->Unlock (surface->hwdata->surface);
   976   surface->pixels = NULL;
   977 }
   978 
   979 static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
   980 {
   981   if (HIDDEN->enable_mga_crtc2)
   982     {
   983        if (HIDDEN->mga_crtc2_stretch)
   984          HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, this->screen->hwdata->surface, &HIDDEN->c2ssize, &HIDDEN->c2dsize); 
   985        else
   986          HIDDEN->c2frame->Blit(HIDDEN->c2frame, this->screen->hwdata->surface, NULL, HIDDEN->c2dsize.x, HIDDEN->c2dsize.y); 
   987 
   988        HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
   989     }
   990 }
   991 
   992 static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects)
   993 {
   994   DFBRegion         region;
   995   int               i;
   996   int               region_valid = 0;
   997   IDirectFBSurface *surface = this->screen->hwdata->surface;
   998 
   999   for (i=0; i<numrects; ++i)
  1000     {
  1001       int x2, y2;
  1002 
  1003       if ( ! rects[i].w ) /* Clipped? */
  1004         continue;
  1005 
  1006       x2 = rects[i].x + rects[i].w - 1;
  1007       y2 = rects[i].y + rects[i].h - 1;
  1008 
  1009       if (region_valid)
  1010         {
  1011           if (rects[i].x < region.x1)
  1012             region.x1 = rects[i].x;
  1013 
  1014           if (rects[i].y < region.y1)
  1015             region.y1 = rects[i].y;
  1016 
  1017           if (x2 > region.x2)
  1018             region.x2 = x2;
  1019 
  1020           if (y2 > region.y2)
  1021             region.y2 = y2;
  1022         }
  1023       else
  1024         {
  1025             region.x1 = rects[i].x;
  1026             region.y1 = rects[i].y;
  1027             region.x2 = x2;
  1028             region.y2 = y2;
  1029 
  1030             region_valid = 1;
  1031         }
  1032     }
  1033 
  1034   if (region_valid)
  1035     {
  1036       if (HIDDEN->enable_mga_crtc2)
  1037         {
  1038           if (HIDDEN->mga_crtc2_stretch)
  1039             HIDDEN->c2frame->StretchBlit(HIDDEN->c2frame, surface, &HIDDEN->c2ssize, &HIDDEN->c2dsize);
  1040           else
  1041             HIDDEN->c2frame->Blit(HIDDEN->c2frame, surface, NULL, HIDDEN->c2dsize.x, HIDDEN->c2dsize.y); 
  1042       
  1043           HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
  1044         }
  1045       else 
  1046         surface->Flip (surface, &region, DSFLIP_WAITFORSYNC);
  1047     }
  1048 }
  1049 
  1050 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
  1051 {
  1052   IDirectFBPalette *palette = this->screen->hwdata->palette;
  1053 
  1054   if (!palette)
  1055     return 0;
  1056 
  1057   if (firstcolor > 255)
  1058     return 0;
  1059 
  1060   if (firstcolor + ncolors > 256)
  1061     ncolors = 256 - firstcolor;
  1062 
  1063   if (ncolors > 0)
  1064     {
  1065       int      i;
  1066       DFBColor entries[ncolors];
  1067 
  1068       for (i=0; i<ncolors; i++)
  1069         {
  1070           entries[i].a = 0xff;
  1071           entries[i].r = colors[i].r;
  1072           entries[i].g = colors[i].g;
  1073           entries[i].b = colors[i].b;
  1074         }
  1075 
  1076       palette->SetEntries (palette, entries, ncolors, firstcolor);
  1077     }
  1078 
  1079   return 1;
  1080 }
  1081 	
  1082 void DirectFB_VideoQuit(_THIS)
  1083 {
  1084   struct DirectFBEnumRect *rect    = enumlist;
  1085 
  1086   if (this->screen->hwdata)
  1087     {
  1088       IDirectFBSurface        *surface = this->screen->hwdata->surface;
  1089       IDirectFBPalette        *palette = this->screen->hwdata->palette;
  1090 
  1091       if (palette)
  1092         palette->Release (palette);
  1093 
  1094       if (surface)
  1095         surface->Release (surface);
  1096 
  1097       this->screen->hwdata->surface = NULL;
  1098       this->screen->hwdata->palette = NULL;
  1099     }
  1100 
  1101   if (HIDDEN->c2frame)
  1102     {
  1103       HIDDEN->c2frame->Release (HIDDEN->c2frame);
  1104       HIDDEN->c2frame = NULL;
  1105     }
  1106 
  1107   if (HIDDEN->eventbuffer)
  1108     {
  1109       HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
  1110       HIDDEN->eventbuffer = NULL;
  1111     }
  1112 
  1113   if (HIDDEN->c2layer)
  1114     {
  1115       HIDDEN->c2layer->Release (HIDDEN->c2layer);
  1116       HIDDEN->c2layer = NULL;
  1117     }
  1118 
  1119   if (HIDDEN->layer)
  1120     {
  1121       HIDDEN->layer->Release (HIDDEN->layer);
  1122       HIDDEN->layer = NULL;
  1123     }
  1124 
  1125   if (HIDDEN->dfb)
  1126     {
  1127       HIDDEN->dfb->Release (HIDDEN->dfb);
  1128       HIDDEN->dfb = NULL;
  1129     }
  1130 
  1131   /* Free video mode list */
  1132   if (HIDDEN->modelist)
  1133     {
  1134       free (HIDDEN->modelist);
  1135       HIDDEN->modelist = NULL;
  1136     }
  1137 
  1138   /* Free mode enumeration list */
  1139   while (rect)
  1140     {
  1141       struct DirectFBEnumRect *next = rect->next;
  1142       free (rect);
  1143       rect = next;
  1144     }
  1145   enumlist = NULL;
  1146 
  1147   HIDDEN->initialized = 0;
  1148 }
  1149 
  1150 
  1151 int DirectFB_ShowWMCursor(_THIS, WMcursor *cursor)
  1152 {
  1153   /* We can only hide or show the default cursor */
  1154   if ( cursor == NULL )
  1155     {
  1156       HIDDEN->layer->SetCursorOpacity(HIDDEN->layer, 0x00);
  1157     }
  1158     else
  1159     {
  1160       HIDDEN->layer->SetCursorOpacity(HIDDEN->layer, 0xFF);
  1161     }
  1162   return 1;
  1163 }
  1164 
  1165 void DirectFB_FinalQuit(void) 
  1166 {
  1167 }