src/video/photon/SDL_ph_video.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 23 Mar 2002 20:19:44 +0000
changeset 315 3333b6e68289
parent 309 2de77f7b7a28
child 320 66f815c147ed
permissions -rw-r--r--
Date: Sat, 23 Mar 2002 13:53:37 +0200
From: "Mike Gorchak" <mike@malva.ua>
Subject: Big QNX patch again.

Added 8bit palette emulation code for window mode with bpp>=15.
Added store/restore original palette for 8bit modes.
Added more information about photon API call fails.
Rewroten change palette code, slow but works.
Fixed bug with set caption before window was inited.
Fixed bugs with some initial state of variables.
Fixed bug with storing old video mode settings.
Fixed bug with switching to fullscreen mode and back.
Fixed few double SEGFAULTS during parachute mode.
Removed compilation warning with no PgWaitHWIdle prototype.
Removed pack of dead unusable code.
Cleanups SDL_PrivateVideoData structure, some headers.
Some code formatting.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@297
     3
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@0
     6
    modify it under the terms of the GNU Library General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@0
     8
    version 2 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@0
    13
    Library General Public License for more details.
slouken@0
    14
slouken@0
    15
    You should have received a copy of the GNU Library General Public
slouken@0
    16
    License along with this library; if not, write to the Free
slouken@0
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@0
    22
slouken@0
    23
#ifdef SAVE_RCSID
slouken@0
    24
static char rcsid =
slouken@0
    25
 "@(#) $Id$";
slouken@0
    26
#endif
slouken@0
    27
slouken@0
    28
#include <stdlib.h>
slouken@0
    29
#include <stdio.h>
slouken@0
    30
#include <unistd.h>
slouken@0
    31
#include <string.h>
slouken@0
    32
#include <sys/ioctl.h>
slouken@0
    33
slouken@0
    34
#include "SDL.h"
slouken@0
    35
#include "SDL_error.h"
slouken@0
    36
#include "SDL_timer.h"
slouken@0
    37
#include "SDL_thread.h"
slouken@0
    38
#include "SDL_video.h"
slouken@0
    39
#include "SDL_mouse.h"
slouken@0
    40
#include "SDL_endian.h"
slouken@0
    41
#include "SDL_sysvideo.h"
slouken@0
    42
#include "SDL_pixels_c.h"
slouken@0
    43
#include "SDL_events_c.h"
slouken@0
    44
#include "SDL_ph_video.h"
slouken@0
    45
#include "SDL_ph_modes_c.h"
slouken@0
    46
#include "SDL_ph_image_c.h"
slouken@0
    47
#include "SDL_ph_events_c.h"
slouken@0
    48
#include "SDL_ph_mouse_c.h"
slouken@19
    49
#include "SDL_ph_wm_c.h"
slouken@0
    50
#include "SDL_phyuv_c.h"
slouken@0
    51
#include "blank_cursor.h"
slouken@0
    52
slouken@0
    53
static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat);
slouken@0
    54
static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
slouken@0
    55
                int width, int height, int bpp, Uint32 flags);
slouken@0
    56
static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
slouken@0
    57
static void ph_VideoQuit(_THIS);
slouken@0
    58
static void ph_DeleteDevice(SDL_VideoDevice *device);
slouken@291
    59
slouken@291
    60
#ifdef HAVE_OPENGL
slouken@309
    61
int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags);
slouken@266
    62
static void ph_GL_SwapBuffers(_THIS);
slouken@291
    63
static int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value);
slouken@291
    64
#endif /* HAVE_OPENGL */
slouken@266
    65
slouken@0
    66
static int ph_Available(void)
slouken@0
    67
{
slouken@309
    68
    int phstat=-1;
slouken@309
    69
slouken@309
    70
    phstat=PtInit(0);
slouken@309
    71
    if (phstat==0)
slouken@309
    72
    {
slouken@309
    73
       return 1;
slouken@309
    74
    }
slouken@309
    75
    else
slouken@309
    76
    {
slouken@309
    77
       return 0;
slouken@309
    78
    }
slouken@0
    79
}
slouken@0
    80
slouken@0
    81
