src/video/photon/SDL_ph_video.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 20 Jan 2003 01:38:37 +0000
changeset 571 8e3ce997621c
parent 380 bce7171e7a85
child 663 8bedd6d61642
permissions -rw-r--r--
Date: Thu, 16 Jan 2003 13:48:31 +0200
From: "Mike Gorchak"
Subject: All QNX patches

whole patches concerning QNX. Almost all code has been rewritten by Julian
and me. Added initial support for hw overlays in QNX and many many others
fixes.

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