symbian-qemu-0.9.1-12/libsdl-trunk/src/video/macrom/SDL_romvideo.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 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