diff -Naur SDL-1.2.11-orig/src/main/macosx/SDLMain.m SDL-1.2.11/src/main/macosx/SDLMain.m --- SDL-1.2.11-orig/src/main/macosx/SDLMain.m 2006-05-11 20:02:32.000000000 -0700 +++ SDL-1.2.11/src/main/macosx/SDLMain.m 2007-03-06 11:41:19.000000000 -0800 @@ -372,6 +372,9 @@ gArgv[i] = argv[i]; gFinderLaunch = NO; } + + /* In case this is a carbon application we need to call NSApplicationLoad(); */ + if(!NSApplicationLoad()) return -1; #if SDL_USE_NIB_FILE [SDLApplication poseAsClass:[NSApplication class]]; diff -Naur SDL-1.2.11-orig/src/video/quartz/SDL_QuartzVideo.h SDL-1.2.11/src/video/quartz/SDL_QuartzVideo.h --- SDL-1.2.11-orig/src/video/quartz/SDL_QuartzVideo.h 2006-05-01 01:02:46.000000000 -0700 +++ SDL-1.2.11/src/video/quartz/SDL_QuartzVideo.h 2007-03-06 11:41:19.000000000 -0800 @@ -92,6 +92,7 @@ Uint32 warp_flag; /* boolean; notify to event loop that a warp just occured */ Uint32 warp_ticks; /* timestamp when the warp occured */ NSWindow *window; /* Cocoa window to implement the SDL window */ + BOOL window_should_be_closed; /* Call [window close]; when tearing down? */ NSQuickDrawView *view; /* the window's view; draw 2D and OpenGL into this view */ SDL_Surface *resize_icon; /* icon for the resize badge, we have to draw it by hand */ SDL_GrabMode current_grab_mode; /* default value is SDL_GRAB_OFF */ @@ -135,6 +136,7 @@ #define device_bpp (this->hidden->bpp) #define mode_flags (this->hidden->flags) #define qz_window (this->hidden->window) +#define qz_window_should_be_closed (this->hidden->window_should_be_closed) #define window_view (this->hidden->view) #define video_set (this->hidden->video_set) #define warp_ticks (this->hidden->warp_ticks) diff -Naur SDL-1.2.11-orig/src/video/quartz/SDL_QuartzVideo.m SDL-1.2.11/src/video/quartz/SDL_QuartzVideo.m --- SDL-1.2.11-orig/src/video/quartz/SDL_QuartzVideo.m 2006-05-01 04:06:53.000000000 -0700 +++ SDL-1.2.11/src/video/quartz/SDL_QuartzVideo.m 2007-03-06 11:46:51.000000000 -0800 @@ -340,11 +340,15 @@ return client_mode_list; } -static SDL_bool QZ_WindowPosition(_THIS, int *x, int *y) +static SDL_bool QZ_WindowPosition(_THIS, int *x, int *y, BOOL flipVertical) { const char *window = getenv("SDL_VIDEO_WINDOW_POS"); if ( window ) { if ( sscanf(window, "%d,%d", x, y) == 2 ) { + if(flipVertical) { + NSRect screenRect = [[NSScreen mainScreen] frame]; + *y = (screenRect.size.height - 1) - *y; + } return SDL_TRUE; } } @@ -400,10 +404,12 @@ /* Release window mode resources */ else { - [ qz_window close ]; - [ qz_window release ]; - qz_window = nil; - window_view = nil; + if ( qz_window_should_be_closed ) { + [ qz_window close ]; + [ qz_window release ]; + qz_window = nil; + window_view = nil; + } /* Release the OpenGL context */ if ( mode_flags & SDL_OPENGL ) @@ -582,6 +588,7 @@ unsigned int style; NSRect contentRect; BOOL isCustom = NO; + BOOL usingCarbonWindow = FALSE; int center_window = 1; int origin_x, origin_y; CGDisplayFadeReservationToken fade_token = kCGDisplayFadeReservationInvalidToken; @@ -631,6 +638,7 @@ qz_window = (NSWindow*)atoi(windowPtrString); window_view = (NSQuickDrawView*)atoi(viewPtrString); isCustom = YES; + qz_window_should_be_closed = FALSE; /* Retain reference to window because we @@ -648,6 +656,80 @@ current->flags |= SDL_NOFRAME; } } + + /* Check for user-specified Carbon window and view position + specified with SDL_WINDOWID and SDL_VIDEO_WINDOW_POS environment variables */ + { + char *carbonWindowPtrString = getenv ("SDL_WINDOWID"); + if (carbonWindowPtrString) { + usingCarbonWindow = TRUE; + isCustom = YES; + WindowRef windowRef = (WindowRef)atoi(carbonWindowPtrString); + NSWindow *cocoaFromCarbonWin = [[NSWindow alloc] initWithWindowRef:windowRef]; + + /* On OS 10.3 it seems that on the first play, if the top-level window has previously been resized, + the frame width/height as gotten from initWithWindowRef is for an old size + i.e. doesn't agree with the current correct size as gotten directly from GetWindowBounds. + Correct that here *only* if and when needed. */ + Rect winBounds; + GetWindowBounds(windowRef, kWindowContentRgn, &winBounds ); + Rect tbBounds; + GetWindowBounds(windowRef, kWindowTitleBarRgn, &tbBounds ); + NSRect correctedFrameRect; + correctedFrameRect.origin.x = winBounds.left; + correctedFrameRect.origin.y = winBounds.top; + correctedFrameRect.size.width = winBounds.right - winBounds.left; + correctedFrameRect.size.height = + (tbBounds.bottom - tbBounds.top) + (winBounds.bottom - winBounds.top); + if(([ cocoaFromCarbonWin frame ].size.width != correctedFrameRect.size.width) + || ([ cocoaFromCarbonWin frame ].size.height != correctedFrameRect.size.height)) { + [cocoaFromCarbonWin setFrame:correctedFrameRect display:NO animate:NO]; + } + + /* Only replace the previous window if it has changed */ + /* Note that initWithWindowRef always returns the same result for the same WindowRef */ + if(cocoaFromCarbonWin != qz_window) { + /* Release any previous window */ + if ( qz_window ) { + [ qz_window release ]; + qz_window = nil; + } + qz_window = cocoaFromCarbonWin; + qz_window_should_be_closed = FALSE; + + /* + Retain reference to window because we + might release it in QZ_UnsetVideoMode + */ + [ qz_window retain ]; + + window_view = nil; + } + + /* Check for SDL_VIDEO_WINDOW_POS environment variable */ + if ( QZ_WindowPosition(this, &origin_x, &origin_y, FALSE) ) { + /* origin_x/y are in screen coordinates but we need to set contentRect in window coordinates */ + contentRect.origin.x = (float)(origin_x - winBounds.left); + contentRect.origin.y = (float)(-origin_y + winBounds.bottom); + /* Unless you make w and h of the view 1 and 1, it will crash later. */ + contentRect.size.width = 1; + contentRect.size.height = 1; + /* If window_view doesn't exist, it will be created below using contentRect, + but if it already exists then we need to reposition it here. */ + if (window_view != nil) { + NSPoint viewOrigin; + viewOrigin.x = contentRect.origin.x; + viewOrigin.y = contentRect.origin.y; + [ window_view setFrameOrigin:viewOrigin ]; + /* this is required for proper display */ + [ qz_window orderOut:nil ]; + [ qz_window makeKeyAndOrderFront:nil ]; + } + } + + + } + } /* Check if we should recreate the window */ if (qz_window == nil) { @@ -665,7 +747,7 @@ } } - if ( QZ_WindowPosition(this, &origin_x, &origin_y) ) { + if ( QZ_WindowPosition(this, &origin_x, &origin_y, FALSE) ) { center_window = 0; contentRect.origin.x = (float)origin_x; contentRect.origin.y = (float)origin_y; @@ -677,6 +759,7 @@ styleMask:style backing:NSBackingStoreBuffered defer:NO ]; + qz_window_should_be_closed = TRUE; if (qz_window == nil) { SDL_SetError ("Could not create the Cocoa window"); @@ -735,11 +818,25 @@ if (window_view == nil) { window_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ]; - [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ]; + if (!usingCarbonWindow) { /* should this really be "if (!(current->flags & SDL_RESIZABLE))" ?*/ + [ window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ]; + } [ [ qz_window contentView ] addSubview:window_view ]; [ window_view release ]; + if (usingCarbonWindow) { + /* this is required for proper display */ + [ qz_window orderOut:nil ]; + } [ qz_window makeKeyAndOrderFront:nil ]; } + + /* Sometimes qdPort is NULL and to fix that we need to lockFocus/unlockFocus + on the NSView. This is needed sometimes on OS 10.3 for example. + See http://developer.apple.com/samplecode/MungSaver/listing2.html */ + if([ window_view qdPort ] == NULL) { + [ window_view lockFocus ]; + [ window_view unlockFocus ]; + } LockPortBits ( [ window_view qdPort ] ); current->pixels = GetPixBaseAddr ( GetPortPixMap ( [ window_view qdPort ] ) );