/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2006 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/

/*
 Written by Darrell Walisser <dwaliss1@purdue.edu>

 Implementation notes ----------------------------------------------------------------------

 A bit on GWorlds in VRAM from technote 1182:

 There are two important things to note about GWorld's allocated in
 VRAM. First, the base address retrieved through GetPixBaseAddr or
 read directly from the PixMap structure can become invalid anytime
 memory is allocated in VRAM. This can occur either by explicit
 allocations, such as calls to NewGWorld, or by implicit ones, such as
 those associated with the internal texture allocation of OpenGL. The
 stored pixel images themselves will still be valid but may have been
 moved in VRAM, thus rendering any stored base addresses invalid.
 You should never store an image's base address for longer than is
 necessary and especially never across calls to NewGWorld or
 texture-creation routines. 

 Secondly, an offscreen pixel image allocated in VRAM can be
 purged at system task time by the display driver. This means any
 time your application yields time such by calling WaitNextEvent or
 SystemTask you can lose your VRAM GWorld contents. While this
 happens infrequently, usually associated with display resolution or
 pixel depth changes you must code for this eventuality. This purge
 can occur whether or not the GWorld is locked or not. A return value
 of false from LockPixels, a NULL return value from GetPixBaseAddr
 or NULL in the baseAddr field of the PixMap mean that the pixel
 image has been purged. To reallocate it you can either call
 UpdateGWorld or Dispose your current GWorld through
 DisposeGWorld and reallocate it via NewGWorld. Either way you must
 then rebuild the pixel image. 

------------------------------------------------------------------------------------

  Currently, I don't account for (1). In my testing, NewGWorld never invalidated
  other existing GWorlds in VRAM. However, I do have protection for (2).
  Namely, I am using GetOSEvent() instead of WaitNextEvent() so that there are no
  context switches (the app hogs the CPU). Eventually a book-keeping system should
  be coded to take care of (1) and (2).
  
------------------------------------------------------------------------------------

  System requirements (* denotes optional):
  
  1. DrawSprocket 1.7.3
  2. *MacOS 9 or later (but *not* Mac OS X) for hardware accelerated blit / fill
  3. *May also require certain graphics hardware for (2). I trust that all Apple OEM
     hardware will work. Third party accelerators may work if they have QuickDraw
     acceleration in the drivers and the drivers have been updated for OS 9. The current
     Voodoo 3 drivers (1.0b12) do not work.
  
  Coding suggestions:
  
  1. Use SDL_UpdateRects !
  
    If no QuickDraw acceleration is present, double-buffered surfaces will use a back buffer
    in System memory. I recommend you use SDL_UpdateRects with double-buffered surfaces
    for best performance on these cards, since the overhead is nearly zero for VRAM back buffer.
    
  2. Load most-resident surfaces first.
  
    If you fill up VRAM or AGP memory, there is no contingency for purging to make room for the next one.
    Therefore, you should load the surfaces you plan to use the most frequently first.
    Sooner or later, I will code LRU replacement to help this.
  
  TODO:
  Some kind of posterized mode for resolutions < 640x480.
  Window support / fullscreen toggle.
  Figure out how much VRAM is available. Put in video->info->video_mem.
  Track VRAM usage.
  
  BUGS:
  I can't create a hardware surface the same size as the screen?! How to fix?
  
  

   COMPILE OPTIONS:
   
   DSP_TRY_CC_AND_AA - Define if you want to try HWA color-key and alpha blitters
                       HW color-key blitting gives substantial improvements,
                       but hw alpha is neck-and-neck with SDL's soft bitter.

   DSP_NO_SYNC_VBL   - Define for HWA double-buffered surfaces: don't sync
                       pseudo-flip to monitor redraw.

   DSP_NO_SYNC_OPENGL - Define for OpenGL surfaces: don't sync buffer swap. Synching buffer
                        swap may result in reduced performance, but can eliminate some
                        tearing artifacts.
   CHANGELOG:
   09/17/00 Lots of little tweaks. Build modelist in reverse order so largest contexts
            list first. Compared various methods with ROM methods and fixed rez switch
            crashing bug in GL Tron. (Woohoo!)
*/

#define DSP_TRY_CC_AND_AA

/* #define DSP_NO_SYNC_VBL */

#define DSP_NO_SYNC_OPENGL


#if defined(__APPLE__) && defined(__MACH__)
#include <Carbon/Carbon.h>
#include <DrawSprocket/DrawSprocket.h>
#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
#include <Carbon.h>
#include <DrawSprocket.h>
#else
#include <LowMem.h>
#include <Gestalt.h>
#include <Devices.h>
#include <DiskInit.h>
#include <QDOffscreen.h>
#include <DrawSprocket.h>
#endif

#include "SDL_video.h"
#include "SDL_syswm.h"
#include "../SDL_sysvideo.h"
#include "../SDL_blit.h"
#include "../SDL_pixels_c.h"
#include "SDL_dspvideo.h"
#include "SDL_macgl_c.h"
#include "SDL_macwm_c.h"
#include "SDL_macmouse_c.h"
#include "SDL_macevents_c.h"

/* Initialization/Query functions */
static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *DSp_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
static int DSp_SetColors(_THIS, int firstcolor, int ncolors,
			 SDL_Color *colors);
static int DSp_CreatePalette(_THIS);
static int DSp_DestroyPalette(_THIS);
static void DSp_VideoQuit(_THIS);

static int DSp_GetMainDevice (_THIS, GDHandle *device);
static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat);
static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects);
static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects);

/* Hardware surface functions */
static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha);
static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key);
static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height);
static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface);
static int DSp_LockHWSurface(_THIS, SDL_Surface *surface);
static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface);
static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface);
static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest);
static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
                           SDL_Surface *dst, SDL_Rect *dstrect);
static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color);

