changeset 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 bf7389310d27
children 25f475cd4981
files src/video/directfb/SDL_DirectFB_events.c src/video/directfb/SDL_DirectFB_video.c src/video/directfb/SDL_DirectFB_video.h
diffstat 3 files changed, 274 insertions(+), 184 deletions(-) [+]
line wrap: on
line diff
--- a/src/video/directfb/SDL_DirectFB_events.c	Wed Aug 21 04:16:31 2002 +0000
+++ b/src/video/directfb/SDL_DirectFB_events.c	Sat Aug 24 15:29:06 2002 +0000
@@ -100,88 +100,88 @@
   for (i=0; i<SDL_TABLESIZE(keymap); ++i)
     keymap[i] = SDLK_UNKNOWN;
 
-  keymap[DIKI_A] = SDLK_a;
-  keymap[DIKI_B] = SDLK_b;
-  keymap[DIKI_C] = SDLK_c;
-  keymap[DIKI_D] = SDLK_d;
-  keymap[DIKI_E] = SDLK_e;
-  keymap[DIKI_F] = SDLK_f;
-  keymap[DIKI_G] = SDLK_g;
-  keymap[DIKI_H] = SDLK_h;
-  keymap[DIKI_I] = SDLK_i;
-  keymap[DIKI_J] = SDLK_j;
-  keymap[DIKI_K] = SDLK_k;
-  keymap[DIKI_L] = SDLK_l;
-  keymap[DIKI_M] = SDLK_m;
-  keymap[DIKI_N] = SDLK_n;
-  keymap[DIKI_O] = SDLK_o;
-  keymap[DIKI_P] = SDLK_p;
-  keymap[DIKI_Q] = SDLK_q;
-  keymap[DIKI_R] = SDLK_r;
-  keymap[DIKI_S] = SDLK_s;
-  keymap[DIKI_T] = SDLK_t;
-  keymap[DIKI_U] = SDLK_u;
-  keymap[DIKI_V] = SDLK_v;
-  keymap[DIKI_W] = SDLK_w;
-  keymap[DIKI_X] = SDLK_x;
-  keymap[DIKI_Y] = SDLK_y;
-  keymap[DIKI_Z] = SDLK_z;
+  keymap[DIKI_A - DIKI_UNKNOWN] = SDLK_a;
+  keymap[DIKI_B - DIKI_UNKNOWN] = SDLK_b;
+  keymap[DIKI_C - DIKI_UNKNOWN] = SDLK_c;
+  keymap[DIKI_D - DIKI_UNKNOWN] = SDLK_d;
+  keymap[DIKI_E - DIKI_UNKNOWN] = SDLK_e;
+  keymap[DIKI_F - DIKI_UNKNOWN] = SDLK_f;
+  keymap[DIKI_G - DIKI_UNKNOWN] = SDLK_g;
+  keymap[DIKI_H - DIKI_UNKNOWN] = SDLK_h;
+  keymap[DIKI_I - DIKI_UNKNOWN] = SDLK_i;
+  keymap[DIKI_J - DIKI_UNKNOWN] = SDLK_j;
+  keymap[DIKI_K - DIKI_UNKNOWN] = SDLK_k;
+  keymap[DIKI_L - DIKI_UNKNOWN] = SDLK_l;
+  keymap[DIKI_M - DIKI_UNKNOWN] = SDLK_m;
+  keymap[DIKI_N - DIKI_UNKNOWN] = SDLK_n;
+  keymap[DIKI_O - DIKI_UNKNOWN] = SDLK_o;
+  keymap[DIKI_P - DIKI_UNKNOWN] = SDLK_p;
+  keymap[DIKI_Q - DIKI_UNKNOWN] = SDLK_q;
+  keymap[DIKI_R - DIKI_UNKNOWN] = SDLK_r;
+  keymap[DIKI_S - DIKI_UNKNOWN] = SDLK_s;
+  keymap[DIKI_T - DIKI_UNKNOWN] = SDLK_t;
+  keymap[DIKI_U - DIKI_UNKNOWN] = SDLK_u;
+  keymap[DIKI_V - DIKI_UNKNOWN] = SDLK_v;
+  keymap[DIKI_W - DIKI_UNKNOWN] = SDLK_w;
+  keymap[DIKI_X - DIKI_UNKNOWN] = SDLK_x;
+  keymap[DIKI_Y - DIKI_UNKNOWN] = SDLK_y;
+  keymap[DIKI_Z - DIKI_UNKNOWN] = SDLK_z;
   
