src/video/photon/SDL_ph_video.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 10 Dec 2003 12:35:56 +0000
changeset 753 b14fdadd8311
parent 718 cbc0f7fabd1c
child 769 b8d311d90021
permissions -rw-r--r--
Date: Thu, 4 Dec 2003 07:48:40 +0200
From: "Mike Gorchak"
Subject: SDL/QNX6 new patch

Here in attachment my patch for the SDL/QNX6 again :) It contain non-crtitical/cosmetic fixes:

1. Fixed window centering at other than the first consoles.
2. Fixed window centering algorithm in case when window height or width are greater than the desktop resolution.
3. Fixed window positioning on other than the first consoles.
4. Fixed occasional input focus lost when switching to fullscreen.
5. Removed the Photon's default chroma color for the overlays, added RGB(12, 6, 12) color instead (very dark pink).
6. Added more checks to the YUV overlay code (fixed crashes during resolution mode switches).
7. Added support for Enter/Backspace keys in unicode mode (used by Maelstrom and by other games).
8. Fixed window restore/maximize function. It works, finally.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@297
     3
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@0
     6
    modify it under the terms of the GNU Library General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@0
     8
    version 2 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@0
    13
    Library General Public License for more details.
slouken@0
    14
slouken@0
    15
    You should have received a copy of the GNU Library General Public
slouken@0
    16
    License along with this library; if not, write to the Free
slouken@0
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@0
    22
slouken@0
    23
#ifdef SAVE_RCSID
slouken@0
    24
static char rcsid =
slouken@0
    25
 "@(#) $Id$";
slouken@0
    26
#endif
slouken@0
    27
slouken@0
    28
#include <stdlib.h>
slouken@0
    29
#include <stdio.h>
slouken@0
    30
#include <unistd.h>
slouken@0
    31
#include <string.h>
slouken@0
    32
#include <sys/ioctl.h>
slouken@0
    33
slouken@0
    34
#include "SDL.h"
slouken@0
    35
#include "SDL_error.h"
slouken@0
    36
#include "SDL_timer.h"
slouken@0
    37
#include "SDL_thread.h"
slouken@0
    38
#include "SDL_video.h"
slouken@0
    39
#include "SDL_mouse.h"
slouken@0
    40
#include "SDL_endian.h"
slouken@0
    41
#include "SDL_sysvideo.h"
slouken@0
    42
#include "SDL_pixels_c.h"
slouken@0
    43
#include "SDL_events_c.h"
slouken@0
    44
#include "SDL_ph_video.h"
slouken@0
    45
#include "SDL_ph_modes_c.h"
slouken@0
    46
#include "SDL_ph_image_c.h"
slouken@0
    47
#include "SDL_ph_events_c.h"
slouken@0
    48
#include "SDL_ph_mouse_c.h"
slouken@19
    49
#include "SDL_ph_wm_c.h"
slouken@0
    50
#include "SDL_phyuv_c.h"
slouken@0
    51
#include "blank_cursor.h"
slouken@0
    52
slouken@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@718
    71
    if (phstatus==-1)
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@0
   119
    device->CheckHWBlit = NULL;
slouken@0
   120
    device->FillHWRect = NULL;
slouken@0
   121
    device->SetHWColorKey = NULL;
slouken@0
   122
    device->SetHWAlpha = NULL;
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@753
   257
        if (!currently_maximized)
slouken@753
   258
        {
slouken@753
   259
            windowpos = getenv("SDL_VIDEO_WINDOW_POS");
slouken@753
   260
            iscentered = getenv("SDL_VIDEO_CENTERED");
slouken@692
   261
slouken@753
   262
            if ((iscentered) || ((windowpos) && (strcmp(windowpos, "center")==0)))
slouken@753
   263
            {
slouken@753
   264
                PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent);
slouken@753
   265
                if (desktop_mode.width>w)
slouken@753
   266
                {
slouken@753
   267
                    pos.x = (desktop_mode.width - w)/2;
slouken@753
   268
                }
slouken@753
   269
                if (desktop_mode.height>h)
slouken@753
   270
                {
slouken@753
   271
                    pos.y = (desktop_mode.height - h)/2;
slouken@753
   272
                }
slouken@753
   273
slouken@753
   274
                pos.x+=desktopextent.ul.x;
slouken@753
   275
                pos.y+=desktopextent.ul.y;
slouken@753
   276
                PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
slouken@753
   277
            }
