changeset 821:30168104389f

Date: Sat, 14 Feb 2004 14:52:40 +0200 From: "Mike Gorchak" Subject: Batch of the QNX6 fixes for the SDL 1. Updated readme.QNX 2. Fixed crashes during intensive window updating under fast machines (got over 200 rectangles for update). 3. Fixed double-buffered fullscreen modes, now it works as needed. 4. Fixed Photon detection algorithm. 5. Fixed HWSURFACE update function. 6. Added SDL_PHOTON_FULLSCREEN_REFRESH environment variable support for control refresh rates under Photon. 7. Added 640x400 fullscreen mode emulation via 640x480 (if videodriver not supports original 640x400 mode of course) shifted by 40 vertical pixels from begin, to center it. It's needed for some old DOS games which ran in doubled 320x200 mode. 8. Added available video ram amount support. 8. Added hardware surface allocation/deallocation support if current videomode and videodriver supports it. 9. Added hardware filling support. 10. Added hardware blits support (simple and colorkeyed). And I've added to testvidinfo test color-keyed blits benchmark (maybe need to add alpha blits benchmark too ?). Currently Photon not supporting any alpha hardware blittings (all drivers lack of alpha blitting code support, only software alpha blitting exist in photon, which is hundreds times slowest than the SDL's one). So I've not added the alpha support. I suppose new QNX 6.3 will have the hardware alpha support, so when it will be done, I'll add alpha support.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 14 Feb 2004 20:22:21 +0000
parents 0b9b4bf3c1e7
children abb915adb1b0
files README.QNX src/video/photon/SDL_ph_events.c src/video/photon/SDL_ph_events_c.h src/video/photon/SDL_ph_image.c src/video/photon/SDL_ph_image_c.h src/video/photon/SDL_ph_modes.c src/video/photon/SDL_ph_video.c src/video/photon/SDL_ph_video.h test/testvidinfo.c
diffstat 9 files changed, 768 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/README.QNX	Sat Feb 14 10:12:27 2004 +0000
+++ b/README.QNX	Sat Feb 14 20:22:21 2004 +0000
@@ -1,5 +1,5 @@
 README by Mike Gorchak <mike@malva.ua>, <lestat@i.com.ua>
-Last changed at 30 Sep 2003.
+Last changed at 14 Feb 2004.
 
 ======================================================================
 Table of Contents:
@@ -13,7 +13,7 @@
 7. Environment variables.
 
 ======================================================================
-OpenGL:
+1. OpenGL:
 
     OpenGL works well and is stable, but fullscreen mode has not  been
 heavily tested yet.
@@ -34,7 +34,7 @@
 PHOGL_ATTRIB_FORCE_HW or PHOGL_ATTRIB_FAVOR_HW.
 
 ======================================================================
-Wheel and multi-button mouses:
+2. Wheel and multi-button mouses:
 
     Photon emits  keyboard  events (key up and down)  when  the  mouse
 wheel is moved. The key_scan field appears valid, and it contains zero.
@@ -54,14 +54,14 @@
    front, but works not with any window, looks like bug-o-feature :).
 
 ======================================================================
-CDROM handling issues:
+3. CDROM handling issues:
 
     Access to CDROM can only be  provided  with  'root'  privileges. I
 can't do anything about that, /dev/cd0 has brw------- permissions  and
 root:root rights.
 
 ======================================================================
-Hardware video overlays:
+4. Hardware video overlays:
 
     Overlays can flicker  during  window  movement,  resizing, etc. It
 happens because the photon driver updates the real window contents be-
@@ -82,20 +82,20 @@
 negative coordinates.
 
 =======================================================================
-Shared library building:
+5. Shared library building:
 
     A shared library can be built, but before running  the  autogen.sh
 script you must manually delete the libtool.m4 stuff from the acinclu-
 de.m4 file (it comes after the ESD detection code up to the end of the
-file), because the libtool stuff in the acinclude.m4 file is very  old
-in SDL distribution before the version 1.2.7 and doesn't know anything
+file), because the libtool stuff in the acinclude.m4 file was very old
+in SDL distribution before the version 1.2.7 and doesn't knew anything
 about QNX. SDL 1.2.7 distribution contain  the  new libtool.m4 script,
 but anyway  it  is  broken :), Just  remove  it, then  run "libtoolize
 --force --copy",  delete the file aclocal.m4 and after  that  run  the
 autogen.sh script.
 
 ======================================================================
-Some building issues:
+6. Some building issues:
 
     Feel free to not use the --disable-shared configure option if you'
 ve read the above comment about 'Shared  library  building'. Otherwise
@@ -123,11 +123,16 @@
                  --prefix=/usr --without-x
 
 ======================================================================
-Environment variables:
+7. Environment variables:
 
     Please note that the photon driver  is  sensible to the  following
 environmental variables:
 
+ * SDL_PHOTON_FULLSCREEN_REFRESH - this environment variable controls
+the refresh rate in all fullscreen modes. Be carefull !!! Photon drivers
+usually do not checking the maximum refresh rate, which video adapter or
+monitor supports.
+
  * SDL_VIDEO_WINDOW_POS - can be  set in the "X,Y" format.  If X and Y
 coordinates are bigger than the current desktop resolution, then  win-
 dow positioning across  virtual  consoles is activated. If X and Y are
--- a/src/video/photon/SDL_ph_events.c	Sat Feb 14 10:12:27 2004 +0000
+++ b/src/video/photon/SDL_ph_events.c	Sat Feb 14 20:22:21 2004 +0000
@@ -47,17 +47,13 @@
 #include "SDL_ph_events_c.h"
 #include "SDL_phyuv_c.h"
 
-
-
 /* The translation tables from a photon keysym to a SDL keysym */
 static SDLKey ODD_keymap[256];
 static SDLKey MISC_keymap[0xFF + 1];
 SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym);
 
 /* Check to see if this is a repeated key.
-   (idea shamelessly lifted from GII -- thanks guys! :)
- */
-
+   (idea shamelessly lifted from GII -- thanks guys! :) */
 static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent)
 {
     PhRect_t *rect = PhGetRects( winEvent );
@@ -117,8 +113,6 @@
     return (mouse_button);
 }
 
-//                   void* PtAppCreateContext();
-
 static int ph_DispatchEvent(_THIS)
 {
     int posted;
@@ -127,7 +121,7 @@
     PhKeyEvent_t* keyEvent;
     PhWindowEvent_t* winEvent;
     int i, buttons;
-    SDL_Rect sdlrects[50]; 
+    SDL_Rect sdlrects[PH_SDL_MAX_RECTS];
 	
     posted = 0;
 	
@@ -217,12 +211,12 @@
                 set_motion_sensitivity(this, -1);
                 posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
             }
