src/video/photon/SDL_ph_video.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 06 May 2004 15:55:06 +0000
changeset 886 05c551e5bc64
parent 837 4bc7e16a13ed
child 910 4ab6d1fd028f
permissions -rw-r--r--
Date: Sat, 24 Apr 2004 15:13:32 +0300
From: "Mike Gorchak"
Subject: SDL updates for the QNX6

1. Updated the README.QNX
2. Updated libtool scripts, which are shipped with SDL for QNX6 support.
3. Added some code to support the new QNX 6.3.0, which is in beta now.
4. Added code to detect the hw features, which driver supports.
5. Added hw alpha blits code.
6. Fixed bug when application switches to fullscreen more the 2 times. (afte\
r that window becames always stay on top).
7. Updated a bit README for the tests.
8. Added information about acceleration show in the testalpha.c test.
9. Added small fixes to the testoverlay2.c test.
10. Added alpha and cc+alpha blits benchmarks to the testvidinfo.c test.
     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     {
    94         memset(device, 0, (sizeof *device));
    95         device->hidden = (struct SDL_PrivateVideoData*)malloc((sizeof *device->hidden));
    96         device->gl_data = NULL;
    97     }
    98     if ((device == NULL) || (device->hidden == NULL))
    99     {
   100         SDL_OutOfMemory();
   101         ph_DeleteDevice(device);
   102         return NULL;
   103     }
   104     memset(device->hidden, 0, (sizeof *device->hidden));
   105 
   106     /* Set the driver flags */
   107     device->handles_any_size = 1;
   108 
   109     /* Set the function pointers */
   110     device->CreateYUVOverlay = ph_CreateYUVOverlay;
   111     device->VideoInit = ph_VideoInit;
   112     device->ListModes = ph_ListModes;
   113     device->SetVideoMode = ph_SetVideoMode;
   114     device->ToggleFullScreen = ph_ToggleFullScreen;
   115     device->UpdateMouse = ph_UpdateMouse;
   116     device->SetColors = ph_SetColors;
   117     device->UpdateRects = NULL;                        /* set up in ph_SetupUpdateFunction */
   118     device->VideoQuit = ph_VideoQuit;
   119     device->AllocHWSurface = ph_AllocHWSurface;
   120     device->CheckHWBlit = ph_CheckHWBlit;
   121     device->FillHWRect = ph_FillHWRect;
   122     device->SetHWColorKey = ph_SetHWColorKey;
   123     device->SetHWAlpha = ph_SetHWAlpha;
   124     device->LockHWSurface = ph_LockHWSurface;
   125     device->UnlockHWSurface = ph_UnlockHWSurface;
   126     device->FlipHWSurface = ph_FlipHWSurface;
   127     device->FreeHWSurface = ph_FreeHWSurface;
   128     device->SetCaption = ph_SetCaption;
   129     device->SetIcon = NULL;
   130     device->IconifyWindow = ph_IconifyWindow;
   131     device->GrabInput = ph_GrabInput;
   132     device->GetWMInfo = ph_GetWMInfo;
   133     device->FreeWMCursor = ph_FreeWMCursor;
   134     device->CreateWMCursor = ph_CreateWMCursor;
   135     device->ShowWMCursor = ph_ShowWMCursor;
   136     device->WarpWMCursor = ph_WarpWMCursor;
   137     device->MoveWMCursor = NULL;
   138     device->CheckMouseMode = ph_CheckMouseMode;
   139     device->InitOSKeymap = ph_InitOSKeymap;
   140     device->PumpEvents = ph_PumpEvents;
   141 
   142     /* OpenGL support. */
   143 #ifdef HAVE_OPENGL
   144     device->GL_MakeCurrent = ph_GL_MakeCurrent;
   145     device->GL_SwapBuffers = ph_GL_SwapBuffers;
   146     device->GL_GetAttribute = ph_GL_GetAttribute;
   147     device->GL_LoadLibrary = ph_GL_LoadLibrary;
   148     device->GL_GetProcAddress = ph_GL_GetProcAddress;
   149 #else
   150     device->GL_MakeCurrent = NULL;
   151     device->GL_SwapBuffers = NULL;
   152     device->GL_GetAttribute = NULL;
   153     device->GL_LoadLibrary = NULL;
   154     device->GL_GetProcAddress = NULL;
   155 #endif /* HAVE_OPENGL */
   156 
   157     device->free = ph_DeleteDevice;
   158     
   159     return device;
   160 }
   161 
   162 VideoBootStrap ph_bootstrap = {
   163     "photon", "QNX Photon video output",
   164     ph_Available, ph_CreateDevice
   165 };
   166 
   167 static void ph_DeleteDevice(SDL_VideoDevice *device)
   168 {
   169     if (device)
   170     {
   171         if (device->hidden)
   172         {
   173             free(device->hidden);
   174             device->hidden = NULL;
   175         }
   176         if (device->gl_data)
   177         {
   178             free(device->gl_data);
   179             device->gl_data = NULL;
   180         }
   181         free(device);
   182         device = NULL;
   183     }
   184 }
   185 
   186 static PtWidget_t *ph_CreateWindow(_THIS)
   187 {
   188     PtWidget_t *widget;
   189     
   190     widget = PtCreateWidget(PtWindow, NULL, 0, NULL);
   191 
   192     return widget;
   193 }
   194 
   195 static int ph_SetupWindow(_THIS, int w, int h, int flags)
   196 {
   197     PtArg_t     args[32];
   198     PhPoint_t   pos = {0, 0};
   199     PhDim_t*    olddim;
   200     PhDim_t     dim = {w, h};
   201     PhRect_t    desktopextent;
   202     int         nargs = 0;
   203     const char* windowpos;
   204     const char* iscentered;
   205     int         x, y;
   206 
   207     /* check if window size has been changed by Window Manager */
   208     PtGetResource(window, Pt_ARG_DIM, &olddim, 0);
   209     if ((olddim->w!=w) || (olddim->h!=h))
   210     {
   211        PtSetArg(&args[nargs++], Pt_ARG_DIM, &dim, 0);
   212     }
   213 
   214     if ((flags & SDL_RESIZABLE) == SDL_RESIZABLE)
   215     {
   216         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_CLOSE);
   217         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_RESIZE);
   218         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);
   219         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);
   220         PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_TRUE, Pt_RESIZE_XY_AS_REQUIRED);
   221     }
   222     else
   223     {
   224         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE | Ph_WM_CLOSE);
   225         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX | Ph_WM_RESTORE);
   226         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_MOVE | Ph_WM_CLOSE);
   227         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);
   228         PtSetArg(&args[nargs++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
   229     }
   230 
   231     if (((flags & SDL_NOFRAME)==SDL_NOFRAME) || ((flags & SDL_FULLSCREEN)==SDL_FULLSCREEN))
   232     {
   233        if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE)
   234        {
   235            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
   236        }
   237        else
   238        {
   239            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Pt_TRUE);
   240            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_BORDER);
   241        }
   242     }
   243     else
   244     {
   245         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_BORDER | Ph_WM_RENDER_TITLE |
   246                                  Ph_WM_RENDER_CLOSE | Ph_WM_RENDER_MENU | Ph_WM_RENDER_MIN);
   247     }
   248 
   249     if ((flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
   250     {
   251         PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
   252         PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL);
   253         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_FFRONT | Ph_WM_MAX | Ph_WM_TOFRONT | Ph_WM_CONSWITCH);
   254         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISFOCUS | Ph_WM_STATE_ISALTKEY);
   255     }
   256     else
   257     {
   258         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_FFRONT | Ph_WM_CONSWITCH);
   259         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISFRONT);
   260         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISALTKEY);
   261 
   262         if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE)
   263         {
   264             PtSetArg(&args[nargs++], Pt_ARG_BASIC_FLAGS, Pt_TRUE, Pt_BASIC_PREVENT_FILL);
   265         }
   266         else
   267         {
   268             PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
   269         }
   270         if (!currently_maximized)
   271         {
   272             windowpos = getenv("SDL_VIDEO_WINDOW_POS");
   273             iscentered = getenv("SDL_VIDEO_CENTERED");
   274 
   275             if ((iscentered) || ((windowpos) && (strcmp(windowpos, "center")==0)))
   276             {
   277                 PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent);
   278                 if (desktop_mode.width>w)
   279                 {
   280                     pos.x = (desktop_mode.width - w)/2;
   281                 }
   282                 if (desktop_mode.height>h)
   283                 {
   284                     pos.y = (desktop_mode.height - h)/2;
   285                 }
   286 
   287                 pos.x+=desktopextent.ul.x;
   288                 pos.y+=desktopextent.ul.y;
   289                 PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
   290             }
   291             else
   292             {
   293                 if (windowpos)
   294                 {
   295                     if (sscanf(windowpos, "%d,%d", &x, &y) == 2)
   296                     {
   297                         if ((x<desktop_mode.width) && (y<desktop_mode.height))
   298                         {
   299                             PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent);
   300                             pos.x=x+desktopextent.ul.x;
   301                             pos.y=y+desktopextent.ul.y;
   302                         }
   303                         PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
   304                     }
   305                 }
   306             }
   307         }
   308 
   309         /* if window is maximized render it as maximized */
   310         if (currently_maximized)
   311         {
   312            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISMAX);
   313         }
   314         else
   315         {
   316            PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISMAX);
   317         }
   318 
   319         /* do not grab the keyboard by default */
   320         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISALTKEY);
   321 
   322         /* bring the focus to the window */
   323         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFOCUS);
   324 
   325         /* allow to catch hide event */
   326         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE);
   327         PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_HIDE);
   328     }
   329 
   330     PtSetResources(window, nargs, args);
   331     PtRealizeWidget(window);
   332     PtWindowToFront(window);
   333 
   334 #if 0 /* FIXME */
   335     PtGetResource(window, Pt_ARG_POS, &olddim, 0);
   336     fprintf(stderr, "POSITION: %d, %d\n", olddim->w, olddim->h);
   337 #endif
   338 
   339     return 0;
   340 }
   341 
   342 static const struct ColourMasks* ph_GetColourMasks(int bpp)
   343 {
   344     /* The alpha mask doesn't appears to be needed */
   345     static const struct ColourMasks phColorMasks[5] = {
   346         /*  8 bit      */  {0, 0, 0, 0, 8},
   347         /* 15 bit ARGB */  {0x7C00, 0x03E0, 0x001F, 0x8000, 15},
   348         /* 16 bit  RGB */  {0xF800, 0x07E0, 0x001F, 0x0000, 16},
   349         /* 24 bit  RGB */  {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24},
   350         /* 32 bit ARGB */  {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32},
   351     };
   352 
   353     switch (bpp)
   354     {
   355         case 8:
   356              return &phColorMasks[0];
   357         case 15:
   358              return &phColorMasks[1];
   359         case 16:
   360              return &phColorMasks[2];
   361         case 24:
   362              return &phColorMasks[3];
   363         case 32:
   364              return &phColorMasks[4];
   365     }
   366     return NULL;
   367 }
   368 
   369 static int ph_VideoInit(_THIS, SDL_PixelFormat* vformat)
   370 {
   371     PgHWCaps_t hwcaps;
   372     int i;
   373 
   374     window=NULL;
   375     desktoppal=SDLPH_PAL_NONE;
   376 
   377 #ifdef HAVE_OPENGL
   378     oglctx=NULL;
   379     oglflags=0;
   380     oglbpp=0;
   381 #endif /* HAVE_OPENGL */
   382     
   383     old_video_mode=-1;
   384     old_refresh_rate=-1;
   385 	
   386     if (NULL == (event = malloc(EVENT_SIZE)))
   387     {
   388         SDL_OutOfMemory();
   389         return -1;
   390     }
   391     memset(event, 0x00, EVENT_SIZE);
   392 
   393     window = ph_CreateWindow(this);
   394     if (window == NULL)
   395     {
   396         SDL_SetError("ph_VideoInit(): Couldn't create video window !\n");
   397         return -1;
   398     }
   399 
   400     /* Create the blank cursor */
   401     SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
   402                                           (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT,
   403                                           (int)BLANK_CHOTX, (int)BLANK_CHOTY);
   404 
   405     if (SDL_BlankCursor == NULL)
   406     {
   407         return -1;
   408     }
   409 
   410     if (PgGetGraphicsHWCaps(&hwcaps) < 0)
   411     {
   412         SDL_SetError("ph_VideoInit(): GetGraphicsHWCaps function failed !\n");
   413         this->FreeWMCursor(this, SDL_BlankCursor);
   414         return -1;
   415     }
   416 
   417     if (PgGetVideoModeInfo(hwcaps.current_video_mode, &desktop_mode) < 0)
   418     {
   419         SDL_SetError("ph_VideoInit(): PgGetVideoModeInfo function failed !\n");
   420         this->FreeWMCursor(this, SDL_BlankCursor);
   421         return -1;
   422     }
   423 
   424     /* We need to return BytesPerPixel as it in used by CreateRGBsurface */
   425     vformat->BitsPerPixel = desktop_mode.bits_per_pixel;
   426     vformat->BytesPerPixel = desktop_mode.bytes_per_scanline/desktop_mode.width;
   427     desktopbpp = desktop_mode.bits_per_pixel;
   428     
   429     /* save current palette */
   430     if (desktopbpp==8)
   431     {
   432         PgGetPalette(savedpal);
   433         PgGetPalette(syspalph);
   434     }
   435     else
   436     {
   437         for(i=0; i<_Pg_MAX_PALETTE; i++)
   438         {
   439             savedpal[i]=PgRGB(0, 0, 0);
   440             syspalph[i]=PgRGB(0, 0, 0);
   441         }
   442     }
   443          
   444     currently_fullscreen = 0;
   445     currently_hided = 0;
   446     currently_maximized = 0;
   447     current_overlay = NULL;
   448 
   449     OCImage.direct_context = NULL;
   450     OCImage.offscreen_context = NULL;
   451     OCImage.offscreen_backcontext = NULL;
   452     OCImage.oldDC = NULL;
   453     OCImage.CurrentFrameData = NULL;
   454     OCImage.FrameData0 = NULL;
   455     OCImage.FrameData1 = NULL;
   456     videomode_emulatemode = 0;
   457     
   458     this->info.wm_available = 1;
   459 
   460     ph_UpdateHWInfo(this);
   461     
   462     return 0;
   463 }
   464 
   465 static SDL_Surface* ph_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
   466 {
   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         /* Error string was filled in the ph_SetupUpdateFunction() */
   562         return NULL;
   563     }
   564 
   565     /* finish window drawing, if we are not in fullscreen, of course */
   566     if ((current->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
   567     {
   568        PtFlush();
   569     }
   570     else
   571     {
   572        PgFlush();
   573     }
   574 
   575     visualbpp=bpp;
   576 
   577     ph_UpdateHWInfo(this);
   578 
   579     SDL_Unlock_EventThread();
   580 
   581     /* We've done! */
   582     return (current);
   583 }
   584 
   585 static void ph_VideoQuit(_THIS)
   586 {
   587     /* restore palette */
   588     if (desktopbpp==8)
   589     {
   590         PgSetPalette(syspalph, 0, -1, 0, 0, 0);
   591         PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
   592         PgFlush();
   593     }
   594 
   595     ph_DestroyImage(this, SDL_VideoSurface); 
   596 
   597     if (window)
   598     {
   599         PtUnrealizeWidget(window);
   600         PtDestroyWidget(window);
   601         window=NULL;
   602     }
   603 
   604     if (event!=NULL)
   605     {
   606         free(event);
   607         event=NULL;
   608     }
   609 }
   610 
   611 static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   612 {
   613     int i;
   614     SDL_Rect updaterect;
   615 
   616     updaterect.x = updaterect.y = 0;
   617     updaterect.w = this->screen->w;
   618     updaterect.h = this->screen->h;
   619 
   620     /* palette emulation code, using palette of the PhImage_t struct */
   621     if (desktoppal==SDLPH_PAL_EMULATE)
   622     {
   623         if ((SDL_Image) && (SDL_Image->palette))
   624         {
   625             for (i=firstcolor; i<firstcolor+ncolors; i++)
   626             {
   627                 syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
   628                 SDL_Image->palette[i] = syspalph[i];
   629             }
   630 
   631             /* image needs to be redrawn */
   632             this->UpdateRects(this, 1, &updaterect);
   633         }
   634     }
   635     else
   636     {
   637         if (desktoppal==SDLPH_PAL_SYSTEM)
   638         {
   639             for (i=firstcolor; i<firstcolor+ncolors; i++)
   640             {
   641                 syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
   642             }
   643 
   644             if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
   645             {
   646                  /* window mode must use soft palette */
   647                 PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
   648                 /* image needs to be redrawn */
   649                 this->UpdateRects(this, 1, &updaterect);
   650             }
   651             else
   652             {
   653                 /* fullscreen mode must use hardware palette */
   654                 PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
   655             }
   656         }
   657         else
   658         {
   659             /* SDLPH_PAL_NONE do nothing */
   660         }
   661     }
   662     
   663     return 1;
   664 }
   665 
   666 #ifdef HAVE_OPENGL
   667 
   668 static void ph_GL_SwapBuffers(_THIS)
   669 {
   670     PgSetRegion(PtWidgetRid(window));
   671     PdOpenGLContextSwapBuffers(oglctx);
   672 }
   673 
   674 static int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
   675 {
   676     switch (attrib)
   677     {
   678         case SDL_GL_DOUBLEBUFFER:
   679              *value=this->gl_config.double_buffer;
   680              break;
   681         case SDL_GL_STENCIL_SIZE:
   682              *value=this->gl_config.stencil_size;
   683              break;
   684         case SDL_GL_DEPTH_SIZE:
   685              *value=this->gl_config.depth_size;
   686              break;
   687         default:
   688              *value=0;
   689              return(-1);
   690     }
   691     return 0;
   692 }
   693 
   694 static int ph_GL_LoadLibrary(_THIS, const char* path)
   695 {
   696    /* if code compiled with HAVE_OPENGL, that mean that library already linked */
   697    this->gl_config.driver_loaded = 1;
   698 
   699    return 0;
   700 }
   701 
   702 static void* ph_GL_GetProcAddress(_THIS, const char* proc)
   703 {
   704    return NULL;
   705 }
   706 
   707 static int ph_GL_MakeCurrent(_THIS)
   708 {
   709     PgSetRegion(PtWidgetRid(window));
   710 
   711     if (oglctx!=NULL)
   712     {
   713         PhDCSetCurrent(oglctx);
   714     }
   715 
   716     return 0;
   717 }
   718 
   719 #endif /* HAVE_OPENGL */