Home | History | Annotate | Download | only in macrom
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2006 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 (at) 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 
    746