diff src/video/directfb/SDL_DirectFB_video.c @ 464:1c4be4a16410

Date: Fri, 23 Aug 2002 11:48:56 +0200 From: Denis Oliver Kropp Subject: Another patch this is another patch fixing key code mapping along with some other fixes and better mode handling.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 24 Aug 2002 15:29:06 +0000
parents f6ffac90895c
children 22581630aab7
line wrap: on
line diff
--- a/src/video/directfb/SDL_DirectFB_video.c	Wed Aug 21 04:16:31 2002 +0000
+++ b/src/video/directfb/SDL_DirectFB_video.c	Sat Aug 24 15:29:06 2002 +0000
@@ -29,6 +29,7 @@
 */
 
 #include <stdlib.h>
+#include <string.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -78,7 +79,7 @@
 	struct DirectFBEnumRect* next;
 };
 
-static struct DirectFBEnumRect *enumlists[NUM_MODELISTS];
+static struct DirectFBEnumRect *enumlist = NULL;
 
 
 /* DirectFB driver bootstrap functions */
@@ -150,6 +151,31 @@
   DirectFB_Available, DirectFB_CreateDevice
 };
 
+static DFBSurfacePixelFormat GetFormatForBpp (int bpp, IDirectFBDisplayLayer *layer)
+{
+  DFBDisplayLayerConfig dlc;
+  int                   bytes = (bpp + 7) / 8;
+
+  layer->GetConfiguration (layer, &dlc);
+
+  if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat))
+    return dlc.pixelformat;
+
+  switch (bytes)
+    {
+    case 1:
+      return DSPF_RGB332;
+    case 2:
+      return DSPF_RGB16;
+    case 3:
+      return DSPF_RGB24;
+    case 4:
+      return DSPF_RGB32;
+    }
+
+  return DSPF_UNKNOWN;
+}
+
 static DFBEnumerationResult EnumModesCallback (unsigned int  width,
                                                unsigned int  height,
                                                unsigned int  bpp,
@@ -158,30 +184,21 @@
   SDL_VideoDevice *this = (SDL_VideoDevice *)data;
   struct DirectFBEnumRect *enumrect;
 
-  switch (bpp)
+  HIDDEN->nummodes++;
+
+  enumrect = calloc(1, sizeof(struct DirectFBEnumRect));
+  if (!enumrect)
     {
-    case 8:
-    case 15:
-    case 16:
-    case 24:
-    case 32:
-      bpp /= 8; --bpp;
-      ++HIDDEN->SDL_nummodes[bpp];
-      enumrect = (struct DirectFBEnumRect*)malloc(sizeof(struct DirectFBEnumRect));
-      if ( !enumrect )
-        {
-          SDL_OutOfMemory();
-          return DFENUM_CANCEL;
-        }
-      enumrect->r.x = 0;
-      enumrect->r.y = 0;
-      enumrect->r.w = width;
-      enumrect->r.h = height;
-      enumrect->next = enumlists[bpp];
-      enumlists[bpp] = enumrect;
-      break;
+      SDL_OutOfMemory();
+      return DFENUM_CANCEL;
     }
 
+  enumrect->r.w  = width;
+  enumrect->r.h  = height;
+  enumrect->next = enumlist;
+
+  enumlist = enumrect;
+
   return DFENUM_OK;
 }
 
@@ -219,13 +236,20 @@
             return DSPF_RGB15;
           break;
           
+        case 8:
+          if (format->Rmask == 0xE0 &&
+              format->Gmask == 0x1C &&
+              format->Bmask == 0x03)
+            return DSPF_RGB332;
+          break;
+          
         case 24:
           if (format->Rmask == 0xFF0000 &&
               format->Gmask == 0x00FF00 &&
               format->Bmask == 0x0000FF)
             return DSPF_RGB24;
           break;
