src/video/photon/SDL_ph_video.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 08 Mar 2006 01:55:32 +0000
changeset 1482 141528317f4f
parent 1402 d910939febfa
child 1545 8d9bb0cf2c2a
permissions -rw-r--r--
QNX changes from Mike Gorchak
     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 #include <unistd.h>
    25 #include <sys/ioctl.h>
    26 
    27 #include "SDL_endian.h"
    28 #include "SDL_timer.h"
    29 #include "SDL_thread.h"
    30 #include "SDL_video.h"
    31 #include "SDL_mouse.h"
    32 #include "../SDL_sysvideo.h"
    33 #include "../SDL_pixels_c.h"
    34 #include "../../events/SDL_events_c.h"
    35 #include "SDL_ph_video.h"
    36 #include "SDL_ph_modes_c.h"
    37 #include "SDL_ph_image_c.h"
    38 #include "SDL_ph_events_c.h"
    39 #include "SDL_ph_mouse_c.h"
    40 #include "SDL_ph_wm_c.h"
    41 #include "SDL_ph_gl.h"
    42 #include "SDL_phyuv_c.h"
    43 #include "../blank_cursor.h"
    44 
    45 static int  ph_VideoInit(_THIS, SDL_PixelFormat *vformat);
    46 static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
    47 static int  ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
    48 static void ph_VideoQuit(_THIS);
    49 static void ph_DeleteDevice(SDL_VideoDevice *device);
    50 
    51 static int phstatus=-1;
    52 
    53 static int ph_Available(void)
    54 {
    55     if (phstatus!=0)
    56     {
    57         phstatus=PtInit(NULL);
    58         if (phstatus==0)
    59         {
    60            return 1;
    61         }
    62         else
    63         {
    64            return 0;
    65         }
    66     }
    67     return 1;
    68 }
    69 
    70 static SDL_VideoDevice* ph_CreateDevice(int devindex)
    71 {
    72     SDL_VideoDevice* device;
    73 
    74     /* Initialize all variables that we clean on shutdown */
    75     device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
    76     if (device)
    77     {
    78         SDL_memset(device, 0, (sizeof *device));
    79         device->hidden = (struct SDL_PrivateVideoData*)SDL_malloc((sizeof *device->hidden));
    80         device->gl_data = NULL;
    81     }
    82     if ((device == NULL) || (device->hidden == NULL))
    83     {
    84         SDL_OutOfMemory();
    85         ph_DeleteDevice(device);
    86         return NULL;
    87     }
    88     SDL_memset(device->hidden, 0, (sizeof *device->hidden));
    89 
    90     /* Set the driver flags */
    91     device->handles_any_size = 1;
    92 
    93     /* Set the function pointers */
    94     device->CreateYUVOverlay = ph_CreateYUVOverlay;
    95     device->VideoInit = ph_VideoInit;
    96     device->ListModes = ph_ListModes;
    97     device->SetVideoMode = ph_SetVideoMode;
    98     device->ToggleFullScreen = ph_ToggleFullScreen;
    99     device->UpdateMouse = ph_UpdateMouse;
   100     device->SetColors = ph_SetColors;
   101     device->UpdateRects = NULL;                        /* set up in ph_SetupUpdateFunction */
   102     device->VideoQuit = ph_VideoQuit;
   103     device->AllocHWSurface = ph_AllocHWSurface;
   104     device->CheckHWBlit = ph_CheckHWBlit;
   105     device->FillHWRect = ph_FillHWRect;
   106     device->SetHWColorKey = ph_SetHWColorKey;
   107     device->SetHWAlpha = ph_SetHWAlpha;
   108     device->LockHWSurface = ph_LockHWSurface;
   109     device->UnlockHWSurface = ph_UnlockHWSurface;
   110     device->FlipHWSurface = ph_FlipHWSurface;
   111     device->FreeHWSurface = ph_FreeHWSurface;
   112     device->SetCaption = ph_SetCaption;
   113     device->SetIcon = NULL;
   114     device->IconifyWindow = ph_IconifyWindow;
   115     device->GrabInput = ph_GrabInput;
   116     device->GetWMInfo = ph_GetWMInfo;
   117     device->FreeWMCursor = ph_FreeWMCursor;
   118     device->CreateWMCursor = ph_CreateWMCursor;
   119     device->ShowWMCursor = ph_ShowWMCursor;
   120     device->WarpWMCursor = ph_WarpWMCursor;
   121     device->MoveWMCursor = NULL;
   122     device->CheckMouseMode = ph_CheckMouseMode;
   123     device->InitOSKeymap = ph_InitOSKeymap;
   124     device->PumpEvents = ph_PumpEvents;
   125 
   126     /* OpenGL support. */
   127 #if SDL_VIDEO_OPENGL
   128     device->GL_MakeCurrent = ph_GL_MakeCurrent;
   129     device->GL_SwapBuffers = ph_GL_SwapBuffers;
   130     device->GL_GetAttribute = ph_GL_GetAttribute;
   131     device->GL_LoadLibrary = ph_GL_LoadLibrary;
   132     device->GL_GetProcAddress = ph_GL_GetProcAddress;
   133 #endif /* SDL_VIDEO_OPENGL */
   134 
   135     device->free = ph_DeleteDevice;
   136     
   137     return device;
   138 }
   139 
   140 VideoBootStrap ph_bootstrap = {
   141     "photon", "QNX Photon video output",
   142     ph_Available, ph_CreateDevice
   143 };
   144 
   145 static void ph_DeleteDevice(SDL_VideoDevice *device)
   146 {
   147     if (device)
   148     {
   149         if (device->hidden)
   150         {
   151             SDL_free(device->hidden);
   152             device->hidden = NULL;
   153         }
   154         if (device->gl_data)
   155         {
   156             SDL_free(device->gl_data);
   157             device->gl_data = NULL;
   158         }
   159         SDL_free(device);
   160         device = NULL;
   161     }
   162 }
   163 
   164 static PtWidget_t *ph_CreateWindow(_THIS)
   165 {
   166     PtWidget_t *widget;
   167     
   168     widget = PtCreateWidget(PtWindow, NULL, 0, NULL);
   169 
   170     return widget;
   171 }
   172 
   173 static int ph_SetupWindow(_THIS, int w, int h, int flags)
   174 {
   175     PtArg_t     args[32];
   176     PhPoint_t   pos = {0, 0};
   177     PhDim_t*    olddim;
   178     PhDim_t     dim = {w, h};
   179     PhRect_t    desktopextent;
   180     int         nargs = 0;
   181     const char* windowpos;
   182     const char* iscentered;
   183     int         x, y;
   184 
   185     /* check if window size has been changed by Window Manager */
   186     PtGetResource(window, Pt_ARG_DIM, &olddim, 0);
   187     if ((olddim->w!=w) || (olddim->h!=h))
   188     {
   189        PtSetArg(&args[nargs++], Pt_ARG_DIM, &dim, 0);
   190     }
   191 
   192     if ((flags & SDL_RESIZABLE) == SDL_RESIZABLE)
   193     {
   194         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_CLOSE);
   195         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_RESIZE);
   196         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MOVE | Ph_WM_CLOSE | Ph_WM_MAX | Ph_WM_RESTORE);
   197         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN);
   198         PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_TRUE, Pt_RESIZE_XY_AS_REQUIRED);
   199     }
   200     else
   201     {
   202         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_CLOSE);
   203         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE);
   204         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_MOVE | Ph_WM_CLOSE);
   205         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX | Ph_WM_RENDER_COLLAPSE | Ph_WM_RENDER_RETURN);
   206         PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
   207     }
   208 
   209     if (((flags & SDL_NOFRAME)==SDL_NOFRAME) || ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN))
   210     {
   211        if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE)
   212        {
   213            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
   214        }
   215        else
   216        {
   217            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
   218            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_BORDER);
   219        }
   220     }
   221     else
   222     {
   223         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE |
   224                                  Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN);
   225     }
   226 
   227     if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
   228     {
   229         PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
   230         PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL);
   231         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_FFRONT | Ph_WM_MAX | Ph_WM_TOFRONT | Ph_WM_CONSWITCH);
   232         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISFOCUS | Ph_WM_STATE_ISALTKEY);
   233     }
   234     else
   235     {
   236         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_FFRONT | Ph_WM_CONSWITCH);
   237         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISFRONT);
   238         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISALTKEY);
   239 
   240         if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE)
   241         {
   242             PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL);
   243         }
   244         else
   245         {
   246             PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
   247         }
   248         if (!currently_maximized)
   249         {
   250             windowpos = SDL_getenv("SDL_VIDEO_WINDOW_POS");
   251             iscentered = SDL_getenv("SDL_VIDEO_CENTERED");
   252 
   253             if ((iscentered) || ((windowpos) && (SDL_strcmp(windowpos, "center")==0)))
   254             {
   255                 PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent);
   256                 if (desktop_mode.width>w)
   257                 {
   258                     pos.x = (desktop_mode.width - w)/2;
   259                 }
   260                 if (desktop_mode.height>h)
   261                 {
   262                     pos.y = (desktop_mode.height - h)/2;
   263                 }
   264 
   265                 pos.x+=desktopextent.ul.x;
   266                 pos.y+=desktopextent.ul.y;
   267                 PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
   268             }
   269             else
   270             {
   271                 if (windowpos)
   272                 {
   273                     if (SDL_sscanf(windowpos, "%d,%d", &x, &y) == 2)
   274                     {
   275                         if ((x<desktop_mode.width) && (y<desktop_mode.height))
   276                         {
   277                             PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent);
   278                             pos.x=x+desktopextent.ul.x;
   279                             pos.y=y+desktopextent.ul.y;
   280                         }
   281                         PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
   282                     }
   283                 }
   284             }
   285         }
   286 
   287         /* if window is maximized render it as maximized */
   288         if (currently_maximized)
   289         {
   290            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISMAX);
   291         }
   292         else
   293         {
   294            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISMAX);
   295         }
   296 
   297         /* do not grab the keyboard by default */
   298         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISALTKEY);
   299 
   300         /* bring the focus to the window */
   301         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFOCUS);
   302 
   303         /* allow to catch hide event */
   304         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE);
   305         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_HIDE);
   306     }
   307 
   308     PtSetResources(window, nargs, args);
   309     PtRealizeWidget(window);
   310     PtWindowToFront(window);
   311 
   312 #if 0 /* FIXME */
   313     PtGetResource(window, Pt_ARG_POS, &olddim, 0);
   314     fprintf(stderr, "POSITION: %d, %d\n", olddim->w, olddim->h);
   315 #endif
   316 
   317     return 0;
   318 }
   319 
   320 static const struct ColourMasks* ph_GetColourMasks(int bpp)
   321 {
   322     /* The alpha mask doesn't appears to be needed */
   323     static const struct ColourMasks phColorMasks[5] = {
   324         /*  8 bit      */  {0, 0, 0, 0, 8},
   325         /* 15 bit ARGB */  {0x7C00, 0x03E0, 0x001F, 0x8000, 15},
   326         /* 16 bit  RGB */  {0xF800, 0x07E0, 0x001F, 0x0000, 16},
   327         /* 24 bit  RGB */  {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24},
   328         /* 32 bit ARGB */  {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32},
   329     };
   330 
   331     switch (bpp)
   332     {
   333         case 8:
   334              return &phColorMasks[0];
   335         case 15:
   336              return &phColorMasks[1];
   337         case 16:
   338              return &phColorMasks[2];
   339         case 24:
   340              return &phColorMasks[3];
   341         case 32:
   342              return &phColorMasks[4];
   343     }
   344     return NULL;
   345 }
   346 
   347 static int ph_VideoInit(_THIS, SDL_PixelFormat* vformat)
   348 {
   349     PgHWCaps_t hwcaps;
   350     int i;
   351 
   352     window=NULL;
   353     desktoppal=SDLPH_PAL_NONE;
   354 
   355 #if SDL_VIDEO_OPENGL
   356     oglctx=NULL;
   357     oglbuffers=NULL;
   358     oglflags=0;
   359     oglbpp=0;
   360 #endif
   361     
   362     old_video_mode=-1;
   363     old_refresh_rate=-1;
   364 	
   365     if (NULL == (phevent = SDL_malloc(EVENT_SIZE)))
   366     {
   367         SDL_OutOfMemory();
   368         return -1;
   369     }
   370     SDL_memset(phevent, 0x00, EVENT_SIZE);
   371 
   372     window = ph_CreateWindow(this);
   373     if (window == NULL)
   374     {
   375         SDL_SetError("ph_VideoInit(): Couldn't create video window !\n");
   376         return -1;
   377     }
   378 
   379     /* Create the blank cursor */
   380     SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
   381                                           (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT,
   382                                           (int)BLANK_CHOTX, (int)BLANK_CHOTY);
   383 
   384     if (SDL_BlankCursor == NULL)
   385     {
   386         return -1;
   387     }
   388 
   389     if (PgGetGraphicsHWCaps(&hwcaps) < 0)
   390     {
   391         SDL_SetError("ph_VideoInit(): GetGraphicsHWCaps function failed !\n");
   392         this->FreeWMCursor(this, SDL_BlankCursor);
   393         return -1;
   394     }
   395 
   396     if (PgGetVideoModeInfo(hwcaps.current_video_mode, &desktop_mode) < 0)
   397     {
   398         SDL_SetError("ph_VideoInit(): PgGetVideoModeInfo function failed !\n");
   399         this->FreeWMCursor(this, SDL_BlankCursor);
   400         return -1;
   401     }
   402 
   403     /* We need to return BytesPerPixel as it in used by CreateRGBsurface */
   404     vformat->BitsPerPixel = desktop_mode.bits_per_pixel;
   405     vformat->BytesPerPixel = desktop_mode.bytes_per_scanline/desktop_mode.width;
   406     desktopbpp = desktop_mode.bits_per_pixel;
   407     
   408     /* save current palette */
   409     if (desktopbpp==8)
   410     {
   411         PgGetPalette(savedpal);
   412         PgGetPalette(syspalph);
   413     }
   414     else
   415     {
   416         for(i=0; i<_Pg_MAX_PALETTE; i++)
   417         {
   418             savedpal[i]=PgRGB(0, 0, 0);
   419             syspalph[i]=PgRGB(0, 0, 0);
   420         }
   421     }
   422          
   423     currently_fullscreen = 0;
   424     currently_hided = 0;
   425     currently_maximized = 0;
   426     current_overlay = NULL;
   427 
   428     OCImage.direct_context = NULL;
   429     OCImage.offscreen_context = NULL;
   430     OCImage.offscreen_backcontext = NULL;
   431     OCImage.oldDC = NULL;
   432     OCImage.CurrentFrameData = NULL;
   433     OCImage.FrameData0 = NULL;
   434     OCImage.FrameData1 = NULL;
   435     videomode_emulatemode = 0;
   436     
   437     this->info.wm_available = 1;
   438 
   439     ph_UpdateHWInfo(this);
   440     
   441     return 0;
   442 }
   443 
   444 static SDL_Surface* ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
   445 {
   446     const struct ColourMasks* mask;
   447 
   448     /* Lock the event thread, in multi-threading environments */
   449     SDL_Lock_EventThread();
   450 
   451     current->flags = flags;
   452 
   453     /* if we do not have desired fullscreen mode, then fallback into window mode */
   454     if (((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && (ph_GetVideoMode(width, height, bpp)==0))
   455     {
   456        current->flags &= ~SDL_FULLSCREEN;
   457        current->flags &= ~SDL_NOFRAME;
   458        current->flags &= ~SDL_RESIZABLE;
   459     }
   460 
   461     ph_SetupWindow(this, width, height, current->flags);
   462 
   463     mask = ph_GetColourMasks(bpp);
   464     if (mask != NULL)
   465     {
   466         SDL_ReallocFormat(current, mask->bpp, mask->red, mask->green, mask->blue, 0);
   467     }
   468     else
   469     {
   470         SDL_SetError("ph_SetVideoMode(): desired bpp is not supported by photon !\n");
   471         return NULL;
   472     }
   473 
   474     if ((current->flags & SDL_OPENGL)==SDL_OPENGL)
   475     {
   476 #if !SDL_VIDEO_OPENGL
   477         /* if no built-in OpenGL support */
   478         SDL_SetError("ph_SetVideoMode(): no OpenGL support, you need to recompile SDL.\n");
   479         current->flags &= ~SDL_OPENGL;
   480         return NULL;
   481 #endif /* SDL_VIDEO_OPENGL */
   482     }
   483     else
   484     {
   485         /* Initialize internal variables */
   486         if ((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
   487         {
   488             if (bpp==8)
   489             {
   490                desktoppal=SDLPH_PAL_SYSTEM;
   491             }
   492 
   493             current->flags &= ~SDL_RESIZABLE; /* no resize for Direct Context */
   494             current->flags |= SDL_HWSURFACE;
   495         }
   496         else
   497         {
   498             /* remove this if we'll have support for the non-fullscreen sw/hw+doublebuf one day */
   499             current->flags &= ~SDL_DOUBLEBUF;
   500 
   501             /* Use offscreen memory if SDL_HWSURFACE flag is set */
   502             if ((current->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
   503             {
   504                 if (desktopbpp!=bpp)
   505                 {
   506                    current->flags &= ~SDL_HWSURFACE;
   507                 }
   508             }
   509 
   510             /* using palette emulation code in window mode */
   511             if (bpp==8)
   512             {
   513                 if (desktopbpp>=15)
   514                 {
   515                     desktoppal = SDLPH_PAL_EMULATE;
   516                 }
   517                 else
   518                 {
   519                     desktoppal = SDLPH_PAL_SYSTEM;
   520                 }
   521             }
   522             else
   523             {
   524                desktoppal = SDLPH_PAL_NONE;
   525             }
   526         }
   527     }
   528 
   529     current->w = width;
   530     current->h = height;
   531 
   532     if (desktoppal==SDLPH_PAL_SYSTEM)
   533     {
   534        current->flags|=SDL_HWPALETTE;
   535     }
   536 
   537     /* Must call at least once for setup image planes */
   538     if (ph_SetupUpdateFunction(this, current, current->flags)==-1)
   539     {
   540         /* Error string was filled in the ph_SetupUpdateFunction() */
   541         return NULL;
   542     }
   543 
   544     /* finish window drawing, if we are not in fullscreen, of course */
   545     if ((current->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
   546     {
   547        PtFlush();
   548     }
   549     else
   550     {
   551        PgFlush();
   552     }
   553 
   554     visualbpp=bpp;
   555 
   556     ph_UpdateHWInfo(this);
   557 
   558     SDL_Unlock_EventThread();
   559 
   560     /* We've done! */
   561     return (current);
   562 }
   563 
   564 static void ph_VideoQuit(_THIS)
   565 {
   566     /* restore palette */
   567     if (desktopbpp==8)
   568     {
   569         PgSetPalette(syspalph, 0, -1, 0, 0, 0);
   570         PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
   571         PgFlush();
   572     }
   573 
   574     ph_DestroyImage(this, SDL_VideoSurface); 
   575 
   576     if (window)
   577     {
   578         PtUnrealizeWidget(window);
   579         PtDestroyWidget(window);
   580         window=NULL;
   581     }
   582 
   583     if (phevent!=NULL)
   584     {
   585         SDL_free(phevent);
   586         phevent=NULL;
   587     }
   588 }
   589 
   590 static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   591 {
   592     int i;
   593     SDL_Rect updaterect;
   594 
   595     updaterect.x = updaterect.y = 0;
   596     updaterect.w = this->screen->w;
   597     updaterect.h = this->screen->h;
   598 
   599     /* palette emulation code, using palette of the PhImage_t struct */
   600     if (desktoppal==SDLPH_PAL_EMULATE)
   601     {
   602         if ((SDL_Image) && (SDL_Image->palette))
   603         {
   604             for (i=firstcolor; i<firstcolor+ncolors; i++)
   605             {
   606                 syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
   607                 SDL_Image->palette[i] = syspalph[i];
   608             }
   609 
   610             /* image needs to be redrawn */
   611             this->UpdateRects(this, 1, &updaterect);
   612         }
   613     }
   614     else
   615     {
   616         if (desktoppal==SDLPH_PAL_SYSTEM)
   617         {
   618             for (i=firstcolor; i<firstcolor+ncolors; i++)
   619             {
   620                 syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
   621             }
   622 
   623             if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
   624             {
   625                  /* window mode must use soft palette */
   626                 PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
   627                 /* image needs to be redrawn */
   628                 this->UpdateRects(this, 1, &updaterect);
   629             }
   630             else
   631             {
   632                 /* fullscreen mode must use hardware palette */
   633                 PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
   634             }
   635         }
   636         else
   637         {
   638             /* SDLPH_PAL_NONE do nothing */
   639         }
   640     }
   641     
   642     return 1;
   643 }
   644