static SDL_VideoDevice *ph_CreateDevice(int devindex)
slouken@0
    82
{
slouken@0
    83
    SDL_VideoDevice *device;
slouken@0
    84
slouken@0
    85
    /* Initialize all variables that we clean on shutdown */
slouken@0
    86
    device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
slouken@309
    87
    if (device) {
slouken@0
    88
        memset(device, 0, (sizeof *device));
slouken@0
    89
        device->hidden = (struct SDL_PrivateVideoData *)
slouken@0
    90
                malloc((sizeof *device->hidden));
slouken@0
    91
        device->gl_data = NULL;
slouken@0
    92
    }
slouken@0
    93
    if ( (device == NULL) || (device->hidden == NULL) ) {
slouken@0
    94
        SDL_OutOfMemory();
slouken@0
    95
        ph_DeleteDevice(device);
slouken@0
    96
        return(0);
slouken@0
    97
    }
slouken@0
    98
    memset(device->hidden, 0, (sizeof *device->hidden));
slouken@0
    99
slouken@0
   100
    /* Set the driver flags */
slouken@279
   101
    device->handles_any_size = 1; /* JB not true for fullscreen */
slouken@0
   102
slouken@0
   103
    /* Set the function pointers */
slouken@266
   104
    device->CreateYUVOverlay = ph_CreateYUVOverlay;
slouken@0
   105
    device->VideoInit = ph_VideoInit;
slouken@0
   106
    device->ListModes = ph_ListModes;
slouken@0
   107
    device->SetVideoMode = ph_SetVideoMode;
slouken@309
   108
    device->ToggleFullScreen = ph_ToggleFullScreen;
slouken@0
   109
    device->UpdateMouse = NULL;	
slouken@0
   110
    device->SetColors = ph_SetColors;
slouken@309
   111
    device->UpdateRects = NULL;         /* ph_ResizeImage */
slouken@0
   112
    device->VideoQuit = ph_VideoQuit;
slouken@0
   113
    device->AllocHWSurface = ph_AllocHWSurface;
slouken@0
   114
    device->CheckHWBlit = NULL;
slouken@0
   115
    device->FillHWRect = NULL;
slouken@0
   116
    device->SetHWColorKey = NULL;
slouken@0
   117
    device->SetHWAlpha = NULL;
slouken@0
   118
    device->LockHWSurface = ph_LockHWSurface;
slouken@0
   119
    device->UnlockHWSurface = ph_UnlockHWSurface;
slouken@0
   120
    device->FlipHWSurface = ph_FlipHWSurface;
slouken@0
   121
    device->FreeHWSurface = ph_FreeHWSurface;
slouken@19
   122
    device->SetCaption = ph_SetCaption;
slouken@0
   123
    device->SetIcon = NULL;
slouken@19
   124
    device->IconifyWindow = ph_IconifyWindow;
slouken@283
   125
    device->GrabInput = ph_GrabInput;
slouken@291
   126
    device->GetWMInfo = ph_GetWMInfo;
slouken@0
   127
    device->FreeWMCursor = ph_FreeWMCursor;
slouken@0
   128
    device->CreateWMCursor = ph_CreateWMCursor;
slouken@0
   129
    device->ShowWMCursor = ph_ShowWMCursor;
slouken@0
   130
    device->WarpWMCursor = ph_WarpWMCursor;
slouken@0
   131
    device->CheckMouseMode = ph_CheckMouseMode;
slouken@0
   132
    device->InitOSKeymap = ph_InitOSKeymap;
slouken@0
   133
    device->PumpEvents = ph_PumpEvents;
slouken@0
   134
slouken@279
   135
    /* OpenGL support. */
slouken@266
   136
    device->GL_LoadLibrary = NULL;
slouken@266
   137
    device->GL_GetProcAddress = NULL;
slouken@266
   138
    device->GL_MakeCurrent = NULL;
slouken@279
   139
#ifdef HAVE_OPENGL
slouken@266
   140
    device->GL_SwapBuffers = ph_GL_SwapBuffers;
slouken@291
   141
    device->GL_GetAttribute = ph_GL_GetAttribute;
slouken@279
   142
#else
slouken@279
   143
    device->GL_SwapBuffers = NULL;
slouken@291
   144
    device->GL_GetAttribute = NULL;
slouken@279
   145
#endif /* HAVE_OPENGL */
slouken@266
   146
slouken@0
   147
    device->free = ph_DeleteDevice;
slouken@0
   148
slouken@0
   149
    return device;
slouken@0
   150
}
slouken@0
   151
slouken@19
   152
VideoBootStrap ph_bootstrap = {
slouken@315
   153
    "photon", "QNX Photon video output",
slouken@315
   154
    ph_Available, ph_CreateDevice
slouken@0
   155
};
slouken@0
   156
slouken@0
   157