#if SDL_VIDEO_OPENGL
   static void DSp_GL_SwapBuffers (_THIS);
#endif

#if ! TARGET_API_MAC_CARBON

    #define GetPortPixRowBytes(x)  ( (*(x->portPixMap))->rowBytes )
   #define GetGDevPixMap(x) ((**(x)).gdPMap)   
   #define GetPortPixMap(x) ((*(x)).portPixMap)
   
   #define GetPixDepth(y)    ((**(y)).pixelSize)
   //#define GetPixRowBytes(y) ((**(y)).rowBytes)
   //#define GetPixBaseAddr(y) ((**(y)).baseAddr)
   #define GetPixCTab(y)     ((**(y)).pmTable)
    #define GetPortBitMapForCopyBits(x) (&(((GrafPtr)(x))->portBits))
   
#else
    #define GetPortPixRowBytes(x) (GetPixRowBytes(GetPortPixMap(x)) )
    #define GetGDevPixMap(x) ((**(x)).gdPMap)

#endif

typedef struct private_hwdata {

  GWorldPtr offscreen;    // offscreen gworld in VRAM or AGP
  
  #ifdef DSP_TRY_CC_AND_AA
    GWorldPtr mask;         // transparent mask
    RGBColor  alpha;        // alpha color
    RGBColor  trans;        // transparent color
  #endif
  
} private_hwdata;

typedef private_hwdata private_swdata ; /* have same fields */

/* Macintosh toolbox driver bootstrap functions */

static int DSp_Available(void)
{
	/* Check for DrawSprocket */
#if ! TARGET_API_MAC_OSX
	/* This check is only meaningful if you weak-link DrawSprocketLib */  
	return ((Ptr)DSpStartup != (Ptr)kUnresolvedCFragSymbolAddress);
#else
	return 1; // DrawSprocket.framework doesn't have it all, but it's there
#endif
}

static void DSp_DeleteDevice(SDL_VideoDevice *device)
{
	/* -dw- taking no chances with null pointers */
	if (device) {
		
   	if (device->hidden) {
   	   
   	   if (device->hidden->dspinfo)
	         SDL_free(device->hidden->dspinfo);
   	   
   	   SDL_free(device->hidden);
   	}
	   SDL_free(device);	
	}
}

static SDL_VideoDevice *DSp_CreateDevice(int devindex)
{
	SDL_VideoDevice *device;

	/* Initialize all variables that we clean on shutdown */
	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
	if ( device ) {
		SDL_memset(device, 0, sizeof (*device));
		device->hidden = (struct SDL_PrivateVideoData *)
				SDL_malloc((sizeof *device->hidden));
	    if (device->hidden)
	        SDL_memset(device->hidden, 0, sizeof ( *(device->hidden) ) );
	}
	if ( (device == NULL) || (device->hidden == NULL) ) {
		SDL_OutOfMemory();
			
		if ( device ) {
			
			if (device->hidden)
				SDL_free(device->hidden);			
			
			SDL_free(device);
		}
		
		return(NULL);
	}
	
	/* Allocate DrawSprocket information */
	device->hidden->dspinfo = (struct DSpInfo *)SDL_malloc(
					(sizeof *device->hidden->dspinfo));
	if ( device->hidden->dspinfo == NULL ) {
		SDL_OutOfMemory();
		SDL_free(device->hidden);
		SDL_free(device);
		return(0);
	}
	SDL_memset(device->hidden->dspinfo, 0, (sizeof *device->hidden->dspinfo));

	/* Set the function pointers */
	device->VideoInit       = DSp_VideoInit;
	device->ListModes       = DSp_ListModes;
	device->SetVideoMode    = DSp_SetVideoMode;
	device->SetColors       = DSp_SetColors;
	device->UpdateRects     = NULL;
	device->VideoQuit       = DSp_VideoQuit;
	device->AllocHWSurface  = DSp_AllocHWSurface;
	device->CheckHWBlit     = NULL;
	device->FillHWRect      = NULL;
	device->SetHWColorKey   = NULL;
	device->SetHWAlpha      = NULL;
	device->LockHWSurface   = DSp_LockHWSurface;
	device->UnlockHWSurface = DSp_UnlockHWSurface;
	device->FlipHWSurface   = DSp_FlipHWSurface;
	device->FreeHWSurface   = DSp_FreeHWSurface;
#if SDL_VIDEO_OPENGL
	device->GL_MakeCurrent  = Mac_GL_MakeCurrent;
	device->GL_SwapBuffers  = DSp_GL_SwapBuffers;
	device->GL_LoadLibrary = Mac_GL_LoadLibrary;
	device->GL_GetProcAddress = Mac_GL_GetProcAddress;
#endif
	device->SetCaption = NULL;
	device->SetIcon = NULL;
	device->IconifyWindow = NULL;
	device->GrabInput = NULL;
	device->GetWMInfo = NULL;
	device->FreeWMCursor    = Mac_FreeWMCursor;
	device->CreateWMCursor  = Mac_CreateWMCursor;
	device->ShowWMCursor    = Mac_ShowWMCursor;
	device->WarpWMCursor    = Mac_WarpWMCursor;
	device->InitOSKeymap    = Mac_InitOSKeymap;
	device->PumpEvents      = Mac_PumpEvents;
	
	device->GrabInput      = NULL;
	device->CheckMouseMode = NULL;
	
	device->free = DSp_DeleteDevice;

	return device;
}

VideoBootStrap DSp_bootstrap = {
	"DSp", "MacOS DrawSprocket",
	DSp_Available, DSp_CreateDevice
};

