src/video/macrom/SDL_romvideo.c
author Ozkan Sezer <sezeroz@gmail.com>
Sun, 14 Oct 2018 15:25:04 +0300
branchSDL-1.2
changeset 12325 c4f2eeda176f
parent 6137 4720145f848b
permissions -rw-r--r--
remove symlink for libSDL-1.0.so.0 from the rpm spec file.

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