src/video/photon/SDL_ph_video.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 06 May 2004 15:55:06 +0000
changeset 886 05c551e5bc64
parent 837 4bc7e16a13ed
child 910 4ab6d1fd028f
permissions -rw-r--r--
Date: Sat, 24 Apr 2004 15:13:32 +0300
From: "Mike Gorchak"
Subject: SDL updates for the QNX6

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