/* Use DSp/Display Manager to build mode list for given screen */
static SDL_Rect**  DSp_BuildModeList (const GDHandle gDevice)
{
	DSpContextAttributes  attributes;
	DSpContextReference   context;
	DisplayIDType         displayID;
	SDL_Rect temp_list [16];
	SDL_Rect **mode_list;
	int width, height, i, j;
        
        #if TARGET_API_MAC_OSX		
	
        displayID = 0;
        
        #else
        /* Ask Display Manager for integer id of screen device */
	if ( DMGetDisplayIDByGDevice (gDevice, &displayID, SDL_TRUE) != noErr ) {
		return NULL;
	}
	#endif
	/* Get the first possible DSp context on this device */
	if ( DSpGetFirstContext (displayID, &context) != noErr ) {
		return NULL;
	}
	
	if ( DSpContext_GetAttributes (context, &attributes) != noErr )
		return NULL;
			
	for ( i = 0; i < SDL_TABLESIZE(temp_list); i++ ) {
		width  = attributes.displayWidth;
		height = attributes.displayHeight;
		
		temp_list [i].x = 0 | attributes.displayBestDepth;
		temp_list [i].y = 0;
		temp_list [i].w = width;
		temp_list [i].h = height;
	
		/* DSp will report many different contexts with the same width and height. */
		/* They will differ in bit depth and refresh rate. */
		/* We will ignore them until we reach one with a different width/height */
		/* When there are no more contexts to look at, we will quit building the list*/
		while ( width == attributes.displayWidth && height == attributes.displayHeight ) {
		
			OSStatus err = DSpGetNextContext (context, &context);
			if (err != noErr)
				if (err == kDSpContextNotFoundErr)
					goto done;
				else
					return NULL;		
			
			if ( DSpContext_GetAttributes (context, &attributes) != noErr )
				return NULL;
				
			temp_list [i].x |= attributes.displayBestDepth;
		}
	}
done:
	i++;          /* i was not incremented before kicking out of the loop */
	
	mode_list = (SDL_Rect**) SDL_malloc (sizeof (SDL_Rect*) * (i+1));
	if (mode_list) {
	
	   /* -dw- new stuff: build in reverse order so largest sizes list first */
		for (j = i-1; j >= 0; j--) {
			mode_list [j] = (SDL_Rect*) SDL_malloc (sizeof (SDL_Rect));	
			if (mode_list [j])
				SDL_memcpy (mode_list [j], &(temp_list [j]), sizeof (SDL_Rect));
			else {
				SDL_OutOfMemory ();
				return NULL;
			}
		}
		mode_list [i] = NULL;		/* append null to the end */
	}
	else {
		SDL_OutOfMemory ();
		return NULL;
	}
		
	return mode_list;
}

static void DSp_IsHWAvailable (_THIS, SDL_PixelFormat *vformat)
{
  /* 
     VRAM GWorlds are only available on OS 9 or later.
     Even with OS 9, some display drivers won't support it, 
     so we create a test GWorld and check for errors. 
  */

  long versionSystem;

  dsp_vram_available = SDL_FALSE;
  dsp_agp_available  = SDL_FALSE;
  
  Gestalt ('sysv', &versionSystem);
  if (0x00000860 < (versionSystem & 0x0000FFFF)) {
    
    GWorldPtr offscreen;
    OSStatus  err;
    Rect      bounds;
    
    SetRect (&bounds, 0, 0, 320, 240);
    
#if useDistantHdwrMem && useLocalHdwrMem
    err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useDistantHdwrMem | noNewDevice);
    if (err == noErr) {
      dsp_vram_available = SDL_TRUE;
      DisposeGWorld (offscreen);
    }
	
    err = NewGWorld (&offscreen, vformat->BitsPerPixel, &bounds, NULL, SDL_Display, useLocalHdwrMem | noNewDevice);
    if (err == noErr) {
      DisposeGWorld (offscreen);
      dsp_agp_available = SDL_TRUE;
    }
#endif
  }
}

static int DSp_GetMainDevice (_THIS, GDHandle *device)
{
    
#if TARGET_API_MAC_OSX
        /* DSpUserSelectContext not available on OS X */
        *device = GetMainDevice();
        return 0;
#else
        
	DSpContextAttributes attrib;
	DSpContextReference  context;
	DisplayIDType        display_id;
	GDHandle             main_device;
	GDHandle             device_list;
	
	device_list = GetDeviceList ();
	main_device = GetMainDevice ();
	
	/* Quick check to avoid slower method when only one display exists */
	if ( (**device_list).gdNextGD == NULL ) {
	  *device = main_device;
	  return 0;
	}
		
	SDL_memset (&attrib, 0, sizeof (DSpContextAttributes));

	/* These attributes are hopefully supported on all devices...*/
	attrib.displayWidth         = 640;
	attrib.displayHeight        = 480;
	attrib.displayBestDepth     = 8;
	attrib.backBufferBestDepth  = 8;
	attrib.displayDepthMask     = kDSpDepthMask_All;
	attrib.backBufferDepthMask  = kDSpDepthMask_All;
	attrib.colorNeeds           = kDSpColorNeeds_Require;
	attrib.pageCount            = 1;
			 
	if (noErr != DMGetDisplayIDByGDevice (main_device, &display_id, SDL_FALSE)) {
		SDL_SetError ("Display Manager couldn't associate GDevice with a Display ID");
		return (-1);
	}
	
	/* Put up dialog on main display to select which display to use */
	if (noErr != DSpUserSelectContext (&attrib, display_id, NULL, &context)) {
		SDL_SetError ("DrawSprocket couldn't create a context");
		return (-1);
	}
         
	if (noErr != DSpContext_GetDisplayID (context, &display_id)) {
		SDL_SetError ("DrawSprocket couldn't get display ID");
		return (-1);
	}
  
	if (noErr != DMGetGDeviceByDisplayID  (display_id, &main_device, SDL_FALSE)) {
		SDL_SetError ("Display Manager couldn't associate Display ID with GDevice");
		return (-1);  
	}

	*device = main_device;
	return (0);
#endif
}