-            /* quit request */
+            /* request quit */
             else if (winEvent->event_f==Ph_WM_CLOSE)
             {
                 posted = SDL_PrivateQuit();
             }
-            /* hide/unhide request */
+            /* request hide/unhide */
             else if (winEvent->event_f==Ph_WM_HIDE)
             {
                 if (currently_hided)
@@ -287,9 +281,16 @@
         {
             if (event->num_rects!=0)
             {
+                int numrects;
+
                 if (SDL_VideoSurface)
                 {
                     rect = PhGetRects(event);
+                    if (event->num_rects>PH_SDL_MAX_RECTS)
+                    {
+                       /* sorry, buffers underrun, we'll update only first PH_SDL_MAX_RECTS rects */
+                       numrects=PH_SDL_MAX_RECTS;
+                    }
 
                     for(i=0; i<event->num_rects; i++)
                     {
@@ -368,6 +369,32 @@
         
         case Ph_EV_INFO:
         {
+           if (event->subtype==Ph_OFFSCREEN_INVALID)
+           {
+              unsigned long* EvInfoData;
+
+              EvInfoData=(unsigned long*)PhGetData(event);
+
+              switch (*EvInfoData)
+              {
+                 case Pg_VIDEO_MODE_SWITCHED:
+                      {
+                      }
+                      break;
+                 case Pg_ENTERED_DIRECT:
+                      {
+                      }
+                      break;
+                 case Pg_EXITED_DIRECT:
+                      {
+                      }
+                      break;
+                 case Pg_DRIVER_STARTED:
+                      {
+                      }
+                      break;
+              }
+           }
         }
         break;
     }
@@ -387,10 +414,9 @@
         {
             case Ph_EVENT_MSG:
                  return 1;
-                 break;
             case -1:
-                 perror("ph_Pending(): PhEventNext failed");
-                 break;
+                 SDL_SetError("ph_Pending(): PhEventNext failed.\n");
+                 return 0;
             default:
                  return 0;
         }
--- a/src/video/photon/SDL_ph_events_c.h	Sat Feb 14 10:12:27 2004 +0000
+++ b/src/video/photon/SDL_ph_events_c.h	Sat Feb 14 20:22:21 2004 +0000
@@ -30,7 +30,9 @@
 
 #include "SDL_ph_video.h"
 
-#define EVENT_SIZE sizeof(PhEvent_t) + 1000
+#define PH_SDL_MAX_RECTS 256
+#define PH_EVENT_SAFETY_POOL 512
+#define EVENT_SIZE (sizeof(PhEvent_t) + 1000 + PH_EVENT_SAFETY_POOL)
 
 /* Functions to be exported */
 extern void ph_InitOSKeymap(_THIS);
--- a/src/video/photon/SDL_ph_image.c	Sat Feb 14 10:12:27 2004 +0000
+++ b/src/video/photon/SDL_ph_image.c	Sat Feb 14 20:22:21 2004 +0000
@@ -164,7 +164,7 @@
 
     screen->pitch = OCImage.offscreen_context->pitch;
 
-    OCImage.dc_ptr = (unsigned char *) PdGetOffscreenContextPtr(OCImage.offscreen_context);
+    OCImage.dc_ptr = (unsigned char *)PdGetOffscreenContextPtr(OCImage.offscreen_context);
 
     if (OCImage.dc_ptr == NULL)
     {
@@ -212,7 +212,7 @@
     
     if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
     {
-        OCImage.offscreen_backcontext = PdDupOffscreenContext(OCImage.offscreen_context, Pg_OSC_CRTC_SAFE | Pg_OSC_MEM_PAGE_ALIGN);
+        OCImage.offscreen_backcontext = PdDupOffscreenContext(OCImage.offscreen_context, Pg_OSC_MEM_PAGE_ALIGN | Pg_OSC_CRTC_SAFE);
         if (OCImage.offscreen_backcontext == NULL)
         {
             SDL_SetError("ph_SetupFullScreenImage(): PdCreateOffscreenContext(back) function failed !\n");
@@ -240,15 +240,32 @@
     }
 
     /* wait for the hardware */
+    PgFlush();
     PgWaitHWIdle();
 
     if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
     {
-        OCImage.current = 1;
-        PhDCSetCurrent(OCImage.offscreen_backcontext);
-        screen->pitch = OCImage.offscreen_backcontext->pitch;
-        screen->pixels = OCImage.FrameData1;
-        PgSwapDisplay(OCImage.offscreen_context, 0);
+        OCImage.current = 0;
+        PhDCSetCurrent(OCImage.offscreen_context);
+        screen->pitch = OCImage.offscreen_context->pitch;
+        screen->pixels = OCImage.FrameData0;
+        
+        /* emulate 640x400 videomode */
+        if (videomode_emulatemode==1)
+        {
+           int i;
+           
+           for (i=0; i<40; i++)
+           {
+              memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
+           }
+           for (i=440; i<480; i++)
+           {
+              memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
+           }
+           screen->pixels+=screen->pitch*40;
+        }
+        PgSwapDisplay(OCImage.offscreen_backcontext, 0);
     }
     else
     {
@@ -256,11 +273,29 @@
         PhDCSetCurrent(OCImage.offscreen_context);
         screen->pitch = OCImage.offscreen_context->pitch;
         screen->pixels = OCImage.FrameData0;
+
+        /* emulate 640x400 videomode */
+        if (videomode_emulatemode==1)
+        {
+           int i;
+           
+           for (i=0; i<40; i++)
+           {
+              memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
+           }
+           for (i=440; i<480; i++)
+           {
+              memset(screen->pixels+screen->pitch*i, 0x00, screen->pitch);
+           }
+           screen->pixels+=screen->pitch*40;
+        }
     }
 
     this->UpdateRects = ph_OCDCUpdate;
 
+    /* wait for the hardware */
     PgFlush();
+    PgWaitHWIdle();
 
     return 0;
 }
@@ -427,73 +462,495 @@
     }
 }
 
+int ph_UpdateHWInfo(_THIS)
+{
+    PgVideoModeInfo_t vmode;
+    PgHWCaps_t hwcaps;
+
+    /* Update video ram amount */
+    if (PgGetGraphicsHWCaps(&hwcaps) < 0)
+    {
+        SDL_SetError("ph_UpdateHWInfo(): GetGraphicsHWCaps() function failed !\n");
+        return -1;
+    }
+    this->info.video_mem=hwcaps.currently_available_video_ram/1024;
+
+    /* obtain current mode capabilities */
+    if (PgGetVideoModeInfo(hwcaps.current_video_mode, &vmode) < 0)
+    {
+        SDL_SetError("ph_UpdateHWInfo(): GetVideoModeInfo() function failed !\n");
+        return -1;
+    }
+
+    this->info.blit_hw = 1;
+
+    if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_ALPHA_BLEND) == PgVM_MODE_CAP2_ALPHA_BLEND)
+    {
+       this->info.blit_hw_A = 1;
+    }
+    else
+    {
+       this->info.blit_hw_A = 0;
+    }
+    
+    if ((vmode.mode_capabilities2 & PgVM_MODE_CAP2_CHROMA) == PgVM_MODE_CAP2_CHROMA)
+    {
+       this->info.blit_hw_CC = 1;
+    }
+    else
+    {
+       this->info.blit_hw_CC = 0;
+    }
+    
+    return 0;
+}
+
 int ph_SetupUpdateFunction(_THIS, SDL_Surface* screen, Uint32 flags)
 {
+    int setupresult=-1;
+
     ph_DestroyImage(this, screen);
     
 #ifdef HAVE_OPENGL
     if ((flags & SDL_OPENGL)==SDL_OPENGL)
     {
-        return ph_SetupOpenGLImage(this, screen);
+        setupresult=ph_SetupOpenGLImage(this, screen);
+    }
+    else
+    {
+#endif /* HAVE_OPENGL */
+       if ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN)
+       {
+           setupresult=ph_SetupFullScreenImage(this, screen);
+       }
+       else
+       {
+          if ((flags & SDL_HWSURFACE)==SDL_HWSURFACE)
+          {
+              setupresult=ph_SetupOCImage(this, screen);
+          }
+          else
+          {
+              setupresult=ph_SetupImage(this, screen);
+          }
+       }
+#ifdef HAVE_OPENGL
     }
 #endif /* HAVE_OPENGL */
-    if ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN)
+    if (setupresult!=-1)
     {
-        return ph_SetupFullScreenImage(this, screen);
+       ph_UpdateHWInfo(this);
     }
