1.2 Quartz video: Ripped out QuickDraw and QuickTime. SDL-1.2
authorRyan C. Gordon <icculus@icculus.org>
Mon, 21 Sep 2009 06:08:23 +0000
branchSDL-1.2
changeset 4204976bc19f8f6b
parent 4203 7e5486073044
child 4205 12da7861173e
1.2 Quartz video: Ripped out QuickDraw and QuickTime.

Now we use the software path for YUV, and CoreGraphics for 2D stuff.

There are several other 10.6 fixes in here, too...now we can build a 64-bit
SDL for Snow Leopard!
configure.in
src/video/quartz/SDL_QuartzGL.m
src/video/quartz/SDL_QuartzVideo.h
src/video/quartz/SDL_QuartzVideo.m
src/video/quartz/SDL_QuartzWM.m
src/video/quartz/SDL_QuartzWindow.h
src/video/quartz/SDL_QuartzWindow.m
src/video/quartz/SDL_QuartzYUV.m
     1.1 --- a/configure.in	Mon Sep 21 04:34:22 2009 +0000
     1.2 +++ b/configure.in	Mon Sep 21 06:08:23 2009 +0000
     1.3 @@ -2696,8 +2696,8 @@
     1.4              need_iokit_framework=yes
     1.5          fi
     1.6          if test x$enable_video_carbon = xyes -o x$enable_video_cocoa = xyes; then
     1.7 -            # The Cocoa backend still needs Carbon, and the YUV code QuickTime
     1.8 -            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuickTime -Wl,-framework,ApplicationServices"
     1.9 +            # The Cocoa backend still needs Carbon
    1.10 +            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,ApplicationServices"
    1.11              EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
    1.12          fi
    1.13          # If either the audio or CD driver is used, add the AudioUnit framework
     2.1 --- a/src/video/quartz/SDL_QuartzGL.m	Mon Sep 21 04:34:22 2009 +0000
     2.2 +++ b/src/video/quartz/SDL_QuartzGL.m	Mon Sep 21 06:08:23 2009 +0000
     2.3 @@ -41,13 +41,24 @@
     2.4  #define NSOpenGLPFASamples ((NSOpenGLPixelFormatAttribute) 56)
     2.5  #endif
     2.6  
     2.7 -
     2.8 +#ifdef __powerpc__   /* we lost this in 10.6, which has no PPC support. */
     2.9  @implementation NSOpenGLContext (CGLContextAccess)
    2.10  - (CGLContextObj) cglContext;
    2.11  {
    2.12      return _contextAuxiliary;
    2.13  }
    2.14  @end
    2.15 +CGLContextObj QZ_GetCGLContextObj(NSOpenGLContext *nsctx)
    2.16 +{
    2.17 +    return [nsctx cglContext];
    2.18 +}
    2.19 +#else
    2.20 +CGLContextObj QZ_GetCGLContextObj(NSOpenGLContext *nsctx)
    2.21 +{
    2.22 +    return (CGLContextObj) [nsctx CGLContextObj];
    2.23 +}
    2.24 +#endif
    2.25 +
    2.26  
    2.27  /* OpenGL helper functions (used internally) */
    2.28  
    2.29 @@ -165,7 +176,7 @@
    2.30  
    2.31      {
    2.32          long cache_max = 64;
    2.33 -        CGLContextObj ctx = [ gl_context cglContext ];
    2.34 +        CGLContextObj ctx = QZ_GetCGLContextObj(gl_context);
    2.35          CGLSetParameter (ctx, GLI_SUBMIT_FUNC_CACHE_MAX, &cache_max);
    2.36          CGLSetParameter (ctx, GLI_ARRAY_FUNC_CACHE_MAX, &cache_max);
    2.37      }
     3.1 --- a/src/video/quartz/SDL_QuartzVideo.h	Mon Sep 21 04:34:22 2009 +0000
     3.2 +++ b/src/video/quartz/SDL_QuartzVideo.h	Mon Sep 21 06:08:23 2009 +0000
     3.3 @@ -53,7 +53,6 @@
     3.4  
     3.5  #include <Cocoa/Cocoa.h>
     3.6  #include <Carbon/Carbon.h>
     3.7 -#include <QuickTime/QuickTime.h>
     3.8  #include <OpenGL/OpenGL.h>	/* For CGL functions and types */
     3.9  #include <IOKit/IOKitLib.h>	/* For powersave handling */
    3.10  #include <pthread.h>
    3.11 @@ -68,13 +67,21 @@
    3.12  #include "../SDL_pixels_c.h"
    3.13  #include "../../events/SDL_events_c.h"
    3.14  
    3.15 +
    3.16 +#ifdef __powerpc__
    3.17  /* 
    3.18      This is a workaround to directly access NSOpenGLContext's CGL context
    3.19      We need this to check for errors NSOpenGLContext doesn't support
    3.20 +    Please note this is only used on PowerPC (Intel Macs are guaranteed to
    3.21 +    have a better API for this, since it showed up in Mac OS X 10.3).
    3.22  */
    3.23  @interface NSOpenGLContext (CGLContextAccess)
    3.24  - (CGLContextObj) cglContext;
    3.25  @end
    3.26 +#endif
    3.27 +
    3.28 +/* use this to get the CGLContext; it handles Cocoa interface changes. */
    3.29 +CGLContextObj QZ_GetCGLContextObj(NSOpenGLContext *nsctx);
    3.30  
    3.31  
    3.32  /* Main driver structure to store required state information */
    3.33 @@ -93,7 +100,8 @@
    3.34      Uint32             warp_flag;          /* boolean; notify to event loop that a warp just occured */
    3.35      Uint32             warp_ticks;         /* timestamp when the warp occured */
    3.36      NSWindow           *window;            /* Cocoa window to implement the SDL window */
    3.37 -    NSQuickDrawView    *view;              /* the window's view; draw 2D and OpenGL into this view */
    3.38 +    NSView             *view;              /* the window's view; draw 2D and OpenGL into this view */
    3.39 +    CGContextRef       cg_context;         /* CoreGraphics rendering context */
    3.40      SDL_Surface        *resize_icon;       /* icon for the resize badge, we have to draw it by hand */
    3.41      SDL_GrabMode       current_grab_mode;  /* default value is SDL_GRAB_OFF */
    3.42      SDL_Rect           **client_mode_list; /* resolution list to pass back to client */
    3.43 @@ -113,14 +121,6 @@
    3.44      Uint8              *current_buffer;    /* the buffer being copied to the screen */
    3.45      BOOL               quit_thread;        /* used to quit the async blitting thread */
    3.46      SInt32             system_version;     /* used to dis-/enable workarounds depending on the system version */
    3.47 -    
    3.48 -    ImageDescriptionHandle yuv_idh;
    3.49 -    MatrixRecordPtr        yuv_matrix;
    3.50 -    DecompressorComponent  yuv_codec;
    3.51 -    ImageSequence          yuv_seq;
    3.52 -    PlanarPixmapInfoYUV420 *yuv_pixmap;
    3.53 -    Sint16                  yuv_width, yuv_height;
    3.54 -    CGrafPtr                yuv_port;
    3.55  
    3.56      void *opengl_library;    /* dynamically loaded OpenGL library. */
    3.57  } SDL_PrivateVideoData;
    3.58 @@ -139,6 +139,7 @@
    3.59  #define mode_flags (this->hidden->flags)
    3.60  #define qz_window (this->hidden->window)
    3.61  #define window_view (this->hidden->view)
    3.62 +#define cg_context (this->hidden->cg_context)
    3.63  #define video_set (this->hidden->video_set)
    3.64  #define warp_ticks (this->hidden->warp_ticks)
    3.65  #define warp_flag (this->hidden->warp_flag)
    3.66 @@ -156,6 +157,7 @@
    3.67  #define cursor_should_be_visible (this->hidden->cursor_should_be_visible)
    3.68  #define cursor_visible (this->hidden->cursor_visible)
    3.69  #define sw_buffers (this->hidden->sw_buffers)
    3.70 +#define sw_contexts (this->hidden->sw_contexts)
    3.71  #define thread (this->hidden->thread)
    3.72  #define sem1 (this->hidden->sem1)
    3.73  #define sem2 (this->hidden->sem2)
    3.74 @@ -215,11 +217,6 @@
    3.75  SDL_GrabMode QZ_GrabInput        (_THIS, SDL_GrabMode grab_mode);
    3.76  /*int          QZ_GetWMInfo        (_THIS, SDL_SysWMinfo *info);*/
    3.77  
    3.78 -/* YUV functions */
    3.79 -SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
    3.80 -                                         Uint32 format, SDL_Surface *display);
    3.81 -
    3.82 -
    3.83  /* Private functions (used internally) */
    3.84  void         QZ_PrivateWarpCursor (_THIS, int x, int y);
    3.85  void         QZ_ChangeGrabState (_THIS, int action);
     4.1 --- a/src/video/quartz/SDL_QuartzVideo.m	Mon Sep 21 04:34:22 2009 +0000
     4.2 +++ b/src/video/quartz/SDL_QuartzVideo.m	Mon Sep 21 06:08:23 2009 +0000
     4.3 @@ -24,7 +24,8 @@
     4.4  #include "SDL_QuartzVideo.h"
     4.5  #include "SDL_QuartzWindow.h"
     4.6  
     4.7 -/* 
     4.8 +#ifdef __powerpc__  /* I'm gambling they fixed this by 10.4. --ryan. */
     4.9 +/*
    4.10      Add methods to get at private members of NSScreen. 
    4.11      Since there is a bug in Apple's screen switching code
    4.12      that does not update this variable when switching
    4.13 @@ -41,6 +42,15 @@
    4.14      _frame = frame;
    4.15  }
    4.16  @end
    4.17 +static inline void QZ_SetFrame(NSScreen *nsscreen, NSRect frame)
    4.18 +{
    4.19 +    [nsscreen setFrame:frame];
    4.20 +}
    4.21 +#else
    4.22 +static inline void QZ_SetFrame(NSScreen *nsscreen, NSRect frame)
    4.23 +{
    4.24 +}
    4.25 +#endif
    4.26  
    4.27  @interface SDLTranslatorResponder : NSTextView
    4.28  {
    4.29 @@ -52,6 +62,8 @@
    4.30  - (void) doCommandBySelector:(SEL) myselector {}
    4.31  @end
    4.32  
    4.33 +/* absent in 10.3.9.  */
    4.34 +CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef);
    4.35  
    4.36  /* Bootstrap functions */
    4.37  static int              QZ_Available ();
    4.38 @@ -79,8 +91,6 @@
    4.39  static void         QZ_DoubleBufferUpdate (_THIS, int num_rects, SDL_Rect *rects);
    4.40  
    4.41  static void         QZ_DirectUpdate     (_THIS, int num_rects, SDL_Rect *rects);
    4.42 -static int          QZ_LockWindow       (_THIS, SDL_Surface *surface);
    4.43 -static void         QZ_UnlockWindow     (_THIS, SDL_Surface *surface);
    4.44  static void         QZ_UpdateRects      (_THIS, int num_rects, SDL_Rect *rects);
    4.45  static void         QZ_VideoQuit        (_THIS);
    4.46  
    4.47 @@ -164,7 +174,14 @@
    4.48      /*device->GetWMInfo     = QZ_GetWMInfo;*/
    4.49      device->GrabInput     = QZ_GrabInput;
    4.50  
    4.51 -    device->CreateYUVOverlay =  QZ_CreateYUVOverlay;
    4.52 +    /*
    4.53 +     * This is a big hassle, needing QuickDraw and QuickTime on older
    4.54 +     *  systems, and god knows what on 10.6, so we immediately fail here,
    4.55 +     *  which causes SDL to make an RGB surface and manage the YUV overlay
    4.56 +     *  in software. Sorry. Use SDL 1.3 if you want YUV rendering in a pixel
    4.57 +     *  shader.  :)
    4.58 +     */
    4.59 +    /*device->CreateYUVOverlay = QZ_CreateYUVOverlay;*/
    4.60  
    4.61      device->free             = QZ_DeleteDevice;
    4.62  
    4.63 @@ -371,6 +388,12 @@
    4.64      this->LockHWSurface   = NULL;
    4.65      this->UnlockHWSurface = NULL;
    4.66      
    4.67 +    if (cg_context) {
    4.68 +        CGContextFlush (cg_context);
    4.69 +        CGContextRelease (cg_context);
    4.70 +        cg_context = nil;
    4.71 +    }
    4.72 +    
    4.73      /* Release fullscreen resources */
    4.74      if ( mode_flags & SDL_FULLSCREEN ) {
    4.75  
    4.76 @@ -412,7 +435,7 @@
    4.77                  See comment in QZ_SetVideoFullscreen for why we do this
    4.78              */
    4.79              screen_rect = NSMakeRect(0,0,device_width,device_height);
    4.80 -            [ [ NSScreen mainScreen ] setFrame:screen_rect ];
    4.81 +            QZ_SetFrame([ NSScreen mainScreen ], screen_rect);
    4.82          }
    4.83      }
    4.84      /* Release window mode resources */
    4.85 @@ -440,7 +463,7 @@
    4.86      NSRect contentRect;
    4.87      BOOL isCustom = NO;
    4.88      CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken;
    4.89 -    
    4.90 +
    4.91      /* Fade to black to hide resolution-switching flicker (and garbage
    4.92         that is displayed by a destroyed OpenGL context, if applicable) */
    4.93      if ( CGAcquireDisplayFadeReservation (5, &fade_token) == kCGErrorSuccess ) {
    4.94 @@ -451,6 +474,12 @@
    4.95      if (video_set == SDL_TRUE)
    4.96          QZ_UnsetVideoMode (this, FALSE);
    4.97  
    4.98 +    /* Sorry, QuickDraw was ripped out. */
    4.99 +    if (getenv("SDL_NSWindowPointer") || getenv("SDL_NSQuickDrawViewPointer")) {
   4.100 +        SDL_SetError ("Embedded QuickDraw windows are no longer supported");
   4.101 +        goto ERR_NO_MATCH;
   4.102 +    }
   4.103 +
   4.104      /* See if requested mode exists */
   4.105      mode = CGDisplayBestModeForParameters (display_id, bpp, width,
   4.106                                             height, &exact_match);
   4.107 @@ -487,7 +516,8 @@
   4.108      current->flags |= SDL_FULLSCREEN;
   4.109      current->flags |= SDL_HWSURFACE;
   4.110      current->flags |= SDL_PREALLOC;
   4.111 -    
   4.112 +    /* current->hwdata = (void *) CGDisplayGetDrawingContext (display_id); */
   4.113 +
   4.114      this->UpdateRects     = QZ_DirectUpdate;
   4.115      this->LockHWSurface   = QZ_LockHWSurface;
   4.116      this->UnlockHWSurface = QZ_UnlockHWSurface;
   4.117 @@ -531,42 +561,12 @@
   4.118      if ( CGDisplayCanSetPalette (display_id) )
   4.119          current->flags |= SDL_HWPALETTE;
   4.120  
   4.121 -    /* The code below checks for any valid custom windows and views.  If none are
   4.122 -       available, then we create new ones.  Window/View code was added in FULLSCREEN
   4.123 -       so that special events like the changing of the cursor image would be handled
   4.124 -       ( only the front-most and active application can change the cursor appearance
   4.125 -       and with no valid window/view in FULLSCREEN, SDL wouldn't update its cursor. )
   4.126 -    */
   4.127 -	/* Check for user-specified window and view */
   4.128 -    {
   4.129 -        char *windowPtrString = getenv ("SDL_NSWindowPointer");
   4.130 -        char *viewPtrString = getenv ("SDL_NSQuickDrawViewPointer");
   4.131 -    
   4.132 -        contentRect = NSMakeRect (0, 0, width, height);
   4.133 -	
   4.134 -        if (windowPtrString && viewPtrString) {
   4.135 -            /* Release any previous window */
   4.136 -            if ( qz_window ) {
   4.137 -                [ qz_window release ];
   4.138 -                qz_window = nil;
   4.139 -            }
   4.140 -            
   4.141 -            qz_window = (NSWindow*)atoi(windowPtrString);
   4.142 -            window_view = (NSQuickDrawView*)atoi(viewPtrString);
   4.143 -            isCustom = YES;
   4.144 -            /* 
   4.145 -                Retain reference to window because we
   4.146 -                might release it in QZ_UnsetVideoMode
   4.147 -            */
   4.148 -            [ qz_window retain ];
   4.149 -        }
   4.150 -    }
   4.151      /* Check if we should recreate the window */
   4.152      if (qz_window == nil) {
   4.153          /* Manually create a window, avoids having a nib file resource */
   4.154          qz_window = [ [ SDL_QuartzWindow alloc ] 
   4.155              initWithContentRect:contentRect
   4.156 -                styleMask:nil 
   4.157 +                styleMask:0
   4.158                      backing:NSBackingStoreBuffered
   4.159                          defer:NO ];
   4.160  
   4.161 @@ -600,7 +600,7 @@
   4.162          [ [ qz_window contentView ] addSubview:window_view ];	
   4.163          [ window_view release ];
   4.164  
   4.165 -        ctx = [ gl_context cglContext ];
   4.166 +        ctx = QZ_GetCGLContextObj (gl_context);
   4.167          err = CGLSetFullScreen (ctx);
   4.168  
   4.169          if (err) {
   4.170 @@ -634,7 +634,7 @@
   4.171          ourselves. This hack should be removed if/when the bug is fixed.
   4.172      */
   4.173      screen_rect = NSMakeRect(0,0,width,height);
   4.174 -    [ [ NSScreen mainScreen ] setFrame:screen_rect ]; 
   4.175 +    QZ_SetFrame([ NSScreen mainScreen ], screen_rect);
   4.176  
   4.177      /* Save the flags to ensure correct tear-down */
   4.178      mode_flags = current->flags;
   4.179 @@ -694,40 +694,16 @@
   4.180          }
   4.181      }
   4.182      
   4.183 -    /* Check for user-specified window and view */
   4.184 -    {
   4.185 -        char *windowPtrString = getenv ("SDL_NSWindowPointer");
   4.186 -        char *viewPtrString = getenv ("SDL_NSQuickDrawViewPointer");
   4.187 -    
   4.188 -        if (windowPtrString && viewPtrString) {
   4.189 -            
   4.190 -            /* Release any previous window */
   4.191 -            if ( qz_window ) {
   4.192 -                [ qz_window release ];
   4.193 -                qz_window = nil;
   4.194 -            }
   4.195 -            
   4.196 -            qz_window = (NSWindow*)atoi(windowPtrString);
   4.197 -            window_view = (NSQuickDrawView*)atoi(viewPtrString);
   4.198 -            isCustom = YES;
   4.199 -            
   4.200 -            /* 
   4.201 -                Retain reference to window because we
   4.202 -                might release it in QZ_UnsetVideoMode
   4.203 -            */
   4.204 -            [ qz_window retain ];
   4.205 -            
   4.206 -            style = [ qz_window styleMask ];
   4.207 -            /* Check resizability */
   4.208 -            if ( style & NSResizableWindowMask )
   4.209 -                current->flags |= SDL_RESIZABLE;
   4.210 -            
   4.211 -            /* Check frame */
   4.212 -            if ( style & NSBorderlessWindowMask )
   4.213 -                current->flags |= SDL_NOFRAME;
   4.214 +    /* Sorry, QuickDraw was ripped out. */
   4.215 +    if (getenv("SDL_NSWindowPointer") || getenv("SDL_NSQuickDrawViewPointer")) {
   4.216 +        SDL_SetError ("Embedded QuickDraw windows are no longer supported");
   4.217 +        if (fade_token != kCGDisplayFadeReservationInvalidToken) {
   4.218 +            CGDisplayFade (fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
   4.219 +            CGReleaseDisplayFadeReservation (fade_token);
   4.220          }
   4.221 +        return NULL;
   4.222      }
   4.223 -    
   4.224 +
   4.225      /* Check if we should recreate the window */
   4.226      if (qz_window == nil) {
   4.227      
   4.228 @@ -807,48 +783,36 @@
   4.229          [ qz_window makeKeyAndOrderFront:nil ];
   4.230          current->flags |= SDL_OPENGL;
   4.231      }
   4.232 -    /* For 2D, we set the subview to an NSQuickDrawView */
   4.233 +    /* For 2D, we build a CGBitmapContext */
   4.234      else {
   4.235 -        short qdbpp = 0;
   4.236 +        CGColorSpaceRef cgColorspace;
   4.237  
   4.238          /* Only recreate the view if it doesn't already exist */
   4.239          if (window_view == nil) {
   4.240          
   4.241 -            window_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
   4.242 +            window_view = [ [ NSView alloc ] initWithFrame:contentRect ];
   4.243              [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
   4.244              [ [ qz_window contentView ] addSubview:window_view ];
   4.245              [ window_view release ];
   4.246              [ qz_window makeKeyAndOrderFront:nil ];
   4.247          }
   4.248          
   4.249 -        LockPortBits ( [ window_view qdPort ] );
   4.250 -        current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );
   4.251 -        current->pitch  = GetPixRowBytes ( GetPortPixMap ( [ window_view qdPort ] ) );
   4.252 -        qdbpp           = GetPixDepth ( GetPortPixMap ( [ window_view qdPort ] ) );
   4.253 -        UnlockPortBits ( [ window_view qdPort ] );
   4.254 -
   4.255 -        /* QuickDraw may give a 16-bit shadow surface on 8-bit displays! */
   4.256 -        *bpp = qdbpp;
   4.257 -
   4.258 +        cgColorspace = CGColorSpaceCreateDeviceRGB();
   4.259 +        current->pitch = 4 * current->w;
   4.260 +        current->pixels = SDL_malloc (current->h * current->pitch);
   4.261 +        
   4.262 +        cg_context = CGBitmapContextCreate (current->pixels, current->w, current->h,
   4.263 +                        8, current->pitch, cgColorspace,
   4.264 +                        kCGImageAlphaNoneSkipFirst);
   4.265 +        CGColorSpaceRelease (cgColorspace);
   4.266 +        
   4.267          current->flags |= SDL_SWSURFACE;
   4.268 -        current->flags |= SDL_PREALLOC;
   4.269          current->flags |= SDL_ASYNCBLIT;
   4.270 +        current->hwdata = (void *) cg_context;
   4.271          
   4.272 -        /* 
   4.273 -            current->pixels now points to the window's pixels
   4.274 -            We want it to point to the *view's* pixels 
   4.275 -        */
   4.276 -        { 
   4.277 -            int vOffset = [ qz_window frame ].size.height - 
   4.278 -                [ window_view frame ].size.height - [ window_view frame ].origin.y;
   4.279 -            
   4.280 -            int hOffset = [ window_view frame ].origin.x;
   4.281 -                    
   4.282 -            current->pixels = (Uint8 *)current->pixels + (vOffset * current->pitch) + hOffset * (qdbpp/8);
   4.283 -        }
   4.284          this->UpdateRects     = QZ_UpdateRects;
   4.285 -        this->LockHWSurface   = QZ_LockWindow;
   4.286 -        this->UnlockHWSurface = QZ_UnlockWindow;
   4.287 +        this->LockHWSurface   = QZ_LockHWSurface;
   4.288 +        this->UnlockHWSurface = QZ_UnlockHWSurface;
   4.289      }
   4.290  
   4.291      /* Save flags to ensure correct teardown */
   4.292 @@ -877,8 +841,8 @@
   4.293      }
   4.294      /* Setup windowed video */
   4.295      else {
   4.296 -        /* Force bpp to the device's bpp */
   4.297 -        bpp = device_bpp;
   4.298 +        /* Force bpp to 32 */
   4.299 +        bpp = 32;
   4.300          current = QZ_SetVideoWindowed (this, current, width, height, &bpp, flags);
   4.301          if (current == NULL)
   4.302              return NULL;
   4.303 @@ -903,9 +867,15 @@
   4.304                  return NULL;
   4.305              case 32:   /* (8)-8-8-8 ARGB */
   4.306                  amask = 0x00000000;
   4.307 +#ifdef __LITTLE_ENDIAN__
   4.308 +                rmask = 0x0000FF00;
   4.309 +                gmask = 0x00FF0000;
   4.310 +                bmask = 0xFF000000;
   4.311 +#else
   4.312                  rmask = 0x00FF0000;
   4.313                  gmask = 0x0000FF00;
   4.314                  bmask = 0x000000FF;
   4.315 +#endif
   4.316                  break;
   4.317          }
   4.318  
   4.319 @@ -1062,6 +1032,9 @@
   4.320          /* On error, skip VBL delay */
   4.321          ERROR:
   4.322          
   4.323 +        /* TODO: use CGContextDrawImage here too!  Create two CGContextRefs the same way we
   4.324 +           create two buffers, replace current_buffer with current_context and set it
   4.325 +           appropriately in QZ_FlipDoubleBuffer.  */
   4.326          while ( h-- ) {
   4.327          
   4.328              SDL_memcpy (dst, src, len);
   4.329 @@ -1105,253 +1078,6 @@
   4.330  #pragma unused(this,num_rects,rects)
   4.331  }
   4.332  
   4.333 -/*
   4.334 -    The obscured code is based on work by Matt Slot fprefect@ambrosiasw.com,
   4.335 -    who supplied sample code for Carbon.
   4.336 -*/
   4.337 -
   4.338 -/*#define TEST_OBSCURED 1*/
   4.339 -
   4.340 -#if TEST_OBSCURED
   4.341 -#include "CGS.h"
   4.342 -#endif
   4.343 -
   4.344 -static int QZ_IsWindowObscured (NSWindow *window) {
   4.345 -
   4.346 -
   4.347 -#if TEST_OBSCURED
   4.348 -
   4.349 -    /*  
   4.350 -        In order to determine if a direct copy to the screen is possible,
   4.351 -        we must figure out if there are any windows covering ours (including shadows).
   4.352 -        This can be done by querying the window server about the on screen
   4.353 -        windows for their screen rectangle and window level.
   4.354 -        The procedure used below is puts accuracy before speed; however, it aims to call
   4.355 -        the window server the fewest number of times possible to keep things reasonable.
   4.356 -        In my testing on a 300mhz G3, this routine typically takes < 2 ms. -DW
   4.357 -    
   4.358 -    Notes:
   4.359 -        -Calls into the Window Server involve IPC which is slow.
   4.360 -        -Getting a rectangle seems slower than getting the window level
   4.361 -        -The window list we get back is in sorted order, top to bottom
   4.362 -        -On average, I suspect, most windows above ours are dock icon windows (hence optimization)
   4.363 -        -Some windows above ours are always there, and cannot move or obscure us (menu bar)
   4.364 -    
   4.365 -    Bugs:
   4.366 -        -no way (yet) to deactivate direct drawing when a window is dragged,
   4.367 -        or suddenly obscured, so drawing continues and can produce garbage
   4.368 -        We need some kind of locking mechanism on window movement to prevent this
   4.369 -    
   4.370 -        -deactivated normal windows use activated normal
   4.371 -        window shadows (slight inaccuraccy)
   4.372 -    */
   4.373 -
   4.374 -    /* Cache the connection to the window server */
   4.375 -    static CGSConnectionID    cgsConnection = (CGSConnectionID) -1;
   4.376 -
   4.377 -    /* Cache the dock icon windows */
   4.378 -    static CGSWindowID          dockIcons[kMaxWindows];
   4.379 -    static int                  numCachedDockIcons = 0;
   4.380 -
   4.381 -    CGSWindowID                windows[kMaxWindows];
   4.382 -    CGSWindowCount             i, count;
   4.383 -    CGSWindowLevel             winLevel;
   4.384 -    CGSRect                    winRect;
   4.385 -
   4.386 -    CGSRect contentRect;
   4.387 -    int     windowNumber;
   4.388 -    int     firstDockIcon;
   4.389 -    int     dockIconCacheMiss;
   4.390 -    int     windowContentOffset;
   4.391 -
   4.392 -    int     obscured = SDL_TRUE;
   4.393 -
   4.394 -    if ( [ window isVisible ] ) {
   4.395 -
   4.396 -        /*  
   4.397 -            walk the window list looking for windows over top of
   4.398 -            (or casting a shadow on) ours 
   4.399 -        */
   4.400 -
   4.401 -        /* 
   4.402 -           Get a connection to the window server
   4.403 -           Should probably be moved out into SetVideoMode() or InitVideo()
   4.404 -        */
   4.405 -        if (cgsConnection == (CGSConnectionID) -1) {
   4.406 -            cgsConnection = (CGSConnectionID) 0;
   4.407 -            cgsConnection = _CGSDefaultConnection ();
   4.408 -        }
   4.409 -
   4.410 -        if (cgsConnection) {
   4.411 -
   4.412 -            if ( ! [ window styleMask ] & NSBorderlessWindowMask )
   4.413 -                windowContentOffset = 22;
   4.414 -            else
   4.415 -                windowContentOffset = 0;
   4.416 -
   4.417 -            windowNumber = [ window windowNumber ];
   4.418 -
   4.419 -            /* The window list is sorted according to order on the screen */
   4.420 -            count = 0;
   4.421 -            CGSGetOnScreenWindowList (cgsConnection, 0, kMaxWindows, windows, &count);
   4.422 -            CGSGetScreenRectForWindow (cgsConnection, windowNumber, &contentRect);
   4.423 -
   4.424 -            /* adjust rect for window title bar (if present) */
   4.425 -            contentRect.origin.y    += windowContentOffset;
   4.426 -            contentRect.size.height -= windowContentOffset;
   4.427 -
   4.428 -            firstDockIcon = -1;
   4.429 -            dockIconCacheMiss = SDL_FALSE;
   4.430 -
   4.431 -            /* 
   4.432 -                The first window is always an empty window with level kCGSWindowLevelTop
   4.433 -                so start at index 1
   4.434 -            */
   4.435 -            for (i = 1; i < count; i++) {
   4.436 -
   4.437 -                /* If we reach our window in the list, it cannot be obscured */
   4.438 -                if (windows[i] == windowNumber) {
   4.439 -
   4.440 -                    obscured = SDL_FALSE;
   4.441 -                    break;
   4.442 -                }
   4.443 -                else {
   4.444 -
   4.445 -                    float shadowSide;
   4.446 -                    float shadowTop;
   4.447 -                    float shadowBottom;
   4.448 -
   4.449 -                    CGSGetWindowLevel (cgsConnection, windows[i], &winLevel);
   4.450 -
   4.451 -                    if (winLevel == kCGSWindowLevelDockIcon) {
   4.452 -
   4.453 -                        int j;
   4.454 -
   4.455 -                        if (firstDockIcon < 0) {
   4.456 -
   4.457 -                            firstDockIcon = i;
   4.458 -
   4.459 -                            if (numCachedDockIcons > 0) {
   4.460 -
   4.461 -                                for (j = 0; j < numCachedDockIcons; j++) {
   4.462 -
   4.463 -                                    if (windows[i] == dockIcons[j])
   4.464 -                                        i++;
   4.465 -                                    else
   4.466 -                                        break;
   4.467 -                                }
   4.468 -
   4.469 -                                if (j != 0) {
   4.470 -
   4.471 -                                    i--;
   4.472 -
   4.473 -                                    if (j < numCachedDockIcons) {
   4.474 -
   4.475 -                                        dockIconCacheMiss = SDL_TRUE;
   4.476 -                                    }
   4.477 -                                }
   4.478 -
   4.479 -                            }
   4.480 -                        }
   4.481 -
   4.482 -                        continue;
   4.483 -                    }
   4.484 -                    else if (winLevel == kCGSWindowLevelMenuIgnore
   4.485 -                             /* winLevel == kCGSWindowLevelTop */) {
   4.486 -
   4.487 -                        continue; /* cannot obscure window */
   4.488 -                    }
   4.489 -                    else if (winLevel == kCGSWindowLevelDockMenu ||
   4.490 -                             winLevel == kCGSWindowLevelMenu) {
   4.491 -
   4.492 -                        shadowSide = 18;
   4.493 -                        shadowTop = 4;
   4.494 -                        shadowBottom = 22;
   4.495 -                    }
   4.496 -                    else if (winLevel == kCGSWindowLevelUtility) {
   4.497 -
   4.498 -                        shadowSide = 8;
   4.499 -                        shadowTop = 4;
   4.500 -                        shadowBottom = 12;
   4.501 -                    }
   4.502 -                    else if (winLevel == kCGSWindowLevelNormal) {
   4.503 -
   4.504 -                        /* 
   4.505 -                            These numbers are for foreground windows,
   4.506 -                            they are too big (but will work) for background windows 
   4.507 -                        */
   4.508 -                        shadowSide = 20;
   4.509 -                        shadowTop = 10;
   4.510 -                        shadowBottom = 24;
   4.511 -                    }
   4.512 -                    else if (winLevel == kCGSWindowLevelDock) {
   4.513 -
   4.514 -                        /* Create dock icon cache */
   4.515 -                        if (numCachedDockIcons != (i-firstDockIcon) ||
   4.516 -                            dockIconCacheMiss) {
   4.517 -
   4.518 -                            numCachedDockIcons = i - firstDockIcon;
   4.519 -                            SDL_memcpy (dockIcons, &(windows[firstDockIcon]),
   4.520 -                                    numCachedDockIcons * sizeof(*windows));
   4.521 -                        }
   4.522 -
   4.523 -                        /* no shadow */
   4.524 -                        shadowSide = 0;
   4.525 -                        shadowTop = 0;
   4.526 -                        shadowBottom = 0;
   4.527 -                    }
   4.528 -                    else {
   4.529 -
   4.530 -                        /*
   4.531 -                            kCGSWindowLevelDockLabel,
   4.532 -                            kCGSWindowLevelDock,
   4.533 -                            kOther???
   4.534 -                        */
   4.535 -
   4.536 -                        /* no shadow */
   4.537 -                        shadowSide = 0;
   4.538 -                        shadowTop = 0;
   4.539 -                        shadowBottom = 0;
   4.540 -                    }
   4.541 -
   4.542 -                    CGSGetScreenRectForWindow (cgsConnection, windows[i], &winRect);
   4.543 -
   4.544 -                    winRect.origin.x -= shadowSide;
   4.545 -                    winRect.origin.y -= shadowTop;
   4.546 -                    winRect.size.width += shadowSide;
   4.547 -                    winRect.size.height += shadowBottom;
   4.548 -
   4.549 -                    if (NSIntersectsRect (contentRect, winRect)) {
   4.550 -
   4.551 -                        obscured = SDL_TRUE;
   4.552 -                        break;
   4.553 -                    }
   4.554 -
   4.555 -                } /* window was not our window */
   4.556 -
   4.557 -            } /* iterate over windows */
   4.558 -
   4.559 -        } /* get cgsConnection */
   4.560 -
   4.561 -    } /* window is visible */
   4.562 -    
   4.563 -    return obscured;
   4.564 -#else
   4.565 -    return SDL_TRUE;
   4.566 -#endif
   4.567 -}
   4.568 -
   4.569 -
   4.570 -/* Locking functions for the software window buffer */
   4.571 -static int QZ_LockWindow (_THIS, SDL_Surface *surface) {
   4.572 -    
   4.573 -    return LockPortBits ( [ window_view qdPort ] );
   4.574 -}
   4.575 -
   4.576 -static void QZ_UnlockWindow (_THIS, SDL_Surface *surface) {
   4.577 -
   4.578 -    UnlockPortBits ( [ window_view qdPort ] );
   4.579 -}
   4.580  
   4.581  /* Resize icon, BMP format */
   4.582  static const unsigned char QZ_ResizeIcon[] = {
   4.583 @@ -1393,41 +1119,34 @@
   4.584      0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0b
   4.585  };
   4.586  
   4.587 -static void QZ_DrawResizeIcon (_THIS, RgnHandle dirtyRegion) {
   4.588 +static void QZ_DrawResizeIcon (_THIS) {
   4.589  
   4.590      /* Check if we should draw the resize icon */
   4.591      if (SDL_VideoSurface->flags & SDL_RESIZABLE) {
   4.592      
   4.593 -        Rect    icon;
   4.594 -        SetRect (&icon, SDL_VideoSurface->w - 13, SDL_VideoSurface->h - 13, 
   4.595 -                    SDL_VideoSurface->w, SDL_VideoSurface->h);
   4.596 -                    
   4.597 -        if (RectInRgn (&icon, dirtyRegion)) {
   4.598 +        SDL_Rect icon_rect;
   4.599          
   4.600 -            SDL_Rect icon_rect;
   4.601 +        /* Create the icon image */
   4.602 +        if (resize_icon == NULL) {
   4.603 +        
   4.604 +            SDL_RWops *rw;
   4.605 +            SDL_Surface *tmp;
   4.606              
   4.607 -            /* Create the icon image */
   4.608 -            if (resize_icon == NULL) {
   4.609 +            rw = SDL_RWFromConstMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon));
   4.610 +            tmp = SDL_LoadBMP_RW (rw, SDL_TRUE);
   4.611 +                                                            
   4.612 +            resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY);
   4.613 +            SDL_SetColorKey (resize_icon, SDL_SRCCOLORKEY, 0xFFFFFF);
   4.614              
   4.615 -                SDL_RWops *rw;
   4.616 -                SDL_Surface *tmp;
   4.617 -                
   4.618 -                rw = SDL_RWFromConstMem (QZ_ResizeIcon, sizeof(QZ_ResizeIcon));
   4.619 -                tmp = SDL_LoadBMP_RW (rw, SDL_TRUE);
   4.620 -                                                                
   4.621 -                resize_icon = SDL_ConvertSurface (tmp, SDL_VideoSurface->format, SDL_SRCCOLORKEY);
   4.622 -                SDL_SetColorKey (resize_icon, SDL_SRCCOLORKEY, 0xFFFFFF);
   4.623 -                
   4.624 -                SDL_FreeSurface (tmp);
   4.625 -            }
   4.626 +            SDL_FreeSurface (tmp);
   4.627 +        }
   4.628              
   4.629 -            icon_rect.x = SDL_VideoSurface->w - 13;
   4.630 -            icon_rect.y = SDL_VideoSurface->h - 13;
   4.631 -            icon_rect.w = 13;
   4.632 -            icon_rect.h = 13;
   4.633 +        icon_rect.x = SDL_VideoSurface->w - 13;
   4.634 +        icon_rect.y = SDL_VideoSurface->h - 13;
   4.635 +        icon_rect.w = 13;
   4.636 +        icon_rect.h = 13;
   4.637              
   4.638 -            SDL_BlitSurface (resize_icon, NULL, SDL_VideoSurface, &icon_rect);
   4.639 -        }
   4.640 +        SDL_BlitSurface (resize_icon, NULL, SDL_VideoSurface, &icon_rect);
   4.641      }
   4.642  }
   4.643  
   4.644 @@ -1441,75 +1160,19 @@
   4.645          /* Do nothing if miniaturized */
   4.646      }
   4.647      
   4.648 -    else if ( ! QZ_IsWindowObscured (qz_window) ) {
   4.649 -
   4.650 -        /* Use direct copy to flush contents to the display */
   4.651 -        CGrafPtr savePort;
   4.652 -        CGrafPtr dstPort, srcPort;
   4.653 -        const BitMap  *dstBits, *srcBits;
   4.654 -        Rect     dstRect, srcRect;
   4.655 -        Point    offset;
   4.656 -        int i;
   4.657 -
   4.658 -        GetPort (&savePort);
   4.659 -
   4.660 -        dstPort = CreateNewPortForCGDisplayID ((UInt32)display_id);
   4.661 -        srcPort = [ window_view qdPort ];
   4.662 -
   4.663 -        offset.h = 0;
   4.664 -        offset.v = 0;
   4.665 -        SetPort (srcPort);
   4.666 -        LocalToGlobal (&offset);
   4.667 -
   4.668 -        SetPort (dstPort);
   4.669 -
   4.670 -        LockPortBits (dstPort);
   4.671 -        LockPortBits (srcPort);
   4.672 -
   4.673 -        dstBits = GetPortBitMapForCopyBits (dstPort);
   4.674 -        srcBits = GetPortBitMapForCopyBits (srcPort);
   4.675 -
   4.676 -        for (i = 0; i < numRects; i++) {
   4.677 -
   4.678 -            SetRect (&srcRect, rects[i].x, rects[i].y,
   4.679 -                     rects[i].x + rects[i].w,
   4.680 -                     rects[i].y + rects[i].h);
   4.681 -
   4.682 -            SetRect (&dstRect,
   4.683 -                     rects[i].x + offset.h,
   4.684 -                     rects[i].y + offset.v,
   4.685 -                     rects[i].x + rects[i].w + offset.h,
   4.686 -                     rects[i].y + rects[i].h + offset.v);
   4.687 -
   4.688 -            CopyBits (srcBits, dstBits,
   4.689 -                      &srcRect, &dstRect, srcCopy, NULL);
   4.690 -
   4.691 -        }
   4.692 -
   4.693 -        SetPort (savePort);
   4.694 -    }
   4.695      else {
   4.696 -        /* Use QDFlushPortBuffer() to flush content to display */
   4.697 -        int i;
   4.698 -        RgnHandle dirty = NewRgn ();
   4.699 -        RgnHandle temp  = NewRgn ();
   4.700 -
   4.701 -        SetEmptyRgn (dirty);
   4.702 -
   4.703 -        /* Build the region of dirty rectangles */
   4.704 -        for (i = 0; i < numRects; i++) {
   4.705 -
   4.706 -            MacSetRectRgn (temp, rects[i].x, rects[i].y,
   4.707 -                        rects[i].x + rects[i].w, rects[i].y + rects[i].h);
   4.708 -            MacUnionRgn (dirty, temp, dirty);
   4.709 -        }
   4.710 -
   4.711 -        QZ_DrawResizeIcon (this, dirty);
   4.712 +        CGContextRef cgc = (CGContextRef)
   4.713 +            [[NSGraphicsContext graphicsContextWithWindow: qz_window]
   4.714 +                graphicsPort];
   4.715 +        QZ_DrawResizeIcon (this);
   4.716 +        CGContextFlush (cg_context);
   4.717 +        CGImageRef image = CGBitmapContextCreateImage (cg_context);
   4.718 +        CGRect rectangle = CGRectMake (0,0,[window_view frame].size.width,[window_view frame].size.height);
   4.719          
   4.720 -        /* Flush the dirty region */
   4.721 -        QDFlushPortBuffer ( [ window_view qdPort ], dirty );
   4.722 -        DisposeRgn (dirty);
   4.723 -        DisposeRgn (temp);
   4.724 +        CGContextDrawImage (cgc, rectangle, image);
   4.725 +        CGImageRelease(image);
   4.726 +        CGContextFlush (cgc);
   4.727 +        CGContextRelease (cgc);
   4.728      }
   4.729  }
   4.730  
     5.1 --- a/src/video/quartz/SDL_QuartzWM.m	Mon Sep 21 04:34:22 2009 +0000
     5.2 +++ b/src/video/quartz/SDL_QuartzWM.m	Mon Sep 21 06:08:23 2009 +0000
     5.3 @@ -171,11 +171,7 @@
     5.4      else {
     5.5         
     5.6          *p = [ window_view convertPoint:*p toView: nil ];
     5.7 -        
     5.8 -        /* We need a workaround in OpenGL mode */
     5.9 -        if ( SDL_VideoSurface->flags & SDL_OPENGL ) {
    5.10 -            p->y = [window_view frame].size.height - p->y;
    5.11 -        }
    5.12 +        p->y = [window_view frame].size.height - p->y;
    5.13      }
    5.14  }
    5.15  
    5.16 @@ -189,11 +185,7 @@
    5.17      else {
    5.18  
    5.19          *p = [ window_view convertPoint:*p fromView: nil ];
    5.20 -        
    5.21 -        /* We need a workaround in OpenGL mode */
    5.22 -        if ( SDL_VideoSurface != NULL && (SDL_VideoSurface->flags & SDL_OPENGL) ) {
    5.23 -            p->y = [window_view frame].size.height - p->y;
    5.24 -        }
    5.25 +        p->y = [window_view frame].size.height - p->y;
    5.26      }
    5.27  }
    5.28  
     6.1 --- a/src/video/quartz/SDL_QuartzWindow.h	Mon Sep 21 04:34:22 2009 +0000
     6.2 +++ b/src/video/quartz/SDL_QuartzWindow.h	Mon Sep 21 06:08:23 2009 +0000
     6.3 @@ -21,6 +21,10 @@
     6.4  */
     6.5  #include "SDL_config.h"
     6.6  
     6.7 +#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1050
     6.8 +typedef unsigned int NSUInteger;
     6.9 +#endif
    6.10 +
    6.11  /* Subclass of NSWindow to fix genie effect and support resize events  */
    6.12  @interface SDL_QuartzWindow : NSWindow
    6.13  - (void)miniaturize:(id)sender;
    6.14 @@ -29,7 +33,7 @@
    6.15  - (void)appDidHide:(NSNotification*)note;
    6.16  - (void)appWillUnhide:(NSNotification*)note;
    6.17  - (void)appDidUnhide:(NSNotification*)note;
    6.18 -- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
    6.19 +- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag;
    6.20  @end
    6.21  
    6.22  /* Delegate for our NSWindow to send SDLQuit() on close */
     7.1 --- a/src/video/quartz/SDL_QuartzWindow.m	Mon Sep 21 04:34:22 2009 +0000
     7.2 +++ b/src/video/quartz/SDL_QuartzWindow.m	Mon Sep 21 06:08:23 2009 +0000
     7.3 @@ -125,31 +125,6 @@
     7.4          newViewFrame = [ window_view frame ];
     7.5          
     7.6          SDL_PrivateResize (newViewFrame.size.width, newViewFrame.size.height);
     7.7 -
     7.8 -        /* If not OpenGL, we have to update the pixels and pitch */
     7.9 -        if ( ! ( SDL_VideoSurface->flags & SDL_OPENGL ) ) {
    7.10 -            
    7.11 -            CGrafPtr thePort = [ window_view qdPort ];
    7.12 -            LockPortBits ( thePort );
    7.13 -            
    7.14 -            SDL_VideoSurface->pixels = GetPixBaseAddr ( GetPortPixMap ( thePort ) );
    7.15 -            SDL_VideoSurface->pitch  = GetPixRowBytes ( GetPortPixMap ( thePort ) );
    7.16 -                        
    7.17 -            /* 
    7.18 -                SDL_VideoSurface->pixels now points to the window's pixels
    7.19 -                We want it to point to the *view's* pixels 
    7.20 -            */
    7.21 -            { 
    7.22 -                int vOffset = [ qz_window frame ].size.height - 
    7.23 -                    newViewFrame.size.height - newViewFrame.origin.y;
    7.24 -                
    7.25 -                int hOffset = newViewFrame.origin.x;
    7.26 -                        
    7.27 -                SDL_VideoSurface->pixels = (Uint8 *)SDL_VideoSurface->pixels + (vOffset * SDL_VideoSurface->pitch) + hOffset * (device_bpp/8);
    7.28 -            }
    7.29 -            
    7.30 -            UnlockPortBits ( thePort );
    7.31 -        }
    7.32      }
    7.33  }
    7.34  
    7.35 @@ -183,7 +158,7 @@
    7.36      SDL_PrivateAppActive (1, SDL_APPACTIVE);
    7.37  }
    7.38  
    7.39 -- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag
    7.40 +- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag
    7.41  {
    7.42      /* Make our window subclass receive these application notifications */
    7.43      [ [ NSNotificationCenter defaultCenter ] addObserver:self
     8.1 --- a/src/video/quartz/SDL_QuartzYUV.m	Mon Sep 21 04:34:22 2009 +0000
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,330 +0,0 @@
     8.4 -/*
     8.5 -    SDL - Simple DirectMedia Layer
     8.6 -    Copyright (C) 1997-2009  Sam Lantinga
     8.7 -
     8.8 -    This library is free software; you can redistribute it and/or
     8.9 -    modify it under the terms of the GNU Library General Public
    8.10 -    License as published by the Free Software Foundation; either
    8.11 -    version 2 of the License, or (at your option) any later version.
    8.12 -
    8.13 -    This library is distributed in the hope that it will be useful,
    8.14 -    but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    8.16 -    Library General Public License for more details.
    8.17 -
    8.18 -    You should have received a copy of the GNU Library General Public
    8.19 -    License along with this library; if not, write to the Free
    8.20 -    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.21 -
    8.22 -    Sam Lantinga
    8.23 -    slouken@libsdl.org
    8.24 -*/
    8.25 -#include "SDL_config.h"
    8.26 -
    8.27 -#include "SDL_QuartzVideo.h"
    8.28 -#include "SDL_QuartzWindow.h"
    8.29 -#include "../SDL_yuvfuncs.h"
    8.30 -
    8.31 -
    8.32 -#define yuv_idh (this->hidden->yuv_idh)
    8.33 -#define yuv_matrix (this->hidden->yuv_matrix)
    8.34 -#define yuv_codec (this->hidden->yuv_codec)
    8.35 -#define yuv_seq (this->hidden->yuv_seq)
    8.36 -#define yuv_pixmap (this->hidden->yuv_pixmap)
    8.37 -#define yuv_data (this->hidden->yuv_data)
    8.38 -#define yuv_width (this->hidden->yuv_width)
    8.39 -#define yuv_height (this->hidden->yuv_height)
    8.40 -#define yuv_port (this->hidden->yuv_port)
    8.41 -
    8.42 -
    8.43 -static int QZ_LockYUV (_THIS, SDL_Overlay *overlay) {
    8.44 -
    8.45 -    return 0;
    8.46 -}
    8.47 -
    8.48 -static void QZ_UnlockYUV (_THIS, SDL_Overlay *overlay) {
    8.49 -
    8.50 -    ;
    8.51 -}
    8.52 -
    8.53 -static int QZ_DisplayYUV (_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) {
    8.54 -
    8.55 -    OSErr err;
    8.56 -    CodecFlags flags;
    8.57 -
    8.58 -    if (dst->x != 0 || dst->y != 0) {
    8.59 -
    8.60 -        SDL_SetError ("Need a dst at (0,0)");
    8.61 -        return -1;
    8.62 -    }
    8.63 -
    8.64 -    if (dst->w != yuv_width || dst->h != yuv_height) {
    8.65 -
    8.66 -        Fixed scale_x, scale_y;
    8.67 -
    8.68 -        scale_x = FixDiv ( Long2Fix (dst->w), Long2Fix (overlay->w) );
    8.69 -        scale_y = FixDiv ( Long2Fix (dst->h), Long2Fix (overlay->h) );
    8.70 -
    8.71 -        SetIdentityMatrix (yuv_matrix);
    8.72 -        ScaleMatrix (yuv_matrix, scale_x, scale_y, Long2Fix (0), Long2Fix (0));
    8.73 -
    8.74 -        SetDSequenceMatrix (yuv_seq, yuv_matrix);
    8.75 -
    8.76 -        yuv_width = dst->w;
    8.77 -        yuv_height = dst->h;
    8.78 -    }
    8.79 -
    8.80 -    if( ( err = DecompressSequenceFrameS(
    8.81 -                                         yuv_seq,
    8.82 -                                         (void*)yuv_pixmap,
    8.83 -                                         sizeof (PlanarPixmapInfoYUV420),
    8.84 -                                         codecFlagUseImageBuffer, &flags, nil ) != noErr ) )
    8.85 -    {
    8.86 -        SDL_SetError ("DecompressSequenceFrameS failed");
    8.87 -    }
    8.88 -
    8.89 -    return err != noErr;
    8.90 -}
    8.91 -
    8.92 -static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) {
    8.93 -
    8.94 -    CDSequenceEnd (yuv_seq);
    8.95 -    ExitMovies();
    8.96 -
    8.97 -    SDL_free (overlay->hwfuncs);
    8.98 -    SDL_free (overlay->pitches);
    8.99 -    SDL_free (overlay->pixels);
   8.100 -
   8.101 -    if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
   8.102 -        [ qz_window close ];
   8.103 -        qz_window = nil;
   8.104 -    }
   8.105 -
   8.106 -    SDL_free (yuv_matrix);
   8.107 -    DisposeHandle ((Handle)yuv_idh);
   8.108 -}
   8.109 -
   8.110 -/* check for 16 byte alignment, bail otherwise */
   8.111 -#define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0)
   8.112 -
   8.113 -/* align a byte offset, return how much to add to make it a multiple of 16 */
   8.114 -#define ALIGN(x) ((16 - (x & 15)) & 15)
   8.115 -
   8.116 -SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,
   8.117 -                                         Uint32 format, SDL_Surface *display) {
   8.118 -
   8.119 -    Uint32 codec;
   8.120 -    OSStatus err;
   8.121 -    CGrafPtr port;
   8.122 -    SDL_Overlay *overlay;
   8.123 -
   8.124 -    if (format == SDL_YV12_OVERLAY ||
   8.125 -        format == SDL_IYUV_OVERLAY) {
   8.126 -
   8.127 -        codec = kYUV420CodecType;
   8.128 -    }
   8.129 -    else {
   8.130 -        SDL_SetError ("Hardware: unsupported video format");
   8.131 -        return NULL;
   8.132 -    }
   8.133 -
   8.134 -    yuv_idh = (ImageDescriptionHandle) NewHandleClear (sizeof(ImageDescription));
   8.135 -    if (yuv_idh == NULL) {
   8.136 -        SDL_OutOfMemory();
   8.137 -        return NULL;
   8.138 -    }
   8.139 -
   8.140 -    yuv_matrix = (MatrixRecordPtr) SDL_malloc (sizeof(MatrixRecord));
   8.141 -    if (yuv_matrix == NULL) {
   8.142 -        SDL_OutOfMemory();
   8.143 -        return NULL;
   8.144 -    }
   8.145 -
   8.146 -    if ( EnterMovies() != noErr ) {
   8.147 -        SDL_SetError ("Could not init QuickTime for YUV playback");
   8.148 -        return NULL;
   8.149 -    }
   8.150 -
   8.151 -    err = FindCodec (codec, bestSpeedCodec, nil, &yuv_codec);
   8.152 -    if (err != noErr) {
   8.153 -        SDL_SetError ("Could not find QuickTime codec for format");
   8.154 -        return NULL;
   8.155 -    }
   8.156 -
   8.157 -    if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {
   8.158 -
   8.159 -        /*
   8.160 -          Acceleration requires a window to be present.
   8.161 -          A CGrafPtr that points to the screen isn't good enough
   8.162 -        */
   8.163 -        NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
   8.164 -
   8.165 -        qz_window = [ [ SDL_QuartzWindow alloc ]
   8.166 -                            initWithContentRect:content
   8.167 -                            styleMask:NSBorderlessWindowMask
   8.168 -                            backing:NSBackingStoreBuffered defer:NO ];
   8.169 -
   8.170 -        if (qz_window == nil) {
   8.171 -            SDL_SetError ("Could not create the Cocoa window");
   8.172 -            return NULL;
   8.173 -        }
   8.174 -
   8.175 -        [ qz_window setContentView:[ [ NSQuickDrawView alloc ] init ] ];
   8.176 -        [ qz_window setReleasedWhenClosed:YES ];
   8.177 -        [ qz_window center ];
   8.178 -        [ qz_window setAcceptsMouseMovedEvents:YES ];
   8.179 -        [ qz_window setLevel:CGShieldingWindowLevel() ];
   8.180 -        [ qz_window makeKeyAndOrderFront:nil ];
   8.181 -
   8.182 -        port = [ [ qz_window contentView ] qdPort ];
   8.183 -        SetPort (port);
   8.184 -        
   8.185 -        /*
   8.186 -            BUG: would like to remove white flash when window kicks in
   8.187 -            {
   8.188 -                Rect r;
   8.189 -                SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
   8.190 -                PaintRect (&r);
   8.191 -                QDFlushPortBuffer (port, nil);
   8.192 -            }
   8.193 -        */
   8.194 -    }
   8.195 -    else {
   8.196 -        port = [ window_view qdPort ];
   8.197 -        SetPort (port);
   8.198 -    }
   8.199 -    
   8.200 -    SetIdentityMatrix (yuv_matrix);
   8.201 -    
   8.202 -    HLock ((Handle)yuv_idh);
   8.203 -    
   8.204 -    (**yuv_idh).idSize = sizeof(ImageDescription);
   8.205 -    (**yuv_idh).cType  = codec;
   8.206 -    (**yuv_idh).version = 1;
   8.207 -    (**yuv_idh).revisionLevel = 0;
   8.208 -    (**yuv_idh).width = width;
   8.209 -    (**yuv_idh).height = height;
   8.210 -    (**yuv_idh).hRes = Long2Fix(72);
   8.211 -    (**yuv_idh).vRes = Long2Fix(72);
   8.212 -    (**yuv_idh).spatialQuality = codecLosslessQuality;
   8.213 -    (**yuv_idh).frameCount = 1;
   8.214 -    (**yuv_idh).clutID = -1;
   8.215 -    (**yuv_idh).dataSize = 0;
   8.216 -    (**yuv_idh).depth = 24;
   8.217 -    
   8.218 -    HUnlock ((Handle)yuv_idh);
   8.219 -    
   8.220 -    err = DecompressSequenceBeginS (
   8.221 -                                    &yuv_seq,
   8.222 -                                    yuv_idh,
   8.223 -                                    NULL,
   8.224 -                                    0,
   8.225 -                                    port,
   8.226 -                                    NULL,
   8.227 -                                    NULL,
   8.228 -                                    yuv_matrix,
   8.229 -                                    0,
   8.230 -                                    NULL,
   8.231 -                                    codecFlagUseImageBuffer,
   8.232 -                                    codecLosslessQuality,
   8.233 -                                    yuv_codec);
   8.234 -    
   8.235 -    if (err != noErr) {
   8.236 -        SDL_SetError ("Error trying to start YUV codec.");
   8.237 -        return NULL;
   8.238 -    }
   8.239 -    
   8.240 -    overlay = (SDL_Overlay*) SDL_malloc (sizeof(*overlay));
   8.241 -    if (overlay == NULL) {
   8.242 -        SDL_OutOfMemory();
   8.243 -        return NULL;
   8.244 -    }
   8.245 -    
   8.246 -    overlay->format      = format;
   8.247 -    overlay->w           = width;
   8.248 -    overlay->h           = height;
   8.249 -    overlay->planes      = 3;
   8.250 -    overlay->hw_overlay  = 1;
   8.251 -    {
   8.252 -        int      offset;
   8.253 -        Uint8  **pixels;
   8.254 -        Uint16  *pitches;
   8.255 -        int      plane2, plane3;
   8.256 -
   8.257 -        if (format == SDL_IYUV_OVERLAY) {
   8.258 -
   8.259 -            plane2 = 1; /* Native codec format */
   8.260 -            plane3 = 2;
   8.261 -        }
   8.262 -        else if (format == SDL_YV12_OVERLAY) {
   8.263 -
   8.264 -            /* switch the U and V planes */
   8.265 -            plane2 = 2; /* U plane maps to plane 3 */
   8.266 -            plane3 = 1; /* V plane maps to plane 2 */
   8.267 -        }
   8.268 -        else {
   8.269 -            SDL_SetError("Unsupported YUV format");
   8.270 -            return NULL;
   8.271 -        }
   8.272 -
   8.273 -        pixels = (Uint8**) SDL_malloc (sizeof(*pixels) * 3);
   8.274 -        pitches = (Uint16*) SDL_malloc (sizeof(*pitches) * 3);
   8.275 -        if (pixels == NULL || pitches == NULL) {
   8.276 -            SDL_OutOfMemory();
   8.277 -            return NULL;
   8.278 -        }
   8.279 -
   8.280 -        /* Fix: jc.bertin@free.fr
   8.281 -           PlanarPixmapInfoYUV420 is a big-endian struct */
   8.282 -        yuv_pixmap = (PlanarPixmapInfoYUV420*)
   8.283 -            SDL_malloc (sizeof(PlanarPixmapInfoYUV420) +
   8.284 -                    (width * height * 2));
   8.285 -        if (yuv_pixmap == NULL) {
   8.286 -            SDL_OutOfMemory ();
   8.287 -            return NULL;
   8.288 -        }
   8.289 -
   8.290 -        /* CHECK_ALIGN(yuv_pixmap); */
   8.291 -        offset  = sizeof(PlanarPixmapInfoYUV420);
   8.292 -        /* offset += ALIGN(offset); */
   8.293 -        /* CHECK_ALIGN(offset); */
   8.294 -
   8.295 -        pixels[0] = (Uint8*)yuv_pixmap + offset;
   8.296 -        /* CHECK_ALIGN(pixels[0]); */
   8.297 -
   8.298 -        pitches[0] = width;
   8.299 -        yuv_pixmap->componentInfoY.offset = EndianS32_NtoB(offset);
   8.300 -        yuv_pixmap->componentInfoY.rowBytes = EndianU32_NtoB(width);
   8.301 -
   8.302 -        offset += width * height;
   8.303 -        pixels[plane2] = (Uint8*)yuv_pixmap + offset;
   8.304 -        pitches[plane2] = width / 2;
   8.305 -        yuv_pixmap->componentInfoCb.offset = EndianS32_NtoB(offset);
   8.306 -        yuv_pixmap->componentInfoCb.rowBytes = EndianU32_NtoB(width / 2);
   8.307 -
   8.308 -        offset += (width * height / 4);
   8.309 -        pixels[plane3] = (Uint8*)yuv_pixmap + offset;
   8.310 -        pitches[plane3] = width / 2;
   8.311 -        yuv_pixmap->componentInfoCr.offset = EndianS32_NtoB(offset);
   8.312 -        yuv_pixmap->componentInfoCr.rowBytes = EndianU32_NtoB(width / 2);
   8.313 -
   8.314 -        overlay->pixels = pixels;
   8.315 -        overlay->pitches = pitches;
   8.316 -    }
   8.317 -
   8.318 -    overlay->hwfuncs = SDL_malloc (sizeof(*overlay->hwfuncs));
   8.319 -    if (overlay->hwfuncs == NULL) {
   8.320 -        SDL_OutOfMemory();
   8.321 -        return NULL;
   8.322 -    }
   8.323 -    
   8.324 -    overlay->hwfuncs->Lock    = QZ_LockYUV;
   8.325 -    overlay->hwfuncs->Unlock  = QZ_UnlockYUV;
   8.326 -    overlay->hwfuncs->Display = QZ_DisplayYUV;
   8.327 -    overlay->hwfuncs->FreeHW  = QZ_FreeHWYUV;
   8.328 -
   8.329 -    yuv_width = overlay->w;
   8.330 -    yuv_height = overlay->h;
   8.331 -    
   8.332 -    return overlay;
   8.333 -}