src/video/photon/SDL_ph_video.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 28 May 2002 19:31:32 +0000
changeset 380 bce7171e7a85
parent 370 ba72f259bc88
child 571 8e3ce997621c
permissions -rw-r--r--
Date: Wed, 22 May 2002 22:30:58 +0300
From: "Mike Gorchak" <mike@malva.com.ua>
Subject: One more QNX patch

Hi !

- Fixed graywin test application. Added properly support for
window size not equal to 640x480.
- Added support for not aligned pitch of image in SDL_SWSURFACE
and SDL_HWSURFACE. Using Photon builtin alignes.
- Added memory clear after each malloc to avoid problems in the
future :)
- Removed unused variables and static variables, fixed some warnings.
- Updated readme.QNX file.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  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,
    55                 int width, int height, int bpp, Uint32 flags);
    56 static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
    57 static void ph_VideoQuit(_THIS);
    58 static void ph_DeleteDevice(SDL_VideoDevice *device);
    59 
    60 #ifdef HAVE_OPENGL
    61 int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags);
    62 static void ph_GL_SwapBuffers(_THIS);
    63 static int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
    64 #endif /* HAVE_OPENGL */
    65 
    66 static int ph_Available(void)
    67 {
    68     int phstat=-1;
    69 
    70     phstat=PtInit(0);
    71     if (phstat==0)
    72     {
    73        return 1;
    74     }
    75     else
    76     {
    77        return 0;
    78     }
    79 }
    80 
    81 static SDL_VideoDevice *ph_CreateDevice(int devindex)
    82 {
    83     SDL_VideoDevice *device;
    84 
    85     /* Initialize all variables that we clean on shutdown */
    86     device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
    87     if (device) {
    88         memset(device, 0, (sizeof *device));
    89         device->hidden = (struct SDL_PrivateVideoData *)
    90                 malloc((sizeof *device->hidden));
    91         device->gl_data = NULL;
    92     }
    93     if ( (device == NULL) || (device->hidden == NULL) ) {
    94         SDL_OutOfMemory();
    95         ph_DeleteDevice(device);
    96         return(0);
    97     }
    98     memset(device->hidden, 0, (sizeof *device->hidden));
    99 
   100     /* Set the driver flags */
   101     device->handles_any_size = 1; /* JB not true for fullscreen */
   102 
   103     /* Set the function pointers */
   104     device->CreateYUVOverlay = ph_CreateYUVOverlay;
   105     device->VideoInit = ph_VideoInit;
   106     device->ListModes = ph_ListModes;
   107     device->SetVideoMode = ph_SetVideoMode;
   108     device->ToggleFullScreen = ph_ToggleFullScreen;
   109     device->UpdateMouse = NULL;	
   110     device->SetColors = ph_SetColors;
   111     device->UpdateRects = NULL;         /* ph_ResizeImage */
   112     device->VideoQuit = ph_VideoQuit;
   113     device->AllocHWSurface = ph_AllocHWSurface;
   114     device->CheckHWBlit = NULL;
   115     device->FillHWRect = NULL;
   116     device->SetHWColorKey = NULL;
   117     device->SetHWAlpha = NULL;
   118     device->LockHWSurface = ph_LockHWSurface;
   119     device->UnlockHWSurface = ph_UnlockHWSurface;
   120     device->FlipHWSurface = ph_FlipHWSurface;
   121     device->FreeHWSurface = ph_FreeHWSurface;
   122     device->SetCaption = ph_SetCaption;
   123     device->SetIcon = NULL;
   124     device->IconifyWindow = ph_IconifyWindow;
   125     device->GrabInput = ph_GrabInput;
   126     device->GetWMInfo = ph_GetWMInfo;
   127     device->FreeWMCursor = ph_FreeWMCursor;
   128     device->CreateWMCursor = ph_CreateWMCursor;
   129     device->ShowWMCursor = ph_ShowWMCursor;
   130     device->WarpWMCursor = ph_WarpWMCursor;
   131     device->CheckMouseMode = ph_CheckMouseMode;
   132     device->InitOSKeymap = ph_InitOSKeymap;
   133     device->PumpEvents = ph_PumpEvents;
   134 
   135     /* OpenGL support. */
   136     device->GL_LoadLibrary = NULL;
   137     device->GL_GetProcAddress = NULL;
   138     device->GL_MakeCurrent = NULL;
   139 #ifdef HAVE_OPENGL
   140     device->GL_SwapBuffers = ph_GL_SwapBuffers;
   141     device->GL_GetAttribute = ph_GL_GetAttribute;
   142 #else
   143     device->GL_SwapBuffers = NULL;
   144     device->GL_GetAttribute = NULL;
   145 #endif /* HAVE_OPENGL */
   146 
   147     device->free = ph_DeleteDevice;
   148 
   149     return device;
   150 }
   151 
   152 VideoBootStrap ph_bootstrap = {
   153     "photon", "QNX Photon video output",
   154     ph_Available, ph_CreateDevice
   155 };
   156 
   157 static void ph_DeleteDevice(SDL_VideoDevice *device)
   158 {
   159     if (device)
   160     {
   161         if (device->hidden)
   162         {
   163             free(device->hidden);
   164             device->hidden = NULL;
   165         }
   166         if (device->gl_data)
   167         {
   168             free(device->gl_data);
   169             device->gl_data = NULL;
   170         }
   171         free(device);
   172         device = NULL;
   173     }
   174 }
   175 
   176 static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
   177 {
   178     PgVideoModeInfo_t my_mode_info;
   179     PgHWCaps_t my_hwcaps;
   180 
   181     window=NULL;
   182     desktoppal=SDLPH_PAL_NONE;
   183 #ifdef HAVE_OPENGL
   184     oglctx=NULL;
   185 #endif /* HAVE_OPENGL */
   186     
   187     captionflag=0;
   188     old_video_mode=-1;
   189     old_refresh_rate=-1;
   190 	
   191     if (NULL == (event = malloc(EVENT_SIZE)))
   192     {
   193         exit(EXIT_FAILURE);
   194     }
   195     memset(event, 0x00, EVENT_SIZE);
   196 
   197     /* Create the blank cursor */
   198     SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
   199                                           (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT,
   200                                           (int)BLANK_CHOTX, (int)BLANK_CHOTY);
   201 
   202     if (SDL_BlankCursor == NULL)
   203     {
   204         printf("ph_VideoInit(): could not create blank cursor !\n");
   205     }
   206 
   207     if (PgGetGraphicsHWCaps(&my_hwcaps) < 0)
   208     {
   209         fprintf(stderr,"ph_VideoInit(): GetGraphicsHWCaps failed !\n");
   210     }
   211 
   212     if (PgGetVideoModeInfo(my_hwcaps.current_video_mode, &my_mode_info) < 0)
   213     {
   214         fprintf(stderr,"ph_VideoInit(): PgGetVideoModeInfo failed !\n");
   215     }
   216 
   217     /* We need to return BytesPerPixel as it in used by CreateRGBsurface */
   218     vformat->BitsPerPixel = my_mode_info.bits_per_pixel;
   219     vformat->BytesPerPixel = my_mode_info.bytes_per_scanline/my_mode_info.width;
   220     desktopbpp = my_mode_info.bits_per_pixel;
   221     
   222     /* save current palette */
   223     if (desktopbpp==8)
   224     {
   225         PgGetPalette(ph_palette);
   226     }
   227          
   228     currently_fullscreen = 0;
   229     
   230     this->info.wm_available = 1;
   231     
   232     return 0;
   233 }
   234 
   235 static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
   236                 int width, int height, int bpp, Uint32 flags)
   237 {
   238     PgDisplaySettings_t settings;
   239     int mode;
   240     PtArg_t arg[32];
   241     PhDim_t dim;
   242     int rtnval;
   243     int i;
   244     unsigned long *tempptr;
   245     int pargc;
   246 
   247     dim.w=width;
   248     dim.h=height;
   249 
   250     /* Lock the event thread, in multi-threading environments */
   251     SDL_Lock_EventThread();
   252 
   253     current->flags = flags;
   254 
   255     /* create window if no OpenGL support selected */
   256     if ((flags & SDL_OPENGL)!=SDL_OPENGL)
   257     {
   258         pargc=0;
   259         
   260         // prevent using HWSURFACE in window mode if desktop bpp != chosen bpp
   261         if ((flags & SDL_HWSURFACE) && (!(flags & SDL_FULLSCREEN)))
   262         {
   263            if (desktopbpp!=bpp)
   264            {
   265               fprintf(stderr, "ph_SetVideoMode(): SDL_HWSURFACE available only with chosen bpp equal desktop bpp !\n");
   266               return NULL;
   267            }
   268         }
   269 
   270         PtSetArg(&arg[pargc++], Pt_ARG_DIM, &dim, 0);
   271         PtSetArg(&arg[pargc++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
   272 
   273         /* enable window minimizing */
   274         PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE);
   275 
   276         /* remove border and caption if no frame flag selected */
   277         if ((flags & SDL_NOFRAME) == SDL_NOFRAME)
   278         {
   279             PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_TITLE | Ph_WM_RENDER_BORDER);
   280         }
   281         else
   282         {
   283             PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_TITLE | Ph_WM_RENDER_BORDER);
   284         }
   285 
   286         /* if window is not resizable then remove resize handles and maximize button */
   287         if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE)
   288         {
   289             PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX);
   290             PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
   291             PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
   292         }
   293         else
   294         {
   295             PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_TRUE, Ph_WM_RENDER_RESIZE | Ph_WM_RENDER_MAX);
   296             /* it is need to be Pt_FALSE to allow the application to process the resize callback */
   297             PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_FALSE, Ph_WM_RESIZE | Ph_WM_MAX);
   298             PtSetArg(&arg[pargc++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_RESIZE | Ph_WM_MAX);
   299         }
   300 
   301         if (window!=NULL)
   302         {
   303             PtUnrealizeWidget(window);
   304             PtDestroyWidget(window);
   305             window=NULL;
   306         }
   307 
   308         window=PtCreateWidget(PtWindow, NULL, pargc, arg);
   309         PtRealizeWidget(window);
   310         
   311         PtFlush();
   312     }
   313 
   314 #ifdef HAVE_OPENGL
   315     if (flags & SDL_OPENGL)
   316     {
   317         /* ph_SetupOpenGLContext creates also window as need */
   318         if (ph_SetupOpenGLContext(this, width, height, bpp, flags)==0)
   319         {
   320             /* setup OGL update function ... ugly method */
   321             ph_ResizeImage(this, current, flags); 
   322         }
   323         else
   324         {
   325             /* if context creation fail, report no OpenGL to high level */
   326             current->flags=(flags & (~SDL_OPENGL));
   327         }
   328 #else
   329     if (flags & SDL_OPENGL) /* if no built-in OpenGL support */
   330     {
   331         fprintf(stderr, "ph_SetVideoMode(): no OpenGL support, try to recompile library.\n");
   332         current->flags=(flags & (~SDL_OPENGL));
   333         return NULL;
   334 #endif /* HAVE_OPENGL */
   335     }
   336     else
   337     {
   338         /* Initialize the window */
   339         if (flags & SDL_FULLSCREEN) /* Direct Context , assume SDL_HWSURFACE also set */
   340         {
   341             /* Get the video mode and set it */
   342             if (flags & SDL_ANYFORMAT)
   343             {
   344                 if ((mode = get_mode_any_format(width, height, bpp)) == 0)
   345                 {
   346                     fprintf(stderr,"ph_SetVideoMode(): get_mode_any_format failed !\n");
   347                     exit(1);
   348                 }
   349             }
   350             else
   351             {
   352                 if ((mode = get_mode(width, height, bpp)) == 0)
   353                 {
   354                     fprintf(stderr,"ph_SetVideoMode(): get_mode failed !\n");
   355                     exit(1);
   356                 }
   357             }
   358             
   359             if (bpp==8)
   360             {
   361                desktoppal=SDLPH_PAL_SYSTEM;
   362             }
   363             
   364             /* save old video mode caps */
   365             PgGetVideoMode(&settings);
   366             old_video_mode=settings.mode;
   367             old_refresh_rate=settings.refresh;
   368 
   369             /* setup new video mode */
   370             settings.mode = mode;
   371             settings.refresh = 0;
   372             settings.flags = 0;
   373 
   374             if (PgSetVideoMode(&settings) < 0)
   375             {
   376                 fprintf(stderr,"ph_SetVideoMode(): PgSetVideoMode failed !\n");
   377             }
   378 
   379             current->flags = (flags & (~SDL_RESIZABLE)); /* no resize for Direct Context */
   380 
   381             /* Begin direct mode */
   382             ph_EnterFullScreen(this);
   383 
   384         } /* end fullscreen flag */
   385         else
   386         {
   387             /* Use offscreen memory iff SDL_HWSURFACE flag is set */
   388             if (flags & SDL_HWSURFACE)
   389             {
   390                 /* no stretch blit in offscreen context */
   391                 current->flags = (flags & (~SDL_RESIZABLE));
   392             }
   393 
   394             /* using palette emulation code in window mode */
   395             if (bpp==8)
   396             {
   397                 if (desktopbpp>=15)
   398                 {
   399                     desktoppal=SDLPH_PAL_EMULATE;
   400                 }
   401                 else
   402                 {
   403                     desktoppal=SDLPH_PAL_SYSTEM;
   404                 }
   405             }
   406             else
   407             {
   408                desktoppal=SDLPH_PAL_NONE;
   409             }
   410         }
   411 
   412 	/* If we are setting video to use the palette make sure we have allocated memory for it */
   413 	if (bpp==8)
   414 	{
   415             current->format->palette = malloc(sizeof(SDL_Palette));
   416             memset(current->format->palette, 0, sizeof(SDL_Palette));
   417             current->format->palette->ncolors = 256;
   418             current->format->palette->colors = (SDL_Color *)malloc(256 *sizeof(SDL_Color));
   419             /* fill the palette */
   420             rtnval = PgGetPalette(ph_palette);
   421 
   422             tempptr = (unsigned long *)current->format->palette->colors;
   423 
   424             for(i=0; i<256; i++)
   425             {
   426                 *tempptr = (((unsigned long)ph_palette[i]) << 8);
   427                 tempptr++;
   428             }
   429         }
   430 
   431     }
   432 
   433     current->w = width;
   434     current->h = height;
   435     current->format->BitsPerPixel = bpp;
   436     current->format->BytesPerPixel = (bpp+7)/8;
   437     current->pitch = SDL_CalculatePitch(current);
   438 
   439     /* Must call at least once it setup image planes */
   440     rtnval = ph_ResizeImage(this, current, flags);
   441     
   442     if (rtnval==-1)
   443     {
   444         fprintf(stderr,"ph_SetVideoMode(): ph_ResizeImage failed !\n");
   445         return NULL;
   446     }
   447 
   448     /* delayed set caption call */
   449     if (captionflag)
   450     {
   451         ph_SetCaption(this, this->wm_title, NULL);
   452     }
   453 
   454     /* finish window drawing */
   455     PtFlush();
   456 
   457     SDL_Unlock_EventThread();
   458 
   459     /* We're done! */
   460     return (current);
   461 }
   462 
   463 static void ph_VideoQuit(_THIS)
   464 {
   465 #ifdef HAVE_OPENGL
   466     PhRegion_t region_info;
   467 #endif /* HAVE_OPENGL */
   468 
   469     ph_DestroyImage(this, SDL_VideoSurface); 
   470 
   471     if (currently_fullscreen)
   472     {
   473         ph_LeaveFullScreen(this);
   474     }
   475 
   476 #ifdef HAVE_OPENGL
   477     /* prevent double SEGFAULT during parachute mode */
   478     if (this->screen)
   479     {
   480         if (((this->screen->flags & SDL_FULLSCREEN)==SDL_FULLSCREEN) &&
   481             ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL))
   482         {
   483             region_info.cursor_type=Ph_CURSOR_POINTER;
   484             region_info.rid=PtWidgetRid(window);
   485             PhRegionChange(Ph_REGION_CURSOR, 0, &region_info, NULL, NULL);
   486         }
   487     }
   488 
   489     PtFlush();
   490 #endif /* HAVE_OPENGL */
   491     
   492     if (window)
   493     {
   494         PtUnrealizeWidget(window);
   495         PtDestroyWidget(window);
   496         window=NULL;
   497     }
   498     
   499     /* restore palette */
   500     if (desktoppal!=SDLPH_PAL_NONE)
   501     {
   502         PgSetPalette(ph_palette, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
   503     }
   504 
   505 #ifdef HAVE_OPENGL
   506     if (oglctx)
   507     {
   508         PhDCSetCurrent(NULL);
   509         PhDCRelease(oglctx);
   510         oglctx=NULL;
   511     }
   512 #endif /* HAVE_OPENGL */
   513 }
   514 
   515 static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
   516 {
   517     int i;
   518     PhPoint_t point={0, 0};
   519     PgColor_t syspalph[_Pg_MAX_PALETTE];
   520 
   521     /* palette emulation code, using palette of the PhImage_t struct */
   522     if (desktoppal==SDLPH_PAL_EMULATE)
   523     {
   524         if ((SDL_Image) && (SDL_Image->palette))
   525         {
   526             for (i=firstcolor; i<firstcolor+ncolors; i++)
   527             {
   528                 SDL_Image->palette[i]  = 0x00000000UL;
   529                 SDL_Image->palette[i] |= colors[i-firstcolor].r<<16;
   530                 SDL_Image->palette[i] |= colors[i-firstcolor].g<<8;
   531                 SDL_Image->palette[i] |= colors[i-firstcolor].b;
   532             }
   533 
   534            /* image needs to be redrawed, very slow method */
   535            PgDrawPhImage(&point, SDL_Image, 0);
   536         }
   537     }
   538     else
   539     {
   540         if (desktoppal==SDLPH_PAL_SYSTEM)
   541         {
   542             for (i=firstcolor; i<firstcolor+ncolors; i++)
   543             {
   544                 syspalph[i]  = 0x00000000UL;
   545                 syspalph[i] |= colors[i-firstcolor].r<<16;
   546                 syspalph[i] |= colors[i-firstcolor].g<<8;
   547                 syspalph[i] |= colors[i-firstcolor].b;
   548             }
   549 
   550             if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
   551             {
   552                 /* window mode must use soft palette */
   553                 PgSetPalette((PgColor_t*)&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_SOFT, 0);
   554                 /* image needs to be redrawed, very slow method */
   555                 if (SDL_Image)
   556                 {
   557                    PgDrawPhImage(&point, SDL_Image, 0);
   558                 }
   559             }
   560             else
   561             {
   562                 /* fullscreen mode must use hardware palette */
   563                 PgSetPalette((PgColor_t*)&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
   564             }
   565         }
   566         else
   567         {
   568             /* SDLPH_PAL_NONE do nothing */
   569         }
   570     }
   571     
   572     return 1;
   573 }
   574 
   575 #ifdef HAVE_OPENGL
   576 
   577 int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags)
   578 {
   579     PtArg_t args[8];
   580     PhDim_t dim;
   581     uint64_t OGLAttrib[PH_OGL_MAX_ATTRIBS];
   582     int OGLargc;
   583     int pargc;
   584 
   585     dim.w=width;
   586     dim.h=height;
   587     
   588     if (oglctx!=NULL)
   589     {
   590        PhDCSetCurrent(NULL);
   591        PhDCRelease(oglctx);
   592        oglctx=NULL;
   593     }
   594 
   595     OGLargc=0;
   596     if (this->gl_config.depth_size)
   597     {
   598         OGLAttrib[OGLargc++]=PHOGL_ATTRIB_DEPTH_BITS;
   599         OGLAttrib[OGLargc++]=this->gl_config.depth_size;
   600     }
   601     if (this->gl_config.stencil_size)
   602     {
   603         OGLAttrib[OGLargc++]=PHOGL_ATTRIB_STENCIL_BITS;
   604         OGLAttrib[OGLargc++]=this->gl_config.stencil_size;
   605     }
   606     OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FORCE_SW;
   607     if (flags & SDL_FULLSCREEN)
   608     {
   609         OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN;
   610         OGLAttrib[OGLargc++]=PHOGL_ATTRIB_DIRECT;
   611         OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN_BEST;
   612         OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN_CENTER;
   613     }
   614     OGLAttrib[OGLargc++]=PHOGL_ATTRIB_NONE;
   615 
   616     if (this->gl_config.double_buffer)
   617     {
   618         oglctx=PdCreateOpenGLContext(2, &dim, 0, OGLAttrib);
   619     }
   620     else
   621     {
   622         oglctx=PdCreateOpenGLContext(1, &dim, 0, OGLAttrib);
   623     }
   624 
   625     if (oglctx==NULL)
   626     {
   627         fprintf(stderr,"ph_SetupOpenGLContext(): cannot create OpenGL context.\n");
   628         return (-1);
   629     }
   630 
   631     PhDCSetCurrent(oglctx);
   632 
   633     pargc=0;
   634 
   635     PtSetArg(&args[pargc++], Pt_ARG_DIM, &dim, 0);
   636     PtSetArg(&args[pargc++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
   637     PtSetArg(&args[pargc++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
   638 
   639     if (flags & SDL_FULLSCREEN)
   640     {
   641         PhPoint_t pos;
   642 
   643         pos.x=0;
   644         pos.y=0;
   645 
   646         PtSetArg(&args[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, ~0);
   647         PtSetArg(&args[pargc++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_FFRONT | Ph_WM_CLOSE | Ph_WM_TOFRONT | Ph_WM_CONSWITCH);
   648         PtSetArg(&args[pargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISFOCUS);
   649         PtSetArg(&args[pargc++], Pt_ARG_POS, &pos, 0);
   650     }
   651     else
   652     {
   653         /* remove border and caption if no frame flag selected */
   654         if ((flags & SDL_NOFRAME) == SDL_NOFRAME)
   655         {
   656             PtSetArg(&args[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, 0, Ph_WM_RENDER_TITLE | Ph_WM_RENDER_BORDER);
   657         }
   658         else
   659         {
   660            /* if window is not resizable then remove resize handles */
   661            if ((flags & SDL_RESIZABLE) != SDL_RESIZABLE)
   662            {
   663                PtSetArg(&args[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, 0, Ph_WM_RENDER_RESIZE);
   664            }
   665         }
   666     }
   667 
   668     if (window!=NULL)
   669     {
   670         PtUnrealizeWidget(window);
   671         PtDestroyWidget(window);
   672         window=NULL;
   673     }
   674 
   675     window=PtCreateWidget(PtWindow, NULL, pargc, args);
   676     PtRealizeWidget(window);
   677 
   678     /* disable mouse for fullscreen */
   679     if (flags & SDL_FULLSCREEN)
   680     {
   681         PhRegion_t region_info;
   682 
   683         region_info.cursor_type=Ph_CURSOR_NONE;
   684         region_info.rid=PtWidgetRid(window);
   685         PhRegionChange(Ph_REGION_CURSOR, 0, &region_info, NULL, NULL);
   686     }
   687 
   688     PtFlush();
   689 
   690     return 0;
   691 }
   692 
   693 void ph_GL_SwapBuffers(_THIS)
   694 {
   695     PgSetRegion(PtWidgetRid(window));
   696     PdOpenGLContextSwapBuffers(oglctx);
   697 }
   698 
   699 int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
   700 {
   701     switch (attrib)
   702     {
   703         case SDL_GL_DOUBLEBUFFER:
   704              *value=this->gl_config.double_buffer;
   705              break;
   706         case SDL_GL_STENCIL_SIZE:
   707              *value=this->gl_config.stencil_size;
   708              break;
   709         case SDL_GL_DEPTH_SIZE:
   710              *value=this->gl_config.depth_size;
   711              break;
   712         default:
   713              *value=0;
   714              return(-1);
   715     }
   716     return 0;
   717 }
   718 
   719 #endif /* HAVE_OPENGL */