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, ¤t->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, ¤t->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, ®ion, 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 +}