-  keymap[DIKI_0] = SDLK_0;
-  keymap[DIKI_1] = SDLK_1;
-  keymap[DIKI_2] = SDLK_2;
-  keymap[DIKI_3] = SDLK_3;
-  keymap[DIKI_4] = SDLK_4;
-  keymap[DIKI_5] = SDLK_5;
-  keymap[DIKI_6] = SDLK_6;
-  keymap[DIKI_7] = SDLK_7;
-  keymap[DIKI_8] = SDLK_8;
-  keymap[DIKI_9] = SDLK_9;
+  keymap[DIKI_0 - DIKI_UNKNOWN] = SDLK_0;
+  keymap[DIKI_1 - DIKI_UNKNOWN] = SDLK_1;
+  keymap[DIKI_2 - DIKI_UNKNOWN] = SDLK_2;
+  keymap[DIKI_3 - DIKI_UNKNOWN] = SDLK_3;
+  keymap[DIKI_4 - DIKI_UNKNOWN] = SDLK_4;
+  keymap[DIKI_5 - DIKI_UNKNOWN] = SDLK_5;
+  keymap[DIKI_6 - DIKI_UNKNOWN] = SDLK_6;
+  keymap[DIKI_7 - DIKI_UNKNOWN] = SDLK_7;
+  keymap[DIKI_8 - DIKI_UNKNOWN] = SDLK_8;
+  keymap[DIKI_9 - DIKI_UNKNOWN] = SDLK_9;
   
-  keymap[DIKI_F1] = SDLK_F1;
-  keymap[DIKI_F2] = SDLK_F2;
-  keymap[DIKI_F3] = SDLK_F3;
-  keymap[DIKI_F4] = SDLK_F4;
-  keymap[DIKI_F5] = SDLK_F5;
-  keymap[DIKI_F6] = SDLK_F6;
-  keymap[DIKI_F7] = SDLK_F7;
-  keymap[DIKI_F8] = SDLK_F8;
-  keymap[DIKI_F9] = SDLK_F9;
-  keymap[DIKI_F10] = SDLK_F10;
-  keymap[DIKI_F11] = SDLK_F11;
-  keymap[DIKI_F12] = SDLK_F12;
+  keymap[DIKI_F1 - DIKI_UNKNOWN] = SDLK_F1;
+  keymap[DIKI_F2 - DIKI_UNKNOWN] = SDLK_F2;
+  keymap[DIKI_F3 - DIKI_UNKNOWN] = SDLK_F3;
+  keymap[DIKI_F4 - DIKI_UNKNOWN] = SDLK_F4;
+  keymap[DIKI_F5 - DIKI_UNKNOWN] = SDLK_F5;
+  keymap[DIKI_F6 - DIKI_UNKNOWN] = SDLK_F6;
+  keymap[DIKI_F7 - DIKI_UNKNOWN] = SDLK_F7;
+  keymap[DIKI_F8 - DIKI_UNKNOWN] = SDLK_F8;
+  keymap[DIKI_F9 - DIKI_UNKNOWN] = SDLK_F9;
+  keymap[DIKI_F10 - DIKI_UNKNOWN] = SDLK_F10;
+  keymap[DIKI_F11 - DIKI_UNKNOWN] = SDLK_F11;
+  keymap[DIKI_F12 - DIKI_UNKNOWN] = SDLK_F12;
   
