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