static int DSp_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
	NumVersion dsp_version = { 0x01, 0x00, 0x00, 0x00 };
	
#if UNIVERSAL_INTERFACES_VERSION > 0x0320
	dsp_version = DSpGetVersion ();
#endif
	
	if (  (dsp_version.majorRev == 1 && dsp_version.minorAndBugRev < 0x73) ||
	      (dsp_version.majorRev < 1)  ) {                          
	    
	   /* StandardAlert (kAlertStopAlert, "\pError!", 
	                "\pI need DrawSprocket 1.7.3 or later!\n"
	                  "You can find a newer version at http://www.apple.com/swupdates.",
	                   NULL, NULL);
	    */              
	    SDL_SetError ("DrawSprocket version is too old. Need 1.7.3 or later.");
	    return (-1);
	}
	
	if ( DSpStartup () != noErr ) {
		SDL_SetError ("DrawSprocket couldn't startup");
		return(-1);
	}
	
	/* Start DSpintosh events */
	Mac_InitEvents(this);

	/* Get a handle to the main monitor, or choose one on multiple monitor setups */
	if ( DSp_GetMainDevice(this, &SDL_Display) <  0)
		return (-1);

	/* Determine pixel format */
    vformat->BitsPerPixel = GetPixDepth ( (**SDL_Display).gdPMap );
	dsp_old_depth = vformat->BitsPerPixel;
		
	switch (vformat->BitsPerPixel) {
		case 16:	
			vformat->Rmask = 0x00007c00;
			vformat->Gmask = 0x000003e0;
			vformat->Bmask = 0x0000001f;
			break;
		default:
			break;
	}
   
   if ( DSp_CreatePalette (this) < 0 ) {
   
      SDL_SetError ("Could not create palette");
      return (-1);
   }
   
	/* Get a list of available fullscreen modes */
	SDL_modelist = DSp_BuildModeList (SDL_Display);
	if (SDL_modelist == NULL) {
		SDL_SetError ("DrawSprocket could not build a mode list");
		return (-1);
	}
	
	/* Check for VRAM and AGP GWorlds for HW Blitting */
	DSp_IsHWAvailable (this, vformat);
	
	this->info.wm_available = 0;

	if (dsp_vram_available || dsp_agp_available) {
    
	  this->info.hw_available = SDL_TRUE;
	  
	  this->CheckHWBlit  = DSp_CheckHWBlit;
	  this->info.blit_hw = SDL_TRUE; 
  
	  this->FillHWRect     = DSp_FillHWRect;
	  this->info.blit_fill = SDL_TRUE;
	  
	#ifdef DSP_TRY_CC_AND_AA  
	  this->SetHWColorKey   = DSp_SetHWColorKey;
	  this->info.blit_hw_CC = SDL_TRUE;
	  
	  this->SetHWAlpha      = DSp_SetHWAlpha;
	  this->info.blit_hw_A  = SDL_TRUE;
	#endif
	
	}  
    
	return(0);
}

static SDL_Rect **DSp_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
	static SDL_Rect *dsp_modes[16];
	int i = 0, j = 0;
	
	if ( format->BitsPerPixel == 0 )
	   return ( (SDL_Rect**) NULL );
	
	while (SDL_modelist[i] != NULL) {
	
	   if (SDL_modelist[i]->x & format->BitsPerPixel) {
	      dsp_modes[j] = SDL_modelist[i];
	      j++;
	   }
	   i++;
	}
	
	dsp_modes[j] = NULL;

	return dsp_modes;
}

/* Various screen update functions available */
static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);

#if ! TARGET_API_MAC_OSX

static volatile unsigned int retrace_count = 0; /* -dw- need volatile because it updates asychronously */

Boolean DSp_VBLProc ( DSpContextReference context, void *ref_con )
{
	retrace_count++;
	
	return 1; /* Darrell, is this right? */
}

static void DSp_SetHWError (OSStatus err, int is_agp)
{
	char message[1024];
	const char *fmt, *mem;

	if ( is_agp ) {
		mem = "AGP Memory";
	} else {
		mem = "VRAM";
	}
	switch(err) {
	    case memFullErr:
		fmt = "Hardware surface possible but not enough %s available";
		break;
	    case cDepthErr:
		fmt = "Hardware surface possible but invalid color depth";
		break;
	    default:
		fmt = "Hardware surface could not be allocated in %s - unknown error";
		break;
	}
	SDL_snprintf(message, SDL_arraysize(message), fmt, mem);
	SDL_SetError(message);
}
#endif // TARGET_API_MAC_OSX

/* put up a dialog to verify display change */
static int DSp_ConfirmSwitch () {

  /* resource id's for dialog */
  const int rDialog = 1002;
  const int bCancel = 1;
  const int bOK     = 2;
  
  DialogPtr dialog;
  OSStatus  err;
  SInt32    response;
  DialogItemIndex       item = 0;
  GrafPtr   savePort;
    
  GetPort (&savePort);
  
  dialog = GetNewDialog (rDialog, NULL, (WindowPtr) -1);
  if (dialog == NULL)
	 return (0);
  
#if TARGET_API_CARBON
  SetPort (GetDialogPort(dialog));
#else
  SetPort ((WindowPtr) dialog);
#endif
  
  SetDialogDefaultItem (dialog, bCancel);
  SetDialogCancelItem  (dialog, bCancel);
  
  SetEventMask (everyEvent);  
  FlushEvents (everyEvent, 0);
   
   /* On MacOS 8.5 or later, we can make the dialog go away after 15 seconds */
   /* This is good since it's possible user can't even see the dialog! */
   /* Requires linking to DialogsLib */
   err = Gestalt(gestaltSystemVersion,&response);
   if (err == noErr && response >= 0x00000850) {
   	SetDialogTimeout(dialog, bCancel, 15);
   }

   do {      
    
    ModalDialog ( NULL, &item );  

   } while ( item != bCancel && item != bOK && err != noErr);


  DisposeDialog (dialog);
  SetPort (savePort);
  
  SetEventMask(everyEvent - autoKeyMask);
  FlushEvents(everyEvent, 0);
   
  return (item - 1);
}

