src/video/macrom/SDL_romvideo.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 28 May 2006 13:04:16 +0000
branchSDL-1.3
changeset 1662 782fd950bd46
parent 1659 14717b52abc0
child 1668 4da1ee79c9af
permissions -rw-r--r--
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.

WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.

The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce

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