-    if ((flags & SDL_HWSURFACE)==SDL_HWSURFACE)
-    {
-        return ph_SetupOCImage(this, screen);
-    }
-
-    return ph_SetupImage(this, screen);
+    
+    return setupresult;
 }
 
 int ph_AllocHWSurface(_THIS, SDL_Surface* surface)
 {
-    return(-1);
+    PgHWCaps_t hwcaps;
+
+    if (surface->hwdata!=NULL)
+    {
+       SDL_SetError("ph_AllocHWSurface(): hwdata already exists!\n");
+       return -1;
+    }
+    surface->hwdata=malloc(sizeof(struct private_hwdata));
+    memset(surface->hwdata, 0x00, sizeof(struct private_hwdata));
+    surface->hwdata->offscreenctx=PdCreateOffscreenContext(0, surface->w, surface->h, Pg_OSC_MEM_PAGE_ALIGN);
+    if (surface->hwdata->offscreenctx == NULL)
+    {
+        SDL_SetError("ph_AllocHWSurface(): PdCreateOffscreenContext() function failed !\n");
+        return -1;
+    }
+    surface->pixels=PdGetOffscreenContextPtr(surface->hwdata->offscreenctx);
+    if (surface->pixels==NULL)
+    {
+        PhDCRelease(surface->hwdata->offscreenctx);
+        SDL_SetError("ph_AllocHWSurface(): PdGetOffscreenContextPtr() function failed !\n");
+        return -1;
+    }
+    surface->pitch=surface->hwdata->offscreenctx->pitch;
+    surface->flags|=SDL_HWSURFACE;
+    surface->flags|=SDL_PREALLOC;
+    
+#if 0 /* FIXME */
+    /* create simple offscreen lock */
+    surface->hwdata->crlockparam.flags=0;
+    if (PdCreateOffscreenLock(surface->hwdata->offscreenctx, &surface->hwdata->crlockparam)!=EOK)
+    {
+        PhDCRelease(surface->hwdata->offscreenctx);
+        SDL_SetError("ph_AllocHWSurface(): Can't create offscreen lock !\n");
+        return -1;
+    }
+#endif /* 0 */
+
+    /* Update video ram amount */
+    if (PgGetGraphicsHWCaps(&hwcaps) < 0)
+    {
+        PdDestroyOffscreenLock(surface->hwdata->offscreenctx);
+        PhDCRelease(surface->hwdata->offscreenctx);
+        SDL_SetError("ph_AllocHWSurface(): GetGraphicsHWCaps() function failed !\n");
+        return -1;
+    }
+    this->info.video_mem=hwcaps.currently_available_video_ram/1024;
+
+    return 0;
 }
 
 void ph_FreeHWSurface(_THIS, SDL_Surface* surface)
 {
+    PgHWCaps_t hwcaps;
+
+    if (surface->hwdata==NULL)
+    {
+       SDL_SetError("ph_FreeHWSurface(): no hwdata!\n");
+       return;
+    }
+    if (surface->hwdata->offscreenctx == NULL)
+    {
+       SDL_SetError("ph_FreeHWSurface(): no offscreen context to delete!\n");
+       return;
+    }
+
+#if 0 /* FIXME */
+    /* unlock the offscreen context if it has been locked before destroy it */
+    if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED)
+    {
+       PdUnlockOffscreen(surface->hwdata->offscreenctx);
+    }
+
+    PdDestroyOffscreenLock(surface->hwdata->offscreenctx);
+#endif /* 0 */
+
+    PhDCRelease(surface->hwdata->offscreenctx);
+    
+    free(surface->hwdata);
+    surface->hwdata=NULL;
+
+    /* Update video ram amount */
+    if (PgGetGraphicsHWCaps(&hwcaps) < 0)
+    {
+        SDL_SetError("ph_FreeHWSurface(): GetGraphicsHWCaps() function failed !\n");
+        return;
+    }
+    this->info.video_mem=hwcaps.currently_available_video_ram/1024;
+
     return;
 }
 
