src/video/photon/SDL_ph_video.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 14 Feb 2004 20:22:21 +0000
changeset 821 30168104389f
parent 769 b8d311d90021
child 837 4bc7e16a13ed
permissions -rw-r--r--
Date: Sat, 14 Feb 2004 14:52:40 +0200
From: "Mike Gorchak"
Subject: Batch of the QNX6 fixes for the SDL

1. Updated readme.QNX
2. Fixed crashes during intensive window updating under fast machines (got over 200 rectangles for update).
3. Fixed double-buffered fullscreen modes, now it works as needed.
4. Fixed Photon detection algorithm.
5. Fixed HWSURFACE update function.
6. Added SDL_PHOTON_FULLSCREEN_REFRESH environment variable support for control refresh rates under Photon.
7. Added 640x400 fullscreen mode emulation via 640x480 (if videodriver not supports original 640x400 mode of course) shifted by 40 vertical pixels from begin, to center it. It's needed for some old DOS games which ran in doubled 320x200 mode.
8. Added available video ram amount support.
8. Added hardware surface allocation/deallocation support if current videomode and videodriver supports it.
9. Added hardware filling support.
10. Added hardware blits support (simple and colorkeyed).

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