static void DSp_UnsetVideoMode(_THIS, SDL_Surface *current)
{
			
		
	 if ( current->flags & SDL_OPENGL )  { 
	   Mac_GL_Quit (this);	   	
	}
		
	if (dsp_context != NULL) {
		
		GWorldPtr front;
		DSpContext_GetFrontBuffer (dsp_context, &front);
		
		if (front != dsp_back_buffer)
		   DisposeGWorld (dsp_back_buffer);
		
		if (current->hwdata)
		   SDL_free(current->hwdata);
		   
		DSpContext_SetState (dsp_context, kDSpContextState_Inactive );
		DSpContext_Release  (dsp_context);
		
		dsp_context = NULL;
	}
    	
    if (SDL_Window != NULL) {
        DisposeWindow (SDL_Window);
        SDL_Window = NULL;
    }    
    
    current->pixels = NULL;
    current->flags  = 0;
}

static SDL_Surface *DSp_SetVideoMode(_THIS,
	SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
{
	
#if !TARGET_API_MAC_OSX
    DisplayIDType        display_id;
	Fixed freq;
#endif
	DSpContextAttributes attrib;
	OSStatus err;
	UInt32 rmask = 0, gmask = 0, bmask = 0;
		
	int   page_count;
	int   double_buf;
	int   hw_surface;
	int   use_dsp_back_buffer;
     
	DSp_UnsetVideoMode (this, current);
       
    if (bpp != dsp_old_depth)
        DSp_DestroyPalette (this);
   
	double_buf = (flags & SDL_DOUBLEBUF) != 0;
	hw_surface = (flags & SDL_HWSURFACE) != 0;
	use_dsp_back_buffer = !dsp_vram_available || !hw_surface ;
	
	current->flags |= SDL_FULLSCREEN;

rebuild:  
  
	if ( double_buf && use_dsp_back_buffer ) {
		page_count = 2;
	} else {
		page_count = 1;
	}

	SDL_memset (&attrib, 0, sizeof (DSpContextAttributes));
	attrib.displayWidth         = width;
	attrib.displayHeight        = height;
	attrib.displayBestDepth     = bpp;
	attrib.backBufferBestDepth  = bpp;
	attrib.displayDepthMask     = kDSpDepthMask_All;
	attrib.backBufferDepthMask  = kDSpDepthMask_All;
	attrib.colorNeeds           = kDSpColorNeeds_Require;
	attrib.colorTable           = 0;
	attrib.pageCount            = page_count;
        #if TARGET_API_MAC_OSX || UNIVERSAL_INTERFACES_VERSION == 0x0320
        
        if ( DSpFindBestContext (&attrib, &dsp_context) != noErr ) {
            SDL_SetError ("DrawSprocket couldn't find a context");
            return NULL;
        }
        
        #else
	if ( noErr != DMGetDisplayIDByGDevice (SDL_Display, &display_id, SDL_FALSE) ) {
		SDL_SetError ("Display Manager couldn't associate GDevice with display_id");
		return NULL;
	}	
	if ( DSpFindBestContextOnDisplayID(&attrib, &dsp_context, display_id) != noErr ) {
		SDL_SetError ("DrawSprocket couldn't find a suitable context on given display");
		return NULL;
	}
	
        #endif		
	if ( DSpContext_Reserve (dsp_context, &attrib) != noErr ) {
		SDL_SetError ("DrawSprocket couldn't get the needed resources to build the display");
		return NULL;
	}
	
	if ( (err = DSpContext_SetState (dsp_context, kDSpContextState_Active)) != noErr ) {
		
		if (err == kDSpConfirmSwitchWarning) {     
		  
		   if ( ! DSp_ConfirmSwitch () ) {
		   
		      DSpContext_Release (dsp_context);
		      dsp_context = NULL;
		      SDL_SetError ("User cancelled display switch");
		      return NULL;
		   }
		   else
		     /* Have to reactivate context. Why? */
		     DSpContext_SetState (dsp_context, kDSpContextState_Active);
		      
	   }
	   else {
	      SDL_SetError ("DrawSprocket couldn't activate the context");
		  return NULL;
	   }
	}
   
   
	if (bpp != dsp_old_depth) {
   	
   	    DSp_CreatePalette  (this);
   
       	/* update format if display depth changed */
       	if (bpp == 16) {
       	
       	   rmask = 0x00007c00;
       	   gmask = 0x000003e0;
       	   bmask = 0x0000001f;
       	}
       	if ( ! SDL_ReallocFormat (current, bpp, rmask, gmask, bmask, 0 ) ) {
       		
       	   SDL_SetError ("Could not reallocate video format.");
       	   return(NULL);
       	}
	}
	
	if (!double_buf) {
		
		/* single-buffer context */
		DSpContext_GetFrontBuffer (dsp_context, &dsp_back_buffer);
			
		current->hwdata   = (private_hwdata*) SDL_malloc (sizeof (private_hwdata));
		if (current ->hwdata == NULL) {
			SDL_OutOfMemory ();
	  		return NULL;		  
		}
		current->hwdata->offscreen = dsp_back_buffer;
	    current->flags   |= SDL_HWSURFACE;
	    this->UpdateRects = DSp_DirectUpdate;
	} 
	else if ( use_dsp_back_buffer ) {
	
		DSpContext_GetBackBuffer  (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer);
		
		current->flags   |= SDL_DOUBLEBUF | SDL_SWSURFACE; /* only front buffer is in VRAM */                                     
	    this->UpdateRects = DSp_DSpUpdate;	
	} 
	else if ( DSp_NewHWSurface(this, &dsp_back_buffer, bpp, width-1, height-1) == 0 ) {
      
      current->hwdata = (private_hwdata*) SDL_malloc (sizeof (private_hwdata));
      if (current ->hwdata == NULL) {
      	SDL_OutOfMemory ();
      	return NULL;		  
      }
      
      SDL_memset (current->hwdata, 0, sizeof (private_hwdata));
      current->hwdata->offscreen = dsp_back_buffer;
      current->flags |= SDL_DOUBLEBUF | SDL_HWSURFACE; 
      this->UpdateRects = DSp_DirectUpdate; /* hardware doesn't do update rects, must be page-flipped */	   
   }  	
   else {

	   DSpContext_Release (dsp_context);	
	   use_dsp_back_buffer = SDL_TRUE;
	   goto  rebuild;
    }
	   	
    current->pitch  = GetPortPixRowBytes(dsp_back_buffer) & 0x3FFF;
	current->pixels = GetPixBaseAddr(GetPortPixMap(dsp_back_buffer));
	
	current->w = width;
	current->h = height;
	
    #if ! TARGET_API_MAC_OSX
        
	if (use_dsp_back_buffer) {
	   
	   DSpContext_GetMonitorFrequency (dsp_context, &freq);
	   DSpContext_SetMaxFrameRate     (dsp_context, freq >> 16);
	}
	
    
	if ( (current->flags & SDL_HWSURFACE) || (current->flags & SDL_OPENGL) )
		DSpContext_SetVBLProc (dsp_context, DSp_VBLProc, NULL);
    #endif
	
	if (bpp == 8)	
	   current->flags |= SDL_HWPALETTE;
	
	if (flags & SDL_OPENGL) {
		   
	   Rect rect;
	   RGBColor rgb = { 0.0, 0.0, 0.0 };
	   GrafPtr save_port;
	   
	   SetRect (&rect, 0, 0, width, height);
	   SDL_Window = NewCWindow(nil, &( (**SDL_Display).gdRect), "\p", SDL_TRUE, plainDBox, (WindowPtr)-1, SDL_FALSE, 0);
		   
	   if (SDL_Window == NULL) {
		 
		   SDL_SetError ("DSp_SetVideoMode : OpenGL window could not be created.");
		   return NULL;  			   	
	   }
	   
	   /* Set window color to black to avoid white flash*/
	   GetPort (&save_port);
#if TARGET_API_MAC_CARBON
		SetPort (GetWindowPort(SDL_Window));
#else
	   SetPort (SDL_Window);
#endif
	      RGBForeColor (&rgb);
	      PaintRect    (&rect);	
	   SetPort (save_port);
	   
	   SetPortWindowPort (SDL_Window);
	   SelectWindow  (SDL_Window);
	     
	   if ( Mac_GL_Init (this) < 0 ) {
	   
	      SDL_SetError ("DSp_SetVideoMode : could not create OpenGL context.");
	      return NULL;
	   }
	   	   	   	   
	   current->flags |= SDL_OPENGL;	
	}
	
	return current; 
}

#ifdef DSP_TRY_CC_AND_AA

static int DSp_MakeHWMask (_THIS, SDL_Surface *surface)
{
    GDHandle save_device;
    CGrafPtr save_port;
    GWorldPtr temp;
    RGBColor black = { 0, 0, 0 };
    RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF };
    Rect     rect;
    
    Uint32 depth = GetPixDepth ( GetGDevPixMap (SDL_Display) );
    
    SetRect (&rect, 0, 0, surface->w, surface->h);
    
    if ( noErr != NewGWorld (&(surface->hwdata->mask), depth, &rect, 0, SDL_Display, 0 ) < 0 ) {
    
        SDL_OutOfMemory ();
        return (-1);
    }   
    
    if ( noErr != NewGWorld (&temp, depth, &rect, 0 , SDL_Display, 0 ) ) {
    
        SDL_OutOfMemory ();
        return (-1);
    }                         

            
    GetGWorld (&save_port, &save_device);
    SetGWorld (surface->hwdata->mask, SDL_Display);
    
    RGBForeColor (&white);
    PaintRect    (&rect);
                 
    RGBBackColor (&(surface->hwdata->trans));
    
    CopyBits ( GetPortBitMapForCopyBits(surface->hwdata->offscreen),
                 GetPortBitMapForCopyBits(surface->hwdata->mask),
    	       &rect, &rect, transparent, NULL );
        
    SetGWorld (surface->hwdata->mask, SDL_Display);    
    SetGWorld (save_port, save_device);     
    return (0);
}

