src/video/directfb/SDL_DirectFB_video.c
changeset 464 1c4be4a16410
parent 297 f6ffac90895c
child 477 22581630aab7
     1.1 --- a/src/video/directfb/SDL_DirectFB_video.c	Wed Aug 21 04:16:31 2002 +0000
     1.2 +++ b/src/video/directfb/SDL_DirectFB_video.c	Sat Aug 24 15:29:06 2002 +0000
     1.3 @@ -29,6 +29,7 @@
     1.4  */
     1.5  
     1.6  #include <stdlib.h>
     1.7 +#include <string.h>
     1.8  #include <stdio.h>
     1.9  #include <fcntl.h>
    1.10  #include <unistd.h>
    1.11 @@ -78,7 +79,7 @@
    1.12  	struct DirectFBEnumRect* next;
    1.13  };
    1.14  
    1.15 -static struct DirectFBEnumRect *enumlists[NUM_MODELISTS];
    1.16 +static struct DirectFBEnumRect *enumlist = NULL;
    1.17  
    1.18  
    1.19  /* DirectFB driver bootstrap functions */
    1.20 @@ -150,6 +151,31 @@
    1.21    DirectFB_Available, DirectFB_CreateDevice
    1.22  };
    1.23  
    1.24 +static DFBSurfacePixelFormat GetFormatForBpp (int bpp, IDirectFBDisplayLayer *layer)
    1.25 +{
    1.26 +  DFBDisplayLayerConfig dlc;
    1.27 +  int                   bytes = (bpp + 7) / 8;
    1.28 +
    1.29 +  layer->GetConfiguration (layer, &dlc);
    1.30 +
    1.31 +  if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat))
    1.32 +    return dlc.pixelformat;
    1.33 +
    1.34 +  switch (bytes)
    1.35 +    {
    1.36 +    case 1:
    1.37 +      return DSPF_RGB332;
    1.38 +    case 2:
    1.39 +      return DSPF_RGB16;
    1.40 +    case 3:
    1.41 +      return DSPF_RGB24;
    1.42 +    case 4:
    1.43 +      return DSPF_RGB32;
    1.44 +    }
    1.45 +
    1.46 +  return DSPF_UNKNOWN;
    1.47 +}
    1.48 +
    1.49  static DFBEnumerationResult EnumModesCallback (unsigned int  width,
    1.50                                                 unsigned int  height,
    1.51                                                 unsigned int  bpp,
    1.52 @@ -158,30 +184,21 @@
    1.53    SDL_VideoDevice *this = (SDL_VideoDevice *)data;
    1.54    struct DirectFBEnumRect *enumrect;
    1.55  
    1.56 -  switch (bpp)
    1.57 +  HIDDEN->nummodes++;
    1.58 +
    1.59 +  enumrect = calloc(1, sizeof(struct DirectFBEnumRect));
    1.60 +  if (!enumrect)
    1.61      {
    1.62 -    case 8:
    1.63 -    case 15:
    1.64 -    case 16:
    1.65 -    case 24:
    1.66 -    case 32:
    1.67 -      bpp /= 8; --bpp;
    1.68 -      ++HIDDEN->SDL_nummodes[bpp];
    1.69 -      enumrect = (struct DirectFBEnumRect*)malloc(sizeof(struct DirectFBEnumRect));
    1.70 -      if ( !enumrect )
    1.71 -        {
    1.72 -          SDL_OutOfMemory();
    1.73 -          return DFENUM_CANCEL;
    1.74 -        }
    1.75 -      enumrect->r.x = 0;
    1.76 -      enumrect->r.y = 0;
    1.77 -      enumrect->r.w = width;
    1.78 -      enumrect->r.h = height;
    1.79 -      enumrect->next = enumlists[bpp];
    1.80 -      enumlists[bpp] = enumrect;
    1.81 -      break;
    1.82 +      SDL_OutOfMemory();
    1.83 +      return DFENUM_CANCEL;
    1.84      }
    1.85  
    1.86 +  enumrect->r.w  = width;
    1.87 +  enumrect->r.h  = height;
    1.88 +  enumrect->next = enumlist;
    1.89 +
    1.90 +  enumlist = enumrect;
    1.91 +
    1.92    return DFENUM_OK;
    1.93  }
    1.94  
    1.95 @@ -219,13 +236,20 @@
    1.96              return DSPF_RGB15;
    1.97            break;
    1.98            
    1.99 +        case 8:
   1.100 +          if (format->Rmask == 0xE0 &&
   1.101 +              format->Gmask == 0x1C &&
   1.102 +              format->Bmask == 0x03)
   1.103 +            return DSPF_RGB332;
   1.104 +          break;
   1.105 +          
   1.106          case 24:
   1.107            if (format->Rmask == 0xFF0000 &&
   1.108                format->Gmask == 0x00FF00 &&
   1.109                format->Bmask == 0x0000FF)
   1.110              return DSPF_RGB24;
   1.111            break;
   1.112 -          
   1.113 +
   1.114          case 32:
   1.115            if (format->Rmask == 0xFF0000 &&
   1.116                format->Gmask == 0x00FF00 &&
   1.117 @@ -243,6 +267,8 @@
   1.118      {
   1.119        switch (format->BitsPerPixel)
   1.120  	{
   1.121 +        case 8:
   1.122 +          return DSPF_RGB332;
   1.123  	case 15:
   1.124  	  return DSPF_RGB15;
   1.125  	case 16:
   1.126 @@ -257,28 +283,67 @@
   1.127    return DSPF_UNKNOWN;
   1.128  }
   1.129  
   1.130 +static const __u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff };
   1.131 +static const __u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff };
   1.132 +
   1.133 +static SDL_Palette *GenerateRGB332Palette()
   1.134 +{
   1.135 +  int          i;
   1.136 +  SDL_Palette *palette;
   1.137 +  SDL_Color   *colors;
   1.138 +
   1.139 +  palette = calloc (1, sizeof(SDL_Palette));
   1.140 +  if (!palette)
   1.141 +    {
   1.142 +      SDL_OutOfMemory();
   1.143 +      return NULL;
   1.144 +    }
   1.145 +
   1.146 +  colors = calloc (256, sizeof(SDL_Color));
   1.147 +  if (!colors)
   1.148 +    {
   1.149 +      SDL_OutOfMemory();
   1.150 +      return NULL;
   1.151 +    }
   1.152 +
   1.153 +  for (i=0; i<256; i++)
   1.154 +    {
   1.155 +      colors[i].r = lookup3to8[ i >> 5 ];
   1.156 +      colors[i].g = lookup3to8[ (i >> 2) & 7 ];
   1.157 +      colors[i].g = lookup2to8[ i & 3 ];
   1.158 +    }
   1.159 +
   1.160 +  palette->ncolors = 256;
   1.161 +  palette->colors  = colors;
   1.162 +
   1.163 +  return palette;
   1.164 +}
   1.165 +
   1.166  static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat, SDL_PixelFormat *format)
   1.167  {
   1.168 -  format->BitsPerPixel = 0;
   1.169    format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
   1.170 +  format->BitsPerPixel = format->BytesPerPixel = 0;
   1.171  
   1.172    switch (pixelformat)
   1.173      {
   1.174      case DSPF_A8:
   1.175        format->Amask = 0x000000FF;
   1.176        break;
   1.177 +
   1.178      case DSPF_RGB15:
   1.179        format->Rmask = 0x00007C00;
   1.180        format->Gmask = 0x000003E0;
   1.181        format->Bmask = 0x0000001F;
   1.182        break;
   1.183 +
   1.184      case DSPF_RGB16:
   1.185        format->Rmask = 0x0000F800;
   1.186        format->Gmask = 0x000007E0;
   1.187        format->Bmask = 0x0000001F;
   1.188        break;
   1.189 +
   1.190      case DSPF_ARGB:
   1.191 -      format->Amask = 0xFF000000;
   1.192 +      format->Amask = 0; /* apps don't seem to like that:  0xFF000000; */
   1.193        /* fall through */
   1.194      case DSPF_RGB24:
   1.195      case DSPF_RGB32:
   1.196 @@ -286,11 +351,21 @@
   1.197        format->Gmask = 0x0000FF00;
   1.198        format->Bmask = 0x000000FF;
   1.199        break;
   1.200 +
   1.201 +    case DSPF_RGB332:
   1.202 +      format->Rmask = 0x000000E0;
   1.203 +      format->Gmask = 0x0000001C;
   1.204 +      format->Bmask = 0x00000003;
   1.205 +
   1.206 +      format->palette = GenerateRGB332Palette();
   1.207 +      break;
   1.208 +
   1.209      default:
   1.210        return -1;
   1.211      }
   1.212  
   1.213 -  format->BitsPerPixel = DFB_BITS_PER_PIXEL(pixelformat);
   1.214 +  format->BitsPerPixel  = DFB_BYTES_PER_PIXEL(pixelformat) * 8;
   1.215 +  format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat);
   1.216  
   1.217    return 0;
   1.218  }
   1.219 @@ -298,44 +373,43 @@
   1.220  
   1.221  int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat)
   1.222  {
   1.223 -  int                    i, j;
   1.224 -  DFBResult              ret;
   1.225 -  IDirectFB             *dfb;
   1.226 -  DFBCardCapabilities    caps;
   1.227 -  IDirectFBDisplayLayer *layer;
   1.228 -  DFBDisplayLayerConfig  dlc;
   1.229 -  IDirectFBEventBuffer  *eventbuffer;
   1.230 +  int                      i;
   1.231 +  DFBResult                ret;
   1.232 +  DFBCardCapabilities      caps;
   1.233 +  DFBDisplayLayerConfig    dlc;
   1.234 +  DFBSurfacePixelFormat    format;
   1.235 +  struct DirectFBEnumRect *rect;
   1.236 +  IDirectFB               *dfb    = NULL;
   1.237 +  IDirectFBDisplayLayer   *layer  = NULL;
   1.238 +  IDirectFBEventBuffer    *events = NULL;
   1.239  
   1.240  
   1.241    ret = DirectFBInit (NULL, NULL);
   1.242    if (ret)
   1.243      {
   1.244        SetDirectFBerror ("DirectFBInit", ret);
   1.245 -      return -1;
   1.246 +      goto error;
   1.247      }
   1.248  
   1.249    ret = DirectFBCreate (&dfb);
   1.250    if (ret)
   1.251      {
   1.252        SetDirectFBerror ("DirectFBCreate", ret);
   1.253 -      return -1;
   1.254 +      goto error;
   1.255      }
   1.256  
   1.257    ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer);
   1.258    if (ret)
   1.259      {
   1.260        SetDirectFBerror ("dfb->GetDisplayLayer", ret);
   1.261 -      dfb->Release (dfb);
   1.262 -      return -1;
   1.263 +      goto error;
   1.264      }
   1.265  
   1.266 -  ret = dfb->CreateEventBuffer (dfb, DICAPS_ALL, &eventbuffer);
   1.267 +  ret = dfb->CreateEventBuffer (dfb, DICAPS_ALL, &events);
   1.268    if (ret)
   1.269      {
   1.270        SetDirectFBerror ("dfb->CreateEventBuffer", ret);
   1.271 -      layer->Release (layer);
   1.272 -      dfb->Release (dfb);
   1.273 -      return -1;
   1.274 +      goto error;
   1.275      }
   1.276    
   1.277    layer->EnableCursor (layer, 1);
   1.278 @@ -343,43 +417,39 @@
   1.279    /* Query layer configuration to determine the current mode and pixelformat */
   1.280    layer->GetConfiguration (layer, &dlc);
   1.281  
   1.282 -  if (DFBToSDLPixelFormat (dlc.pixelformat, vformat))
   1.283 +  /* FIXME: Returning RGB332 as the default mode doesn't work (everything is black) */
   1.284 +  if ((format = dlc.pixelformat) == DSPF_RGB332)
   1.285 +    format = DSPF_RGB16;
   1.286 +
   1.287 +  if (DFBToSDLPixelFormat (format, vformat))
   1.288      {
   1.289        SDL_SetError ("Unsupported pixelformat");
   1.290 -      layer->Release (layer);
   1.291 -      dfb->Release (dfb);
   1.292 -      return -1;
   1.293 +      goto error;
   1.294      }
   1.295  
   1.296    /* Enumerate the available fullscreen modes */
   1.297 -  for ( i=0; i<NUM_MODELISTS; ++i )
   1.298 -    enumlists[i] = NULL;
   1.299 -
   1.300    ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this);
   1.301    if (ret)
   1.302      {
   1.303        SetDirectFBerror ("dfb->EnumVideoModes", ret);
   1.304 -      layer->Release (layer);
   1.305 -      dfb->Release (dfb);
   1.306 -      return(-1);
   1.307 +      goto error;
   1.308      }
   1.309 -  for ( i=0; i<NUM_MODELISTS; ++i )
   1.310 +
   1.311 +  HIDDEN->modelist = calloc (HIDDEN->nummodes + 1, sizeof(SDL_Rect *));
   1.312 +  if (!HIDDEN->modelist)
   1.313      {
   1.314 -      struct DirectFBEnumRect *rect;
   1.315 -      HIDDEN->SDL_modelist[i] = (SDL_Rect **) malloc
   1.316 -        ((HIDDEN->SDL_nummodes[i]+1)*sizeof(SDL_Rect *));
   1.317 -      if ( HIDDEN->SDL_modelist[i] == NULL )
   1.318 -        {
   1.319 -          SDL_OutOfMemory();
   1.320 -          return(-1);
   1.321 -        }
   1.322 -      for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next )
   1.323 -        {
   1.324 -          HIDDEN->SDL_modelist[i][j]=(SDL_Rect *)rect;
   1.325 -        }
   1.326 -      HIDDEN->SDL_modelist[i][j] = NULL;
   1.327 +      SDL_OutOfMemory();
   1.328 +      goto error;
   1.329      }
   1.330  
   1.331 +  for (i = 0, rect = enumlist; rect; ++i, rect = rect->next )
   1.332 +    {
   1.333 +      HIDDEN->modelist[i] = &rect->r;
   1.334 +    }
   1.335 +
   1.336 +  HIDDEN->modelist[i] = NULL;
   1.337 +
   1.338 +
   1.339    /* Query card capabilities to get the video memory size */
   1.340    dfb->GetCardCapabilities (dfb, &caps);
   1.341  
   1.342 @@ -394,15 +464,27 @@
   1.343    HIDDEN->initialized = 1;
   1.344    HIDDEN->dfb         = dfb;
   1.345    HIDDEN->layer       = layer;
   1.346 -  HIDDEN->eventbuffer = eventbuffer;
   1.347 +  HIDDEN->eventbuffer = events;
   1.348  
   1.349    return 0;
   1.350 +
   1.351 + error:
   1.352 +  if (events)
   1.353 +    events->Release (events);
   1.354 +  
   1.355 +  if (layer)
   1.356 +    layer->Release (layer);
   1.357 +
   1.358 +  if (dfb)
   1.359 +    dfb->Release (dfb);
   1.360 +
   1.361 +  return -1;
   1.362  }
   1.363  
   1.364  static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
   1.365  {
   1.366    if (flags & SDL_FULLSCREEN)
   1.367 -    return HIDDEN->SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1];
   1.368 +    return HIDDEN->modelist;
   1.369    else
   1.370      if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN)
   1.371        return (SDL_Rect**) -1;
   1.372 @@ -410,7 +492,7 @@
   1.373    return NULL;
   1.374  }
   1.375  
   1.376 -SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
   1.377 +static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
   1.378  {
   1.379    DFBResult             ret;
   1.380    DFBSurfaceDescription dsc;
   1.381 @@ -430,13 +512,12 @@
   1.382    else if (!current->hwdata)
   1.383      {
   1.384        /* Allocate the hardware acceleration data */
   1.385 -      current->hwdata = (struct private_hwdata *) malloc (sizeof(*current->hwdata));
   1.386 +      current->hwdata = (struct private_hwdata *) calloc (1, sizeof(*current->hwdata));
   1.387        if (!current->hwdata)
   1.388          {
   1.389            SDL_OutOfMemory();
   1.390            return NULL;
   1.391  	}
   1.392 -      memset (current->hwdata, 0, sizeof(*current->hwdata));
   1.393      }
   1.394  
   1.395    /* Set cooperative level depending on flag SDL_FULLSCREEN */
   1.396 @@ -471,8 +552,9 @@
   1.397      }
   1.398  
   1.399    /* Create primary surface */
   1.400 -  dsc.flags = DSDESC_CAPS;
   1.401 -  dsc.caps  = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
   1.402 +  dsc.flags       = DSDESC_CAPS | DSDESC_PIXELFORMAT;
   1.403 +  dsc.caps        = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
   1.404 +  dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer);
   1.405  
   1.406    ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface);
   1.407    if (ret && (flags & SDL_DOUBLEBUF))
   1.408 @@ -524,7 +606,7 @@
   1.409    dsc.flags  = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   1.410    dsc.width  = surface->w;
   1.411    dsc.height = surface->h;
   1.412 -  dsc.caps   = surface->flags & SDL_DOUBLEBUF ? DSCAPS_FLIPPING : 0;
   1.413 +  dsc.caps   = (surface->flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0;
   1.414  
   1.415    /* find the right pixelformat */
   1.416    dsc.pixelformat = SDLToDFBPixelFormat (surface->format);
   1.417 @@ -532,7 +614,7 @@
   1.418      return -1;
   1.419  
   1.420    /* Allocate the hardware acceleration data */
   1.421 -  surface->hwdata = (struct private_hwdata *) malloc (sizeof(*surface->hwdata));
   1.422 +  surface->hwdata = (struct private_hwdata *) calloc (1, sizeof(*surface->hwdata));
   1.423    if (surface->hwdata == NULL)
   1.424      {
   1.425        SDL_OutOfMemory();
   1.426 @@ -581,21 +663,12 @@
   1.427  static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
   1.428                                  SDL_Surface *dst, SDL_Rect *dstrect)
   1.429  {
   1.430 -  DFBRectangle             sr, dr;
   1.431 -  IDirectFBSurface        *surface;
   1.432 -  DFBSurfaceBlittingFlags  flags = DSBLIT_NOFX;
   1.433 +  DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
   1.434  
   1.435 -  sr.x = srcrect->x;
   1.436 -  sr.y = srcrect->y;
   1.437 -  sr.w = srcrect->w;
   1.438 -  sr.h = srcrect->h;
   1.439 +  DFBRectangle sr = { srcrect->x, srcrect->y, srcrect->w, srcrect->h };
   1.440 +  DFBRectangle dr = { dstrect->x, dstrect->y, dstrect->w, dstrect->h };
   1.441  
   1.442 -  dr.x = dstrect->x;
   1.443 -  dr.y = dstrect->y;
   1.444 -  dr.w = dstrect->w;
   1.445 -  dr.h = dstrect->h;
   1.446 -
   1.447 -  surface = dst->hwdata->surface;
   1.448 +  IDirectFBSurface *surface = dst->hwdata->surface;
   1.449  
   1.450    if (src->flags & SDL_SRCCOLORKEY)
   1.451      {
   1.452 @@ -737,29 +810,47 @@
   1.453  int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   1.454  {
   1.455    fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n");
   1.456 -  return 0;
   1.457 +  return -1;
   1.458  }
   1.459  	
   1.460  void DirectFB_VideoQuit(_THIS)
   1.461  {
   1.462 -  int i, j;
   1.463 +  struct DirectFBEnumRect *rect = enumlist;
   1.464 +
   1.465 +  if (HIDDEN->eventbuffer)
   1.466 +    {
   1.467 +      HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
   1.468 +      HIDDEN->eventbuffer = NULL;
   1.469 +    }
   1.470  
   1.471 -  HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
   1.472 -  HIDDEN->layer->Release (HIDDEN->layer);
   1.473 -  HIDDEN->dfb->Release (HIDDEN->dfb);
   1.474 +  if (HIDDEN->layer)
   1.475 +    {
   1.476 +      HIDDEN->layer->Release (HIDDEN->layer);
   1.477 +      HIDDEN->layer = NULL;
   1.478 +    }
   1.479  
   1.480 -  /* Free video mode lists */
   1.481 -  for ( i=0; i<NUM_MODELISTS; ++i )
   1.482 +  if (HIDDEN->dfb)
   1.483      {
   1.484 -      if ( HIDDEN->SDL_modelist[i] != NULL )
   1.485 -        {
   1.486 -          for ( j=0; HIDDEN->SDL_modelist[i][j]; ++j )
   1.487 -            free(HIDDEN->SDL_modelist[i][j]);
   1.488 -          free(HIDDEN->SDL_modelist[i]);
   1.489 -          HIDDEN->SDL_modelist[i] = NULL;
   1.490 -        }
   1.491 +      HIDDEN->dfb->Release (HIDDEN->dfb);
   1.492 +      HIDDEN->dfb = NULL;
   1.493 +    }
   1.494 +
   1.495 +  /* Free video mode list */
   1.496 +  if (HIDDEN->modelist)
   1.497 +    {
   1.498 +      free (HIDDEN->modelist);
   1.499 +      HIDDEN->modelist = NULL;
   1.500      }
   1.501  
   1.502 +  /* Free mode enumeration list */
   1.503 +  while (rect)
   1.504 +    {
   1.505 +      struct DirectFBEnumRect *next = rect->next;
   1.506 +      free (rect);
   1.507 +      rect = next;
   1.508 +    }
   1.509 +  enumlist = NULL;
   1.510 +
   1.511    HIDDEN->initialized = 0;
   1.512  }
   1.513