src/video/directfb/SDL_DirectFB_video.c
changeset 167 cb384ef627f6
child 219 f928da36f0e9
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/video/directfb/SDL_DirectFB_video.c	Tue Sep 04 22:53:46 2001 +0000
     1.3 @@ -0,0 +1,746 @@
     1.4 +/*
     1.5 +	SDL - Simple DirectMedia Layer
     1.6 +	Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     1.7 +
     1.8 +	This library is free software; you can redistribute it and/or
     1.9 +	modify it under the terms of the GNU Library General Public
    1.10 +	License as published by the Free Software Foundation; either
    1.11 +	version 2 of the License, or (at your option) any later version.
    1.12 +
    1.13 +	This library is distributed in the hope that it will be useful,
    1.14 +	but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16 +	Library General Public License for more details.
    1.17 +
    1.18 +	You should have received a copy of the GNU Library General Public
    1.19 +	License along with this library; if not, write to the Free
    1.20 +	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.21 +
    1.22 +	Sam Lantinga
    1.23 +	slouken@devolution.com
    1.24 +*/
    1.25 +
    1.26 +#ifdef SAVE_RCSID
    1.27 +static char rcsid =
    1.28 + "@(#) $Id$";
    1.29 +#endif
    1.30 +
    1.31 +/* DirectFB video driver implementation.
    1.32 +*/
    1.33 +
    1.34 +#include <stdlib.h>
    1.35 +#include <stdio.h>
    1.36 +#include <fcntl.h>
    1.37 +#include <unistd.h>
    1.38 +#include <sys/mman.h>
    1.39 +
    1.40 +#include <directfb.h>
    1.41 +
    1.42 +#include "SDL.h"
    1.43 +#include "SDL_error.h"
    1.44 +#include "SDL_video.h"
    1.45 +#include "SDL_mouse.h"
    1.46 +#include "SDL_sysvideo.h"
    1.47 +#include "SDL_pixels_c.h"
    1.48 +#include "SDL_events_c.h"
    1.49 +#include "SDL_DirectFB_video.h"
    1.50 +#include "SDL_DirectFB_events.h"
    1.51 +
    1.52 +
    1.53 +/* Initialization/Query functions */
    1.54 +static int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat);
    1.55 +static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
    1.56 +static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
    1.57 +static int DirectFB_SetColors(_THIS, int firstcolor, int ncolors,
    1.58 +			 SDL_Color *colors);
    1.59 +static void DirectFB_VideoQuit(_THIS);
    1.60 +
    1.61 +/* Hardware surface functions */
    1.62 +static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface);
    1.63 +static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
    1.64 +static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface);
    1.65 +static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface);
    1.66 +static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface);
    1.67 +static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
    1.68 +static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
    1.69 +                                SDL_Surface *dst, SDL_Rect *dstrect);
    1.70 +static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);
    1.71 +static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha);
    1.72 +static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface);
    1.73 +
    1.74 +/* Various screen update functions available */
    1.75 +static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
    1.76 +static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects);
    1.77 +
    1.78 +/* This is the rect EnumModes2 uses */
    1.79 +struct DirectFBEnumRect {
    1.80 +	SDL_Rect r;
    1.81 +	struct DirectFBEnumRect* next;
    1.82 +};
    1.83 +
    1.84 +static struct DirectFBEnumRect *enumlists[NUM_MODELISTS];
    1.85 +
    1.86 +
    1.87 +/* DirectFB driver bootstrap functions */
    1.88 +
    1.89 +static int DirectFB_Available(void)
    1.90 +{
    1.91 +  return 1;
    1.92 +}
    1.93 +
    1.94 +static void DirectFB_DeleteDevice(SDL_VideoDevice *device)
    1.95 +{
    1.96 +  free(device->hidden);
    1.97 +  free(device);
    1.98 +}
    1.99 +
   1.100 +static SDL_VideoDevice *DirectFB_CreateDevice(int devindex)
   1.101 +{
   1.102 +  SDL_VideoDevice *device;
   1.103 +
   1.104 +  /* Initialize all variables that we clean on shutdown */
   1.105 +  device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
   1.106 +  if (device)
   1.107 +    {
   1.108 +      memset (device, 0, (sizeof *device));
   1.109 +      device->hidden = (struct SDL_PrivateVideoData *) malloc (sizeof (*device->hidden));
   1.110 +    }
   1.111 +  if (device == NULL  ||  device->hidden == NULL)
   1.112 +    {
   1.113 +      SDL_OutOfMemory();
   1.114 +      if (device)
   1.115 +        {
   1.116 +          free (device);
   1.117 +        }
   1.118 +      return(0);
   1.119 +    }
   1.120 +  memset (device->hidden, 0, sizeof (*device->hidden));
   1.121 +
   1.122 +  /* Set the function pointers */
   1.123 +  device->VideoInit = DirectFB_VideoInit;
   1.124 +  device->ListModes = DirectFB_ListModes;
   1.125 +  device->SetVideoMode = DirectFB_SetVideoMode;
   1.126 +  device->SetColors = DirectFB_SetColors;
   1.127 +  device->UpdateRects = NULL;
   1.128 +  device->VideoQuit = DirectFB_VideoQuit;
   1.129 +  device->AllocHWSurface = DirectFB_AllocHWSurface;
   1.130 +  device->CheckHWBlit = DirectFB_CheckHWBlit;
   1.131 +  device->FillHWRect = DirectFB_FillHWRect;
   1.132 +  device->SetHWColorKey = DirectFB_SetHWColorKey;
   1.133 +  device->SetHWAlpha = DirectFB_SetHWAlpha;
   1.134 +  device->LockHWSurface = DirectFB_LockHWSurface;
   1.135 +  device->UnlockHWSurface = DirectFB_UnlockHWSurface;
   1.136 +  device->FlipHWSurface = DirectFB_FlipHWSurface;
   1.137 +  device->FreeHWSurface = DirectFB_FreeHWSurface;
   1.138 +  device->SetCaption = NULL;
   1.139 +  device->SetIcon = NULL;
   1.140 +  device->IconifyWindow = NULL;
   1.141 +  device->GrabInput = NULL;
   1.142 +  device->GetWMInfo = NULL;
   1.143 +  device->InitOSKeymap = DirectFB_InitOSKeymap;
   1.144 +  device->PumpEvents = DirectFB_PumpEvents;
   1.145 +
   1.146 +  device->free = DirectFB_DeleteDevice;
   1.147 +
   1.148 +  return device;
   1.149 +}
   1.150 +
   1.151 +VideoBootStrap DirectFB_bootstrap = {
   1.152 +  "directfb", "DirectFB",
   1.153 +  DirectFB_Available, DirectFB_CreateDevice
   1.154 +};
   1.155 +
   1.156 +static DFBEnumerationResult EnumModesCallback (unsigned int  width,
   1.157 +                                               unsigned int  height,
   1.158 +                                               unsigned int  bpp,
   1.159 +                                               void         *data)
   1.160 +{
   1.161 +  SDL_VideoDevice *this = (SDL_VideoDevice *)data;
   1.162 +  struct DirectFBEnumRect *enumrect;
   1.163 +
   1.164 +  switch (bpp)
   1.165 +    {
   1.166 +    case 8:
   1.167 +    case 15:
   1.168 +    case 16:
   1.169 +    case 24:
   1.170 +    case 32:
   1.171 +      bpp /= 8; --bpp;
   1.172 +      ++HIDDEN->SDL_nummodes[bpp];
   1.173 +      enumrect = (struct DirectFBEnumRect*)malloc(sizeof(struct DirectFBEnumRect));
   1.174 +      if ( !enumrect )
   1.175 +        {
   1.176 +          SDL_OutOfMemory();
   1.177 +          return DFENUM_CANCEL;
   1.178 +        }
   1.179 +      enumrect->r.x = 0;
   1.180 +      enumrect->r.y = 0;
   1.181 +      enumrect->r.w = width;
   1.182 +      enumrect->r.h = height;
   1.183 +      enumrect->next = enumlists[bpp];
   1.184 +      enumlists[bpp] = enumrect;
   1.185 +      break;
   1.186 +    }
   1.187 +
   1.188 +  return DFENUM_OK;
   1.189 +}
   1.190 +
   1.191 +struct private_hwdata {
   1.192 +  IDirectFBSurface *surface;
   1.193 +};
   1.194 +
   1.195 +void SetDirectFBerror (const char *function, DFBResult code)
   1.196 +{
   1.197 +  const char *error = DirectFBErrorString (code);
   1.198 +
   1.199 +  if (error)
   1.200 +    SDL_SetError("%s: %s", function, error);
   1.201 +  else
   1.202 +    SDL_SetError("Unknown error code from %s", function);
   1.203 +}
   1.204 +
   1.205 +static DFBSurfacePixelFormat SDLToDFBPixelFormat (SDL_PixelFormat *format)
   1.206 +{
   1.207 +  if (format->Rmask && format->Gmask && format->Bmask)
   1.208 +    {
   1.209 +      switch (format->BitsPerPixel)
   1.210 +        {
   1.211 +        case 16:
   1.212 +          if (format->Rmask == 0xF800 &&
   1.213 +              format->Gmask == 0x07E0 &&
   1.214 +              format->Bmask == 0x001F)
   1.215 +            return DSPF_RGB16;
   1.216 +          /* fall through */
   1.217 +          
   1.218 +        case 15:
   1.219 +          if (format->Rmask == 0x7C00 &&
   1.220 +              format->Gmask == 0x03E0 &&
   1.221 +              format->Bmask == 0x001F)
   1.222 +            return DSPF_RGB15;
   1.223 +          break;
   1.224 +          
   1.225 +        case 24:
   1.226 +          if (format->Rmask == 0xFF0000 &&
   1.227 +              format->Gmask == 0x00FF00 &&
   1.228 +              format->Bmask == 0x0000FF)
   1.229 +            return DSPF_RGB24;
   1.230 +          break;
   1.231 +          
   1.232 +        case 32:
   1.233 +          if (format->Rmask == 0xFF0000 &&
   1.234 +              format->Gmask == 0x00FF00 &&
   1.235 +              format->Bmask == 0x0000FF)
   1.236 +            {
   1.237 +              if (format->Amask == 0xFF000000)
   1.238 +                return DSPF_ARGB;
   1.239 +              else
   1.240 +                return DSPF_RGB32;
   1.241 +            }
   1.242 +          break;
   1.243 +        }
   1.244 +    }
   1.245 +  else
   1.246 +    {
   1.247 +      switch (format->BitsPerPixel)
   1.248 +	{
   1.249 +	case 15:
   1.250 +	  return DSPF_RGB15;
   1.251 +	case 16:
   1.252 +	  return DSPF_RGB16;
   1.253 +	case 24:
   1.254 +	  return DSPF_RGB24;
   1.255 +	case 32:
   1.256 +	  return DSPF_RGB32;
   1.257 +	}
   1.258 +    }
   1.259 +
   1.260 +  return DSPF_UNKNOWN;
   1.261 +}
   1.262 +
   1.263 +static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat, SDL_PixelFormat *format)
   1.264 +{
   1.265 +  format->BitsPerPixel = 0;
   1.266 +  format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
   1.267 +
   1.268 +  switch (pixelformat)
   1.269 +    {
   1.270 +    case DSPF_A8:
   1.271 +      format->Amask = 0x000000FF;
   1.272 +      break;
   1.273 +    case DSPF_RGB15:
   1.274 +      format->Rmask = 0x00007C00;
   1.275 +      format->Gmask = 0x000003E0;
   1.276 +      format->Bmask = 0x0000001F;
   1.277 +      break;
   1.278 +    case DSPF_RGB16:
   1.279 +      format->Rmask = 0x0000F800;
   1.280 +      format->Gmask = 0x000007E0;
   1.281 +      format->Bmask = 0x0000001F;
   1.282 +      break;
   1.283 +    case DSPF_ARGB:
   1.284 +      format->Amask = 0xFF000000;
   1.285 +      /* fall through */
   1.286 +    case DSPF_RGB24:
   1.287 +    case DSPF_RGB32:
   1.288 +      format->Rmask = 0x00FF0000;
   1.289 +      format->Gmask = 0x0000FF00;
   1.290 +      format->Bmask = 0x000000FF;
   1.291 +      break;
   1.292 +    default:
   1.293 +      return -1;
   1.294 +    }
   1.295 +
   1.296 +  format->BitsPerPixel = BITS_PER_PIXEL(pixelformat);
   1.297 +
   1.298 +  return 0;
   1.299 +}
   1.300 +
   1.301 +
   1.302 +int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat)
   1.303 +{
   1.304 +  int                    i, j;
   1.305 +  DFBResult              ret;
   1.306 +  IDirectFB             *dfb;
   1.307 +  DFBCardCapabilities    caps;
   1.308 +  IDirectFBDisplayLayer *layer;
   1.309 +  DFBDisplayLayerConfig  dlc;
   1.310 +  IDirectFBInputBuffer  *inputbuffer;
   1.311 +
   1.312 +
   1.313 +  ret = DirectFBInit (NULL, NULL);
   1.314 +  if (ret)
   1.315 +    {
   1.316 +      SetDirectFBerror ("DirectFBInit", ret);
   1.317 +      return -1;
   1.318 +    }
   1.319 +
   1.320 +  ret = DirectFBCreate (&dfb);
   1.321 +  if (ret)
   1.322 +    {
   1.323 +      SetDirectFBerror ("DirectFBCreate", ret);
   1.324 +      return -1;
   1.325 +    }
   1.326 +
   1.327 +  ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer);
   1.328 +  if (ret)
   1.329 +    {
   1.330 +      SetDirectFBerror ("dfb->GetDisplayLayer", ret);
   1.331 +      dfb->Release (dfb);
   1.332 +      return -1;
   1.333 +    }
   1.334 +
   1.335 +  ret = dfb->CreateInputBuffer (dfb, DICAPS_BUTTONS | DICAPS_AXIS | DICAPS_KEYS,
   1.336 +                                &inputbuffer);
   1.337 +  if (ret)
   1.338 +    {
   1.339 +      SetDirectFBerror ("dfb->CreateInputBuffer", ret);
   1.340 +      layer->Release (layer);
   1.341 +      dfb->Release (dfb);
   1.342 +      return -1;
   1.343 +    }
   1.344 +  
   1.345 +  layer->EnableCursor (layer, 1);
   1.346 +
   1.347 +  /* Query layer configuration to determine the current mode and pixelformat */
   1.348 +  layer->GetConfiguration (layer, &dlc);
   1.349 +
   1.350 +  if (DFBToSDLPixelFormat (dlc.pixelformat, vformat))
   1.351 +    {
   1.352 +      SDL_SetError ("Unsupported pixelformat");
   1.353 +      layer->Release (layer);
   1.354 +      dfb->Release (dfb);
   1.355 +      return -1;
   1.356 +    }
   1.357 +
   1.358 +  /* Enumerate the available fullscreen modes */
   1.359 +  for ( i=0; i<NUM_MODELISTS; ++i )
   1.360 +    enumlists[i] = NULL;
   1.361 +
   1.362 +  ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this);
   1.363 +  if (ret)
   1.364 +    {
   1.365 +      SetDirectFBerror ("dfb->EnumVideoModes", ret);
   1.366 +      layer->Release (layer);
   1.367 +      dfb->Release (dfb);
   1.368 +      return(-1);
   1.369 +    }
   1.370 +  for ( i=0; i<NUM_MODELISTS; ++i )
   1.371 +    {
   1.372 +      struct DirectFBEnumRect *rect;
   1.373 +      HIDDEN->SDL_modelist[i] = (SDL_Rect **) malloc
   1.374 +        ((HIDDEN->SDL_nummodes[i]+1)*sizeof(SDL_Rect *));
   1.375 +      if ( HIDDEN->SDL_modelist[i] == NULL )
   1.376 +        {
   1.377 +          SDL_OutOfMemory();
   1.378 +          return(-1);
   1.379 +        }
   1.380 +      for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next )
   1.381 +        {
   1.382 +          HIDDEN->SDL_modelist[i][j]=(SDL_Rect *)rect;
   1.383 +        }
   1.384 +      HIDDEN->SDL_modelist[i][j] = NULL;
   1.385 +    }
   1.386 +
   1.387 +  /* Query card capabilities to get the video memory size */
   1.388 +  dfb->GetCardCapabilities (dfb, &caps);
   1.389 +
   1.390 +  this->info.wm_available = 1;
   1.391 +  this->info.hw_available = 1;
   1.392 +  this->info.blit_hw      = 1;
   1.393 +  this->info.blit_hw_CC   = 1;
   1.394 +  this->info.blit_hw_A    = 1;
   1.395 +  this->info.blit_fill    = 1;
   1.396 +  this->info.video_mem    = caps.video_memory / 1024;
   1.397 +
   1.398 +  HIDDEN->initialized = 1;
   1.399 +  HIDDEN->dfb         = dfb;
   1.400 +  HIDDEN->layer       = layer;
   1.401 +  HIDDEN->inputbuffer = inputbuffer;
   1.402 +
   1.403 +  return 0;
   1.404 +}
   1.405 +
   1.406 +static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
   1.407 +{
   1.408 +  if (flags & SDL_FULLSCREEN)
   1.409 +    return HIDDEN->SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1];
   1.410 +  else
   1.411 +    if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN)
   1.412 +      return (SDL_Rect**) -1;
   1.413 +
   1.414 +  return NULL;
   1.415 +}
   1.416 +
   1.417 +SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
   1.418 +{
   1.419 +  DFBResult             ret;
   1.420 +  DFBSurfaceDescription dsc;
   1.421 +  DFBSurfacePixelFormat pixelformat;
   1.422 +
   1.423 +  fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
   1.424 +           width, height, bpp, flags);
   1.425 +
   1.426 +  flags |= SDL_FULLSCREEN;
   1.427 +
   1.428 +  /* Release previous primary surface */
   1.429 +  if (current->hwdata && current->hwdata->surface)
   1.430 +    {
   1.431 +      current->hwdata->surface->Release (current->hwdata->surface);
   1.432 +      current->hwdata->surface = NULL;
   1.433 +    }
   1.434 +  else if (!current->hwdata)
   1.435 +    {
   1.436 +      /* Allocate the hardware acceleration data */
   1.437 +      current->hwdata = (struct private_hwdata *) malloc (sizeof(*current->hwdata));
   1.438 +      if (!current->hwdata)
   1.439 +        {
   1.440 +          SDL_OutOfMemory();
   1.441 +          return NULL;
   1.442 +	}
   1.443 +      memset (current->hwdata, 0, sizeof(*current->hwdata));
   1.444 +    }
   1.445 +
   1.446 +  /* Set cooperative level depending on flag SDL_FULLSCREEN */
   1.447 +  if (flags & SDL_FULLSCREEN)
   1.448 +    {
   1.449 +      ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN);
   1.450 +      if (ret)
   1.451 +        {
   1.452 +          DirectFBError ("dfb->SetCooperativeLevel", ret);
   1.453 +          flags &= ~SDL_FULLSCREEN;
   1.454 +        }
   1.455 +    }
   1.456 +  else
   1.457 +    HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
   1.458 +
   1.459 +  /* Set video mode */
   1.460 +  ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
   1.461 +  if (ret)
   1.462 +    {
   1.463 +      if (flags & SDL_FULLSCREEN)
   1.464 +        {
   1.465 +          flags &= ~SDL_FULLSCREEN;
   1.466 +          HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
   1.467 +          ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
   1.468 +        }
   1.469 +
   1.470 +      if (ret)
   1.471 +        {
   1.472 +          SetDirectFBerror ("dfb->SetVideoMode", ret);
   1.473 +          return NULL;
   1.474 +        }
   1.475 +    }
   1.476 +
   1.477 +  /* Create primary surface */
   1.478 +  dsc.flags = DSDESC_CAPS;
   1.479 +  dsc.caps  = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
   1.480 +
   1.481 +  ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface);
   1.482 +  if (ret && (flags & SDL_DOUBLEBUF))
   1.483 +    {
   1.484 +      /* Try without double buffering */
   1.485 +      dsc.caps &= ~DSCAPS_FLIPPING;
   1.486 +      ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface);
   1.487 +    }
   1.488 +  if (ret)
   1.489 +    {
   1.490 +      SetDirectFBerror ("dfb->CreateSurface", ret);
   1.491 +      current->hwdata->surface = NULL;
   1.492 +      return NULL;
   1.493 +    }
   1.494 +
   1.495 +  current->w     = width;
   1.496 +  current->h     = height;
   1.497 +  current->flags = SDL_HWSURFACE | SDL_PREALLOC;
   1.498 +
   1.499 +  if (flags & SDL_FULLSCREEN)
   1.500 +    {
   1.501 +      current->flags |= SDL_FULLSCREEN;
   1.502 +      this->UpdateRects = DirectFB_DirectUpdate;
   1.503 +    }
   1.504 +  else
   1.505 +    this->UpdateRects = DirectFB_WindowedUpdate;
   1.506 +
   1.507 +  if (dsc.caps & DSCAPS_FLIPPING)
   1.508 +    current->flags |= SDL_DOUBLEBUF;
   1.509 +
   1.510 +  current->hwdata->surface->GetPixelFormat (current->hwdata->surface, &pixelformat);
   1.511 +  DFBToSDLPixelFormat (pixelformat, current->format);
   1.512 +
   1.513 +  return current;
   1.514 +}
   1.515 +
   1.516 +static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface)
   1.517 +{
   1.518 +  DFBResult             ret;
   1.519 +  DFBSurfaceDescription dsc;
   1.520 +
   1.521 +  /*  fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n",
   1.522 +      surface->w, surface->h, surface->format->BitsPerPixel, surface->flags);*/
   1.523 +
   1.524 +  if (surface->w < 8 || surface->h < 8)
   1.525 +    return -1;
   1.526 +
   1.527 +  /* fill surface description */
   1.528 +  dsc.flags  = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   1.529 +  dsc.width  = surface->w;
   1.530 +  dsc.height = surface->h;
   1.531 +  dsc.caps   = surface->flags & SDL_DOUBLEBUF ? DSCAPS_FLIPPING : 0;
   1.532 +
   1.533 +  /* find the right pixelformat */
   1.534 +  dsc.pixelformat = SDLToDFBPixelFormat (surface->format);
   1.535 +  if (dsc.pixelformat == DSPF_UNKNOWN)
   1.536 +    return -1;
   1.537 +
   1.538 +  /* Allocate the hardware acceleration data */
   1.539 +  surface->hwdata = (struct private_hwdata *) malloc (sizeof(*surface->hwdata));
   1.540 +  if (surface->hwdata == NULL)
   1.541 +    {
   1.542 +      SDL_OutOfMemory();
   1.543 +      return -1;
   1.544 +    }
   1.545 +
   1.546 +  /* Create the surface */
   1.547 +  ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface->hwdata->surface);
   1.548 +  if (ret)
   1.549 +    {
   1.550 +      SetDirectFBerror ("dfb->CreateSurface", ret);
   1.551 +      free (surface->hwdata);
   1.552 +      surface->hwdata = NULL;
   1.553 +      return -1;
   1.554 +    }
   1.555 +
   1.556 +  surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
   1.557 +
   1.558 +  return 0;
   1.559 +}
   1.560 +
   1.561 +static void DirectFB_FreeHWSurface(_THIS, SDL_Surface *surface)
   1.562 +{
   1.563 +  if (surface->hwdata && HIDDEN->initialized)
   1.564 +    {
   1.565 +      surface->hwdata->surface->Release (surface->hwdata->surface);
   1.566 +      free (surface->hwdata);
   1.567 +      surface->hwdata = NULL;
   1.568 +    }
   1.569 +}
   1.570 +
   1.571 +static int DirectFB_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
   1.572 +{
   1.573 +  /*  fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
   1.574 +      src->hwdata, dst->hwdata);*/
   1.575 +
   1.576 +  if (!src->hwdata || !dst->hwdata)
   1.577 +    return 0;
   1.578 +
   1.579 +  src->flags |= SDL_HWACCEL;
   1.580 +  src->map->hw_blit = DirectFB_HWAccelBlit;
   1.581 +
   1.582 +  return 1;
   1.583 +}
   1.584 +
   1.585 +static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
   1.586 +                                SDL_Surface *dst, SDL_Rect *dstrect)
   1.587 +{
   1.588 +  DFBRectangle             sr, dr;
   1.589 +  IDirectFBSurface        *surface;
   1.590 +  DFBSurfaceBlittingFlags  flags = DSBLIT_NOFX;
   1.591 +
   1.592 +  sr.x = srcrect->x;
   1.593 +  sr.y = srcrect->y;
   1.594 +  sr.w = srcrect->w;
   1.595 +  sr.h = srcrect->h;
   1.596 +
   1.597 +  dr.x = dstrect->x;
   1.598 +  dr.y = dstrect->y;
   1.599 +  dr.w = dstrect->w;
   1.600 +  dr.h = dstrect->h;
   1.601 +
   1.602 +  surface = dst->hwdata->surface;
   1.603 +
   1.604 +  if (src->flags & SDL_SRCCOLORKEY)
   1.605 +    {
   1.606 +      flags |= DSBLIT_SRC_COLORKEY;
   1.607 +      surface->SetSrcColorKey (surface, src->format->colorkey);
   1.608 +    }
   1.609 +
   1.610 +  if (src->flags & SDL_SRCALPHA)
   1.611 +    {
   1.612 +      flags |= DSBLIT_BLEND_COLORALPHA;
   1.613 +      surface->SetColor (surface, 0xff, 0xff, 0xff, src->format->alpha);
   1.614 +    }
   1.615 +
   1.616 +  surface->SetBlittingFlags (surface, flags);
   1.617 +
   1.618 +  if (sr.w == dr.w && sr.h == dr.h)
   1.619 +    surface->Blit (surface, src->hwdata->surface, &sr, dr.x, dr.y);
   1.620 +  else
   1.621 +    surface->StretchBlit (surface, src->hwdata->surface, &sr, &dr);
   1.622 +
   1.623 +  return 0;
   1.624 +}
   1.625 +
   1.626 +static int DirectFB_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
   1.627 +{
   1.628 +  SDL_PixelFormat  *fmt     = dst->format;
   1.629 +  IDirectFBSurface *surface = dst->hwdata->surface;
   1.630 +
   1.631 +  /* ugly */
   1.632 +  surface->SetColor (surface,
   1.633 +                     (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
   1.634 +                     (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
   1.635 +                     (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift), 0xFF);
   1.636 +  surface->FillRectangle (surface, dstrect->x, dstrect->y, dstrect->w, dstrect->h);
   1.637 +
   1.638 +  return 0;
   1.639 +}
   1.640 +
   1.641 +static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
   1.642 +{
   1.643 +  return 0;
   1.644 +}
   1.645 +
   1.646 +static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha)
   1.647 +{
   1.648 +  return 0;
   1.649 +}
   1.650 +
   1.651 +static int DirectFB_FlipHWSurface(_THIS, SDL_Surface *surface)
   1.652 +{
   1.653 +  return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL, DSFLIP_WAITFORSYNC);
   1.654 +}
   1.655 +
   1.656 +static int DirectFB_LockHWSurface(_THIS, SDL_Surface *surface)
   1.657 +{
   1.658 +  DFBResult  ret;
   1.659 +  void      *data;
   1.660 +  int        pitch;
   1.661 +
   1.662 +  ret = surface->hwdata->surface->Lock (surface->hwdata->surface,
   1.663 +                                        DSLF_WRITE, &data, &pitch);
   1.664 +  if (ret)
   1.665 +    {
   1.666 +      SetDirectFBerror ("surface->Lock", ret);
   1.667 +      return -1;
   1.668 +    }
   1.669 +
   1.670 +  surface->pixels = data;
   1.671 +  surface->pitch  = pitch;
   1.672 +
   1.673 +  return 0;
   1.674 +}
   1.675 +
   1.676 +static void DirectFB_UnlockHWSurface(_THIS, SDL_Surface *surface)
   1.677 +{
   1.678 +  surface->hwdata->surface->Unlock (surface->hwdata->surface);
   1.679 +  surface->pixels = NULL;
   1.680 +}
   1.681 +
   1.682 +static void DirectFB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
   1.683 +{
   1.684 +}
   1.685 +
   1.686 +static void DirectFB_WindowedUpdate(_THIS, int numrects, SDL_Rect *rects)
   1.687 +{
   1.688 +  IDirectFBSurface *surface = this->screen->hwdata->surface;
   1.689 +  DFBRegion region = { rects->x, rects->y,
   1.690 +                       rects->x + rects->w - 1,
   1.691 +                       rects->y + rects->h - 1 };
   1.692 +
   1.693 +  while (--numrects)
   1.694 +    {
   1.695 +      int x2, y2;
   1.696 +
   1.697 +      rects++;
   1.698 +
   1.699 +      if (rects->x < region.x1)
   1.700 +        region.x1 = rects->x;
   1.701 +
   1.702 +      if (rects->y < region.y1)
   1.703 +        region.y1 = rects->y;
   1.704 +
   1.705 +      x2 = rects->x + rects->w - 1;
   1.706 +      y2 = rects->y + rects->h - 1;
   1.707 +
   1.708 +      if (x2 > region.x2)
   1.709 +        region.x2 = x2;
   1.710 +
   1.711 +      if (y2 > region.y2)
   1.712 +        region.y2 = y2;
   1.713 +    }
   1.714 +
   1.715 +  surface->Flip (surface, &region, DSFLIP_WAITFORSYNC);
   1.716 +}
   1.717 +
   1.718 +int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   1.719 +{
   1.720 +  fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n");
   1.721 +  return 0;
   1.722 +}
   1.723 +	
   1.724 +void DirectFB_VideoQuit(_THIS)
   1.725 +{
   1.726 +  int i, j;
   1.727 +
   1.728 +  HIDDEN->inputbuffer->Release (HIDDEN->inputbuffer);
   1.729 +  HIDDEN->layer->Release (HIDDEN->layer);
   1.730 +  HIDDEN->dfb->Release (HIDDEN->dfb);
   1.731 +
   1.732 +  /* Free video mode lists */
   1.733 +  for ( i=0; i<NUM_MODELISTS; ++i )
   1.734 +    {
   1.735 +      if ( HIDDEN->SDL_modelist[i] != NULL )
   1.736 +        {
   1.737 +          for ( j=0; HIDDEN->SDL_modelist[i][j]; ++j )
   1.738 +            free(HIDDEN->SDL_modelist[i][j]);
   1.739 +          free(HIDDEN->SDL_modelist[i]);
   1.740 +          HIDDEN->SDL_modelist[i] = NULL;
   1.741 +        }
   1.742 +    }
   1.743 +
   1.744 +  HIDDEN->initialized = 0;
   1.745 +}
   1.746 +
   1.747 +void DirectFB_FinalQuit(void) 
   1.748 +{
   1.749 +}