static int DSp_SetHWAlpha(_THIS, SDL_Surface *surface, UInt8 alpha)
{
    surface->hwdata->alpha.red   = (alpha / 255.0) * 65535;
    surface->hwdata->alpha.blue  = (alpha / 255.0) * 65535;
    surface->hwdata->alpha.green = (alpha / 255.0) * 65535;

    surface->flags |= SDL_SRCALPHA;

    if (surface->flags & SDL_SRCCOLORKEY) {
        return(DSp_MakeHWMask (this, surface));
    }
    return(0);
}

static int DSp_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
{
    CGrafPtr save_port;
    GDHandle save_device;
    
    GetGWorld (&save_port, &save_device);
    SetGWorld (surface->hwdata->offscreen, NULL);
    
    Index2Color (key, &(surface->hwdata->trans));
    surface->flags |= SDL_SRCCOLORKEY;    
    
    SetGWorld (save_port, save_device);
    
    if ( surface->flags & SDL_SRCALPHA ) {
        return(DSp_MakeHWMask (this, surface));    
    } 
    return(0);
}

#endif /* DSP_TRY_CC_AND_AA */

static int DSp_NewHWSurface(_THIS, CGrafPtr *port, int depth, int width, int height) {
   
   OSStatus err;
   Rect     bounds;
		
	SetRect (&bounds, 0, 0, width, height);
   
 #if useDistantHdwrMem && useLocalHdwrMem
    if (dsp_vram_available) {
	   /* try VRAM */
   	  err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useDistantHdwrMem | noNewDevice );
      if (err != noErr)
         DSp_SetHWError (err, SDL_FALSE);        
      else
         return (0);      
    }
    
    if (dsp_agp_available) {
      /* try AGP */
      err = NewGWorld (port, depth, &bounds, 0 , SDL_Display, useLocalHdwrMem | noNewDevice );
                                            
      if (err != noErr)
         DSp_SetHWError (err, SDL_TRUE);
      else   
         return (0);     
     }  