static void ph_DeleteDevice(SDL_VideoDevice *device)
slouken@0
   158
{
slouken@309
   159
    if (device)
slouken@309
   160
    {
slouken@309
   161
        if (device->hidden)
slouken@309
   162
        {
slouken@0
   163
            free(device->hidden);
slouken@0
   164
            device->hidden = NULL;
slouken@0
   165
        }
slouken@309
   166
        if (device->gl_data)
slouken@309
   167
        {
slouken@0
   168
            free(device->gl_data);
slouken@0
   169
            device->gl_data = NULL;
slouken@0
   170
        }
slouken@0
   171
        free(device);
slouken@0
   172
        device = NULL;
slouken@0
   173
    }
slouken@0
   174
}
slouken@0
   175
slouken@0
   176
static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
slouken@0
   177
{
slouken@309
   178
    int i;
slouken@309
   179
    unsigned long *tempptr;
slouken@309
   180
    int rtnval;
slouken@309
   181
    PgVideoModeInfo_t my_mode_info;
slouken@309
   182
    PgHWCaps_t my_hwcaps;
slouken@309
   183
slouken@309
   184
    window=NULL;
slouken@309
   185
    oglctx=NULL;
slouken@315
   186
    desktoppal=SDLPH_PAL_NONE;
slouken@315
   187
    
slouken@315
   188
    captionflag=0;
slouken@315
   189
    old_video_mode=-1;
slouken@315
   190
    old_refresh_rate=-1;
slouken@0
   191
	
slouken@309
   192
    if (NULL == (event = malloc(EVENT_SIZE)))
slouken@309
   193
    {
slouken@309
   194
        exit(EXIT_FAILURE);
slouken@309
   195
    }
slouken@0
   196
slouken@309
   197
    /* Create the blank cursor */
slouken@309
   198
    SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
slouken@309
   199
                                          (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT,
slouken@309
   200
                                          (int)BLANK_CHOTX, (int)BLANK_CHOTY);
slouken@0
   201
slouken@309
   202
    if (SDL_BlankCursor == NULL)
slouken@309
   203
    {
slouken@309
   204
        printf("ph_VideoInit: could not create blank cursor\n");
slouken@309
   205
    }
slouken@0
   206
slouken@309
   207
    if (PgGetGraphicsHWCaps(&my_hwcaps) < 0)
slouken@309
   208
    {
slouken@309
   209
        fprintf(stderr,"ph_VideoInit: GetGraphicsHWCaps failed!! \n");
slouken@309
   210
    }
slouken@0
   211
slouken@309
   212
    if (PgGetVideoModeInfo(my_hwcaps.current_video_mode, &my_mode_info) < 0)
slouken@309
   213
    {
slouken@309
   214
        fprintf(stderr,"ph_VideoInit:  PgGetVideoModeInfo failed\n");
slouken@309
   215
    }
slouken@0
   216
slouken@309
   217
    /* We need to return BytesPerPixel as it in used by CreateRGBsurface */
slouken@309
   218
    vformat->BitsPerPixel = my_mode_info.bits_per_pixel;
slouken@309
   219
    vformat->BytesPerPixel = my_mode_info.bytes_per_scanline/my_mode_info.width;
slouken@315
   220
    desktopbpp = my_mode_info.bits_per_pixel;
slouken@309
   221
         
slouken@309
   222
    /* return a palette if we are in 256 color mode */
slouken@309
   223
    if (vformat->BitsPerPixel == 8)
slouken@309
   224
    {
slouken@309
   225
        vformat->palette = malloc(sizeof(SDL_Palette));
slouken@309
   226
        memset(vformat->palette, 0, sizeof(SDL_Palette));
slouken@309
   227
        vformat->palette->ncolors = 256;
slouken@309
   228
        vformat->palette->colors = (SDL_Color *)malloc(256 *sizeof(SDL_Color));
slouken@0
   229
slouken@309
   230
        /* fill the palette */
slouken@309
   231
        rtnval = PgGetPalette(ph_palette);
slouken@309
   232
        if (rtnval < 0)
slouken@309
   233
        {
slouken@309
   234
	    fprintf(stderr, "ph_VideoInit: PgGetPalette failed\n");
slouken@309
   235
        }
slouken@0
   236
slouken@309
   237
        tempptr = (unsigned long *)vformat->palette->colors;
slouken@0
   238
slouken@309
   239
        for(i=0;i<256; i++)
slouken@309
   240
        {
slouken@309
   241
            *tempptr = (((unsigned long)ph_palette[i]) << 8);
slouken@309
   242
            tempptr++;
slouken@309
   243
        }		
slouken@309
   244
    }
slouken@0
   245
slouken@19
   246
    currently_fullscreen = 0;
slouken@19
   247
    
slouken@19
   248
    this->info.wm_available = 1;
slouken@19
   249
    
slouken@0
   250
    return 0;
slouken@0
   251
}
slouken@0
   252