-  keymap[DIKI_ESCAPE] = SDLK_ESCAPE;
-  keymap[DIKI_LEFT] = SDLK_LEFT;
-  keymap[DIKI_RIGHT] = SDLK_RIGHT;
-  keymap[DIKI_UP] = SDLK_UP;
-  keymap[DIKI_DOWN] = SDLK_DOWN;
-  keymap[DIKI_CONTROL_L] = SDLK_LCTRL;
-  keymap[DIKI_CONTROL_R] = SDLK_RCTRL;
-  keymap[DIKI_SHIFT_L] = SDLK_LSHIFT;
-  keymap[DIKI_SHIFT_R] = SDLK_RSHIFT;
-  keymap[DIKI_ALT_L] = SDLK_LALT;
-  keymap[DIKI_ALTGR] = SDLK_RALT;
-  keymap[DIKI_TAB] = SDLK_TAB;
-  keymap[DIKI_ENTER] = SDLK_RETURN;
-  keymap[DIKI_SPACE] = SDLK_SPACE;
-  keymap[DIKI_BACKSPACE] = SDLK_BACKSPACE;
-  keymap[DIKI_INSERT] = SDLK_INSERT;
-  keymap[DIKI_DELETE] = SDLK_DELETE;
-  keymap[DIKI_HOME] = SDLK_HOME;
-  keymap[DIKI_END] = SDLK_END;
-  keymap[DIKI_PAGE_UP] = SDLK_PAGEUP;
-  keymap[DIKI_PAGE_DOWN] = SDLK_PAGEDOWN;
-  keymap[DIKI_CAPS_LOCK] = SDLK_CAPSLOCK;
-  keymap[DIKI_NUM_LOCK] = SDLK_NUMLOCK;
-  keymap[DIKI_SCROLL_LOCK] = SDLK_SCROLLOCK;
-  keymap[DIKI_PRINT] = SDLK_PRINT;
-  keymap[DIKI_PAUSE] = SDLK_PAUSE;
-  keymap[DIKI_KP_DIV] = SDLK_KP_DIVIDE;
-  keymap[DIKI_KP_MULT] = SDLK_KP_MULTIPLY;
-  keymap[DIKI_KP_MINUS] = SDLK_KP_MINUS;
-  keymap[DIKI_KP_PLUS] = SDLK_KP_PLUS;
-  keymap[DIKI_KP_ENTER] = SDLK_KP_ENTER;
+  keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDLK_ESCAPE;
+  keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDLK_LEFT;
+  keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDLK_RIGHT;
+  keymap[DIKI_UP - DIKI_UNKNOWN] = SDLK_UP;
+  keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDLK_DOWN;
+  keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDLK_LCTRL;
+  keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDLK_RCTRL;
+  keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDLK_LSHIFT;
+  keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDLK_RSHIFT;
+  keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDLK_LALT;
+  keymap[DIKI_ALTGR - DIKI_UNKNOWN] = SDLK_RALT;
+  keymap[DIKI_TAB - DIKI_UNKNOWN] = SDLK_TAB;
+  keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDLK_RETURN;
+  keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDLK_SPACE;
+  keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDLK_BACKSPACE;
+  keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDLK_INSERT;
+  keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDLK_DELETE;
+  keymap[DIKI_HOME - DIKI_UNKNOWN] = SDLK_HOME;
+  keymap[DIKI_END - DIKI_UNKNOWN] = SDLK_END;
+  keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDLK_PAGEUP;
+  keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDLK_PAGEDOWN;
+  keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDLK_CAPSLOCK;
+  keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDLK_NUMLOCK;
+  keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDLK_SCROLLOCK;
+  keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDLK_PRINT;
+  keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDLK_PAUSE;
+  keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDLK_KP_DIVIDE;
+  keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDLK_KP_MULTIPLY;
+  keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDLK_KP_MINUS;
+  keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDLK_KP_PLUS;
+  keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDLK_KP_ENTER;
 }
 
 
@@ -195,7 +195,7 @@
   if (ev->key_symbol > 0 && ev->key_symbol < 128)
     keysym->sym = ev->key_symbol;
   else
-    keysym->sym = keymap[ev->key_id];
+    keysym->sym = keymap[ev->key_id - DIKI_UNKNOWN];
 
   return keysym;
 }
--- 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;
 }
 
--- a/src/video/directfb/SDL_DirectFB_video.h	Wed Aug 21 04:16:31 2002 +0000
+++ b/src/video/directfb/SDL_DirectFB_video.h	Sat Aug 24 15:29:06 2002 +0000
@@ -45,9 +45,8 @@
   IDirectFBDisplayLayer *layer;
   IDirectFBEventBuffer  *eventbuffer;
 
-#define NUM_MODELISTS	4		/* 8, 16, 24, and 32 bits-per-pixel */
-  int SDL_nummodes[NUM_MODELISTS];
-  SDL_Rect **SDL_modelist[NUM_MODELISTS];
+  int nummodes;
+  SDL_Rect **modelist;
 };
 
 #define HIDDEN (this->hidden)