src/video/photon/SDL_ph_video.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 18 Jul 2004 19:46:38 +0000
changeset 910 4ab6d1fd028f
parent 886 05c551e5bc64
child 1312 c9b51268668f
permissions -rw-r--r--
Date: Sat, 26 Jun 2004 14:58:42 +0300
From: "Mike Gorchak"
Subject: QNX 6.3 fixes for SDL

Sam, I've added new OpenGL framework for SDL, which appeared in the new QNX version - 6.3. I've leave compatibility with previous QNX versions. And I've moved all GL specific functions to the separate module, like it done for the other platforms.

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