+int ph_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
+{
+   if ((src->hwdata==NULL) && (src != this->screen))
+   {
+      SDL_SetError("ph_CheckHWBlit(): Source surface haven't hardware specific data.\n");
+      src->flags&=~SDL_HWACCEL;
+      return -1;
+   }
+   if ((src->flags & SDL_HWSURFACE) != SDL_HWSURFACE)
+   {
+      SDL_SetError("ph_CheckHWBlit(): Source surface isn't a hardware surface.\n");
+      src->flags&=~SDL_HWACCEL;
+      return -1;
+   }
+
+   if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
+   {
+       if (this->info.blit_hw_CC!=1)
+       {
+           src->flags&=~SDL_HWACCEL;
+           src->map->hw_blit=NULL;
+           return -1;
+       }
+   }
+
+   if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA)
+   {
+       if (this->info.blit_hw_A!=1)
+       {
+           src->flags&=~SDL_HWACCEL;
+           src->map->hw_blit=NULL;
+           return -1;
+       }
+   }
+
+   src->flags|=SDL_HWACCEL;
+   src->map->hw_blit = ph_HWAccelBlit;
+
+   return 1;
+}
+
+PgColor_t ph_ExpandColor(_THIS, SDL_Surface* surface, Uint32 color)
+{
+    Uint32 truecolor;
+
+    /* Photon API accepts true colors only during hw filling operations */
+    switch(surface->format->BitsPerPixel)
+    {
+       case 8:
+            {
+                if ((surface->format->palette) && (color<=surface->format->palette->ncolors))
+                {
+                    truecolor=PgRGB(surface->format->palette->colors[color].r,
+                                    surface->format->palette->colors[color].g,
+                                    surface->format->palette->colors[color].b);
+                }
+                else
+                {
+                    SDL_SetError("ph_ExpandColor(): Color out of range for the 8bpp mode !\n");
+                    return 0xFFFFFFFFUL;
+                }
+            }
+            break;
+       case 15: 
+            {
+                truecolor = ((color & 0x00007C00UL) << 9) |   /* R */
+                            ((color & 0x000003E0UL) << 6) |   /* G */
+                            ((color & 0x0000001FUL) << 3) |   /* B */
+                            ((color & 0x00007000UL) << 4) |   /* R compensation */
+                            ((color & 0x00000380UL) << 1) |   /* G compensation */
+                            ((color & 0x0000001CUL) >> 2);    /* B compensation */
+            }
+            break;
+       case 16: 
+            {
+                truecolor = ((color & 0x0000F800UL) << 8) |   /* R */
+                            ((color & 0x000007E0UL) << 5) |   /* G */
+                            ((color & 0x0000001FUL) << 3) |   /* B */
+                            ((color & 0x0000E000UL) << 3) |   /* R compensation */
+                            ((color & 0x00000600UL) >> 1) |   /* G compensation */
+                            ((color & 0x0000001CUL) >> 2);    /* B compensation */
+
+            }
+            break;
+       case 24: 
+            {
+                truecolor=color & 0x00FFFFFFUL;
+            }
+            break;
+       case 32: 
+            {
+                truecolor=color;
+            }
+            break;
+       default:
+            {
+                SDL_SetError("ph_ExpandColor(): Unsupported depth for the hardware operations !\n");
+                return 0xFFFFFFFFUL;
+            }
+    }
+
+    return truecolor;
+}
+
+int ph_FillHWRect(_THIS, SDL_Surface* surface, SDL_Rect* rect, Uint32 color)
+{
+    PgColor_t oldcolor;
+    Uint32 truecolor;
+    int ydisp=0;
+
+    truecolor=ph_ExpandColor(this, surface, color);
+    if (truecolor==0xFFFFFFFFUL)
+    {
+        return -1;
+    }
+
+    oldcolor=PgSetFillColor(truecolor);
+
+    /* 640x400 videomode emulation */
+    if (videomode_emulatemode==1)
+    {
+        ydisp+=40;
+    }
+
+    PgDrawIRect(rect->x, rect->y+ydisp, rect->w+rect->x-1, rect->h+rect->y+ydisp-1, Pg_DRAW_FILL);
+    PgSetFillColor(oldcolor);
+    PgFlush();
+    PgWaitHWIdle();
+
+    return 0;
+}
+
 int ph_FlipHWSurface(_THIS, SDL_Surface* screen)
 {
+    PhArea_t farea;
+
     if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
     {
+        /* flush all drawing ops before blitting */
+        PgFlush();
         PgWaitHWIdle();
-        if (OCImage.current==0)
+
+        farea.pos.x=0;
+        farea.pos.y=0;
+        farea.size.w=screen->w;
+        farea.size.h=screen->h;
+
+        /* emulate 640x400 videomode */
+        if (videomode_emulatemode==1)
         {
-            PgSwapDisplay(OCImage.offscreen_context, 0);
-            OCImage.current=1;
-            screen->pitch = OCImage.offscreen_backcontext->pitch;
-            screen->pixels = OCImage.FrameData1;
-            PhDCSetCurrent(OCImage.offscreen_backcontext);
-            PgFlush();
+            farea.pos.y+=40;
         }
-        else
-        {
-            PgSwapDisplay(OCImage.offscreen_backcontext, 0);
-            OCImage.current=0;
-            screen->pitch = OCImage.offscreen_context->pitch;
-            screen->pixels = OCImage.FrameData0;
-            PhDCSetCurrent(OCImage.offscreen_context);
-            PgFlush();
-        }
+
+        PgContextBlitArea(OCImage.offscreen_context, &farea, OCImage.offscreen_backcontext, &farea);
+
+        /* flush the blitting */
+        PgFlush();
+        PgWaitHWIdle();
     }
     return 0;
 }
 
-int ph_LockHWSurface(_THIS, SDL_Surface *surface)
+int ph_LockHWSurface(_THIS, SDL_Surface* surface)
 {
-    return(0);
+
+#if 0 /* FIXME */
+    int lockresult;
+
+    if (surface->hwdata == NULL)
+    {
+        return;
+    }
+
+    surface->hwdata->lockparam.flags=0;
+    surface->hwdata->lockparam.time_out=NULL;
+    lockresult=PdLockOffscreen(surface->hwdata->offscreenctx, &surface->hwdata->lockparam);
+
+    switch (lockresult)
+    {
+       case EOK:
+                 break;
+       case Pg_OSC_LOCK_DEADLOCK: 
+                 SDL_SetError("ph_LockHWSurface(): Deadlock detected !\n");
+                 return -1;
+       case Pg_OSC_LOCK_INVALID:
+                 SDL_SetError("ph_LockHWSurface(): Lock invalid !\n");
+                 return -1;
+       default:
+                 SDL_SetError("ph_LockHWSurface(): Can't lock the surface !\n");
+                 return -1;
+    }
+#endif /* 0 */
+
+    return 0;
+}
+
+void ph_UnlockHWSurface(_THIS, SDL_Surface* surface)
+{
+
+#if 0 /* FIXME */
+    int unlockresult;
+
+    if ((surface == NULL) || (surface->hwdata == NULL))
+    {
+        return;
+    }
+
+    if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED)
+    {
+        unlockresult=PdUnlockOffscreen(surface->hwdata->offscreenctx);
+    }
+#endif /* 0 */
+
+    return;
 }
 
