src/video/macrom/SDL_romvideo.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 25 Jul 2004 19:43:56 +0000
changeset 916 46916168361d
parent 774 0c3e00cc9580
child 1032 c1c2efca4548
permissions -rw-r--r--
Date: Sun, 25 Jul 2004 23:10:03 +0800
From: Chris Taylor
Subject: SDL for Macintosh Programmer's Workshop: removed dynamic loading

I'm working on a game called D2X which uses SDL, and I recently ported
it to Mac OS 9. I used MPW to build it. It uses OpenGL. To get it to
work, I had to build SDL so it doesn't dynamically load OpenGL. This is
because I don't think MPW supports dynamic loading. The following patch
makes sure when SDL is built under MPW, dynamic loading of shared
libraries is disabled.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 #include <stdio.h>
    29 #include <stdlib.h>
    30 
    31 #if TARGET_API_MAC_CARBON
    32 #include <Carbon.h>
    33 /* The fullscreen code requires the QuickTime framework, and the window
    34    is still at the back on MacOS X, which is where this code is needed.
    35  */
    36 #if USE_QUICKTIME
    37 #include <QuickTime/Movies.h>
    38 #endif
    39 #else
    40 #include <LowMem.h>
    41 #include <Gestalt.h>
    42 #include <Devices.h>
    43 #include <DiskInit.h>
    44 #include <QDOffscreen.h>
    45 #endif
    46 
    47 #include "SDL_video.h"
    48 #include "SDL_error.h"
    49 #include "SDL_syswm.h"
    50 #include "SDL_sysvideo.h"
    51 #include "SDL_romvideo.h"
    52 #include "SDL_macgl_c.h"
    53 #include "SDL_macwm_c.h"
    54 #include "SDL_macmouse_c.h"
    55 #include "SDL_macevents_c.h"
    56 
    57 /* Initialization/Query functions */
    58 static int ROM_VideoInit(_THIS, SDL_PixelFormat *vformat);
    59 static SDL_Rect **ROM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
    60 static SDL_Surface *ROM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
    61 static int ROM_SetColors(_THIS, int firstcolor, int ncolors,
    62 			 SDL_Color *colors);
    63 static void ROM_VideoQuit(_THIS);
    64 
    65 /* Hardware surface functions */
    66 static int ROM_AllocHWSurface(_THIS, SDL_Surface *surface);
    67 static int ROM_LockHWSurface(_THIS, SDL_Surface *surface);
    68 static void ROM_UnlockHWSurface(_THIS, SDL_Surface *surface);
    69 static void ROM_FreeHWSurface(_THIS, SDL_Surface *surface);
    70 
    71 #if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
    72 /* Saved state for the menu bar */
    73 static RgnHandle	gSaveGrayRgn = nil;
    74 static short		gSaveMenuBar = 0;
    75 static Boolean		gSaveCSVis = true;
    76 
    77 #if powerc
    78 /* Mixed mode glue to activate the 68K emulator and twiddle a register */
    79 #define ONEWORDSTUB(p1) \
    80 		{ 0x41FA, 0x0010, 0x209F, (p1), 0x41FA, \
    81 		  0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
    82 
    83 #define TWOWORDSTUB(p1,p2) \
    84 		{ 0x41FA, 0x0012, 0x209F, (p1), (p2), 0x41FA, \
    85 		  0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
    86 
    87 #define THREEWORDSTUB(p1,p2,p3) \
    88 		{ 0x41FA, 0x0014, 0x209F, (p1), (p2), (p3), 0x41FA, \
    89 		  0x0008, 0x2F10, 0x4E75, 0x0000, 0x0000, 0x0000 }
    90 
    91 /* ControlStrip inline glue for PowerPC */
    92 static pascal Boolean SBIsControlStripVisible(void)
    93 {
    94 	static short procData[] = TWOWORDSTUB(0x7000, 0xAAF2);
    95 	ProcInfoType procInfo = kD0DispatchedPascalStackBased
    96 				| RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
    97             	| DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode);
    98             				
    99 	return((Boolean) CallUniversalProc((UniversalProcPtr) procData, procInfo, 0x00));
   100 }
   101 
   102 static pascal void SBShowHideControlStrip(Boolean showIt)
   103 {
   104 	static short procData[] = THREEWORDSTUB(0x303C, 0x0101, 0xAAF2);
   105 	ProcInfoType procInfo = kD0DispatchedPascalStackBased
   106 				| DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kFourByteCode)
   107 				| DISPATCHED_STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Boolean)));
   108 
   109 	CallUniversalProc((UniversalProcPtr) procData, procInfo, 0x01, showIt);
   110 }
   111 #endif /* powerc */
   112 #endif /* !TARGET_API_MAC_CARBON */
   113 
   114 /* Macintosh toolbox driver bootstrap functions */
   115 
   116 static int ROM_Available(void)
   117 {
   118 	return(1);
   119 }
   120 
   121 static void ROM_DeleteDevice(SDL_VideoDevice *device)
   122 {
   123 	free(device->hidden);
   124 	free(device);
   125 }
   126 
   127 static SDL_VideoDevice *ROM_CreateDevice(int devindex)
   128 {
   129 	SDL_VideoDevice *device;
   130 
   131 	/* Initialize all variables that we clean on shutdown */
   132 	device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
   133 	if ( device ) {
   134 		memset(device, 0, (sizeof *device));
   135 		device->hidden = (struct SDL_PrivateVideoData *)
   136 				malloc((sizeof *device->hidden));
   137 	}
   138 	if ( (device == NULL) || (device->hidden == NULL) ) {
   139 		SDL_OutOfMemory();
   140 		if ( device ) {
   141 			free(device);
   142 		}
   143 		return(0);
   144 	}
   145 	memset(device->hidden, 0, (sizeof *device->hidden));
   146 
   147 	/* Set the function pointers */
   148 	device->VideoInit = ROM_VideoInit;
   149 	device->ListModes = ROM_ListModes;
   150 	device->SetVideoMode = ROM_SetVideoMode;
   151 	device->SetColors = ROM_SetColors;
   152 	device->UpdateRects = NULL;
   153 	device->VideoQuit = ROM_VideoQuit;
   154 	device->AllocHWSurface = ROM_AllocHWSurface;
   155 	device->CheckHWBlit = NULL;
   156 	device->FillHWRect = NULL;
   157 	device->SetHWColorKey = NULL;
   158 	device->SetHWAlpha = NULL;
   159 	device->LockHWSurface = ROM_LockHWSurface;
   160 	device->UnlockHWSurface = ROM_UnlockHWSurface;
   161 	device->FlipHWSurface = NULL;
   162 	device->FreeHWSurface = ROM_FreeHWSurface;
   163 #ifdef HAVE_OPENGL
   164 	device->GL_MakeCurrent = Mac_GL_MakeCurrent;
   165 	device->GL_SwapBuffers = Mac_GL_SwapBuffers;
   166 #ifdef __MWERKS__
   167 	device->GL_LoadLibrary = Mac_GL_LoadLibrary;
   168 	device->GL_GetProcAddress = Mac_GL_GetProcAddress;
   169 #else
   170 	device->GL_LoadLibrary = NULL;
   171 	device->GL_GetProcAddress = NULL;
   172 #endif	// CodeWarrior
   173 #endif	// Have OpenGL
   174 	device->SetCaption = Mac_SetCaption;
   175 	device->SetIcon = NULL;
   176 	device->IconifyWindow = NULL;
   177 	device->GrabInput = NULL;
   178 	device->GetWMInfo = NULL;
   179 	device->FreeWMCursor = Mac_FreeWMCursor;
   180 	device->CreateWMCursor = Mac_CreateWMCursor;
   181 	device->ShowWMCursor = Mac_ShowWMCursor;
   182 	device->WarpWMCursor = Mac_WarpWMCursor;
   183 	device->InitOSKeymap = Mac_InitOSKeymap;
   184 	device->PumpEvents = Mac_PumpEvents;
   185 
   186 	device->free = ROM_DeleteDevice;
   187 
   188 	return device;
   189 }
   190 
   191 VideoBootStrap TOOLBOX_bootstrap = {
   192 	"toolbox", "MacOS ROM Toolbox",
   193 	ROM_Available, ROM_CreateDevice
   194 };
   195 
   196 
   197 static int ROM_VideoInit(_THIS, SDL_PixelFormat *vformat)
   198 {
   199 	long info;
   200 	
   201 	/* Check out some things about the system */
   202 	Gestalt(gestaltQuickdrawVersion, &info);
   203 	if ( info == gestaltOriginalQD ) {
   204 		SDL_SetError("Color Quickdraw not available");
   205 		return(-1);
   206 	}
   207 
   208 	/* Start ROMintosh events */
   209 	Mac_InitEvents(this);
   210 
   211 	/* Get a handle to the main monitor */
   212 	SDL_Display = GetMainDevice();
   213 
   214 	/* Determine pixel format */
   215 	vformat->BitsPerPixel = (**(**SDL_Display).gdPMap).pixelSize;
   216 	switch (vformat->BitsPerPixel) {
   217 		case 16:	/* 5-5-5 RGB */
   218 			vformat->Rmask = 0x00007c00;
   219 			vformat->Gmask = 0x000003e0;
   220 			vformat->Bmask = 0x0000001f;
   221 			break;
   222 		default:
   223 			break;
   224 	}
   225 
   226 	/* Create our palette */
   227 	SDL_CTab = (CTabHandle)NewHandle(sizeof(ColorSpec)*256 + 8);
   228 	if ( SDL_CTab == nil ) {
   229 		SDL_OutOfMemory();
   230 		return(-1);
   231 	}
   232 	(**SDL_CTab).ctSeed = GetCTSeed();
   233 	(**SDL_CTab).ctFlags = 0;
   234 	(**SDL_CTab).ctSize = 255;
   235 	CTabChanged(SDL_CTab);
   236 	SDL_CPal = NewPalette(256, SDL_CTab, pmExplicit+pmTolerant, 0);
   237 
   238 	/* Get a list of available fullscreen modes */
   239 	SDL_modelist = (SDL_Rect **)malloc((1+1)*sizeof(SDL_Rect *));
   240 	if ( SDL_modelist ) {
   241 		SDL_modelist[0] = (SDL_Rect *)malloc(sizeof(SDL_Rect));
   242 		if ( SDL_modelist[0] ) {
   243 			SDL_modelist[0]->x = 0;
   244 			SDL_modelist[0]->y = 0;
   245 			SDL_modelist[0]->w = (**SDL_Display).gdRect.right;
   246 			SDL_modelist[0]->h = (**SDL_Display).gdRect.bottom;
   247 		}
   248 		SDL_modelist[1] = NULL;
   249 	}
   250 
   251 	/* Fill in some window manager capabilities */
   252 	this->info.wm_available = 1;
   253 
   254 	/* We're done! */
   255 	return(0);
   256 }
   257 
   258 static SDL_Rect **ROM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
   259 {
   260 	if ( this->screen->format->BitsPerPixel == format->BitsPerPixel ) {
   261 		if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
   262 			return(SDL_modelist);
   263 		} else {
   264 			return((SDL_Rect **)-1);
   265 		}
   266 	} else {
   267 		return((SDL_Rect **)0);
   268 	}
   269 }
   270 
   271 static void ROM_HideMenuBar(_THIS)
   272 {
   273 #if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
   274 	RgnHandle		drawRgn = nil;
   275 	RgnHandle		tempRgn = nil;
   276 	RgnHandle		grayRgn = nil;
   277 	WindowPtr		window = nil;
   278 	GDHandle		gd = nil;
   279 	GrafPtr			savePort;
   280 	long			response;
   281 	short			height;
   282 	EventRecord		theEvent;
   283 
   284 	height = GetMBarHeight();
   285 	
   286 	if ( height > 0 ) {
   287 		tempRgn = NewRgn();
   288 		drawRgn = NewRgn();
   289 		gSaveGrayRgn = NewRgn();
   290 		if ( ! tempRgn || ! drawRgn || ! gSaveGrayRgn ) {
   291 			goto CLEANUP;
   292 		}
   293 		grayRgn = GetGrayRgn(); /* No need to check for this */
   294 	
   295 		GetPort(&savePort);
   296 
   297 		/* Hide the control strip if it's present, and record its 
   298 		   previous position into the dirty region for redrawing. 
   299 		   This isn't necessary, but may help catch stray bits. */
   300 		CopyRgn(grayRgn, tempRgn);
   301 		if (!Gestalt(gestaltControlStripAttr, &response) && 
   302 			(response & (1L << gestaltControlStripExists))) {
   303 			gSaveCSVis = SBIsControlStripVisible();
   304 			if (gSaveCSVis)
   305 				SBShowHideControlStrip(false);
   306 		}
   307 		DiffRgn(grayRgn, tempRgn, drawRgn);
   308 
   309 		/* Save the gray region once the control strip is hidden*/
   310 		CopyRgn(grayRgn, gSaveGrayRgn);
   311 
   312 		/* Change the menu height in lowmem */
   313 		gSaveMenuBar = height;
   314 		LMSetMBarHeight(0);
   315 		
   316 		/* Walk the monitor rectangles, and combine any pieces that
   317 		   aren't in GrayRgn: menubar, round corners, fake floaters. */
   318 		for(gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) 
   319 			{
   320 			if (!TestDeviceAttribute(gd, screenDevice)) continue;
   321 			if (!TestDeviceAttribute(gd, screenActive)) continue;
   322 
   323 			RectRgn(tempRgn, &(*gd)->gdRect);	/* Get the whole screen */
   324 			DiffRgn(tempRgn, grayRgn, tempRgn); /* Subtract out GrayRgn */
   325 			UnionRgn(tempRgn, drawRgn, drawRgn);/* Combine all the bits */
   326 			}
   327 			
   328 		/* Add the bits into the GrayRgn */
   329 		UnionRgn(drawRgn, grayRgn, grayRgn);
   330 
   331 		/* Modify the vis regions of exposed windows */
   332 		window = (FrontWindow()) ? FrontWindow() : (WindowPtr) -1L;
   333 		PaintBehind(window, drawRgn);
   334 		CalcVisBehind(window, drawRgn);
   335 
   336 		SetPort(savePort);
   337 		
   338 		/* Yield time so that floaters can catch up */
   339 		EventAvail(0, &theEvent);
   340 		EventAvail(0, &theEvent);
   341 		EventAvail(0, &theEvent);
   342 		EventAvail(0, &theEvent);
   343 		}
   344 
   345 CLEANUP:
   346 
   347 	if (tempRgn) DisposeRgn(tempRgn);
   348 	if (drawRgn) DisposeRgn(drawRgn);
   349 #endif /* !TARGET_API_MAC_CARBON */
   350 }
   351 	
   352 static void ROM_ShowMenuBar(_THIS)
   353 {
   354 #if !TARGET_API_MAC_CARBON /* This seems not to be available? -sts Aug 2000 */
   355 	RgnHandle		drawRgn = nil;
   356 	RgnHandle		menuRgn = nil;
   357 	RgnHandle		tempRgn = nil;
   358 	RgnHandle		grayRgn = nil;
   359 	WindowPtr		window = nil;
   360 	GrafPtr			wMgrPort;
   361 	GrafPtr			savePort;
   362 	Rect			menuRect;
   363 	long			response;
   364 	short			height;
   365 	EventRecord		theEvent;
   366 	RGBColor		saveRGB;
   367 	RGBColor		blackRGB = { 0, 0, 0 };
   368 
   369 	height = GetMBarHeight();
   370 	
   371 	if ((height <= 0) && (gSaveMenuBar > 0)) {
   372 		drawRgn = NewRgn();
   373 		menuRgn = NewRgn();
   374 		tempRgn = NewRgn();
   375 		if ( ! tempRgn || ! drawRgn || ! gSaveGrayRgn ) {
   376 			goto CLEANUP;
   377 		}
   378 		grayRgn = GetGrayRgn(); /* No need to check for this */
   379 	
   380 		GetPort(&savePort);
   381 		GetWMgrPort(&wMgrPort);
   382 
   383 		/* Set the height properly */
   384 		LMSetMBarHeight(gSaveMenuBar);
   385 
   386 		/* Restore the old GrayRgn: rounded corners, etc, but not
   387 		   the menubar -- subtract that out first! */
   388 		if (gSaveGrayRgn)
   389 			{
   390 			menuRect = (*GetMainDevice())->gdRect;
   391 			menuRect.bottom = menuRect.top + gSaveMenuBar;
   392 			RectRgn(menuRgn, &menuRect);
   393 
   394 			DiffRgn(grayRgn, gSaveGrayRgn, drawRgn); 	/* What do we inval? */
   395 			DiffRgn(drawRgn, menuRgn, drawRgn);			/* Clip out the menu */
   396 			
   397 			/* Now redraw the corners and other bits black */
   398 			SetPort(wMgrPort);
   399 			GetClip(tempRgn);
   400 			SetClip(drawRgn);
   401 			GetForeColor(&saveRGB);
   402 			RGBForeColor(&blackRGB);
   403 			PaintRgn(drawRgn);
   404 			RGBForeColor(&saveRGB);
   405 			SetClip(tempRgn);
   406 			SetPort(savePort);
   407 			
   408 			UnionRgn(drawRgn, menuRgn, drawRgn);		/* Put back the menu */
   409 
   410 			/* Now actually restore the GrayRgn */
   411 			CopyRgn(gSaveGrayRgn, grayRgn);
   412 			DisposeRgn(gSaveGrayRgn);
   413 			gSaveGrayRgn = nil;
   414 			}
   415 
   416 		/* Modify the vis regions of exposed windows and draw menubar */
   417 		window = (FrontWindow()) ? FrontWindow() : (WindowPtr) -1L;
   418 		PaintBehind(window, drawRgn);
   419 		CalcVisBehind(window, drawRgn);
   420 		DrawMenuBar();
   421 
   422 		SetPort(savePort);
   423 		gSaveMenuBar = 0;
   424 
   425 		/* Now show the control strip if it's present */
   426 		if (!Gestalt(gestaltControlStripAttr, &response) && 
   427 				(response & (1L << gestaltControlStripExists)))
   428 			{
   429 			if (gSaveCSVis && !SBIsControlStripVisible())
   430 				SBShowHideControlStrip(true);
   431 			gSaveCSVis = true;
   432 			}
   433 
   434 		/* Yield time so that floaters can catch up */
   435 		EventAvail(0, &theEvent);
   436 		EventAvail(0, &theEvent);
   437 		EventAvail(0, &theEvent);
   438 		EventAvail(0, &theEvent);
   439 		}
   440 
   441 CLEANUP:
   442 
   443 	if (drawRgn) DisposeRgn(drawRgn);
   444 	if (menuRgn) DisposeRgn(menuRgn);
   445 	if (tempRgn) DisposeRgn(tempRgn);
   446 #endif /* !TARGET_API_MAC_CARBON */
   447 }
   448 
   449 /* Various screen update functions available */
   450 static void ROM_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
   451 static void ROM_WindowUpdate(_THIS, int numrects, SDL_Rect *rects);
   452 
   453 static void ROM_UnsetVideoMode(_THIS, SDL_Surface *current)
   454 {
   455 	/* Free the current window, if any */
   456 	if ( SDL_Window != nil ) {
   457 		GWorldPtr memworld;
   458 		
   459 		/* Handle OpenGL support */
   460 		Mac_GL_Quit(this);
   461 
   462 		memworld = (GWorldPtr)GetWRefCon(SDL_Window);
   463 		if ( memworld != nil ) {
   464 			UnlockPixels(GetGWorldPixMap(memworld));
   465 			DisposeGWorld(memworld);
   466 		}
   467 		if ( (current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
   468 #if USE_QUICKTIME
   469 			EndFullScreen(fullscreen_ctx, nil);
   470 			SDL_Window = nil;
   471 #else
   472 			ROM_ShowMenuBar(this);
   473 #endif
   474 		}
   475 	}
   476 	current->pixels = NULL;
   477 	current->flags &= ~(SDL_HWSURFACE|SDL_FULLSCREEN);
   478 }
   479 
   480 static SDL_Surface *ROM_SetVideoMode(_THIS, SDL_Surface *current,
   481 				int width, int height, int bpp, Uint32 flags)
   482 {
   483 	Rect wrect, orect;
   484 #if TARGET_API_MAC_CARBON
   485 	Rect tmprect;
   486 #endif
   487 
   488 	/* Free any previous video mode */
   489 	ROM_UnsetVideoMode(this, current);
   490 
   491 	/* Create the ROM window and SDL video surface */
   492 	current->flags = 0;		/* Clear flags */
   493 	current->w = width;
   494 	current->h = height;
   495 	SetRect(&wrect, 0, 0, width, height);
   496 	if ( SDL_Window ) {
   497 		/* If we recreate the window, don't move it around */
   498 #if TARGET_API_MAC_CARBON
   499 		orect = *GetWindowPortBounds(SDL_Window, &tmprect);
   500 #else
   501 		orect = SDL_Window->portRect;
   502 #endif
   503 		OffsetRect(&wrect, orect.left, orect.top);
   504 	} else {
   505 		/* Center the window the first time we show it */
   506 		OffsetRect(&wrect,
   507 		(SDL_modelist[0]->w-width)/2, (SDL_modelist[0]->h-height)/2);
   508 	}
   509 
   510 #if MACOSX && !USE_QUICKTIME
   511 	/* Hum.. fullscreen mode is broken */
   512 	flags &= ~SDL_FULLSCREEN;
   513 #endif
   514 	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
   515 		/* Create the fullscreen window and use screen bits */
   516 		current->flags |= SDL_HWSURFACE|SDL_FULLSCREEN;
   517 		if ( SDL_Window ) {
   518 			DisposeWindow(SDL_Window);
   519 		}
   520 #if USE_QUICKTIME
   521 		BeginFullScreen(&fullscreen_ctx, nil, 0,0, &SDL_Window, nil, 0);
   522 #else
   523 		SDL_Window = NewCWindow(nil, &wrect, "\p", true, plainDBox,
   524 						(WindowPtr)-1, false, 0);
   525 		ROM_HideMenuBar(this);
   526 #endif
   527 		current->pitch = (**(**SDL_Display).gdPMap).rowBytes & 0x3FFF;
   528 		current->pixels = (**(**SDL_Display).gdPMap).baseAddr;
   529 		this->UpdateRects = ROM_DirectUpdate;
   530 	} else {
   531 		GWorldPtr memworld;
   532 		PixMapHandle pixmap;
   533 		int style;
   534 
   535 		style = noGrowDocProc;
   536 		if ( flags & SDL_NOFRAME ) {
   537 			style = plainDBox;
   538 			current->flags |= SDL_NOFRAME;
   539 		} else
   540 		if ( flags & SDL_RESIZABLE ) {
   541 			style = zoomDocProc;
   542 			current->flags |= SDL_RESIZABLE;
   543 		}
   544 		if ( SDL_Window && (style == current_style) ) {
   545 			/* Resize existing window, if necessary */
   546 			if ( ((orect.right-orect.left) != width) ||
   547 			     ((orect.bottom-orect.top) != height) ) {
   548 				SizeWindow(SDL_Window, width, height, false);
   549 			}
   550 		} else {
   551 			/* Recreate the window in the new style */
   552 			if ( SDL_Window ) {
   553 				DisposeWindow(SDL_Window);
   554 			}
   555 			SDL_Window = NewCWindow(nil, &wrect, "\p", true,
   556 			                        style, (WindowPtr)-1, true, 0);
   557 
   558 			/* Set the window title, if any */
   559 			{ char *title;
   560 				SDL_WM_GetCaption(&title, NULL);
   561 				if ( title ) {
   562 					Mac_SetCaption(this, title, NULL);
   563 				}
   564 			}
   565 		}
   566 		current_style = style;
   567 		SetPalette(SDL_Window, SDL_CPal, false);
   568 		ActivatePalette(SDL_Window);
   569 		if ( NewGWorld(&memworld, 0,
   570 #if TARGET_API_MAC_CARBON
   571 			       GetWindowPortBounds(SDL_Window, &tmprect),
   572 #else
   573 			       &SDL_Window->portRect,
   574 #endif
   575 			       SDL_CTab, nil, 0) != noErr ) {
   576 			SDL_SetError("NewGWorld() failed");
   577 			return(NULL);
   578 		}
   579 		SetWRefCon(SDL_Window, (long)memworld);
   580 		pixmap = GetGWorldPixMap(memworld);
   581 		LockPixels(pixmap);
   582 		current->pitch = (**pixmap).rowBytes & 0x3FFF;
   583 		current->pixels = GetPixBaseAddr(pixmap);
   584 		this->UpdateRects = ROM_WindowUpdate;
   585 	}
   586 	SetPortWindowPort(SDL_Window);
   587 	SelectWindow(SDL_Window);
   588 
   589 	/* Handle OpenGL support */
   590 	if ( flags & SDL_OPENGL ) {
   591 		if ( Mac_GL_Init(this) == 0 ) {
   592 			current->flags |= SDL_OPENGL;
   593 		} else {
   594 			current = NULL;
   595 		}
   596 	}
   597 	
   598 	if ( (flags & SDL_HWPALETTE) && (flags & SDL_FULLSCREEN) )
   599 	   current->flags |= SDL_HWPALETTE;
   600 	   
   601 	/* We're live! */
   602 	return(current);
   603 }
   604 
   605 /* We don't actually allow hardware surfaces other than the main one */
   606 static int ROM_AllocHWSurface(_THIS, SDL_Surface *surface)
   607 {
   608 	return(-1);
   609 }
   610 static void ROM_FreeHWSurface(_THIS, SDL_Surface *surface)
   611 {
   612 	return;
   613 }
   614 static int ROM_LockHWSurface(_THIS, SDL_Surface *surface)
   615 {
   616 	return(0);
   617 }
   618 static void ROM_UnlockHWSurface(_THIS, SDL_Surface *surface)
   619 {
   620 	return;
   621 }
   622 
   623 static void ROM_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
   624 {
   625 	/* The application is already updating the visible video memory */
   626 	return;
   627 }
   628 
   629 static void ROM_WindowUpdate(_THIS, int numrects, SDL_Rect *rects)
   630 {
   631 	GWorldPtr memworld;
   632 	GrafPtr saveport;
   633 	CGrafPtr thePort;
   634 	const BitMap *memBits;
   635 	const BitMap *winBits;
   636 	int i;
   637 	Rect update;
   638 	
   639 	/* Copy from the offscreen GWorld to the window port */
   640 	GetPort(&saveport);
   641 	SetPortWindowPort(SDL_Window);
   642 	thePort = GetWindowPort(SDL_Window);
   643 	memworld = (GWorldPtr)GetWRefCon(SDL_Window);
   644 #if TARGET_API_MAC_CARBON
   645 	memBits = GetPortBitMapForCopyBits((CGrafPtr) memworld);
   646 #else
   647 	memBits = &((GrafPtr)memworld)->portBits;
   648 #endif
   649 #if TARGET_API_MAC_CARBON
   650 	winBits = GetPortBitMapForCopyBits(thePort);
   651 #else
   652 	winBits = &SDL_Window->portBits;
   653 #endif
   654 	for ( i=0; i<numrects; ++i ) {
   655 		update.left = rects[i].x;
   656 		update.right = rects[i].x+rects[i].w;
   657 		update.top = rects[i].y;
   658 		update.bottom = rects[i].y+rects[i].h;
   659 		CopyBits(memBits, winBits,
   660 			 &update, &update, srcCopy, nil);
   661 	}
   662 #if TARGET_API_MAC_CARBON
   663 	if ( QDIsPortBuffered(thePort) ) {
   664 		QDFlushPortBuffer(thePort, NULL);
   665 	}
   666 #endif
   667 	SetPort(saveport);
   668 }
   669 
   670 static int ROM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   671 {
   672 	CTabHandle cTab;
   673 	int i;
   674 
   675 	/* Get the colortable from the either the display or window */
   676 	if ( (this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
   677 		cTab = (**(**SDL_Display).gdPMap).pmTable;
   678 	} else {
   679 		cTab = SDL_CTab;
   680 	}
   681 
   682 	/* Verify the range of colors */
   683 	if ( (firstcolor+ncolors) > ((**cTab).ctSize+1) ) {
   684 		return(0);
   685 	}
   686 	
   687 	/* Set the screen palette and update the display */
   688 	for ( i=0; i< ncolors; ++i ) {
   689 	        int j = firstcolor + i;
   690 		(**cTab).ctTable[j].value = j;
   691 		(**cTab).ctTable[j].rgb.red = colors[i].r << 8 | colors[i].r;
   692 		(**cTab).ctTable[j].rgb.green = colors[i].g << 8 | colors[i].g;
   693 		(**cTab).ctTable[j].rgb.blue = colors[i].b << 8 | colors[i].b;
   694 	}
   695 //	if ( (this->screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) 
   696 {
   697 		GDevice **odisplay;
   698 		odisplay = GetGDevice();
   699 		SetGDevice(SDL_Display);
   700 		SetEntries(0, (**cTab).ctSize, (ColorSpec *)&(**cTab).ctTable);
   701 		SetGDevice(odisplay);
   702 	}
   703 	return(1);
   704 }
   705 
   706 void ROM_VideoQuit(_THIS)
   707 {
   708 	int i;
   709 
   710 	/* Free current video mode */
   711 	ROM_UnsetVideoMode(this, this->screen);
   712 	if ( SDL_Window ) {
   713 		DisposeWindow(SDL_Window);
   714 		SDL_Window = nil;
   715 	}
   716 
   717 	/* Free palette and restore original one */
   718 	if ( SDL_CTab != nil ) {
   719 		DisposeHandle((Handle)SDL_CTab);
   720 		SDL_CTab = nil;
   721 	}
   722 	if ( SDL_CPal != nil ) {
   723 		DisposePalette(SDL_CPal);
   724 		SDL_CPal = nil;
   725 	}
   726 	RestoreDeviceClut(GetMainDevice());
   727 
   728 	/* Free list of video modes */
   729 	if ( SDL_modelist != NULL ) {
   730 		for ( i=0; SDL_modelist[i]; ++i ) {
   731 			free(SDL_modelist[i]);
   732 		}
   733 		free(SDL_modelist);
   734 		SDL_modelist = NULL;
   735 	}
   736 }
   737