slouken@753
   278
            else
slouken@753
   279
            {
slouken@753
   280
                if (windowpos)
slouken@753
   281
                {
slouken@753
   282
                    if (sscanf(windowpos, "%d,%d", &x, &y) == 2)
slouken@753
   283
                    {
slouken@753
   284
                        if ((x<desktop_mode.width) && (y<desktop_mode.height))
slouken@753
   285
                        {
slouken@753
   286
                            PhWindowQueryVisible(Ph_QUERY_CONSOLE, 0, 0, &desktopextent);
slouken@753
   287
                            pos.x=x+desktopextent.ul.x;
slouken@753
   288
                            pos.y=y+desktopextent.ul.y;
slouken@753
   289
                        }
slouken@753
   290
                        PtSetArg(&args[nargs++], Pt_ARG_POS, &pos, 0);
slouken@753
   291
                    }
slouken@753
   292
                }
slouken@753
   293
            }
slouken@753
   294
        }
slouken@753
   295
slouken@753
   296
        PtSetArg(&args[nargs++], Pt_ARG_FILL_COLOR, Pg_BLACK, 0);
slouken@753
   297
        
slouken@753
   298
        /* if window is maximized render it as maximized */
slouken@753
   299
        if (currently_maximized)
slouken@692
   300
        {
slouken@753
   301
           PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISMAX);
slouken@753
   302
        }
slouken@692
   303
        else
slouken@692
   304
        {
slouken@753
   305
           PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISMAX);
slouken@692
   306
        }
slouken@692
   307
slouken@753
   308
        /* do not grab the keyboard by default */
slouken@753
   309
        PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_FALSE, Ph_WM_STATE_ISALTKEY);
slouken@692
   310
slouken@753
   311
        /* bring the focus to the window */
slouken@753
   312
        PtSetArg(&args[nargs++], Pt_ARG_WINDOW_STATE, Pt_TRUE, Ph_WM_STATE_ISFOCUS);
slouken@753
   313
slouken@753
   314
        /* allow to catch hide events */
slouken@571
   315
        PtSetArg(&args[nargs++], Pt_ARG_WINDOW_MANAGED_FLAGS, Pt_TRUE, Ph_WM_HIDE);
slouken@663
   316
        PtSetArg(&args[nargs++], Pt_ARG_WINDOW_NOTIFY_FLAGS, Pt_TRUE, Ph_WM_HIDE);
slouken@571
   317
    }
slouken@571
   318
slouken@571
   319
    PtSetResources(window, nargs, args);
slouken@571
   320
    PtRealizeWidget(window);
slouken@692
   321
    PtWindowToFront(window);
slouken@571
   322
slouken@571
   323
    return 0;
slouken@571
   324
}
slouken@571
   325
slouken@663
   326
static const struct ColourMasks* ph_GetColourMasks(int bpp)
slouken@663
   327
{
slouken@663
   328
    /* The alpha mask doesn't appears to be needed */
slouken@663
   329
    static const struct ColourMasks phColorMasks[5] = {
slouken@663
   330
        /*  8 bit      */  {0, 0, 0, 0, 8},
slouken@663
   331
        /* 15 bit ARGB */  {0x7C00, 0x03E0, 0x001F, 0x8000, 15},
slouken@663
   332
        /* 16 bit  RGB */  {0xF800, 0x07E0, 0x001F, 0x0000, 16},
slouken@663
   333
        /* 24 bit  RGB */  {0xFF0000, 0x00FF00, 0x0000FF, 0x000000, 24},
slouken@663
   334
        /* 32 bit ARGB */  {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 32},
slouken@663
   335
    };
slouken@663
   336
slouken@663
   337
    switch (bpp)
slouken@663
   338
    {
slouken@663
   339
        case 8:
slouken@663
   340
             return &phColorMasks[0];
slouken@663
   341
        case 15:
slouken@663
   342
             return &phColorMasks[1];
slouken@663
   343
        case 16:
slouken@663
   344
             return &phColorMasks[2];
slouken@663
   345
        case 24:
slouken@663
   346
             return &phColorMasks[3];
slouken@663
   347
        case 32:
slouken@663
   348
             return &phColorMasks[4];
slouken@663
   349
    }
slouken@663
   350
    return NULL;
slouken@663
   351
}
slouken@663
   352