-void ph_UnlockHWSurface(_THIS, SDL_Surface *surface)
+int ph_HWAccelBlit(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect)
 {
-    return;
+    SDL_VideoDevice* this=current_video;
+    PhArea_t srcarea;
+    PhArea_t dstarea;
+    int ydisp=0;
+
+    /* 640x400 videomode emulation */
+    if (videomode_emulatemode==1)
+    {
+       ydisp+=40;
+    }
+
+    srcarea.pos.x=srcrect->x;
+    srcarea.pos.y=srcrect->y;
+    srcarea.size.w=srcrect->w;
+    srcarea.size.h=srcrect->h;
+
+    dstarea.pos.x=dstrect->x;
+    dstarea.pos.y=dstrect->y;
+    dstarea.size.w=dstrect->w;
+    dstarea.size.h=dstrect->h;
+
+    if (((src == this->screen) || (src->hwdata!=NULL)) && ((dst == this->screen) || (dst->hwdata!=NULL)))
+    {
+        if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
+        {
+            ph_SetHWColorKey(this, src, src->format->colorkey);
+            PgChromaOn();
+        }
+
+        if (dst == this->screen)
+        {
+            if (src == this->screen)
+            {
+                /* blitting from main screen to main screen */
+                dstarea.pos.y+=ydisp;
+                srcarea.pos.y+=ydisp;
+                PgContextBlitArea(OCImage.offscreen_context, &srcarea, OCImage.offscreen_context, &dstarea);
+            }
+            else
+            {
+                /* blitting from offscreen to main screen */
+                dstarea.pos.y+=ydisp;
+                PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, OCImage.offscreen_context, &dstarea);
+            }
+        }
+        else
+        {
+            if (src == this->screen)
+            {
+                /* blitting from main screen to offscreen */
+                srcarea.pos.y+=ydisp;
+                PgContextBlitArea(OCImage.offscreen_context, &srcarea, dst->hwdata->offscreenctx, &dstarea);
+            }
+            else
+            {
+                /* blitting offscreen to offscreen */
+                PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, dst->hwdata->offscreenctx, &dstarea);
+            }
+        }
+
+        if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY)
+        {
+            PgChromaOff();
+        }
+    }
+    else
+    {
+        SDL_SetError("ph_HWAccelBlit(): Source or target surface is not a hardware surface !\n");
+        return -1;
+    }
+
+    PgFlush();
+    PgWaitHWIdle();
+
+    return 0;
+}
+
+int ph_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
+{
+    if (surface->hwdata!=NULL)
+    {
+        surface->hwdata->colorkey=ph_ExpandColor(this, surface, key);
+        if (surface->hwdata->colorkey==0xFFFFFFFFUL)
+        {
+            return -1;
+        }
+    }
+    PgSetChroma(surface->hwdata->colorkey, Pg_CHROMA_SRC_MATCH | Pg_CHROMA_NODRAW);
+
+    return 0;
+}
+
+int ph_SetHWAlpha(_THIS, SDL_Surface* surface, Uint8 alpha)
+{
+    return -1;
 }
 
 #ifdef HAVE_OPENGL
@@ -513,12 +970,12 @@
 
     for (i=0; i<numrects; ++i) 
     {
-    	if (rects[i].w==0) /* Clipped? */
+    	if (rects[i].w==0) /* Clipped? dunno why but this occurs sometime. */
         { 
             continue;
         }
 
-    	if (rects[i].h==0) /* Clipped? */
+    	if (rects[i].h==0) /* Clipped? dunno why but this occurs sometime. */
         { 
             continue;
         }
@@ -532,13 +989,14 @@
 
         if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0)
         {
-            SDL_SetError("ph_NormalUpdate(): PgDrawPhImageRectmx failed !\n");
+            SDL_SetError("ph_NormalUpdate(): PgDrawPhImageRectmx failed!\n");
+            return;
         }
     }
 
     if (PgFlush() < 0)
     {
-    	SDL_SetError("ph_NormalUpdate(): PgFlush failed.\n");
+    	SDL_SetError("ph_NormalUpdate(): PgFlush() function failed!\n");
     }
 }
 
@@ -546,12 +1004,15 @@
 {
     int i;
 
-    PhPoint_t zero = {0};
+    PhPoint_t zero = {0, 0};
     PhArea_t src_rect;
     PhArea_t dest_rect;
 
+    PgSetTranslation(&zero, 0);
     PgSetRegion(PtWidgetRid(window));
     PgSetClipping(0, NULL);
+
+    PgFlush();
     PgWaitHWIdle();
 
     for (i=0; i<numrects; ++i)
@@ -565,7 +1026,7 @@
         {
             continue;
         }
-
+        
         src_rect.pos.x=rects[i].x;
         src_rect.pos.y=rects[i].y;
         dest_rect.pos.x=rects[i].x;
@@ -575,12 +1036,7 @@
         src_rect.size.h=rects[i].h;
         dest_rect.size.w=rects[i].w;
         dest_rect.size.h=rects[i].h;
-
-        zero.x = 0;
-        zero.y = 0;
-        PgSetTranslation(&zero, 0);
-        PgSetRegion(PtWidgetRid(window));
-        PgSetClipping(0, NULL);
+        
         PgContextBlitArea(OCImage.offscreen_context, &src_rect, NULL, &dest_rect);
     }
 
--- a/src/video/photon/SDL_ph_image_c.h	Sat Feb 14 10:12:27 2004 +0000
+++ b/src/video/photon/SDL_ph_image_c.h	Sat Feb 14 20:22:21 2004 +0000
@@ -31,19 +31,33 @@
 #include "SDL_events_c.h"
 #include "SDL_ph_video.h"
 
+struct private_hwdata
+{
+   PdOffscreenContext_t* offscreenctx;
+   PdOSCCreateLockParams_t crlockparam;
+   PdOSCLockParams_t lockparam;
+   Uint32 colorkey;
+};
+
 extern int ph_SetupImage(_THIS, SDL_Surface* screen);
 extern void ph_DestroyImage(_THIS, SDL_Surface* screen);
 extern int ph_SetupUpdateFunction(_THIS, SDL_Surface* screen, Uint32 flags);
 