-          
+
         case 32:
           if (format->Rmask == 0xFF0000 &&
               format->Gmask == 0x00FF00 &&
@@ -243,6 +267,8 @@
     {
       switch (format->BitsPerPixel)
 	{
+        case 8:
+          return DSPF_RGB332;
 	case 15:
 	  return DSPF_RGB15;
 	case 16:
@@ -257,28 +283,67 @@
   return DSPF_UNKNOWN;
 }
 
+static const __u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff };
+static const __u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff };
+
+static SDL_Palette *GenerateRGB332Palette()
+{
+  int          i;
+  SDL_Palette *palette;
+  SDL_Color   *colors;
+
+  palette = calloc (1, sizeof(SDL_Palette));
+  if (!palette)
+    {
+      SDL_OutOfMemory();
+      return NULL;
+    }
+
+  colors = calloc (256, sizeof(SDL_Color));
+  if (!colors)
+    {
+      SDL_OutOfMemory();
+      return NULL;
+    }
+
+  for (i=0; i<256; i++)
+    {
+      colors[i].r = lookup3to8[ i >> 5 ];
+      colors[i].g = lookup3to8[ (i >> 2) & 7 ];
+      colors[i].g = lookup2to8[ i & 3 ];
+    }
+
+  palette->ncolors = 256;
+  palette->colors  = colors;
+
+  return palette;
+}
+
 static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat, SDL_PixelFormat *format)
 {
-  format->BitsPerPixel = 0;
   format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
+  format->BitsPerPixel = format->BytesPerPixel = 0;
 
   switch (pixelformat)
     {
     case DSPF_A8:
       format->Amask = 0x000000FF;
       break;
+
     case DSPF_RGB15:
       format->Rmask = 0x00007C00;
       format->Gmask = 0x000003E0;
       format->Bmask = 0x0000001F;
       break;
+
     case DSPF_RGB16:
       format->Rmask = 0x0000F800;
       format->Gmask = 0x000007E0;
       format->Bmask = 0x0000001F;
       break;
+
     case DSPF_ARGB:
-      format->Amask = 0xFF000000;
+      format->Amask = 0; /* apps don't seem to like that:  0xFF000000; */
       /* fall through */
     case DSPF_RGB24:
     case DSPF_RGB32:
@@ -286,11 +351,21 @@
       format->Gmask = 0x0000FF00;
       format->Bmask = 0x000000FF;
       break;
+
+    case DSPF_RGB332:
+      format->Rmask = 0x000000E0;
+      format->Gmask = 0x0000001C;
+      format->Bmask = 0x00000003;
+
+      format->palette = GenerateRGB332Palette();
+      break;
+
     default:
       return -1;
     }
 
-  format->BitsPerPixel = DFB_BITS_PER_PIXEL(pixelformat);
+  format->BitsPerPixel  = DFB_BYTES_PER_PIXEL(pixelformat) * 8;
+  format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat);
 
   return 0;
 }
@@ -298,44 +373,43 @@
 
 int DirectFB_VideoInit(_THIS, SDL_PixelFormat *vformat)
 {
-  int                    i, j;
-  DFBResult              ret;
-  IDirectFB             *dfb;
-  DFBCardCapabilities    caps;
-  IDirectFBDisplayLayer *layer;
-  DFBDisplayLayerConfig  dlc;
-  IDirectFBEventBuffer  *eventbuffer;
+  int                      i;
+  DFBResult                ret;
+  DFBCardCapabilities      caps;
+  DFBDisplayLayerConfig    dlc;
+  DFBSurfacePixelFormat    format;
+  struct DirectFBEnumRect *rect;
+  IDirectFB               *dfb    = NULL;
+  IDirectFBDisplayLayer   *layer  = NULL;
+  IDirectFBEventBuffer    *events = NULL;
 
 
   ret = DirectFBInit (NULL, NULL);
   if (ret)
     {
       SetDirectFBerror ("DirectFBInit", ret);
-      return -1;
+      goto error;
     }
 
   ret = DirectFBCreate (&dfb);
   if (ret)
     {
       SetDirectFBerror ("DirectFBCreate", ret);
-      return -1;
+      goto error;
     }
 
   ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer);
   if (ret)
     {
       SetDirectFBerror ("dfb->GetDisplayLayer", ret);
-      dfb->Release (dfb);
-      return -1;
+      goto error;
     }
 