#endif
                  
   return (-1);  
}

static int DSp_AllocHWSurface(_THIS, SDL_Surface *surface)
{
	GWorldPtr temp;
	 	 
	if ( DSp_NewHWSurface (this, &temp, surface->format->BitsPerPixel, surface->w, surface->h) < 0 )
	   return (-1);
			
	surface->hwdata = (private_hwdata*) SDL_malloc (sizeof (private_hwdata));
	if (surface->hwdata == NULL) {
		SDL_OutOfMemory ();
		return -1;
	}
	
	SDL_memset (surface->hwdata, 0, sizeof(private_hwdata));
	surface->hwdata->offscreen = temp;
	surface->pitch	 = GetPixRowBytes (GetPortPixMap (temp)) & 0x3FFF;
	surface->pixels  = GetPixBaseAddr (GetPortPixMap (temp));
	surface->flags	|= SDL_HWSURFACE;
#ifdef DSP_TRY_CC_AND_AA	
	surface->flags  |= SDL_HWACCEL;
#endif	
	return 0;
}

static void DSp_FreeHWSurface(_THIS, SDL_Surface *surface)
{	
	if (surface->hwdata->offscreen != NULL)
		DisposeGWorld (surface->hwdata->offscreen);
	SDL_free(surface->hwdata);

    surface->pixels = NULL;
}

static int DSp_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dest)
{
	int accelerated;

	/* Set initial acceleration on */
	src->flags |= SDL_HWACCEL;

	/* Set the surface attributes */
	if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
		if ( ! this->info.blit_hw_A ) {
			src->flags &= ~SDL_HWACCEL;
		}
	}
	if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
		if ( ! this->info.blit_hw_CC ) {
			src->flags &= ~SDL_HWACCEL;
		}
	}

	/* Check to see if final surface blit is accelerated */
	accelerated = !!(src->flags & SDL_HWACCEL);
	if ( accelerated ) {
		src->map->hw_blit = DSp_HWAccelBlit;
	}
	return(accelerated);
}

static int DSp_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
                           SDL_Surface *dst, SDL_Rect *dstrect)
{
	CGrafPtr save_port;
	GDHandle save_device;
	Rect src_rect, dst_rect;
    RGBColor black = { 0, 0, 0 };
    RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF };

#ifdef DSP_TRY_CC_AND_AA		
	UInt32 mode;	
#endif
	
	SetRect (&src_rect, srcrect->x, srcrect->y, srcrect->x + srcrect->w, srcrect->y + srcrect->h);
	SetRect (&dst_rect, dstrect->x, dstrect->y, dstrect->x + dstrect->w, dstrect->y + dstrect->h);
	
	GetGWorld (&save_port, &save_device);
	SetGWorld (dst->hwdata->offscreen, NULL);		
		
	RGBForeColor (&black);
	RGBBackColor (&white);
		
#ifdef DSP_TRY_CC_AND_AA
	
	if ( (src->flags & SDL_SRCCOLORKEY) &&
	     (src->flags & SDL_SRCALPHA)  ) {
	     
	     OpColor (&(src->hwdata->alpha));	           
    
         CopyDeepMask ( GetPortBitMapForCopyBits(src->hwdata->offscreen),
                        GetPortBitMapForCopyBits(src->hwdata->mask),
                        GetPortBitMapForCopyBits(dst->hwdata->offscreen),
	                    &src_rect, &src_rect, &dst_rect,
	                    blend,
	                    NULL );                	                    
	}
	else {
    	
    	if ( src->flags & SDL_SRCCOLORKEY) {		    	    	    
    	    RGBBackColor (&(src->hwdata->trans) );	    
    	    mode = transparent;
    	}
    	else if (src->flags & SDL_SRCALPHA) {
    	
    	    OpColor (&(src->hwdata->alpha));
    	    mode = blend;
    	}    	
    	else {
    	
    	    mode = srcCopy;   	    
    	}            
    	
        CopyBits ( GetPortBitMapForCopyBits(src->hwdata->offscreen),
                   GetPortBitMapForCopyBits(dst->hwdata->offscreen),
    	           &src_rect, &dst_rect, mode, NULL );
    }	
#else
    
    CopyBits ( &(((GrafPtr)(src->hwdata->offscreen))->portBits),
    	           &(((GrafPtr)(dst->hwdata->offscreen))->portBits),
    	           &src_rect, &dst_rect, srcCopy, NULL );

#endif /* DSP_TRY_CC_AND_AA */           
	                             
	SetGWorld (save_port, save_device);

	return(0);
}