-extern int ph_AllocHWSurface(_THIS, SDL_Surface *surface);
-extern void ph_FreeHWSurface(_THIS, SDL_Surface *surface);
-extern int ph_LockHWSurface(_THIS, SDL_Surface *surface);
-extern void ph_UnlockHWSurface(_THIS, SDL_Surface *surface);
-extern int ph_FlipHWSurface(_THIS, SDL_Surface *surface);
+extern int ph_AllocHWSurface(_THIS, SDL_Surface* surface);
+extern void ph_FreeHWSurface(_THIS, SDL_Surface* surface);
+extern int ph_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst);
+extern int ph_FillHWRect(_THIS, SDL_Surface* surface, SDL_Rect* rect, Uint32 color);
+extern int ph_LockHWSurface(_THIS, SDL_Surface* surface);
+extern void ph_UnlockHWSurface(_THIS, SDL_Surface* surface);
+extern int ph_FlipHWSurface(_THIS, SDL_Surface* surface);
+extern int ph_SetHWColorKey(_THIS, SDL_Surface* surface, Uint32 key);
+extern int ph_SetHWAlpha(_THIS, SDL_Surface* surface, Uint8 alpha);
+extern int ph_HWAccelBlit(SDL_Surface* src, SDL_Rect *srcrect, SDL_Surface* dst, SDL_Rect* dstrect);
+extern int ph_UpdateHWInfo(_THIS);
 
-extern void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects);
-extern void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects);
-extern void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect *rects);
-extern void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect *rects);
+extern void ph_NormalUpdate(_THIS, int numrects, SDL_Rect* rects);
+extern void ph_OCUpdate(_THIS, int numrects, SDL_Rect* rects);
+extern void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect* rects);
+extern void ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects);
 
 #endif /* __SDL_PH_IMAGE_H__ */
--- a/src/video/photon/SDL_ph_modes.c	Sat Feb 14 10:12:27 2004 +0000
+++ b/src/video/photon/SDL_ph_modes.c	Sat Feb 14 20:22:21 2004 +0000
@@ -80,7 +80,7 @@
         SDL_modearray[i]=&SDL_modelist[i];
     }
 
-    if (PgGetVideoModeList( &mode_list ) < 0)
+    if (PgGetVideoModeList(&mode_list) < 0)
     {
        SDL_SetError("ph_ListModes(): PgGetVideoModeList() function failed !\n");
        return NULL;
@@ -109,10 +109,10 @@
 
     for(i=0; i<j; i++)
     {
-        SDL_modelist[i].w = Amodelist[j - i -1].w;
-        SDL_modelist[i].h = Amodelist[j - i -1].h;
-        SDL_modelist[i].x = Amodelist[j - i -1].x;
-        SDL_modelist[i].y = Amodelist[j - i -1].y;
+        SDL_modelist[i].w = Amodelist[j - i - 1].w;
+        SDL_modelist[i].h = Amodelist[j - i - 1].h;
+        SDL_modelist[i].x = Amodelist[j - i - 1].x;
+        SDL_modelist[i].y = Amodelist[j - i - 1].y;
     }
     SDL_modearray[j]=NULL;
 	
@@ -129,32 +129,54 @@
 int ph_GetVideoMode(int width, int height, int bpp)
 {
     int i;
+    int modestage=0;
+    int closestmode=0;
 
     if (PgGetVideoModeList(&mode_list) < 0)
     {
         return -1;
     }
 
+    /* special case for the double-sized 320x200 mode */
+    if ((width==640) && (height==400))
+    {
+       modestage=1;
+    }
+
     /* search list for exact match */
-    for (i=0;i<mode_list.num_modes;i++)
+    for (i=0; i<mode_list.num_modes; i++)
     {
         if (PgGetVideoModeInfo(mode_list.modes[i], &mode_info) < 0)
         {
             return 0;
         }
 
-        if ((mode_info.width == width) && 
-            (mode_info.height == height) && 
+        if ((mode_info.width == width) && (mode_info.height == height) && 
             (mode_info.bits_per_pixel == bpp))
         {
             return mode_list.modes[i];
         }
+        else
+        {
+           if ((modestage) && (mode_info.width == width) && (mode_info.height == height+80) && 
+               (mode_info.bits_per_pixel == bpp))
+           {
+              modestage=2;
+              closestmode=mode_list.modes[i];
+           }
+        }
+    }
+
+    /* if we are here, then no 640x400xbpp mode found and we'll emulate it via 640x480xbpp mode */
+    if (modestage==2)
+    {
+       return closestmode;
     }
 
     return (i == mode_list.num_modes) ? 0 : mode_list.modes[i];
 }
 
-/* return the mode associated with width, height and bpp */
+/* return the mode associated with width, height and bpp               */
 /* if requested bpp is not found the mode with closest bpp is returned */
 int get_mode_any_format(int width, int height, int bpp)
 {
@@ -235,6 +257,8 @@
 {
     PgDisplaySettings_t settings;
     int mode;
+    char* refreshrate;
+    int refreshratenum;
 
     if (!currently_fullscreen)
     {
@@ -254,6 +278,22 @@
                 SDL_SetError("ph_EnterFullScreen(): can't find appropriate video mode !\n");
                 return 0;
             }
+            if (PgGetVideoModeInfo(mode, &mode_info) < 0)
+            {
+                SDL_SetError("ph_EnterFullScreen(): can't get video mode capabilities !\n");
+                return 0;
+            }
+            if (mode_info.height != screen->h)
+            {
+               if ((mode_info.height==480) && (screen->h==400))
+               {
+                  videomode_emulatemode=1;
+               }
+            }
+            else
+            {
+               videomode_emulatemode=0;
+            }
         }
 
         /* save old video mode caps */
@@ -266,6 +306,15 @@
         settings.refresh = 0;
         settings.flags = 0;
 
+        refreshrate=getenv("SDL_PHOTON_FULLSCREEN_REFRESH");
+        if (refreshrate!=NULL)
+        {
+           if (sscanf(refreshrate, "%d", &refreshratenum)==1)
+           {
+               settings.refresh = refreshratenum;
+           }
+        }
+
         if (PgSetVideoMode(&settings) < 0)
         {
             SDL_SetError("ph_EnterFullScreen(): PgSetVideoMode() call failed !\n");
--- a/src/video/photon/SDL_ph_video.c	Sat Feb 14 10:12:27 2004 +0000
+++ b/src/video/photon/SDL_ph_video.c	Sat Feb 14 20:22:21 2004 +0000
@@ -68,7 +68,7 @@
 
 static int ph_Available(void)
 {
-    if (phstatus==-1)
+    if (phstatus!=0)
     {
         phstatus=PtInit(NULL);
         if (phstatus==0)
@@ -116,10 +116,10 @@
     device->UpdateRects = NULL;         /* set up in ph_SetupUpdateFunction */
     device->VideoQuit = ph_VideoQuit;
     device->AllocHWSurface = ph_AllocHWSurface;
-    device->CheckHWBlit = NULL;
-    device->FillHWRect = NULL;
-    device->SetHWColorKey = NULL;
-    device->SetHWAlpha = NULL;
+    device->CheckHWBlit = ph_CheckHWBlit;
+    device->FillHWRect = ph_FillHWRect;
+    device->SetHWColorKey = ph_SetHWColorKey;
+    device->SetHWAlpha = ph_SetHWAlpha;
     device->LockHWSurface = ph_LockHWSurface;
     device->UnlockHWSurface = ph_UnlockHWSurface;
     device->FlipHWSurface = ph_FlipHWSurface;
@@ -254,6 +254,14 @@
     }
     else
     {
+        if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE)
+        {
+            PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL);
+        }
+        else
+        {
+            PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
+        }
         if (!currently_maximized)
         {
             windowpos = getenv("SDL_VIDEO_WINDOW_POS");
@@ -293,8 +301,6 @@
             }
         }
 
-        PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
-        
         /* if window is maximized render it as maximized */
         if (currently_maximized)
         {
@@ -311,7 +317,7 @@
         /* bring the focus to the window */
         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFOCUS);
 
-        /* allow to catch hide events */
+        /* allow to catch hide event */
         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE);
         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_HIDE);
     }