-  ret = dfb->CreateEventBuffer (dfb, DICAPS_ALL, &eventbuffer);
+  ret = dfb->CreateEventBuffer (dfb, DICAPS_ALL, &events);
   if (ret)
     {
       SetDirectFBerror ("dfb->CreateEventBuffer", ret);
-      layer->Release (layer);
-      dfb->Release (dfb);
-      return -1;
+      goto error;
     }
   
   layer->EnableCursor (layer, 1);
@@ -343,43 +417,39 @@
   /* Query layer configuration to determine the current mode and pixelformat */
   layer->GetConfiguration (layer, &dlc);
 
-  if (DFBToSDLPixelFormat (dlc.pixelformat, vformat))
+  /* FIXME: Returning RGB332 as the default mode doesn't work (everything is black) */
+  if ((format = dlc.pixelformat) == DSPF_RGB332)
+    format = DSPF_RGB16;
+
+  if (DFBToSDLPixelFormat (format, vformat))
     {
       SDL_SetError ("Unsupported pixelformat");
-      layer->Release (layer);
-      dfb->Release (dfb);
-      return -1;
+      goto error;
     }
 
   /* Enumerate the available fullscreen modes */
-  for ( i=0; i<NUM_MODELISTS; ++i )
-    enumlists[i] = NULL;
-
   ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this);
   if (ret)
     {
       SetDirectFBerror ("dfb->EnumVideoModes", ret);
-      layer->Release (layer);
-      dfb->Release (dfb);
-      return(-1);
+      goto error;
     }
-  for ( i=0; i<NUM_MODELISTS; ++i )
+
+  HIDDEN->modelist = calloc (HIDDEN->nummodes + 1, sizeof(SDL_Rect *));
+  if (!HIDDEN->modelist)
     {
-      struct DirectFBEnumRect *rect;
-      HIDDEN->SDL_modelist[i] = (SDL_Rect **) malloc
-        ((HIDDEN->SDL_nummodes[i]+1)*sizeof(SDL_Rect *));
-      if ( HIDDEN->SDL_modelist[i] == NULL )
-        {
-          SDL_OutOfMemory();
-          return(-1);
-        }
-      for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next )
-        {
-          HIDDEN->SDL_modelist[i][j]=(SDL_Rect *)rect;
-        }
-      HIDDEN->SDL_modelist[i][j] = NULL;
+      SDL_OutOfMemory();
+      goto error;
     }
 
+  for (i = 0, rect = enumlist; rect; ++i, rect = rect->next )
+    {
+      HIDDEN->modelist[i] = &rect->r;
+    }
+
+  HIDDEN->modelist[i] = NULL;
+
+
   /* Query card capabilities to get the video memory size */
   dfb->GetCardCapabilities (dfb, &caps);
 
@@ -394,15 +464,27 @@
   HIDDEN->initialized = 1;
   HIDDEN->dfb         = dfb;
   HIDDEN->layer       = layer;
-  HIDDEN->eventbuffer = eventbuffer;
+  HIDDEN->eventbuffer = events;
 
   return 0;
+
+ error:
+  if (events)
+    events->Release (events);
+  
+  if (layer)
+    layer->Release (layer);
+
+  if (dfb)
+    dfb->Release (dfb);
+
+  return -1;
 }
 
 static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
 {
   if (flags & SDL_FULLSCREEN)
-    return HIDDEN->SDL_modelist[((format->BitsPerPixel + 7) / 8) - 1];
+    return HIDDEN->modelist;
   else
     if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN)
       return (SDL_Rect**) -1;
@@ -410,7 +492,7 @@
   return NULL;
 }
 
-SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
+static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
 {
   DFBResult             ret;
   DFBSurfaceDescription dsc;
@@ -430,13 +512,12 @@
   else if (!current->hwdata)
     {
       /* Allocate the hardware acceleration data */
-      current->hwdata = (struct private_hwdata *) malloc (sizeof(*current->hwdata));
+      current->hwdata = (struct private_hwdata *) calloc (1, sizeof(*current->hwdata));
       if (!current->hwdata)
         {
           SDL_OutOfMemory();
           return NULL;
 	}
-      memset (current->hwdata, 0, sizeof(*current->hwdata));
     }
 
   /* Set cooperative level depending on flag SDL_FULLSCREEN */
@@ -471,8 +552,9 @@
     }
 
   /* Create primary surface */
