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