slouken@0
   353
static int ph_VideoInit(_THIS, SDL_PixelFormat *vformat)
slouken@0
   354
{
slouken@309
   355
    PgHWCaps_t my_hwcaps;
slouken@663
   356
    int i;
slouken@309
   357
slouken@309
   358
    window=NULL;
slouken@320
   359
    desktoppal=SDLPH_PAL_NONE;
slouken@701
   360
slouken@320
   361
#ifdef HAVE_OPENGL
slouken@309
   362
    oglctx=NULL;
slouken@701
   363
    oglflags=0;
slouken@701
   364
    oglbpp=0;
slouken@320
   365
#endif /* HAVE_OPENGL */
slouken@315
   366
    
slouken@315
   367
    old_video_mode=-1;
slouken@315
   368
    old_refresh_rate=-1;
slouken@0
   369
	
slouken@309
   370
    if (NULL == (event = malloc(EVENT_SIZE)))
slouken@309
   371
    {
slouken@571
   372
        SDL_OutOfMemory();
slouken@571
   373
        return -1;
slouken@309
   374
    }
slouken@380
   375
    memset(event, 0x00, EVENT_SIZE);
slouken@0
   376
slouken@571
   377
    window = ph_CreateWindow(this);
slouken@571
   378
    if (window == NULL)
slouken@571
   379
    {
slouken@663
   380
        SDL_SetError("ph_VideoInit(): Couldn't create video window !\n");
slouken@571
   381
        return -1;
slouken@571
   382
    }
slouken@571
   383
slouken@309
   384
    /* Create the blank cursor */
slouken@309
   385
    SDL_BlankCursor = this->CreateWMCursor(this, blank_cdata, blank_cmask,
slouken@309
   386
                                          (int)BLANK_CWIDTH, (int)BLANK_CHEIGHT,
slouken@309
   387
                                          (int)BLANK_CHOTX, (int)BLANK_CHOTY);
slouken@0
   388
slouken@309
   389
    if (SDL_BlankCursor == NULL)
slouken@309
   390
    {
slouken@663
   391
        return -1;
slouken@309
   392
    }
slouken@0
   393
slouken@309
   394
    if (PgGetGraphicsHWCaps(&my_hwcaps) < 0)
slouken@309
   395
    {
slouken@663
   396
        SDL_SetError("ph_VideoInit(): GetGraphicsHWCaps function failed !\n");
slouken@663
   397
        this->FreeWMCursor(this, SDL_BlankCursor);
slouken@663
   398
        return -1;
slouken@309
   399
    }
slouken@0
   400
slouken@692
   401
    if (PgGetVideoModeInfo(my_hwcaps.current_video_mode, &desktop_mode) < 0)
slouken@309
   402
    {
slouken@663
   403
        SDL_SetError("ph_VideoInit(): PgGetVideoModeInfo function failed !\n");
slouken@663
   404
        this->FreeWMCursor(this, SDL_BlankCursor);
slouken@663
   405
        return -1;
slouken@309
   406
    }
slouken@0
   407
slouken@309
   408
    /* We need to return BytesPerPixel as it in used by CreateRGBsurface */
slouken@692
   409
    vformat->BitsPerPixel = desktop_mode.bits_per_pixel;
slouken@692
   410
    vformat->BytesPerPixel = desktop_mode.bytes_per_scanline/desktop_mode.width;
slouken@692
   411
    desktopbpp = desktop_mode.bits_per_pixel;
slouken@320
   412
    
slouken@320
   413
    /* save current palette */
slouken@320
   414
    if (desktopbpp==8)
slouken@320
   415
    {
slouken@571
   416
        PgGetPalette(savedpal);
slouken@571
   417
        PgGetPalette(syspalph);
slouken@320
   418
    }
slouken@663
   419
    else
slouken@663
   420
    {
slouken@663
   421
        for(i=0; i<_Pg_MAX_PALETTE; i++)
slouken@663
   422
        {
slouken@663
   423
            savedpal[i]=PgRGB(0, 0, 0);
slouken@663
   424
            syspalph[i]=PgRGB(0, 0, 0);
slouken@663
   425
        }
slouken@663
   426
    }
slouken@309
   427
         
slouken@19
   428
    currently_fullscreen = 0;
slouken@663
   429
    currently_hided = 0;
slouken@753
   430
    currently_maximized = 0;
slouken@663
   431
    current_overlay = NULL;
slouken@663
   432
slouken@663
   433
    OCImage.direct_context = NULL;
slouken@663
   434
    OCImage.offscreen_context = NULL;
slouken@663
   435
    OCImage.offscreen_backcontext = NULL;
slouken@663
   436
    OCImage.oldDC = NULL;
slouken@663
   437
    OCImage.CurrentFrameData = NULL;
slouken@663
   438
    OCImage.FrameData0 = NULL;
slouken@663
   439
    OCImage.FrameData1 = NULL;
slouken@19
   440
    
slouken@19
   441
    this->info.wm_available = 1;
slouken@19
   442
    
slouken@0
   443
    return 0;
slouken@0
   444
}
slouken@0
   445
