src/video/cybergfx/SDL_cgxvideo.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 29 May 2006 04:04:35 +0000
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
permissions -rw-r--r--
more tweaking indent options
     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 /*
    25  * CGX based SDL video driver implementation by Gabriele Greco
    26  * gabriele.greco@aruba.it
    27  */
    28 
    29 #include "SDL_endian.h"
    30 #include "SDL_timer.h"
    31 #include "SDL_thread.h"
    32 #include "SDL_video.h"
    33 #include "SDL_mouse.h"
    34 #include "../SDL_sysvideo.h"
    35 #include "../SDL_pixels_c.h"
    36 #include "../../events/SDL_events_c.h"
    37 #include "SDL_cgxgl_c.h"
    38 #include "SDL_cgxvideo.h"
    39 #include "SDL_cgxwm_c.h"
    40 #include "SDL_amigamouse_c.h"
    41 #include "SDL_amigaevents_c.h"
    42 #include "SDL_cgxmodes_c.h"
    43 #include "SDL_cgximage_c.h"
    44 
    45 /* Initialization/Query functions */
    46 static int CGX_VideoInit(_THIS, SDL_PixelFormat * vformat);
    47 static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface * current, int width,
    48                                      int height, int bpp, Uint32 flags);
    49 static int CGX_ToggleFullScreen(_THIS, int on);
    50 static void CGX_UpdateMouse(_THIS);
    51 static int CGX_SetColors(_THIS, int firstcolor, int ncolors,
    52                          SDL_Color * colors);
    53 static void CGX_VideoQuit(_THIS);
    54 
    55 /* CGX driver bootstrap functions */
    56 
    57 struct Library *CyberGfxBase = NULL;
    58 struct IntuitionBase *IntuitionBase = NULL;
    59 struct GfxBase *GfxBase = NULL;
    60 
    61 int
    62 CGX_SetGamma(_THIS, float red, float green, float blue)
    63 {
    64     SDL_SetError("Gamma correction not supported");
    65     return -1;
    66 }
    67 
    68 int
    69 CGX_GetGamma(_THIS, float red, float green, float blue)
    70 {
    71     SDL_SetError("Gamma correction not supported");
    72     return -1;
    73 }
    74 
    75 int
    76 CGX_SetGammaRamp(_THIS, Uint16 * ramp)
    77 {
    78 #if 0
    79     Int i, ncolors;
    80     XColor xcmap[256];
    81 
    82     /* See if actually setting the gamma is supported */
    83     if (SDL_Visual->class != DirectColor) {
    84         SDL_SetError("Gamma correction not supported on this visual");
    85         return (-1);
    86     }
    87 
    88     /* Calculate the appropriate palette for the given gamma ramp */
    89     ncolors = SDL_Visual->map_entries;
    90     for (i = 0; i < ncolors; ++i) {
    91         Uint8 c = (256 * i / ncolors);
    92         xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c, c);
    93         xcmap[i].red = ramp[0 * 256 + c];
    94         xcmap[i].green = ramp[1 * 256 + c];
    95         xcmap[i].blue = ramp[2 * 256 + c];
    96         xcmap[i].flags = (DoRed | DoGreen | DoBlue);
    97     }
    98     XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors);
    99     XSync(GFX_Display, False);
   100 
   101     return (0);
   102 
   103 #else
   104     SDL_SetError("Gamma correction not supported on this visual");
   105     return (-1);
   106 
   107 #endif
   108 }
   109 
   110 static void
   111 DestroyScreen(_THIS)
   112 {
   113     if (currently_fullscreen) {
   114         if (this->hidden->dbuffer) {
   115             extern struct MsgPort *safeport, *dispport;
   116 
   117             this->hidden->dbuffer = 0;
   118 
   119             if (safeport) {
   120                 while (GetMsg(safeport) != NULL);
   121                 DeleteMsgPort(safeport);
   122             }
   123             if (dispport) {
   124                 while (GetMsg(dispport) != NULL);
   125                 DeleteMsgPort(dispport);
   126             }
   127 
   128             this->hidden->SB[0]->sb_DBufInfo->dbi_SafeMessage.
   129                 mn_ReplyPort =
   130                 this->hidden->SB[0]->sb_DBufInfo->dbi_DispMessage.
   131                 mn_ReplyPort = NULL;
   132             this->hidden->SB[1]->sb_DBufInfo->dbi_SafeMessage.
   133                 mn_ReplyPort =
   134                 this->hidden->SB[1]->sb_DBufInfo->dbi_DispMessage.
   135                 mn_ReplyPort = NULL;
   136 
   137             if (this->hidden->SB[1])
   138                 FreeScreenBuffer(SDL_Display, this->hidden->SB[1]);
   139             if (this->hidden->SB[0])
   140                 FreeScreenBuffer(SDL_Display, this->hidden->SB[0]);
   141 
   142 
   143             this->hidden->SB[0] = this->hidden->SB[1] = NULL;
   144 
   145             if (SDL_RastPort && SDL_RastPort != &SDL_Display->RastPort)
   146                 SDL_free(SDL_RastPort);
   147 
   148             SDL_RastPort = NULL;
   149         }
   150         CloseScreen(GFX_Display);
   151         currently_fullscreen = 0;
   152     } else if (GFX_Display)
   153         UnlockPubScreen(NULL, GFX_Display);
   154 
   155     GFX_Display = NULL;
   156 }
   157 
   158 static int
   159 CGX_Available(void)
   160 {
   161     struct Library *l;
   162 
   163     l = OpenLibrary("cybergraphics.library", 0L);
   164 
   165     if (l != NULL) {
   166         D(bug("CGX video device AVAILABLE\n"));
   167         CloseLibrary(l);
   168     }
   169     D(
   170          else
   171          bug("**CGX video device UNAVAILABLE\n"));
   172 
   173     return (l != NULL);
   174 }
   175 
   176 static void
   177 CGX_DeleteDevice(SDL_VideoDevice * device)
   178 {
   179     if (device) {
   180         if (device->hidden) {
   181             SDL_free(device->hidden);
   182         }
   183         if (device->gl_data) {
   184             SDL_free(device->gl_data);
   185         }
   186         SDL_free(device);
   187     }
   188 }
   189 
   190 static SDL_VideoDevice *
   191 CGX_CreateDevice(int devindex)
   192 {
   193     SDL_VideoDevice *device;
   194 
   195     /* Initialize all variables that we clean on shutdown */
   196     device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
   197     if (device) {
   198         SDL_memset(device, 0, (sizeof *device));
   199         device->hidden = (struct SDL_PrivateVideoData *)
   200             SDL_malloc((sizeof *device->hidden));
   201         device->gl_data = (struct SDL_PrivateGLData *)
   202             SDL_malloc((sizeof *device->gl_data));
   203     }
   204     if ((device == NULL) || (device->hidden == NULL) ||
   205         (device->gl_data == NULL)) {
   206         D(bug("Unable to create video device!\n"));
   207         SDL_OutOfMemory();
   208         CGX_DeleteDevice(device);
   209         return (0);
   210     }
   211     SDL_memset(device->hidden, 0, sizeof(*device->hidden));
   212     SDL_memset(device->gl_data, 0, sizeof(*device->gl_data));
   213 
   214     /* Set the driver flags */
   215     device->handles_any_size = 1;
   216 
   217     /* Set the function pointers */
   218     device->VideoInit = CGX_VideoInit;
   219     device->ListModes = CGX_ListModes;
   220     device->SetVideoMode = CGX_SetVideoMode;
   221     device->ToggleFullScreen = CGX_ToggleFullScreen;
   222     device->UpdateMouse = CGX_UpdateMouse;
   223     device->SetColors = CGX_SetColors;
   224     device->UpdateRects = NULL;
   225     device->VideoQuit = CGX_VideoQuit;
   226     device->AllocHWSurface = CGX_AllocHWSurface;
   227     device->CheckHWBlit = CGX_CheckHWBlit;
   228     device->FillHWRect = CGX_FillHWRect;
   229     device->SetHWColorKey = CGX_SetHWColorKey;
   230     device->SetHWAlpha = NULL;
   231     device->LockHWSurface = CGX_LockHWSurface;
   232     device->UnlockHWSurface = CGX_UnlockHWSurface;
   233     device->FlipHWSurface = CGX_FlipHWSurface;
   234     device->FreeHWSurface = CGX_FreeHWSurface;
   235     device->SetGamma = CGX_SetGamma;
   236     device->GetGamma = CGX_GetGamma;
   237     device->SetGammaRamp = CGX_SetGammaRamp;
   238     device->GetGammaRamp = NULL;
   239 #if SDL_VIDEO_OPENGL
   240     device->GL_LoadLibrary = CGX_GL_LoadLibrary;
   241     device->GL_GetProcAddress = CGX_GL_GetProcAddress;
   242     device->GL_GetAttribute = CGX_GL_GetAttribute;
   243     device->GL_MakeCurrent = CGX_GL_MakeCurrent;
   244     device->GL_SwapBuffers = CGX_GL_SwapBuffers;
   245 #endif
   246     device->SetIcon = CGX_SetIcon;
   247     device->SetCaption = CGX_SetCaption;
   248     device->IconifyWindow = NULL;       /* CGX_IconifyWindow; */
   249     device->GrabInput = NULL /* CGX_GrabInput */ ;
   250     device->GetWMInfo = CGX_GetWMInfo;
   251     device->FreeWMCursor = amiga_FreeWMCursor;
   252     device->CreateWMCursor = amiga_CreateWMCursor;
   253     device->ShowWMCursor = amiga_ShowWMCursor;
   254     device->WarpWMCursor = amiga_WarpWMCursor;
   255     device->CheckMouseMode = amiga_CheckMouseMode;
   256     device->InitOSKeymap = amiga_InitOSKeymap;
   257     device->PumpEvents = amiga_PumpEvents;
   258 
   259     device->free = CGX_DeleteDevice;
   260 
   261     return device;
   262 }
   263 
   264 VideoBootStrap CGX_bootstrap = {
   265     "CGX", "AmigaOS CyberGraphics", CGX_Available, CGX_CreateDevice
   266 };
   267 
   268 Uint32
   269 MakeBitMask(_THIS, int type, int format, int *bpp)
   270 {
   271     D(if (type == 0) bug("REAL pixel format: "));
   272 
   273     if (this->hidden->depth == *bpp) {
   274 
   275         switch (format) {
   276         case PIXFMT_LUT8:
   277             D(if (type == 0) bug("LUT8\n"));
   278             return 0;
   279         case PIXFMT_BGR15:
   280         case PIXFMT_RGB15PC:
   281             switch (type) {
   282             case 0:
   283                 D(bug("RGB15PC/BGR15\n"));
   284                 return 31;
   285             case 1:
   286                 return 992;
   287             case 2:
   288                 return 31744;
   289             }
   290         case PIXFMT_RGB15:
   291         case PIXFMT_BGR15PC:
   292             switch (type) {
   293             case 0:
   294                 D(bug("RGB15/BGR15PC\n"));
   295                 return 31744;
   296             case 1:
   297                 return 992;
   298             case 2:
   299                 return 31;
   300             }
   301         case PIXFMT_BGR16PC:
   302         case PIXFMT_RGB16:
   303             switch (type) {
   304             case 0:
   305                 D(bug("RGB16PC\n"));
   306                 return 63488;
   307             case 1:
   308                 return 2016;
   309             case 2:
   310                 return 31;
   311             }
   312         case PIXFMT_BGR16:
   313         case PIXFMT_RGB16PC:
   314             switch (type) {
   315             case 0:
   316                 D(bug("RGB16PC/BGR16\n"));
   317                 return 31;
   318             case 1:
   319                 return 2016;
   320             case 2:
   321                 return 63488;
   322             }
   323 
   324         case PIXFMT_RGB24:
   325             switch (type) {
   326             case 0:
   327                 D(bug("RGB24/BGR24\n"));
   328                 return 0xff0000;
   329             case 1:
   330                 return 0xff00;
   331             case 2:
   332                 return 0xff;
   333             }
   334         case PIXFMT_BGR24:
   335             switch (type) {
   336             case 0:
   337                 D(bug("BGR24\n"));
   338                 return 0xff;
   339             case 1:
   340                 return 0xff00;
   341             case 2:
   342                 return 0xff0000;
   343             }
   344         case PIXFMT_ARGB32:
   345             switch (type) {
   346             case 0:
   347                 D(bug("ARGB32\n"));
   348                 return 0xff0000;
   349             case 1:
   350                 return 0xff00;
   351             case 2:
   352                 return 0xff;
   353             }
   354         case PIXFMT_BGRA32:
   355             switch (type) {
   356             case 0:
   357                 D(bug("BGRA32\n"));
   358                 return 0xff00;
   359             case 1:
   360                 return 0xff0000;
   361             case 2:
   362                 return 0xff000000;
   363             }
   364         case PIXFMT_RGBA32:
   365             switch (type) {
   366             case 0:
   367                 D(bug("RGBA32\n"));
   368                 return 0xff000000;
   369             case 1:
   370                 return 0xff0000;
   371             case 2:
   372                 return 0xff00;
   373             }
   374         default:
   375             D(bug("Unknown pixel format! Default to 24bit\n"));
   376             return (Uint32) (255 << (type * 8));
   377         }
   378     } else {
   379         D(if (type == 0)
   380           bug("DIFFERENT from screen.\nAllocated screen format: "));
   381 
   382         switch (*bpp) {
   383         case 32:
   384             D(if (type == 0) bug("RGBA32\n"));
   385             switch (type) {
   386             case 0:
   387                 return 0xff000000;
   388             case 1:
   389                 return 0xff0000;
   390             case 2:
   391                 return 0xff00;
   392             }
   393             break;
   394         case 24:
   395           use_truecolor:
   396             switch (type) {
   397             case 0:
   398                 D(bug("RGB24\n"));
   399                 return 0xff0000;
   400             case 1:
   401                 return 0xff00;
   402             case 2:
   403                 return 0xff;
   404             }
   405         case 16:
   406         case 15:
   407             D(if (type == 0)
   408               bug("Not supported, switching to 24bit!\n"));
   409             *bpp = 24;
   410             goto use_truecolor;
   411             break;
   412         default:
   413             D(if (type == 0) bug("This is a chunky display\n"));
   414 // For chunky display mask is always 0;
   415             return 0;
   416         }
   417     }
   418     return 0;
   419 }
   420 
   421 static int
   422 CGX_VideoInit(_THIS, SDL_PixelFormat * vformat)
   423 {
   424     int i;
   425     struct Library *RTGBase;
   426 
   427     D(bug("VideoInit... Opening libraries\n"));
   428 
   429     if (!IntuitionBase) {
   430         if (!
   431             (IntuitionBase =
   432              (struct IntuitionBase *) OpenLibrary("intuition.library",
   433                                                   39L))) {
   434             SDL_SetError("Couldn't open intuition V39+");
   435             return -1;
   436         }
   437     }
   438 
   439     if (!GfxBase) {
   440         if (!
   441             (GfxBase =
   442              (struct GfxBase *) OpenLibrary("graphics.library", 39L))) {
   443             SDL_SetError("Couldn't open graphics V39+");
   444             return -1;
   445         }
   446     }
   447 
   448     if (!CyberGfxBase) {
   449         if (!(CyberGfxBase = OpenLibrary("cybergraphics.library", 40L))) {
   450             SDL_SetError("Couldn't open cybergraphics.");
   451             return (-1);
   452         }
   453     }
   454 
   455     if (RTGBase = OpenLibrary("libs:picasso96/rtg.library", 0L)) {
   456         extern int use_picasso96;
   457 
   458         CloseLibrary(RTGBase);
   459         use_picasso96 = 1;
   460     }
   461 
   462     D(bug("Library intialized, locking screen...\n"));
   463 
   464     SDL_Display = LockPubScreen(NULL);
   465 
   466     if (SDL_Display == NULL) {
   467         D(bug("Cannot lock display...\n"));
   468         SDL_SetError("Couldn't lock the display");
   469         return (-1);
   470     }
   471     this->info.current_w = SDL_Display->Width;
   472     this->info.current_h = SDL_Display->Height;
   473 
   474     D(bug("Checking if we are using a CGX native display...\n"));
   475 
   476     if (!IsCyberModeID(GetVPModeID(&SDL_Display->ViewPort))) {
   477         Uint32 okid =
   478             BestCModeIDTags(CYBRBIDTG_NominalWidth, SDL_Display->Width,
   479                             CYBRBIDTG_NominalHeight, SDL_Display->Height,
   480                             CYBRBIDTG_Depth, 8,
   481                             TAG_DONE);
   482 
   483         D(bug("Default visual is not CGX native!\n"));
   484 
   485         UnlockPubScreen(NULL, SDL_Display);
   486 
   487         GFX_Display = NULL;
   488 
   489         if (okid != INVALID_ID) {
   490             GFX_Display = OpenScreenTags(NULL,
   491                                          SA_Width, SDL_Display->Width,
   492                                          SA_Height, SDL_Display->Height,
   493                                          SA_Depth, 8, SA_Quiet, TRUE,
   494                                          SA_ShowTitle, FALSE,
   495                                          SA_DisplayID, okid, TAG_DONE);
   496         }
   497 
   498         if (!GFX_Display) {
   499             SDL_SetError("Unable to open a suited CGX display");
   500             return -1;
   501         } else
   502             SDL_Display = GFX_Display;
   503 
   504     } else
   505         GFX_Display = SDL_Display;
   506 
   507 
   508     /* See whether or not we need to swap pixels */
   509 
   510     swap_pixels = 0;
   511 
   512 // Non e' detto che sia cosi' pero', alcune schede potrebbero gestire i modi in modo differente
   513 
   514     if (SDL_BYTEORDER == SDL_LIL_ENDIAN) {
   515         swap_pixels = 1;
   516     }
   517 
   518     D(bug("Before GetVideoModes....\n"));
   519 
   520     /* Get the available video modes */
   521     if (CGX_GetVideoModes(this) < 0)
   522         return -1;
   523 
   524     /* Determine the default screen depth:
   525        Use the default visual (or at least one with the same depth) */
   526 
   527     for (i = 0; i < this->hidden->nvisuals; i++)
   528         if (this->hidden->visuals[i].depth ==
   529             GetCyberMapAttr(SDL_Display->RastPort.BitMap, CYBRMATTR_DEPTH))
   530             break;
   531     if (i == this->hidden->nvisuals) {
   532         /* default visual was useless, take the deepest one instead */
   533         i = 0;
   534     }
   535     SDL_Visual = this->hidden->visuals[i].visual;
   536 
   537 //      SDL_XColorMap = SDL_DisplayColormap;
   538 
   539     this->hidden->depth = this->hidden->visuals[i].depth;
   540     D(bug("Init: Setting screen depth to: %ld\n", this->hidden->depth));
   541     vformat->BitsPerPixel = this->hidden->visuals[i].depth;     /* this->hidden->visuals[i].bpp; */
   542 
   543     {
   544         int form;
   545         APTR handle;
   546         struct DisplayInfo info;
   547 
   548         if (!(handle = FindDisplayInfo(this->hidden->visuals[i].visual))) {
   549             D(bug("Unable to get visual info...\n"));
   550             return -1;
   551         }
   552 
   553         if (!GetDisplayInfoData
   554             (handle, (char *) &info, sizeof(struct DisplayInfo), DTAG_DISP,
   555              NULL)) {
   556             D(bug("Unable to get visual info data...\n"));
   557             return -1;
   558         }
   559 
   560         form = GetCyberIDAttr(CYBRIDATTR_PIXFMT, SDL_Visual);
   561 
   562 // In this case I use makebitmask in a way that I'm sure I'll get PIXFMT pixel mask
   563 
   564         if (vformat->BitsPerPixel > 8) {
   565             vformat->Rmask = MakeBitMask(this, 0, form, &this->hidden->depth);
   566             vformat->Gmask = MakeBitMask(this, 1, form, &this->hidden->depth);
   567             vformat->Bmask = MakeBitMask(this, 2, form, &this->hidden->depth);
   568         }
   569     }
   570 
   571     /* See if we have been passed a window to use */
   572 /*	SDL_windowid = SDL_getenv("SDL_WINDOWID"); */
   573     SDL_windowid = NULL;
   574 
   575     /* Create the blank cursor */
   576     SDL_BlankCursor = AllocMem(16, MEMF_CHIP | MEMF_CLEAR);
   577 
   578     /* Fill in some window manager capabilities */
   579     this->info.wm_available = 1;
   580     this->info.blit_hw = 1;
   581     this->info.blit_hw_CC = 1;
   582     this->info.blit_sw = 1;
   583     this->info.blit_fill = 1;
   584     this->info.video_mem = 2000000;     // Not always true but almost any Amiga card has this memory!
   585 
   586     this->hidden->same_format = 0;
   587     SDL_RastPort = &SDL_Display->RastPort;
   588     /* We're done! */
   589     D(bug("End of CGX_VideoInit\n"));
   590 
   591     return (0);
   592 }
   593 
   594 void
   595 CGX_DestroyWindow(_THIS, SDL_Surface * screen)
   596 {
   597     D(bug("Destroy Window...\n"));
   598 
   599     if (!SDL_windowid) {
   600         /* Hide the managed window */
   601         int was_fullscreen = 0;
   602 
   603         /* Clean up OpenGL */
   604         if (screen) {
   605             screen->flags &= ~SDL_INTERNALOPENGL;
   606         }
   607 
   608         if (screen && (screen->flags & SDL_FULLSCREEN)) {
   609             was_fullscreen = 1;
   610             screen->flags &= ~SDL_FULLSCREEN;
   611 //                      CGX_LeaveFullScreen(this); tolto x crash
   612         }
   613 
   614         /* Destroy the output window */
   615         if (SDL_Window) {
   616             CloseWindow(SDL_Window);
   617             SDL_Window = NULL;
   618         }
   619 
   620         /* Free the colormap entries */
   621         if (SDL_XPixels) {
   622             int numcolors;
   623             unsigned long pixel;
   624 
   625             if (this->screen->format && this->hidden->depth == 8
   626                 && !was_fullscreen) {
   627                 numcolors = 1 << this->screen->format->BitsPerPixel;
   628 
   629                 if (numcolors > 256)
   630                     numcolors = 256;
   631 
   632                 if (!was_fullscreen && this->hidden->depth == 8) {
   633                     for (pixel = 0; pixel < numcolors; pixel++) {
   634                         if (SDL_XPixels[pixel] >= 0)
   635                             ReleasePen(GFX_Display->ViewPort.
   636                                        ColorMap, SDL_XPixels[pixel]);
   637                     }
   638                 }
   639             }
   640             SDL_free(SDL_XPixels);
   641             SDL_XPixels = NULL;
   642         }
   643     }
   644 }
   645 
   646 static void
   647 CGX_SetSizeHints(_THIS, int w, int h, Uint32 flags)
   648 {
   649     if (flags & SDL_RESIZABLE) {
   650         WindowLimits(SDL_Window, 32, 32, 4096, 4096);
   651     } else {
   652         WindowLimits(SDL_Window, w, h, w, h);
   653     }
   654     if (flags & SDL_FULLSCREEN) {
   655         flags &= ~SDL_RESIZABLE;
   656     } else if (SDL_getenv("SDL_VIDEO_CENTERED")) {
   657         int display_w, display_h;
   658 
   659         display_w = SDL_Display->Width;
   660         display_h = SDL_Display->Height;
   661         ChangeWindowBox(SDL_Window,
   662                         (display_w - w - SDL_Window->BorderLeft -
   663                          SDL_Window->BorderRight) / 2,
   664                         (display_h - h - SDL_Window->BorderTop -
   665                          SDL_Window->BorderBottom) / 2,
   666                         w + SDL_Window->BorderLeft +
   667                         SDL_Window->BorderRight,
   668                         h + SDL_Window->BorderTop + SDL_Window->BorderBottom);
   669     }
   670 }
   671 
   672 int
   673 CGX_CreateWindow(_THIS, SDL_Surface * screen,
   674                  int w, int h, int bpp, Uint32 flags)
   675 {
   676 #if 0
   677     int i, depth;
   678     Uint32 vis;
   679 #endif
   680     D(bug("CGX_CreateWindow\n"));
   681 
   682     /* If a window is already present, destroy it and start fresh */
   683     if (SDL_Window) {
   684         CGX_DestroyWindow(this, screen);
   685     }
   686 
   687     /* See if we have been given a window id */
   688     if (SDL_windowid) {
   689         SDL_Window = (struct Window *) atol(SDL_windowid);
   690     } else {
   691         SDL_Window = 0;
   692     }
   693 
   694     /* find out which visual we are going to use */
   695 #if 0
   696 /* questo l'ho spostato nell'apertura dello schermo, in quanto su Amiga le finestre
   697    hanno il pixel mode degli schermi.
   698  */
   699     /*if ( flags & SDL_INTERNALOPENGL ) {
   700        SDL_SetError("OpenGL not supported by the Amiga SDL!");
   701        return -1;
   702        }
   703        else { */
   704     for (i = 0; i < this->hidden->nvisuals; i++) {
   705         if (this->hidden->visuals[i].depth == bpp)      /* era .depth */
   706             break;
   707     }
   708     if (i == this->hidden->nvisuals) {
   709         SDL_SetError("No matching visual for requested depth");
   710         return -1;              /* should never happen */
   711     }
   712     vis = this->hidden->visuals[i].visual;
   713     depth = this->hidden->visuals[i].depth;
   714 //      }
   715     SDL_Visual = vis;
   716     this->hidden->depth = depth;
   717     D(bug("Setting screen depth to: %ld\n", this->hidden->depth));
   718 #endif
   719 
   720     /* Allocate the new pixel format for this video mode */
   721     {
   722         Uint32 form;
   723         APTR handle;
   724         struct DisplayInfo info;
   725 
   726         if (!(handle = FindDisplayInfo(SDL_Visual)))
   727             return -1;
   728 
   729         if (!GetDisplayInfoData
   730             (handle, (char *) &info, sizeof(struct DisplayInfo), DTAG_DISP,
   731              NULL))
   732             return -1;
   733 
   734         form = GetCyberIDAttr(CYBRIDATTR_PIXFMT, SDL_Visual);
   735 
   736         if (flags & SDL_HWSURFACE) {
   737             if (bpp != this->hidden->depth) {
   738                 bpp = this->hidden->depth;
   739                 D(bug("Accel forces bpp to be equal (%ld)\n", bpp));
   740             }
   741         }
   742 
   743         D(bug
   744           ("BEFORE screen allocation: bpp:%ld (real:%ld)\n", bpp,
   745            this->hidden->depth));
   746 
   747 /* With this call if needed I'll revert the wanted bpp to a bpp best suited for the display, actually occurs
   748    only with requested format 15/16bit and display format != 15/16bit
   749  */
   750 
   751         if (!SDL_ReallocFormat(screen, bpp,
   752                                MakeBitMask(this, 0, form, &bpp),
   753                                MakeBitMask(this, 1, form, &bpp),
   754                                MakeBitMask(this, 2, form, &bpp), 0))
   755             return -1;
   756 
   757         D(bug
   758           ("AFTER screen allocation: bpp:%ld (real:%ld)\n", bpp,
   759            this->hidden->depth));
   760 
   761     }
   762 
   763     /* Create the appropriate colormap */
   764 /*
   765 	if ( SDL_XColorMap != SDL_DisplayColormap ) {
   766 		XFreeColormap(SDL_Display, SDL_XColorMap);
   767 	}
   768 */
   769     if (GetCyberMapAttr(SDL_Display->RastPort.BitMap, CYBRMATTR_PIXFMT) ==
   770         PIXFMT_LUT8 || bpp == 8) {
   771         int ncolors, i;
   772         D(bug("XPixels palette allocation...\n"));
   773 
   774         /* Allocate the pixel flags */
   775 
   776         if (bpp == 8)
   777             ncolors = 256;
   778         else
   779             ncolors = 1 << screen->format->BitsPerPixel;
   780 
   781         SDL_XPixels = (Sint32 *) SDL_malloc(ncolors * sizeof(Sint32));
   782 
   783         if (SDL_XPixels == NULL) {
   784             SDL_OutOfMemory();
   785             return -1;
   786         }
   787 
   788 
   789         for (i = 0; i < ncolors; i++)
   790             SDL_XPixels[i] = -1;
   791 
   792         /* always allocate a private colormap on non-default visuals */
   793         if (bpp == 8)
   794             flags |= SDL_HWPALETTE;
   795 
   796         if (flags & SDL_HWPALETTE)
   797             screen->flags |= SDL_HWPALETTE;
   798     }
   799 
   800     /* resize the (possibly new) window manager window */
   801 
   802     /* Create (or use) the X11 display window */
   803 
   804     if (!SDL_windowid) {
   805         if (flags & SDL_FULLSCREEN) {
   806             SDL_Window = OpenWindowTags(NULL, WA_Width, w, WA_Height, h,
   807                                         WA_Flags,
   808                                         WFLG_ACTIVATE | WFLG_RMBTRAP |
   809                                         WFLG_BORDERLESS | WFLG_BACKDROP |
   810                                         WFLG_REPORTMOUSE, WA_IDCMP,
   811                                         IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS
   812                                         | IDCMP_MOUSEMOVE,
   813                                         WA_CustomScreen,
   814                                         (ULONG) SDL_Display, TAG_DONE);
   815 
   816             D(bug
   817               ("Opening backdrop window %ldx%ld on display %lx!\n", w, h,
   818                SDL_Display));
   819         } else {
   820             /* Create GimmeZeroZero window when OpenGL is used */
   821             unsigned long gzz = FALSE;
   822             if (flags & SDL_INTERNALOPENGL) {
   823                 gzz = TRUE;
   824             }
   825 
   826             SDL_Window =
   827                 OpenWindowTags(NULL, WA_InnerWidth, w, WA_InnerHeight, h,
   828                                WA_Flags,
   829                                WFLG_REPORTMOUSE | WFLG_ACTIVATE |
   830                                WFLG_RMBTRAP | ((flags & SDL_NOFRAME) ? 0
   831                                                : (WFLG_DEPTHGADGET |
   832                                                   WFLG_CLOSEGADGET |
   833                                                   WFLG_DRAGBAR |
   834                                                   ((flags &
   835                                                     SDL_RESIZABLE) ?
   836                                                    WFLG_SIZEGADGET |
   837                                                    WFLG_SIZEBBOTTOM :
   838                                                    0))), WA_IDCMP,
   839                                IDCMP_RAWKEY | IDCMP_CLOSEWINDOW |
   840                                IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
   841                                IDCMP_MOUSEMOVE, WA_PubScreen,
   842                                (ULONG) SDL_Display, WA_GimmeZeroZero,
   843                                gzz, TAG_DONE);
   844             D(bug("Opening WB window of size: %ldx%ld!\n", w, h));
   845         }
   846 
   847         if (!SDL_Window)
   848             return -1;
   849     }
   850 
   851     this->hidden->BytesPerPixel =
   852         GetCyberMapAttr(SDL_Window->RPort->BitMap, CYBRMATTR_BPPIX);
   853 
   854     if (screen->flags & SDL_DOUBLEBUF) {
   855         if (SDL_RastPort = SDL_malloc(sizeof(struct RastPort))) {
   856             InitRastPort(SDL_RastPort);
   857             SDL_RastPort->BitMap = this->hidden->SB[1]->sb_BitMap;
   858         } else
   859             return -1;
   860     } else
   861         SDL_RastPort = SDL_Window->RPort;
   862 
   863     if (flags & SDL_HWSURFACE)
   864         screen->flags |= SDL_HWSURFACE;
   865 
   866     if (!SDL_windowid) {
   867         CGX_SetSizeHints(this, w, h, flags);
   868     }
   869 
   870     /* Set our colormaps when not setting a GL mode */
   871 /*
   872 	if ( ! (flags & SDL_INTERNALOPENGL) ) {
   873 		XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap);
   874 	}
   875 */
   876 
   877     /* Map them both and go fullscreen, if requested */
   878     if (!SDL_windowid) {
   879         if (flags & SDL_FULLSCREEN) {
   880             screen->flags |= SDL_FULLSCREEN;
   881             currently_fullscreen = 1;
   882 //                      CGX_EnterFullScreen(this); Ci siamo gia'!
   883         } else {
   884             screen->flags &= ~SDL_FULLSCREEN;
   885         }
   886     }
   887     screen->w = w;
   888     screen->h = h;
   889     screen->pitch = SDL_CalculatePitch(screen);
   890     CGX_ResizeImage(this, screen, flags);
   891 
   892     /* Make OpenGL Context if needed */
   893     if (flags & SDL_INTERNALOPENGL) {
   894         if (this->gl_data->gl_active == 0) {
   895             if (CGX_GL_Init(this) < 0)
   896                 return -1;
   897             else
   898                 screen->flags |= SDL_INTERNALOPENGL;
   899         } else {
   900             if (CGX_GL_Update(this) < 0)
   901                 return -1;
   902             else
   903                 screen->flags |= SDL_INTERNALOPENGL;
   904         }
   905     }
   906 }
   907 
   908 int
   909 CGX_ResizeWindow(_THIS, SDL_Surface * screen, int w, int h, Uint32 flags)
   910 {
   911     D(bug("CGX_ResizeWindow\n"));
   912 
   913     if (!SDL_windowid) {
   914         /* Resize the window manager window */
   915         CGX_SetSizeHints(this, w, h, flags);
   916 
   917         ChangeWindowBox(SDL_Window, SDL_Window->LeftEdge,
   918                         SDL_Window->TopEdge,
   919                         w + SDL_Window->BorderLeft +
   920                         SDL_Window->BorderRight,
   921                         h + SDL_Window->BorderTop + SDL_Window->BorderBottom);
   922 
   923         screen->w = w;
   924         screen->h = h;
   925         screen->pitch = SDL_CalculatePitch(screen);
   926         CGX_ResizeImage(this, screen, flags);
   927     }
   928     return (0);
   929 }
   930 
   931 static SDL_Surface *
   932 CGX_SetVideoMode(_THIS, SDL_Surface * current,
   933                  int width, int height, int bpp, Uint32 flags)
   934 {
   935     Uint32 saved_flags;
   936     int needcreate = 0;
   937 
   938     D(bug("CGX_SetVideoMode current:%lx\n", current));
   939 
   940     /* Lock the event thread, in multi-threading environments */
   941     SDL_Lock_EventThread();
   942 
   943 // Check if the window needs to be closed or can be resized
   944 
   945     if ((flags & SDL_FULLSCREEN)
   946         || (current && current->flags & SDL_FULLSCREEN
   947             && !(flags & SDL_FULLSCREEN)))
   948         needcreate = 1;
   949 
   950 // Check if we need to close an already existing videomode...
   951 
   952     if (current && current->flags & SDL_FULLSCREEN
   953         && !(flags & SDL_FULLSCREEN)) {
   954         unsigned long i;
   955         D(bug("Destroying image, window & screen!\n"));
   956 
   957         CGX_DestroyImage(this, current);
   958         CGX_DestroyWindow(this, current);
   959         DestroyScreen(this);
   960         GFX_Display = SDL_Display = LockPubScreen(NULL);
   961 
   962         bpp = this->hidden->depth =
   963             GetCyberMapAttr(SDL_Display->RastPort.BitMap, CYBRMATTR_DEPTH);
   964 
   965         for (i = 0; i < this->hidden->nvisuals; i++) {
   966             if (this->hidden->visuals[i].depth == bpp)  /* era .depth */
   967                 break;
   968         }
   969         if (i == this->hidden->nvisuals) {
   970             SDL_SetError("No matching visual for requested depth");
   971             return NULL;        /* should never happen */
   972         }
   973         SDL_Visual = this->hidden->visuals[i].visual;
   974 
   975         D(bug("Setting screen depth to: %ld\n", this->hidden->depth));
   976 
   977     }
   978     /* Check the combination of flags we were passed */
   979     if (flags & SDL_FULLSCREEN) {
   980         int i;
   981 
   982         /* Clear fullscreen flag if not supported */
   983         if (SDL_windowid) {
   984             flags &= ~SDL_FULLSCREEN;
   985         } else if (current && current->flags & SDL_FULLSCREEN) {
   986             if (current->w != width ||
   987                 current->h != height ||
   988                 (this->hidden && this->hidden->depth != bpp)) {
   989                 D(bug("Deleting previous window...\n"));
   990                 CGX_DestroyImage(this, current);
   991                 CGX_DestroyWindow(this, current);
   992                 DestroyScreen(this);
   993                 goto buildnewscreen;
   994             }
   995         } else
   996           buildnewscreen:
   997         {
   998             Uint32 okid = BestCModeIDTags(CYBRBIDTG_NominalWidth, width,
   999                                           CYBRBIDTG_NominalHeight,
  1000                                           height,
  1001                                           CYBRBIDTG_Depth, bpp,
  1002                                           TAG_DONE);
  1003 
  1004             GFX_Display = NULL;
  1005 
  1006             D(bug("Opening screen...\n"));
  1007 
  1008             if (okid != INVALID_ID)
  1009                 GFX_Display = OpenScreenTags(NULL,
  1010                                              SA_Width, width,
  1011                                              SA_Height, height,
  1012                                              SA_Quiet, TRUE,
  1013                                              SA_ShowTitle, FALSE,
  1014                                              SA_Depth, bpp, SA_DisplayID,
  1015                                              okid, TAG_DONE);
  1016 
  1017             if (!GFX_Display) {
  1018                 GFX_Display = SDL_Display;
  1019                 flags &= ~SDL_FULLSCREEN;
  1020                 flags &= ~SDL_DOUBLEBUF;
  1021             } else {
  1022                 UnlockPubScreen(NULL, SDL_Display);
  1023                 SDL_Display = GFX_Display;
  1024 
  1025                 D(bug("Screen opened.\n"));
  1026 
  1027                 if (flags & SDL_DOUBLEBUF) {
  1028                     int ok = 0;
  1029                     D(bug("Start of DBuffering allocations...\n"));
  1030 
  1031                     if (this->hidden->SB[0] =
  1032                         AllocScreenBuffer(SDL_Display, NULL,
  1033                                           SB_SCREEN_BITMAP)) {
  1034 
  1035                         if (this->hidden->SB[1] =
  1036                             AllocScreenBuffer(SDL_Display, NULL, 0L)) {
  1037                             extern struct MsgPort *safeport, *dispport;
  1038 
  1039                             safeport = CreateMsgPort();
  1040                             dispport = CreateMsgPort();
  1041 
  1042                             if (!safeport || !dispport) {
  1043                                 if (safeport) {
  1044                                     DeleteMsgPort(safeport);
  1045                                     safeport = NULL;
  1046                                 }
  1047                                 if (dispport) {
  1048                                     DeleteMsgPort(dispport);
  1049                                     dispport = NULL;
  1050                                 }
  1051                                 FreeScreenBuffer(SDL_Display,
  1052                                                  this->hidden->SB[0]);
  1053                                 FreeScreenBuffer(SDL_Display,
  1054                                                  this->hidden->SB[1]);
  1055                             } else {
  1056                                 extern ULONG safe_sigbit, disp_sigbit;
  1057                                 int i;
  1058 
  1059                                 safe_sigbit = 1L << safeport->mp_SigBit;
  1060                                 disp_sigbit = 1L << dispport->mp_SigBit;
  1061 
  1062                                 for (i = 0; i < 2; i++) {
  1063                                     this->hidden->SB[i]->
  1064                                         sb_DBufInfo->
  1065                                         dbi_SafeMessage.
  1066                                         mn_ReplyPort = safeport;
  1067                                     this->hidden->SB[i]->
  1068                                         sb_DBufInfo->
  1069                                         dbi_DispMessage.
  1070                                         mn_ReplyPort = dispport;
  1071                                 }
  1072 
  1073                                 ok = 1;
  1074                                 D(bug("Dbuffering enabled!\n"));
  1075                                 this->hidden->dbuffer = 1;
  1076                                 current->flags |= SDL_DOUBLEBUF;
  1077                             }
  1078                         } else {
  1079                             FreeScreenBuffer(SDL_Display,
  1080                                              this->hidden->SB[1]);
  1081                             this->hidden->SB[0] = NULL;
  1082                         }
  1083                     }
  1084 
  1085                     if (!ok)
  1086                         flags &= ~SDL_DOUBLEBUF;
  1087                 }
  1088             }
  1089 
  1090             if (GetCyberMapAttr
  1091                 (SDL_Display->RastPort.BitMap, CYBRMATTR_DEPTH) == bpp)
  1092                 this->hidden->same_format = 1;
  1093         }
  1094 
  1095         bpp = this->hidden->depth =
  1096             GetCyberMapAttr(SDL_Display->RastPort.BitMap, CYBRMATTR_DEPTH);
  1097         D(bug("Setting screen depth to: %ld\n", this->hidden->depth));
  1098 
  1099         for (i = 0; i < this->hidden->nvisuals; i++)
  1100             if (this->hidden->visuals[i].depth == bpp)  /* era .depth */
  1101                 break;
  1102 
  1103         if (i == this->hidden->nvisuals) {
  1104             SDL_SetError("No matching visual for requested depth");
  1105             return NULL;        /* should never happen */
  1106         }
  1107         SDL_Visual = this->hidden->visuals[i].visual;
  1108 
  1109     }
  1110 
  1111     /* Set up the X11 window */
  1112     saved_flags = current->flags;
  1113 
  1114     if (SDL_Window
  1115         && (saved_flags & SDL_INTERNALOPENGL) == (flags & SDL_INTERNALOPENGL)
  1116         && bpp == current->format->BitsPerPixel && !needcreate) {
  1117         if (CGX_ResizeWindow(this, current, width, height, flags) < 0) {
  1118             current = NULL;
  1119             goto done;
  1120         }
  1121     } else {
  1122         if (CGX_CreateWindow(this, current, width, height, bpp, flags) < 0) {
  1123             current = NULL;
  1124             goto done;
  1125         }
  1126     }
  1127 
  1128 #if 0
  1129     /* Set up the new mode framebuffer */
  1130     if (((current->w != width) || (current->h != height)) ||
  1131         ((saved_flags & SDL_INTERNALOPENGL) != (flags & SDL_INTERNALOPENGL)))
  1132     {
  1133         current->w = width;
  1134         current->h = height;
  1135         current->pitch = SDL_CalculatePitch(current);
  1136         CGX_ResizeImage(this, current, flags);
  1137     }
  1138 #endif
  1139 
  1140     current->flags |= (flags & SDL_RESIZABLE);  // Resizable only if the user asked it
  1141 
  1142   done:
  1143     /* Release the event thread */
  1144     SDL_Unlock_EventThread();
  1145 
  1146     /* We're done! */
  1147     return (current);
  1148 }
  1149 
  1150 static int
  1151 CGX_ToggleFullScreen(_THIS, int on)
  1152 {
  1153     Uint32 event_thread;
  1154 
  1155     /* Don't switch if we don't own the window */
  1156     if (SDL_windowid) {
  1157         return (0);
  1158     }
  1159 
  1160     /* Don't lock if we are the event thread */
  1161     event_thread = SDL_EventThreadID();
  1162     if (event_thread && (SDL_ThreadID() == event_thread)) {
  1163         event_thread = 0;
  1164     }
  1165     if (event_thread) {
  1166         SDL_Lock_EventThread();
  1167     }
  1168     if (on) {
  1169         this->screen->flags |= SDL_FULLSCREEN;
  1170         CGX_EnterFullScreen(this);
  1171     } else {
  1172         this->screen->flags &= ~SDL_FULLSCREEN;
  1173         CGX_LeaveFullScreen(this);
  1174     }
  1175 
  1176     CGX_RefreshDisplay(this);
  1177     if (event_thread) {
  1178         SDL_Unlock_EventThread();
  1179     }
  1180 
  1181     SDL_ResetKeyboard();
  1182 
  1183     return (1);
  1184 }
  1185 
  1186 static void
  1187 SetSingleColor(Uint32 fmt, unsigned char r, unsigned char g, unsigned char b,
  1188                unsigned char *c)
  1189 {
  1190     switch (fmt) {
  1191     case PIXFMT_BGR15:
  1192     case PIXFMT_RGB15PC:
  1193         {
  1194             Uint16 *t = (Uint16 *) c;
  1195             *t = (r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10);
  1196         }
  1197         break;
  1198     case PIXFMT_RGB15:
  1199     case PIXFMT_BGR15PC:
  1200         {
  1201             Uint16 *t = (Uint16 *) c;
  1202             *t = (b >> 3) | ((g >> 3) << 5) | ((r >> 3) << 10);
  1203         }
  1204         break;
  1205     case PIXFMT_BGR16PC:
  1206     case PIXFMT_RGB16:
  1207         {
  1208             Uint16 *t = (Uint16 *) c;
  1209             *t = (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11);
  1210         }
  1211         break;
  1212     case PIXFMT_BGR16:
  1213     case PIXFMT_RGB16PC:
  1214         {
  1215             Uint16 *t = (Uint16 *) c;
  1216             *t = (r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11);
  1217         }
  1218         break;
  1219     case PIXFMT_RGB24:
  1220         c[0] = r;
  1221         c[1] = g;
  1222         c[2] = b;
  1223         c[3] = 0;
  1224         break;
  1225     case PIXFMT_BGR24:
  1226         c[0] = b;
  1227         c[1] = g;
  1228         c[2] = r;
  1229         c[3] = 0;
  1230         break;
  1231     case PIXFMT_ARGB32:
  1232         c[0] = 0;
  1233         c[1] = r;
  1234         c[2] = g;
  1235         c[3] = b;
  1236         break;
  1237     case PIXFMT_BGRA32:
  1238         c[0] = b;
  1239         c[1] = g;
  1240         c[2] = r;
  1241         c[3] = 0;
  1242         break;
  1243     case PIXFMT_RGBA32:
  1244         c[0] = r;
  1245         c[1] = g;
  1246         c[2] = b;
  1247         c[3] = 0;
  1248         break;
  1249 
  1250     default:
  1251         D(bug("Error, SetSingleColor with PIXFMT %ld!\n", fmt));
  1252     }
  1253 }
  1254 
  1255 /* Update the current mouse state and position */
  1256 static void
  1257 CGX_UpdateMouse(_THIS)
  1258 {
  1259     /* Lock the event thread, in multi-threading environments */
  1260     SDL_Lock_EventThread();
  1261 
  1262     if (currently_fullscreen) {
  1263         SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
  1264         SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX,
  1265                                SDL_Display->MouseY);
  1266     } else {
  1267         if (SDL_Display->MouseX >=
  1268             (SDL_Window->LeftEdge + SDL_Window->BorderLeft)
  1269             && SDL_Display->MouseX <
  1270             (SDL_Window->LeftEdge + SDL_Window->Width -
  1271              SDL_Window->BorderRight)
  1272             && SDL_Display->MouseY >=
  1273             (SDL_Window->TopEdge + SDL_Window->BorderLeft)
  1274             && SDL_Display->MouseY <
  1275             (SDL_Window->TopEdge + SDL_Window->Height -
  1276              SDL_Window->BorderBottom)) {
  1277             SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
  1278             SDL_PrivateMouseMotion(0, 0,
  1279                                    SDL_Display->MouseX -
  1280                                    SDL_Window->LeftEdge -
  1281                                    SDL_Window->BorderLeft,
  1282                                    SDL_Display->MouseY -
  1283                                    SDL_Window->TopEdge -
  1284                                    SDL_Window->BorderTop);
  1285         } else {
  1286             SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
  1287         }
  1288     }
  1289     SDL_Unlock_EventThread();
  1290 }
  1291 
  1292 static int
  1293 CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
  1294 {
  1295     int i;
  1296 
  1297     /* Check to make sure we have a colormap allocated */
  1298 
  1299     /* It's easy if we have a hidden colormap */
  1300     if ((this->screen->flags & SDL_HWPALETTE) && currently_fullscreen) {
  1301         ULONG xcmap[256 * 3 + 2];
  1302 
  1303         xcmap[0] = (ncolors << 16);
  1304         xcmap[0] += firstcolor;
  1305 
  1306 //              D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors));
  1307 
  1308         for (i = 0; i < ncolors; i++) {
  1309             xcmap[i * 3 + 1] = colors[i + firstcolor].r << 24;
  1310             xcmap[i * 3 + 2] = colors[i + firstcolor].g << 24;
  1311             xcmap[i * 3 + 3] = colors[i + firstcolor].b << 24;
  1312         }
  1313         xcmap[ncolors * 3 + 1] = 0;
  1314         LoadRGB32(&GFX_Display->ViewPort, xcmap);
  1315     } else {
  1316 // XPixels are not needed on 8bit screen with hwpalette
  1317         unsigned long pixel;
  1318 
  1319         if (SDL_XPixels == NULL) {
  1320             D(bug("SetColors without colormap!"));
  1321             return (0);
  1322         }
  1323 
  1324         if (this->hidden->depth == 8) {
  1325 // In this case I have to unalloc and realloc the full palette
  1326             D(bug("Obtaining %ld colors on the screen\n", ncolors));
  1327 
  1328             /* Free existing allocated colors */
  1329             for (pixel = 0;
  1330                  pixel < this->screen->format->palette->ncolors; ++pixel) {
  1331                 if (SDL_XPixels[pixel] >= 0)
  1332                     ReleasePen(GFX_Display->ViewPort.ColorMap,
  1333                                SDL_XPixels[pixel]);
  1334             }
  1335 
  1336             /* Try to allocate all the colors */
  1337             for (i = 0; i < this->screen->format->palette->ncolors; ++i) {
  1338                 SDL_XPixels[i] =
  1339                     ObtainBestPenA(GFX_Display->ViewPort.ColorMap,
  1340                                    colors[i].r << 24,
  1341                                    colors[i].g << 24,
  1342                                    colors[i].b << 24, NULL);
  1343             }
  1344         } else {
  1345 #ifndef USE_CGX_WRITELUTPIXEL
  1346             Uint32 fmt;
  1347             D(bug("Preparing a conversion pixel table...\n"));
  1348 
  1349             fmt =
  1350                 GetCyberMapAttr(SDL_Display->RastPort.BitMap,
  1351                                 CYBRMATTR_PIXFMT);
  1352 
  1353             for (i = 0; i < ncolors; i++) {
  1354                 SetSingleColor(fmt, colors[firstcolor + i].r,
  1355                                colors[firstcolor + i].g,
  1356                                colors[firstcolor + i].b, (unsigned char *)
  1357                                &SDL_XPixels[firstcolor + i]);
  1358             }
  1359 #else
  1360 //                      D(bug("Executing XPixel(%lx) remapping: (from %ld, %ld colors) first: r%ld g%ld b%ld\n",SDL_XPixels,firstcolor,ncolors,colors[firstcolor].r,colors[firstcolor].g,colors[firstcolor].b));
  1361             for (i = 0; i < ncolors; i++)
  1362                 SDL_XPixels[i + firstcolor] =
  1363                     (colors[firstcolor + i].r << 16) +
  1364                     (colors[firstcolor + i].g << 8) + colors[firstcolor +
  1365                                                              i].b;
  1366 #endif
  1367         }
  1368     }
  1369 
  1370 // Actually it cannot fail!
  1371 
  1372     return 1;
  1373 }
  1374 
  1375 /* Note:  If we are terminated, this could be called in the middle of
  1376    another SDL video routine -- notably UpdateRects.
  1377 */
  1378 static void
  1379 CGX_VideoQuit(_THIS)
  1380 {
  1381     /* Shutdown everything that's still up */
  1382     /* The event thread should be done, so we can touch SDL_Display */
  1383     D(bug("CGX_VideoQuit\n"));
  1384 
  1385     if (SDL_Display != NULL) {
  1386         /* Clean up OpenGL */
  1387         if (this->gl_data->gl_active == 1) {
  1388             CGX_GL_Quit(this);
  1389         }
  1390         /* Start shutting down the windows */
  1391         D(bug("Destroying image...\n"));
  1392         CGX_DestroyImage(this, this->screen);
  1393         D(bug("Destroying window...\n"));
  1394         CGX_DestroyWindow(this, this->screen);
  1395 // Otherwise SDL_VideoQuit will try to free it!
  1396         SDL_VideoSurface = NULL;
  1397 
  1398         CGX_FreeVideoModes(this);
  1399 
  1400         /* Free that blank cursor */
  1401         if (SDL_BlankCursor != NULL) {
  1402             FreeMem(SDL_BlankCursor, 16);
  1403             SDL_BlankCursor = NULL;
  1404         }
  1405 
  1406         /* Close the X11 graphics connection */
  1407         this->hidden->same_format = 0;
  1408 
  1409         D(bug("Destroying screen...\n"));
  1410 
  1411         if (GFX_Display != NULL)
  1412             DestroyScreen(this);
  1413 
  1414         /* Close the X11 display connection */
  1415         SDL_Display = NULL;
  1416 
  1417         /* Unload GL library after X11 shuts down */
  1418     }
  1419 
  1420     D(bug("Closing libraries...\n"));
  1421 
  1422     if (CyberGfxBase) {
  1423         CloseLibrary(CyberGfxBase);
  1424         CyberGfxBase = NULL;
  1425     }
  1426 
  1427     if (IntuitionBase) {
  1428         CloseLibrary((struct Library *) IntuitionBase);
  1429         IntuitionBase = NULL;
  1430     }
  1431     if (GfxBase) {
  1432         CloseLibrary((struct Library *) GfxBase);
  1433         GfxBase = NULL;
  1434     }
  1435 
  1436     if (this->screen && (this->screen->flags & SDL_HWSURFACE)) {
  1437         /* Direct screen access, no memory buffer */
  1438         this->screen->pixels = NULL;
  1439     }
  1440     D(bug("End of CGX_VideoQuit.\n"));
  1441 
  1442 }
  1443 
  1444 /* vi: set ts=4 sw=4 expandtab: */