slouken@0
   253
static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
slouken@0
   254
                int width, int height, int bpp, Uint32 flags)
slouken@0
   255
{
slouken@0
   256
    PgDisplaySettings_t settings;
slouken@309
   257
    int mode;
slouken@309
   258
    PtArg_t arg[32];
slouken@309
   259
    PhDim_t dim;
slouken@266
   260
    int rtnval;
slouken@266
   261
    int i;
slouken@266
   262
    unsigned long *tempptr;
slouken@309
   263
    int pargc;
slouken@0
   264
slouken@266
   265
    dim.w=width;
slouken@266
   266
    dim.h=height;
slouken@0
   267
slouken@0
   268
    /* Lock the event thread, in multi-threading environments */
slouken@0
   269
    SDL_Lock_EventThread();
slouken@0
   270
slouken@309
   271
    /* create window if no OpenGL support selected */
slouken@309
   272
    if ((flags & SDL_OPENGL)!=SDL_OPENGL)
slouken@0
   273
    {
slouken@309
   274
        pargc=0;
slouken@309
   275
slouken@309
   276
        PtSetArg(&arg[pargc++], Pt_ARG_DIM, &dim, 0);
slouken@309
   277
        PtSetArg(&arg[pargc++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
slouken@309
   278
slouken@309
   279
        if (window!=NULL)
slouken@0
   280
        {
slouken@309
   281
            PtUnrealizeWidget(window);
slouken@309
   282
            PtDestroyWidget(window);
slouken@309
   283
            window=NULL;
slouken@309
   284
        }
slouken@309
   285
slouken@309
   286
        window=PtCreateWidget(PtWindow, NULL, pargc-1, arg);
slouken@309
   287
        PtRealizeWidget(window);
slouken@315
   288
        
slouken@309
   289
        PtFlush();
slouken@309
   290
    }
slouken@309
   291
slouken@309
   292
#ifdef HAVE_OPENGL
slouken@309
   293
    if (flags & SDL_OPENGL)
slouken@309
   294
    {
slouken@309
   295
        /* ph_SetupOpenGLContext creates also window as need */
slouken@309
   296
        if (ph_SetupOpenGLContext(this, width, height, bpp, flags)==0)
slouken@309
   297
        {
slouken@309
   298
            current->flags=flags;
slouken@309
   299
            /* setup OGL update function ... ugly method */
slouken@309
   300
            ph_ResizeImage(this, current, flags); 
slouken@0
   301
        }
slouken@0
   302
        else
slouken@0
   303
        {
slouken@309
   304
            /* if context creation fail, report no OpenGL to high level */
slouken@309
   305
            current->flags=(flags & (~SDL_OPENGL));
slouken@309
   306
        }
slouken@309
   307
#else
slouken@309
   308
    if (flags & SDL_OPENGL) /* if no built-in OpenGL support */
slouken@309
   309
    {
slouken@309
   310
        fprintf(stderr, "error: no OpenGL support, try to recompile library.\n");
slouken@309
   311
        current->flags=(flags & (~SDL_OPENGL));
slouken@309
   312
        return NULL;
slouken@309
   313
#endif /* HAVE_OPENGL */
slouken@309
   314
    }
slouken@309
   315
    else
slouken@309
   316
    {
slouken@309
   317
        /* Initialize the window */
slouken@309
   318
        if (flags & SDL_FULLSCREEN) /* Direct Context , assume SDL_HWSURFACE also set */
slouken@309
   319
        {
slouken@309
   320
            /* Get the video mode and set it */
slouken@309
   321
            if (flags & SDL_ANYFORMAT)
slouken@0
   322
            {
slouken@309
   323
                if ((mode = get_mode_any_format(width, height, bpp)) == 0)
slouken@309
   324
                {
slouken@309
   325
                    fprintf(stderr,"error: get_mode_any_format failed\n");
slouken@309
   326
                    exit(1);
slouken@309
   327
                }
slouken@309
   328
            }
slouken@309
   329
            else
slouken@309
   330
            {
slouken@309
   331
                if ((mode = get_mode(width, height, bpp)) == 0)
slouken@309
   332
                {
slouken@309
   333
                    fprintf(stderr,"error: get_mode failed\n");
slouken@309
   334
                    exit(1);
slouken@309
   335
                }
slouken@309
   336
            }
slouken@315
   337
            
slouken@315
   338
            if (bpp==8)
slouken@315
   339
            {
slouken@315
   340
               desktoppal=SDLPH_PAL_SYSTEM;
slouken@315
   341
            }
slouken@315
   342
            
slouken@315
   343
            /* save old video mode caps */
slouken@315
   344
            PgGetVideoMode(&settings);
slouken@315
   345
            old_video_mode=settings.mode;
slouken@315
   346
            old_refresh_rate=settings.refresh;
slouken@315
   347
slouken@315
   348
            /* setup new video mode */
slouken@309
   349
            settings.mode = mode;
slouken@309
   350
            settings.refresh = 0;
slouken@315
   351
            settings.flags = 0;
slouken@309
   352
slouken@315
   353
            if (PgSetVideoMode(&settings) < 0)
slouken@309
   354
            {
slouken@309
   355
                fprintf(stderr,"error: PgSetVideoMode failed\n");
slouken@309
   356
            }
slouken@309
   357
slouken@309
   358
            current->flags = (flags & (~SDL_RESIZABLE)); /* no resize for Direct Context */
slouken@309
   359
slouken@309
   360
            /* Begin direct mode */
slouken@309
   361
            ph_EnterFullScreen(this);
slouken@309
   362
slouken@309
   363
        } /* end fullscreen flag */
slouken@309
   364
        else
slouken@309
   365
        {
slouken@309
   366
            if (flags & SDL_HWSURFACE)  /* Use offscreen memory iff SDL_HWSURFACE flag is set */
slouken@309
   367
            {
slouken@309
   368
                /* Hardware surface is Offsceen Context.  ph_ResizeImage handles the switch */
slouken@309
   369
                current->flags = (flags & (~SDL_RESIZABLE)); /* no stretch blit in offscreen context */
slouken@309
   370
            }
slouken@309
   371
            else /* must be SDL_SWSURFACE */
slouken@309
   372
            {
slouken@309
   373
                current->flags = (flags | SDL_RESIZABLE); /* yes we can resize as this is a software surface */
slouken@0
   374
            }
slouken@315
   375
            /* using palette emulation code in window mode */
slouken@315
   376
            if (bpp==8)
slouken@315
   377
            {
slouken@315
   378
                if (desktopbpp>=15)
slouken@315
   379
                {
slouken@315
   380
                    desktoppal=SDLPH_PAL_EMULATE;
slouken@315
   381
                }
slouken@315
   382
                else
slouken@315
   383
                {
slouken@315
   384
                    desktoppal=SDLPH_PAL_SYSTEM;
slouken@315
   385
                }
slouken@315
   386
            }
slouken@315
   387
            else
slouken@315
   388
            {
slouken@315
   389
               desktoppal=SDLPH_PAL_NONE;
slouken@315
   390
            }
slouken@0
   391
        }
slouken@266
   392
slouken@309
   393
	/* If we are setting video to use the palette make sure we have allocated memory for it */
slouken@309
   394
	if (bpp==8)
slouken@309
   395
	{
slouken@309
   396
            current->format->palette = malloc(sizeof(SDL_Palette));
slouken@309
   397
            memset(current->format->palette, 0, sizeof(SDL_Palette));
slouken@309
   398
            current->format->palette->ncolors = 256;
slouken@309
   399
            current->format->palette->colors = (SDL_Color *)malloc(256 *sizeof(SDL_Color));
slouken@309
   400
            /* fill the palette */
slouken@309
   401
            rtnval = PgGetPalette(ph_palette);
slouken@309
   402
slouken@309
   403
            tempptr = (unsigned long *)current->format->palette->colors;
slouken@309
   404
slouken@309
   405
            for(i=0; i<256; i++)
slouken@309
   406
            {
slouken@309
   407
                *tempptr = (((unsigned long)ph_palette[i]) << 8);
slouken@309
   408
                tempptr++;
slouken@309
   409
            }
slouken@0
   410
        }
slouken@0
   411
slouken@0
   412
    }
slouken@0
   413
slouken@309
   414
    current->w = width;
slouken@309
   415
    current->h = height;
slouken@309
   416
    current->format->BitsPerPixel = bpp;
slouken@309
   417
    current->format->BytesPerPixel = (bpp+7)/8;
slouken@309
   418
    current->pitch = SDL_CalculatePitch(current);
slouken@309
   419
    /* Must call at least once it setup image planes */
slouken@309
   420
    ph_ResizeImage(this, current, flags);
slouken@0
   421
slouken@315
   422
    /* delayed set caption call */
slouken@315
   423
    if (captionflag)
slouken@315
   424
    {
slouken@315
   425
        ph_SetCaption(this, this->wm_title, NULL);
slouken@315
   426
    }
slouken@315
   427
slouken@0
   428
    SDL_Unlock_EventThread();
slouken@0
   429
slouken@0
   430
    /* We're done! */
slouken@315
   431
    return (current);
slouken@0
   432
}
slouken@0
   433
slouken@0
   434
static void ph_VideoQuit(_THIS)
slouken@0
   435
{
slouken@309
   436
    PhRegion_t region_info;
slouken@309
   437
slouken@283
   438
    ph_DestroyImage(this, SDL_VideoSurface); 
slouken@0
   439
slouken@279
   440
    if (currently_fullscreen)
slouken@279
   441
    {
slouken@315
   442
        ph_LeaveFullScreen(this);
slouken@279
   443
    }
slouken@309
   444
slouken@309
   445
#ifdef HAVE_OPENGL
slouken@315
   446
    /* prevent double SEGFAULT with parachute mode */
slouken@315
   447
    if (this->screen)
slouken@309
   448
    {
slouken@315
   449
        if (((this->screen->flags & SDL_FULLSCREEN)==SDL_FULLSCREEN) &&
slouken@315
   450
            ((this->screen->flags & SDL_OPENGL)==SDL_OPENGL))
slouken@315
   451
        {
slouken@315
   452
            region_info.cursor_type=Ph_CURSOR_POINTER;
slouken@315
   453
            region_info.rid=PtWidgetRid(window);
slouken@315
   454
            PhRegionChange(Ph_REGION_CURSOR, 0, &region_info, NULL, NULL);
slouken@315
   455
        }
slouken@309
   456
    }
slouken@309
   457
slouken@309
   458
    PtFlush();
slouken@309
   459
#endif /* HAVE_OPENGL */
slouken@309
   460
    
slouken@309
   461
    if (window)
slouken@309
   462
    {
slouken@309
   463
        PtUnrealizeWidget(window);
slouken@309
   464
        PtDestroyWidget(window);
slouken@309
   465
        window=NULL;
slouken@309
   466
    }
slouken@315
   467
    
slouken@315
   468
    /* restore palette */
slouken@315
   469
    if (desktoppal!=SDLPH_PAL_NONE)
slouken@315
   470
    {
slouken@315
   471
        PgSetPalette(ph_palette, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
slouken@315
   472
    }
slouken@309
   473
slouken@309
   474
#ifdef HAVE_OPENGL
slouken@309
   475
    if (oglctx)
slouken@309
   476
    {
slouken@309
   477
        PhDCSetCurrent(NULL);
slouken@309
   478
        PhDCRelease(oglctx);
slouken@309
   479
        oglctx=NULL;
slouken@309
   480
    }
slouken@309
   481
#endif /* HAVE_OPENGL */
slouken@0
   482
}
slouken@0
   483
slouken@0
   484
static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
slouken@0
   485
{
slouken@315
   486
    int i;
slouken@315
   487
    PhPoint_t point={0, 0};
slouken@315
   488
    PgColor_t syspalph[_Pg_MAX_PALETTE];
slouken@0
   489
slouken@315
   490
    /* palette emulation code, using palette of the PhImage_t struct */
slouken@315
   491
    if (desktoppal==SDLPH_PAL_EMULATE)
slouken@315
   492
    {
slouken@315
   493
        if ((SDL_Image) && (SDL_Image->palette))
slouken@315
   494
        {
slouken@315
   495
            for (i=firstcolor; i<firstcolor+ncolors; i++)
slouken@315
   496
            {
slouken@315
   497
                SDL_Image->palette[i]  = 0x00000000UL;
slouken@315
   498
                SDL_Image->palette[i] |= colors[i-firstcolor].r<<16;
slouken@315
   499
                SDL_Image->palette[i] |= colors[i-firstcolor].g<<8;
slouken@315
   500
                SDL_Image->palette[i] |= colors[i-firstcolor].b;
slouken@315
   501
            }
slouken@315
   502
        }
slouken@315
   503
        /* image needs to be redrawed, very slow method */
slouken@315
   504
        PgDrawPhImage(&point, SDL_Image, 0);
slouken@315
   505
    }
slouken@315
   506
    else
slouken@315
   507
    {
slouken@315
   508
        if (desktoppal==SDLPH_PAL_SYSTEM)
slouken@315
   509
        {
slouken@315
   510
            for (i=firstcolor; i<firstcolor+ncolors; i++)
slouken@315
   511
            {
slouken@315
   512
                syspalph[i]  = 0x00000000UL;
slouken@315
   513
                syspalph[i] |= colors[i-firstcolor].r<<16;
slouken@315
   514
                syspalph[i] |= colors[i-firstcolor].g<<8;
slouken@315
   515
                syspalph[i] |= colors[i-firstcolor].b;
slouken@315
   516
            }
slouken@0
   517
slouken@315
   518
            if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
slouken@315
   519
            {
slouken@315
   520
                /* window mode must use soft palette */
slouken@315
   521
                PgSetPalette((PgColor_t*)&syspalph, 0, firstcolor, ncolors, Pg_PALSET_SOFT, 0);
slouken@315
   522
                /* image needs to be redrawed, very slow method */
slouken@315
   523
                PgDrawPhImage(&point, SDL_Image, 0);
slouken@315
   524
            }
slouken@315
   525
            else
slouken@315
   526
            {
slouken@315
   527
                /* fullscreen mode must use hardware palette */
slouken@315
   528
                PgSetPalette((PgColor_t*)&syspalph, 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
slouken@315
   529
            }
slouken@315
   530
        }
slouken@315
   531
        else
slouken@315
   532
        {
slouken@315
   533
            /* SDLPH_PAL_NONE do nothing */
slouken@315
   534
        }
slouken@0
   535
    }
slouken@315
   536
    
slouken@315
   537
    return 1;
slouken@0
   538
}
slouken@0
   539
slouken@279
   540
#ifdef HAVE_OPENGL
slouken@309
   541
slouken@309
   542
int ph_SetupOpenGLContext(_THIS, int width, int height, int bpp, Uint32 flags)
slouken@309
   543
{
slouken@309
   544
    PtArg_t args[8];
slouken@309
   545
    PhDim_t dim;
slouken@309
   546
    uint64_t OGLAttrib[PH_OGL_MAX_ATTRIBS];
slouken@309
   547
    int OGLargc;
slouken@309
   548
    int pargc;
slouken@309
   549
slouken@309
   550
    dim.w=width;
slouken@309
   551
    dim.h=height;
slouken@309
   552
    
slouken@309
   553
    if (oglctx!=NULL)
slouken@309
   554
    {
slouken@309
   555
       PhDCSetCurrent(NULL);
slouken@309
   556
       PhDCRelease(oglctx);
slouken@309
   557
       oglctx=NULL;
slouken@309
   558
    }
slouken@309
   559
slouken@309
   560
    OGLargc=0;
slouken@309
   561
    if (this->gl_config.depth_size)
slouken@309
   562
    {
slouken@309
   563
        OGLAttrib[OGLargc++]=PHOGL_ATTRIB_DEPTH_BITS;
slouken@309
   564
        OGLAttrib[OGLargc++]=this->gl_config.depth_size;
slouken@309
   565
    }
slouken@309
   566
    if (this->gl_config.stencil_size)
slouken@309
   567
    {
slouken@309
   568
        OGLAttrib[OGLargc++]=PHOGL_ATTRIB_STENCIL_BITS;
slouken@309
   569
        OGLAttrib[OGLargc++]=this->gl_config.stencil_size;
slouken@309
   570
    }
slouken@309
   571
    OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FORCE_SW;
slouken@309
   572
    if (flags & SDL_FULLSCREEN)
slouken@309
   573
    {
slouken@309
   574
        OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN;
slouken@309
   575
        OGLAttrib[OGLargc++]=PHOGL_ATTRIB_DIRECT;
slouken@309
   576
        OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN_BEST;
slouken@309
   577
        OGLAttrib[OGLargc++]=PHOGL_ATTRIB_FULLSCREEN_CENTER;
slouken@309
   578
    }
slouken@309
   579
    OGLAttrib[OGLargc++]=PHOGL_ATTRIB_NONE;
slouken@309
   580
slouken@309
   581
    if (this->gl_config.double_buffer)
slouken@309
   582
    {
slouken@309
   583
        oglctx=PdCreateOpenGLContext(2, &dim, 0, OGLAttrib);
slouken@309
   584
    }
slouken@309
   585
    else
slouken@309
   586
    {
slouken@309
   587
        oglctx=PdCreateOpenGLContext(1, &dim, 0, OGLAttrib);
slouken@309
   588
    }
slouken@309
   589
    if (oglctx==NULL)
slouken@309
   590
    {
slouken@309
   591
        fprintf(stderr,"error: cannot create OpenGL context.\n");
slouken@309
   592
        return (-1);
slouken@309
   593
    }
slouken@309
   594
slouken@309
   595
    PhDCSetCurrent(oglctx);
slouken@309
   596
slouken@309
   597
    pargc=0;
slouken@309
   598
slouken@309
   599
    PtSetArg(&args[pargc++], Pt_ARG_DIM, &dim, 0);
slouken@309
   600
    PtSetArg(&args[pargc++], Pt_ARG_RESIZE_FLAGS, Pt_FALSE, Pt_RESIZE_XY_AS_REQUIRED);
slouken@309
   601
    PtSetArg(&args[pargc++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
slouken@309
   602
slouken@309
   603
    if (flags & SDL_FULLSCREEN)
slouken@309
   604
    {
slouken@309
   605
        PhPoint_t pos;
slouken@309
   606
slouken@309
   607
        pos.x=0;
slouken@309
   608
        pos.y=0;
slouken@309
   609
slouken@309
   610
        PtSetArg(&args[pargc++], Pt_ARG_WINDOW_RENDER_FLAGS, Pt_FALSE, ~0);
slouken@309
   611
        PtSetArg(&args[pargc++], Pt_ARG_WINDOW_MANAGED_FLAGS,Pt_TRUE, Ph_WM_FFRONT | Ph_WM_CLOSE | Ph_WM_TOFRONT | Ph_WM_CONSWITCH);
slouken@309
   612
        PtSetArg(&args[pargc++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFRONT | Ph_WM_STATE_ISFOCUS);
slouken@309
   613
        PtSetArg(&args[pargc++], Pt_ARG_POS, &pos, 0);
slouken@309
   614
    }
slouken@309
   615
slouken@309
   616
    if (window!=NULL)
slouken@309
   617
    {
slouken@309
   618
        PtUnrealizeWidget(window);
slouken@309
   619
        PtDestroyWidget(window);
slouken@309
   620
        window=NULL;
slouken@309
   621
    }
slouken@309
   622
slouken@309
   623
    window=PtCreateWidget(PtWindow, NULL, pargc-1, args);
slouken@309
   624
    PtRealizeWidget(window);
slouken@309
   625
slouken@309
   626
    /* disable mouse for fullscreen */
slouken@309
   627
    if (flags & SDL_FULLSCREEN)
slouken@309
   628
    {
slouken@309
   629
        PhRegion_t region_info;
slouken@309
   630
slouken@309
   631
        region_info.cursor_type=Ph_CURSOR_NONE;
slouken@309
   632
        region_info.rid=PtWidgetRid(window);
slouken@309
   633
        PhRegionChange(Ph_REGION_CURSOR, 0, &region_info, NULL, NULL);
slouken@309
   634
    }
slouken@309
   635
slouken@309
   636
    PtFlush();
slouken@309
   637
slouken@309
   638
    return 0;
slouken@309
   639
}
slouken@309
   640
slouken@266
   641
void ph_GL_SwapBuffers(_THIS)
slouken@266
   642
{
slouken@291
   643
    PgSetRegion(PtWidgetRid(window));
slouken@309
   644
    PdOpenGLContextSwapBuffers(oglctx);
slouken@266
   645
}
slouken@266
   646
slouken@291
   647
int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
slouken@0
   648
{
slouken@291
   649
    switch (attrib)
slouken@291
   650
    {
slouken@291
   651
        case SDL_GL_DOUBLEBUFFER:
slouken@291
   652
             *value=this->gl_config.double_buffer;
slouken@291
   653
             break;
slouken@291
   654
        case SDL_GL_STENCIL_SIZE:
slouken@291
   655
             *value=this->gl_config.stencil_size;
slouken@291
   656
             break;
slouken@291
   657
        case SDL_GL_DEPTH_SIZE:
slouken@291
   658
             *value=this->gl_config.depth_size;
slouken@291
   659
             break;
slouken@291
   660
        default:
slouken@291
   661
             *value=0;
slouken@291
   662
             return(-1);
slouken@291
   663
    }
slouken@291
   664
    return 0;
slouken@291
   665
}
slouken@0
   666
slouken@291
   667
#endif /* HAVE_OPENGL */