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