-  dsc.flags = DSDESC_CAPS;
-  dsc.caps  = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
+  dsc.flags       = DSDESC_CAPS | DSDESC_PIXELFORMAT;
+  dsc.caps        = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
+  dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer);
 
   ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &current->hwdata->surface);
   if (ret && (flags & SDL_DOUBLEBUF))
@@ -524,7 +606,7 @@
   dsc.flags  = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   dsc.width  = surface->w;
   dsc.height = surface->h;
-  dsc.caps   = surface->flags & SDL_DOUBLEBUF ? DSCAPS_FLIPPING : 0;
+  dsc.caps   = (surface->flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0;
 
   /* find the right pixelformat */
   dsc.pixelformat = SDLToDFBPixelFormat (surface->format);
@@ -532,7 +614,7 @@
     return -1;
 
   /* Allocate the hardware acceleration data */
-  surface->hwdata = (struct private_hwdata *) malloc (sizeof(*surface->hwdata));
+  surface->hwdata = (struct private_hwdata *) calloc (1, sizeof(*surface->hwdata));
   if (surface->hwdata == NULL)
     {
       SDL_OutOfMemory();
@@ -581,21 +663,12 @@
 static int DirectFB_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
                                 SDL_Surface *dst, SDL_Rect *dstrect)
 {
-  DFBRectangle             sr, dr;
-  IDirectFBSurface        *surface;
-  DFBSurfaceBlittingFlags  flags = DSBLIT_NOFX;
+  DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
 
-  sr.x = srcrect->x;
-  sr.y = srcrect->y;
-  sr.w = srcrect->w;
-  sr.h = srcrect->h;
+  DFBRectangle sr = { srcrect->x, srcrect->y, srcrect->w, srcrect->h };
+  DFBRectangle dr = { dstrect->x, dstrect->y, dstrect->w, dstrect->h };
 
-  dr.x = dstrect->x;
-  dr.y = dstrect->y;
-  dr.w = dstrect->w;
-  dr.h = dstrect->h;
-
-  surface = dst->hwdata->surface;
+  IDirectFBSurface *surface = dst->hwdata->surface;
 
   if (src->flags & SDL_SRCCOLORKEY)
     {
@@ -737,29 +810,47 @@
 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
 {
   fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n");
-  return 0;
+  return -1;
 }
 	
 void DirectFB_VideoQuit(_THIS)
 {
-  int i, j;
+  struct DirectFBEnumRect *rect = enumlist;
+
+  if (HIDDEN->eventbuffer)
+    {
+      HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
+      HIDDEN->eventbuffer = NULL;
+    }
 
-  HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
-  HIDDEN->layer->Release (HIDDEN->layer);
-  HIDDEN->dfb->Release (HIDDEN->dfb);
+  if (HIDDEN->layer)
+    {
+      HIDDEN->layer->Release (HIDDEN->layer);
+      HIDDEN->layer = NULL;
+    }
 
-  /* Free video mode lists */
-  for ( i=0; i<NUM_MODELISTS; ++i )
+  if (HIDDEN->dfb)
     {
-      if ( HIDDEN->SDL_modelist[i] != NULL )
-        {
-          for ( j=0; HIDDEN->SDL_modelist[i][j]; ++j )
-            free(HIDDEN->SDL_modelist[i][j]);
-          free(HIDDEN->SDL_modelist[i]);
-          HIDDEN->SDL_modelist[i] = NULL;
-        }
+      HIDDEN->dfb->Release (HIDDEN->dfb);
+      HIDDEN->dfb = NULL;
+    }
+
+  /* Free video mode list */
+  if (HIDDEN->modelist)
+    {
+      free (HIDDEN->modelist);
+      HIDDEN->modelist = NULL;
     }
 
+  /* Free mode enumeration list */
+  while (rect)
+    {
+      struct DirectFBEnumRect *next = rect->next;
+      free (rect);
+      rect = next;
+    }
+  enumlist = NULL;
+
   HIDDEN->initialized = 0;
 }