@@ -320,6 +326,11 @@
     PtRealizeWidget(window);
     PtWindowToFront(window);
 
+#if 0 /* FIXME */
+    PtGetResource(window, Pt_ARG_POS, &olddim, 0);
+    fprintf(stderr, "POSITION: %d, %d\n", olddim->w, olddim->h);
+#endif
+
     return 0;
 }
 
@@ -350,9 +361,9 @@
     return NULL;
 }
 
-static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
+static int ph_VideoInit(_THIS, SDL_PixelFormat* vformat)
 {
-    PgHWCaps_t my_hwcaps;
+    PgHWCaps_t hwcaps;
     int i;
 
     window=NULL;
@@ -391,14 +402,14 @@
         return -1;
     }
 
-    if (PgGetGraphicsHWCaps(&my_hwcaps) < 0)
+    if (PgGetGraphicsHWCaps(&hwcaps) < 0)
     {
         SDL_SetError("ph_VideoInit(): GetGraphicsHWCaps function failed !\n");
         this->FreeWMCursor(this, SDL_BlankCursor);
         return -1;
     }
 
-    if (PgGetVideoModeInfo(my_hwcaps.current_video_mode, &desktop_mode) < 0)
+    if (PgGetVideoModeInfo(hwcaps.current_video_mode, &desktop_mode) < 0)
     {
         SDL_SetError("ph_VideoInit(): PgGetVideoModeInfo function failed !\n");
         this->FreeWMCursor(this, SDL_BlankCursor);
@@ -437,15 +448,22 @@
     OCImage.CurrentFrameData = NULL;
     OCImage.FrameData0 = NULL;
     OCImage.FrameData1 = NULL;
+    videomode_emulatemode = 0;
     
+    this->info.video_mem=hwcaps.currently_available_video_ram/1024;
     this->info.wm_available = 1;
+    this->info.hw_available = 1;
+    this->info.blit_fill = 1;
+    this->info.blit_hw = 1;
+    this->info.blit_hw_A = 0;
+    this->info.blit_hw_CC = 1;
     
     return 0;
 }
 
-static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
-                int width, int height, int bpp, Uint32 flags)
+static SDL_Surface* ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
 {
+    PgHWCaps_t hwcaps;
     const struct ColourMasks* mask;
 
     /* Lock the event thread, in multi-threading environments */
@@ -474,13 +492,13 @@
         return NULL;
     }
 
