• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
SBIsControlStripVisible(void)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 
SBShowHideControlStrip(Boolean showIt)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 
ROM_Available(void)114 static int ROM_Available(void)
115 {
116 	return(1);
117 }
118 
ROM_DeleteDevice(SDL_VideoDevice * device)119 static void ROM_DeleteDevice(SDL_VideoDevice *device)
120 {
121 	SDL_free(device->hidden);
122 	SDL_free(device);
123 }
124 
ROM_CreateDevice(int devindex)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 
ROM_VideoInit(_THIS,SDL_PixelFormat * vformat)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 
ROM_ListModes(_THIS,SDL_PixelFormat * format,Uint32 flags)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 
ROM_HideMenuBar(_THIS)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 
ROM_ShowMenuBar(_THIS)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 
ROM_UnsetVideoMode(_THIS,SDL_Surface * current)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 
ROM_SetVideoMode(_THIS,SDL_Surface * current,int width,int height,int bpp,Uint32 flags)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 */
ROM_AllocHWSurface(_THIS,SDL_Surface * surface)607 static int ROM_AllocHWSurface(_THIS, SDL_Surface *surface)
608 {
609 	return(-1);
610 }
ROM_FreeHWSurface(_THIS,SDL_Surface * surface)611 static void ROM_FreeHWSurface(_THIS, SDL_Surface *surface)
612 {
613 	return;
614 }
ROM_LockHWSurface(_THIS,SDL_Surface * surface)615 static int ROM_LockHWSurface(_THIS, SDL_Surface *surface)
616 {
617 	return(0);
618 }
ROM_UnlockHWSurface(_THIS,SDL_Surface * surface)619 static void ROM_UnlockHWSurface(_THIS, SDL_Surface *surface)
620 {
621 	return;
622 }
623 
ROM_DirectUpdate(_THIS,int numrects,SDL_Rect * rects)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 
ROM_WindowUpdate(_THIS,int numrects,SDL_Rect * rects)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 
ROM_SetColors(_THIS,int firstcolor,int ncolors,SDL_Color * colors)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 
ROM_VideoQuit(_THIS)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