slouken@0
   446
static SDL_Surface *ph_SetVideoMode(_THIS, SDL_Surface *current,
slouken@0
   447
                int width, int height, int bpp, Uint32 flags)
slouken@0
   448
{
slouken@663
   449
    const struct ColourMasks* mask;
slouken@0
   450
slouken@0
   451
    /* Lock the event thread, in multi-threading environments */
slouken@0
   452
    SDL_Lock_EventThread();
slouken@0
   453
slouken@320
   454
    current->flags = flags;
slouken@320
   455
slouken@663
   456
    /* if we do not have desired fullscreen mode, then fallback into window mode */
slouken@663
   457
    if (((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && (ph_GetVideoMode(width, height, bpp)==0))
slouken@663
   458
    {
slouken@663
   459
       current->flags &= ~SDL_FULLSCREEN;
slouken@663
   460
       current->flags &= ~SDL_NOFRAME;
slouken@663
   461
       current->flags &= ~SDL_RESIZABLE;
slouken@663
   462
    }
slouken@663
   463
slouken@663
   464
    ph_SetupWindow(this, width, height, current->flags);
slouken@663
   465
slouken@663
   466
    mask = ph_GetColourMasks(bpp);
slouken@663
   467
    if (mask != NULL)
slouken@663
   468
    {
slouken@663
   469
        SDL_ReallocFormat(current, mask->bpp, mask->red, mask->green, mask->blue, 0);
slouken@663
   470
    }
slouken@663
   471
    else
slouken@663
   472
    {
slouken@663
   473
        SDL_SetError("ph_SetVideoMode(): desired bpp is not supported by photon !\n");
slouken@663
   474
        return NULL;
slouken@663
   475
    }
slouken@309
   476
slouken@309
   477
#ifdef HAVE_OPENGL
slouken@701
   478
    if ((current->flags & SDL_OPENGL)==SDL_OPENGL)
slouken@309
   479
    {
slouken@309
   480
#else
slouken@701
   481
    if ((current->flags & SDL_OPENGL)==SDL_OPENGL) /* if no built-in OpenGL support */
slouken@309
   482
    {
slouken@663
   483
        SDL_SetError("ph_SetVideoMode(): no OpenGL support, try to recompile library.\n");
slouken@571
   484
        current->flags &= ~SDL_OPENGL;
slouken@309
   485
        return NULL;
slouken@309
   486
#endif /* HAVE_OPENGL */
slouken@309
   487
    }
slouken@309
   488
    else
slouken@309
   489
    {
slouken@663
   490
        /* Initialize internal variables */
slouken@663
   491
        if ((current->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
slouken@309
   492
        {
slouken@315
   493
            if (bpp==8)
slouken@315
   494
            {
slouken@315
   495
               desktoppal=SDLPH_PAL_SYSTEM;
slouken@315
   496
            }
slouken@309
   497
slouken@571
   498
            current->flags &= ~SDL_RESIZABLE; /* no resize for Direct Context */
slouken@692
   499
            current->flags |= SDL_HWSURFACE;
slouken@663
   500
        }
slouken@309
   501
        else
slouken@309
   502
        {
slouken@663
   503
            /* remove this if we'll support non-fullscreen sw/hw+doublebuf */
slouken@663
   504
            current->flags &= ~SDL_DOUBLEBUF;
slouken@663
   505
slouken@663
   506
            /* Use offscreen memory if SDL_HWSURFACE flag is set */
slouken@663
   507
            if ((current->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
slouken@309
   508
            {
slouken@663
   509
slouken@663
   510
                if (desktopbpp!=bpp)
slouken@663
   511
                {
slouken@663
   512
                   current->flags &= ~SDL_HWSURFACE;
slouken@663
   513
                }
slouken@309
   514
            }
slouken@320
   515
slouken@315
   516
            /* using palette emulation code in window mode */
slouken@315
   517
            if (bpp==8)
slouken@315
   518
            {
slouken@315
   519
                if (desktopbpp>=15)
slouken@315
   520
                {
slouken@663
   521
                    desktoppal = SDLPH_PAL_EMULATE;
slouken@315
   522
                }
slouken@315
   523
                else
slouken@315
   524
                {
slouken@663
   525
                    desktoppal = SDLPH_PAL_SYSTEM;
slouken@571
   526
                }
slouken@315
   527
            }
slouken@315
   528
            else
slouken@315
   529
            {
slouken@663
   530
               desktoppal = SDLPH_PAL_NONE;
slouken@315
   531
            }
slouken@0
   532
        }
slouken@0
   533
    }
slouken@0
   534
slouken@309
   535
    current->w = width;
slouken@309
   536
    current->h = height;
slouken@571
   537
slouken@663
   538
    if (desktoppal==SDLPH_PAL_SYSTEM)
slouken@663
   539
    {
slouken@663
   540
       current->flags|=SDL_HWPALETTE;
slouken@663
   541
    }
slouken@370
   542
slouken@663
   543
    /* Must call at least once for setup image planes */
slouken@663
   544
    if (ph_SetupUpdateFunction(this, current, current->flags)==-1)
slouken@370
   545
    {
slouken@370
   546
        return NULL;
slouken@370
   547
    }
slouken@0
   548
slouken@663
   549
    /* finish window drawing, if we are not in fullscreen, of course */
slouken@663
   550
    if ((current->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
slouken@663
   551
    {
slouken@663
   552
       PtFlush();
slouken@663
   553
    }
slouken@692
   554
    else
slouken@692
   555
    {
slouken@692
   556
       PgFlush();
slouken@692
   557
    }
slouken@320
   558
slouken@0
   559
    SDL_Unlock_EventThread();
slouken@0
   560
slouken@0
   561
    /* We're done! */
slouken@315
   562
    return (current);
slouken@0
   563
}
slouken@0
   564
slouken@0
   565
static void ph_VideoQuit(_THIS)
slouken@0
   566
{
slouken@663
   567
    /* restore palette */
slouken@663
   568
    if (desktopbpp==8)
slouken@663
   569
    {
slouken@663
   570
        PgSetPalette(syspalph, 0, -1, 0, 0, 0);
slouken@663
   571
        PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0);
slouken@663
   572
        PgFlush();
slouken@663
   573
    }
slouken@663
   574
slouken@283
   575
    ph_DestroyImage(this, SDL_VideoSurface); 
slouken@0
   576
slouken@309
   577
    if (window)
slouken@309
   578
    {
slouken@309
   579
        PtUnrealizeWidget(window);
slouken@309
   580
        PtDestroyWidget(window);
slouken@309
   581
        window=NULL;
slouken@309
   582
    }
slouken@309
   583
slouken@571
   584
    if (event!=NULL)
slouken@571
   585
    {
slouken@571
   586
        free(event);
slouken@571
   587
        event=NULL;
slouken@571
   588
    }
slouken@0
   589
}
slouken@0
   590
slouken@0
   591
static int ph_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
slouken@0
   592
{
slouken@315
   593
    int i;
slouken@571
   594
    SDL_Rect updaterect;
slouken@571
   595
slouken@571
   596
    updaterect.x = updaterect.y = 0;
slouken@571
   597
    updaterect.w = this->screen->w;
slouken@571
   598
    updaterect.h = this->screen->h;
slouken@0
   599
slouken@315
   600
    /* palette emulation code, using palette of the PhImage_t struct */
slouken@315
   601
    if (desktoppal==SDLPH_PAL_EMULATE)
slouken@315
   602
    {
slouken@315
   603
        if ((SDL_Image) && (SDL_Image->palette))
slouken@315
   604
        {
slouken@315
   605
            for (i=firstcolor; i<firstcolor+ncolors; i++)
slouken@315
   606
            {
slouken@571
   607
                syspalph[i] = PgRGB(colors[i-firstcolor].r, colors[i-firstcolor].g, colors[i-firstcolor].b);
slouken@571
   608
                SDL_Image->palette[i] = syspalph[i];
slouken@315
   609
            }
slouken@663
   610
slouken@571
   611
            /* image needs to be redrawn */
slouken@571
   612
            this->UpdateRects(this, 1, &updaterect);
slouken@315
   613
        }
slouken@315
   614
    }
slouken@315
   615
    else
slouken@315
   616
    {
slouken@315
   617
        if (desktoppal==SDLPH_PAL_SYSTEM)
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@315
   622
            }
slouken@0
   623
slouken@315
   624
            if ((this->screen->flags & SDL_FULLSCREEN) != SDL_FULLSCREEN)
slouken@315
   625
            {
slouken@571
   626
                 /* window mode must use soft palette */
slouken@663
   627
                PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
slouken@571
   628
                /* image needs to be redrawn */
slouken@571
   629
                this->UpdateRects(this, 1, &updaterect);
slouken@315
   630
            }
slouken@315
   631
            else
slouken@315
   632
            {
slouken@315
   633
                /* fullscreen mode must use hardware palette */
slouken@663
   634
                PgSetPalette(&syspalph[firstcolor], 0, firstcolor, ncolors, Pg_PALSET_GLOBAL, 0);
slouken@315
   635
            }
slouken@315
   636
        }
slouken@315
   637
        else
slouken@315
   638
        {
slouken@315
   639
            /* SDLPH_PAL_NONE do nothing */
slouken@315
   640
        }
slouken@0
   641
    }
slouken@315
   642
    
slouken@315
   643
    return 1;
slouken@0
   644
}
slouken@0
   645
slouken@279
   646
#ifdef HAVE_OPENGL
slouken@309
   647
slouken@701
   648
static void ph_GL_SwapBuffers(_THIS)
slouken@266
   649
{
slouken@291
   650
    PgSetRegion(PtWidgetRid(window));
slouken@309
   651
    PdOpenGLContextSwapBuffers(oglctx);
slouken@266
   652
}
slouken@266
   653
slouken@701
   654
static int ph_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
slouken@0
   655
{
slouken@291
   656
    switch (attrib)
slouken@291
   657
    {
slouken@291
   658
        case SDL_GL_DOUBLEBUFFER:
slouken@291
   659
             *value=this->gl_config.double_buffer;
slouken@291
   660
             break;
slouken@291
   661
        case SDL_GL_STENCIL_SIZE:
slouken@291
   662
             *value=this->gl_config.stencil_size;
slouken@291
   663
             break;
slouken@291
   664
        case SDL_GL_DEPTH_SIZE:
slouken@291
   665
             *value=this->gl_config.depth_size;
slouken@291
   666
             break;
slouken@291
   667
        default:
slouken@291
   668
             *value=0;
slouken@291
   669
             return(-1);
slouken@291
   670
    }
slouken@291
   671
    return 0;
slouken@291
   672
}
slouken@0
   673
slouken@701
   674
static int ph_GL_LoadLibrary(_THIS, const char* path)
slouken@663
   675
{
slouken@701
   676
   /* if code compiled with HAVE_OPENGL, that mean that library already linked */
slouken@663
   677
   this->gl_config.driver_loaded = 1;
slouken@663
   678
slouken@663
   679
   return 0;
slouken@663
   680
}
slouken@663
   681
slouken@701
   682
static void* ph_GL_GetProcAddress(_THIS, const char* proc)
slouken@663
   683
{
slouken@663
   684
   return NULL;
slouken@663
   685
}
slouken@663
   686
slouken@701
   687
static int ph_GL_MakeCurrent(_THIS)
slouken@701
   688
{
slouken@701
   689
    PgSetRegion(PtWidgetRid(window));
slouken@571
   690
slouken@701
   691
    if (oglctx!=NULL)
slouken@571
   692
    {
slouken@701
   693
        PhDCSetCurrent(oglctx);
slouken@571
   694
    }
slouken@571
   695
slouken@701
   696
    return 0;
slouken@571
   697
}
slouken@701
   698
slouken@701
   699
#endif /* HAVE_OPENGL */