static int DSp_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
{
	CGrafPtr save_port;
	GDHandle save_device;
	Rect     fill_rect;
	RGBColor rgb;
		
	SetRect (&fill_rect, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
	
	GetGWorld (&save_port, &save_device);
	SetGWorld (dst->hwdata->offscreen, NULL);

    Index2Color (color, &rgb);
    
	RGBForeColor (&rgb);
	PaintRect (&fill_rect);

	SetGWorld (save_port, save_device);    

	return(0);
}

static int DSp_FlipHWSurface(_THIS, SDL_Surface *surface)
{
	  if ( (surface->flags & SDL_HWSURFACE) ) {
		CGrafPtr dsp_front_buffer, save_port;
		Rect rect;
		
    #if ! TARGET_API_MAC_OSX
		unsigned int old_count;
	#endif
    	
		/* pseudo page flipping for VRAM back buffer*/ 
		DSpContext_GetFrontBuffer (dsp_context, &dsp_front_buffer);
		SetRect (&rect, 0, 0, surface->w-1, surface->h-1);  	
  		
  		GetPort ((GrafPtr *)&save_port);
  		SetPort ((GrafPtr)dsp_front_buffer);
  		
  		/* wait for retrace */
  		/* I have tried doing the swap in interrupt routine (VBL Proc) to do */
  		/* it asynchronously, but apparently CopyBits isn't interrupt safe  */		   
        
            #if ! TARGET_API_MAC_OSX
		#ifndef DSP_NO_SYNC_VBL
    		old_count = retrace_count;
    		while (old_count == retrace_count)
    			  ;
		#endif				  
            #endif
  		
          CopyBits ( GetPortBitMapForCopyBits(dsp_back_buffer),
                      GetPortBitMapForCopyBits(dsp_front_buffer),
  			   &rect, &rect, srcCopy, NULL );
  	
  		SetPort ((GrafPtr)save_port);
  		
	} else {
		/* not really page flipping at all: DSp just blits the dirty rectangles from DSp_UpdateRects */	    
		Boolean busy_flag;
		DSpContext_SwapBuffers (dsp_context, NULL, &busy_flag); /* this  waits for VBL */
		DSpContext_GetBackBuffer (dsp_context, kDSpBufferKind_Normal, &dsp_back_buffer);
        surface->pixels =  GetPixBaseAddr( GetPortPixMap(dsp_back_buffer) );
	}
	return(0);
}

static int DSp_LockHWSurface(_THIS, SDL_Surface *surface)
{
	if ( LockPixels (GetGWorldPixMap (surface->hwdata->offscreen)) )
		return 0;
	else
		return -1;
}

static void DSp_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
	UnlockPixels (GetGWorldPixMap (surface->hwdata->offscreen));
}

static void DSp_DirectUpdate(_THIS, int numrects, SDL_Rect *sdl_rects)
{
	return;
}

static void DSp_DSpUpdate(_THIS, int numrects, SDL_Rect *sdl_rects)
{
#if ! TARGET_API_MAC_OSX /* Unsupported DSp in here */
	int i;
	Rect rect;
	
	for (i = 0; i < numrects; i++) {
	
		rect.top    = sdl_rects[i].y;
		rect.left   = sdl_rects[i].x;
		rect.bottom = sdl_rects[i].h + sdl_rects[i].y;
		rect.right  = sdl_rects[i].w + sdl_rects[i].x;
		
		DSpContext_InvalBackBufferRect (dsp_context, &rect);		
	}
#endif
}

static int DSp_CreatePalette(_THIS) {


	/* Create our palette */
	SDL_CTab = (CTabHandle)NewHandle(sizeof(ColorSpec)*256 + 8);
	if ( SDL_CTab == nil ) {
		SDL_OutOfMemory();
		return(-1);
	}
	(**SDL_CTab).ctSeed = GetCTSeed();
	(**SDL_CTab).ctFlags = 0;
	(**SDL_CTab).ctSize = 255;
	CTabChanged(SDL_CTab);
	SDL_CPal = NewPalette(256, SDL_CTab, pmExplicit+pmTolerant, 0);
	
	return 0;
}

static int DSp_DestroyPalette(_THIS) {

	/* Free palette and restore original one */
	if ( SDL_CTab != nil ) {
		DisposeHandle((Handle)SDL_CTab);
		SDL_CTab = nil;
	}
	if ( SDL_CPal != nil ) {
		DisposePalette(SDL_CPal);
		SDL_CPal = nil;
	}
	RestoreDeviceClut(SDL_Display);
	
   return (0);
}

static int DSp_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
	CTabHandle   cTab;
	
	int i;

	cTab = SDL_CTab;
	
	/* Verify the range of colors */
	if ( (firstcolor+ncolors) > ((**cTab).ctSize+1) ) {
		return(0);
	}
	
	/* Set the screen palette and update the display */
	for(i = 0; i < ncolors; i++) {
	        int j = firstcolor + i;
	        (**cTab).ctTable[j].value = j;
		(**cTab).ctTable[j].rgb.red = colors[i].r << 8 | colors[i].r;
		(**cTab).ctTable[j].rgb.green = colors[i].g << 8 | colors[i].g;
		(**cTab).ctTable[j].rgb.blue = colors[i].b << 8 | colors[i].b;
	}
	
	SetGDevice(SDL_Display);
	SetEntries(0, (**cTab).ctSize, (ColorSpec *)&(**cTab).ctTable);

	return(1);
}

void DSp_VideoQuit(_THIS)
{
	int i;
	
	/* Free current video mode */
	DSp_UnsetVideoMode(this, this->screen);

   /* Free Palette and restore original */
   DSp_DestroyPalette (this);

	/* Free list of video modes */
	if ( SDL_modelist != NULL ) {
		for ( i=0; SDL_modelist[i]; i++ ) {
			SDL_free(SDL_modelist[i]);
		}
		SDL_free(SDL_modelist);
		SDL_modelist = NULL;
	}
	
	/* Unload DrawSprocket */
   DSpShutdown ();
}

#if SDL_VIDEO_OPENGL

/* swap buffers with v-sync */
static void DSp_GL_SwapBuffers (_THIS) {

   #ifndef DSP_NO_SYNC_OPENGL
   
       unsigned int old_count;
          
       old_count = retrace_count;
       while (old_count == retrace_count)
          ;
   #endif
      
   aglSwapBuffers (glContext);
}

#endif