-#ifdef HAVE_OPENGL
     if ((current->flags & SDL_OPENGL)==SDL_OPENGL)
     {
-#else
-    if ((current->flags & SDL_OPENGL)==SDL_OPENGL) /* if no built-in OpenGL support */
+#if !defined(HAVE_OPENGL)
+    if ((current->flags & SDL_OPENGL)==SDL_OPENGL)
     {
-        SDL_SetError("ph_SetVideoMode(): no OpenGL support, try to recompile library.\n");
+        /* if no built-in OpenGL support */
+        SDL_SetError("ph_SetVideoMode(): no OpenGL support, you need to recompile SDL.\n");
         current->flags &= ~SDL_OPENGL;
         return NULL;
 #endif /* HAVE_OPENGL */
@@ -500,13 +518,12 @@
         }
         else
         {
-            /* remove this if we'll support non-fullscreen sw/hw+doublebuf */
+            /* remove this if we'll have support for the non-fullscreen sw/hw+doublebuf one day */
             current->flags &= ~SDL_DOUBLEBUF;
 
             /* Use offscreen memory if SDL_HWSURFACE flag is set */
             if ((current->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
             {
-
                 if (desktopbpp!=bpp)
                 {
                    current->flags &= ~SDL_HWSURFACE;
@@ -556,9 +573,18 @@
        PgFlush();
     }
 
+    visualbpp=bpp;
+
+    if (PgGetGraphicsHWCaps(&hwcaps) < 0)
+    {
+        SDL_SetError("ph_SetVideoMode(): GetGraphicsHWCaps function failed !\n");
+        return NULL;
+    }
+    this->info.video_mem=hwcaps.currently_available_video_ram/1024;
+
     SDL_Unlock_EventThread();
 
-    /* We're done! */
+    /* We've done! */
     return (current);
 }
 
--- a/src/video/photon/SDL_ph_video.h	Sat Feb 14 10:12:27 2004 +0000
+++ b/src/video/photon/SDL_ph_video.h	Sat Feb 14 20:22:21 2004 +0000
@@ -96,8 +96,9 @@
 
     int mouse_relative;
     WMcursor* BlankCursor;
+    uint32_t videomode_emulatemode;
 
-    Uint32 depth;	            /* current visual depth (not bpp)              */
+    Uint32 visualbpp;	            /* current visual bpp                          */
     Uint32 desktopbpp;              /* bpp of desktop at the moment of start       */
     Uint32 desktoppal;              /* palette mode emulation or system            */
 
@@ -109,25 +110,27 @@
     SDL_Overlay* overlay;
 };
 
-#define mode_settings        (this->hidden->mode_settings)
-#define window	             (this->hidden->Window)
-#define SDL_Image            (this->hidden->image)
-#define OCImage              (this->hidden->ocimage)
-#define old_video_mode       (this->hidden->old_video_mode)
-#define old_refresh_rate     (this->hidden->old_refresh_rate)
-#define graphics_card_caps   (this->hidden->graphics_card_caps)
-#define desktopbpp           (this->hidden->desktopbpp)
-#define desktoppal           (this->hidden->desktoppal)
-#define savedpal             (this->hidden->savedpal)
-#define syspalph             (this->hidden->syspalph)
-#define currently_fullscreen (this->hidden->currently_fullscreen)
-#define currently_hided      (this->hidden->currently_hided)
-#define currently_maximized  (this->hidden->currently_maximized)
-#define event                (this->hidden->event)
-#define current_overlay      (this->hidden->overlay)
-#define desktop_mode         (this->hidden->desktop_mode)
-#define mouse_relative       (this->hidden->mouse_relative)
-#define SDL_BlankCursor      (this->hidden->BlankCursor)
+#define mode_settings         (this->hidden->mode_settings)
+#define window	              (this->hidden->Window)
+#define SDL_Image             (this->hidden->image)
+#define OCImage               (this->hidden->ocimage)
+#define old_video_mode        (this->hidden->old_video_mode)
+#define old_refresh_rate      (this->hidden->old_refresh_rate)
+#define graphics_card_caps    (this->hidden->graphics_card_caps)
+#define desktopbpp            (this->hidden->desktopbpp)
+#define visualbpp             (this->hidden->visualbpp)
+#define desktoppal            (this->hidden->desktoppal)
+#define savedpal              (this->hidden->savedpal)
+#define syspalph              (this->hidden->syspalph)
+#define currently_fullscreen  (this->hidden->currently_fullscreen)
+#define currently_hided       (this->hidden->currently_hided)
+#define currently_maximized   (this->hidden->currently_maximized)
+#define event                 (this->hidden->event)
+#define current_overlay       (this->hidden->overlay)
+#define desktop_mode          (this->hidden->desktop_mode)
+#define mouse_relative        (this->hidden->mouse_relative)
+#define SDL_BlankCursor       (this->hidden->BlankCursor)
+#define videomode_emulatemode (this->hidden->videomode_emulatemode)
 
 #ifdef HAVE_OPENGL
      #define oglctx               (this->hidden->OGLContext)
--- a/test/testvidinfo.c	Sat Feb 14 10:12:27 2004 +0000
+++ b/test/testvidinfo.c	Sat Feb 14 20:22:21 2004 +0000
@@ -27,6 +27,12 @@
 	if ( flags & SDL_DOUBLEBUF ) {
 		printf(" | SDL_DOUBLEBUF");
 	}
+	if ( flags & SDL_SRCCOLORKEY ) {
+		printf(" | SDL_SRCCOLORKEY");
+	}
+	if ( flags & SDL_RLEACCEL ) {
+		printf(" | SDL_RLEACCEL");
+	}
 }
 
 int RunBlitTests(SDL_Surface *screen, SDL_Surface *bmp, int blitcount)
@@ -67,7 +73,7 @@
 	float seconds;
 	int i;
 	Uint8 r, g, b;
-	SDL_Surface *bmp, *tmp;
+	SDL_Surface *bmp, *bmpcc, *tmp;
 	SDL_Event event;
 
 	while ( SDL_PollEvent(&event) ) {
@@ -116,6 +122,7 @@
 			return 0;
 	}
 
+        /* run the generic blit test */
 	bmp = SDL_LoadBMP("sample.bmp");
 	if ( ! bmp ) {
 		printf("Couldn't load sample.bmp: %s\n", SDL_GetError());
@@ -135,6 +142,29 @@
 		printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
 	}
 
+        /* run the colorkeyed blit test */
+	bmpcc = SDL_LoadBMP("sample.bmp");
+	if ( ! bmpcc ) {
+		printf("Couldn't load sample.bmp: %s\n", SDL_GetError());
+		return 0;
+	}
+	printf("Running freshly loaded cc blit test: %dx%d at %d bpp, flags: ",
+		bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel);
+        SDL_SetColorKey(bmpcc, SDL_SRCCOLORKEY | SDL_RLEACCEL, *(Uint8 *)bmpcc->pixels);
+
+	PrintFlags(bmpcc->flags);
+	printf("\n");
+	then = SDL_GetTicks();
+	frames = RunBlitTests(screen, bmpcc, NUM_BLITS);
+	now = SDL_GetTicks();
+	seconds = (float)(now - then) / 1000.0f;
+	if ( seconds > 0.0f ) {
+		printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
+	} else {
+		printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
+	}
+
+        /* run the generic blit test */
 	tmp = bmp;
 	bmp = SDL_DisplayFormat(bmp);
 	SDL_FreeSurface(tmp);
@@ -155,6 +185,30 @@
 	} else {
 		printf("%d blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
 	}
+
+        /* run the colorkeyed blit test */
+	tmp = bmpcc;
+	bmpcc = SDL_DisplayFormat(bmpcc);
+	SDL_FreeSurface(tmp);
+	if ( ! bmpcc ) {
+		printf("Couldn't convert sample.bmp: %s\n", SDL_GetError());
+		return 0;
+	}
+	printf("Running display format cc blit test: %dx%d at %d bpp, flags: ",
+		bmpcc->w, bmpcc->h, bmpcc->format->BitsPerPixel);
+	PrintFlags(bmpcc->flags);
+	printf("\n");
+	then = SDL_GetTicks();
+	frames = RunBlitTests(screen, bmpcc, NUM_BLITS);
+	now = SDL_GetTicks();
+	seconds = (float)(now - then) / 1000.0f;
+	if ( seconds > 0.0f ) {
+		printf("%d cc blits / %d updates in %2.2f seconds, %2.2f FPS\n", NUM_BLITS*frames, frames, seconds, (float)frames / seconds);
+	} else {
+		printf("%d cc blits / %d updates in zero seconds!\n", NUM_BLITS*frames, frames);
+	}
+
+	SDL_FreeSurface(bmpcc);
 	SDL_FreeSurface(bmp);
 
 	while ( SDL_PollEvent(&event) ) {