src/video/directfb/SDL_DirectFB_video.c
author Sam Lantinga
Sun, 28 May 2006 13:04:16 +0000
branchSDL-1.3
changeset 1662 782fd950bd46
parent 1659 14717b52abc0
child 1668 4da1ee79c9af
permissions -rw-r--r--
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.

WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.

The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce

The headers are being converted to automatically generate doxygen documentation.
slouken@167
     1
/*
slouken@1312
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@167
     4
slouken@1312
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@1312
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@167
     9
slouken@1312
    10
    This library is distributed in the hope that it will be useful,
slouken@1312
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@1312
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@167
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@167
    18
slouken@1312
    19
    Sam Lantinga
slouken@1312
    20
    slouken@libsdl.org
icculus@728
    21
icculus@728
    22
	MGA CRTC2 support by Thomas Jarosch - tomj@simonv.com
icculus@728
    23
	CRTC2 support is inspired by mplayer's dfbmga driver
icculus@728
    24
	written by Ville Syrj��<syrjala@sci.fi>
slouken@167
    25
*/
slouken@1402
    26
#include "SDL_config.h"
slouken@167
    27
slouken@167
    28
/* DirectFB video driver implementation.
slouken@167
    29
*/
slouken@167
    30
slouken@167
    31
#include <fcntl.h>
slouken@167
    32
#include <unistd.h>
slouken@167
    33
#include <sys/mman.h>
slouken@167
    34
slouken@167
    35
#include <directfb.h>
icculus@1165
    36
#include <directfb_version.h>
slouken@167
    37
slouken@167
    38
#include "SDL_video.h"
slouken@167
    39
#include "SDL_mouse.h"
slouken@1361
    40
#include "../SDL_sysvideo.h"
slouken@1361
    41
#include "../SDL_pixels_c.h"
slouken@1361
    42
#include "../../events/SDL_events_c.h"
slouken@167
    43
#include "SDL_DirectFB_video.h"
slouken@167
    44
#include "SDL_DirectFB_events.h"
slouken@478
    45
#include "SDL_DirectFB_yuv.h"
slouken@167
    46
slouken@767
    47
/* The implementation dependent data for the window manager cursor */
slouken@1662
    48
struct WMcursor
slouken@1662
    49
{
slouken@1662
    50
    int unused;
slouken@767
    51
};
slouken@767
    52
slouken@167
    53
slouken@167
    54
/* Initialization/Query functions */
slouken@1662
    55
static int DirectFB_VideoInit (_THIS, SDL_PixelFormat * vformat);
slouken@1662
    56
static SDL_Rect **DirectFB_ListModes (_THIS, SDL_PixelFormat * format,
slouken@1662
    57
                                      Uint32 flags);
slouken@1662
    58
static SDL_Surface *DirectFB_SetVideoMode (_THIS, SDL_Surface * current,
slouken@1662
    59
                                           int width, int height, int bpp,
slouken@1662
    60
                                           Uint32 flags);
slouken@1662
    61
static int DirectFB_SetColors (_THIS, int firstcolor, int ncolors,
slouken@1662
    62
                               SDL_Color * colors);
slouken@1662
    63
static void DirectFB_VideoQuit (_THIS);
slouken@167
    64
slouken@167
    65
/* Hardware surface functions */
slouken@1662
    66
static int DirectFB_AllocHWSurface (_THIS, SDL_Surface * surface);
slouken@1662
    67
static int DirectFB_FillHWRect (_THIS, SDL_Surface * dst, SDL_Rect * dstrect,
slouken@1662
    68
                                Uint32 color);
slouken@1662
    69
static int DirectFB_LockHWSurface (_THIS, SDL_Surface * surface);
slouken@1662
    70
static void DirectFB_UnlockHWSurface (_THIS, SDL_Surface * surface);
slouken@1662
    71
static void DirectFB_FreeHWSurface (_THIS, SDL_Surface * surface);
slouken@1662
    72
static int DirectFB_CheckHWBlit (_THIS, SDL_Surface * src, SDL_Surface * dst);
slouken@1662
    73
static int DirectFB_HWAccelBlit (SDL_Surface * src, SDL_Rect * srcrect,
slouken@1662
    74
                                 SDL_Surface * dst, SDL_Rect * dstrect);
slouken@1662
    75
static int DirectFB_SetHWColorKey (_THIS, SDL_Surface * surface, Uint32 key);
slouken@1662
    76
static int DirectFB_SetHWAlpha (_THIS, SDL_Surface * surface, Uint8 alpha);
slouken@1662
    77
static int DirectFB_FlipHWSurface (_THIS, SDL_Surface * surface);
slouken@1662
    78
static int DirectFB_ShowWMCursor (_THIS, WMcursor * cursor);
slouken@167
    79
slouken@167
    80
/* Various screen update functions available */
slouken@1662
    81
static void DirectFB_DirectUpdate (_THIS, int numrects, SDL_Rect * rects);
slouken@1662
    82
static void DirectFB_WindowedUpdate (_THIS, int numrects, SDL_Rect * rects);
slouken@167
    83
slouken@167
    84
/* This is the rect EnumModes2 uses */
slouken@1662
    85
struct DirectFBEnumRect
slouken@1662
    86
{
slouken@1662
    87
    SDL_Rect r;
slouken@1662
    88
    struct DirectFBEnumRect *next;
slouken@167
    89
};
slouken@167
    90
slouken@464
    91
static struct DirectFBEnumRect *enumlist = NULL;
slouken@167
    92
slouken@167
    93
slouken@167
    94
/* DirectFB driver bootstrap functions */
slouken@167
    95
slouken@1662
    96
static int
slouken@1662
    97
DirectFB_Available (void)
slouken@167
    98
{
slouken@1662
    99
    return 1;
slouken@167
   100
}
slouken@167
   101
slouken@1662
   102
static void
slouken@1662
   103
DirectFB_DeleteDevice (SDL_VideoDevice * device)
slouken@167
   104
{
slouken@1662
   105
    SDL_free (device->hidden);
slouken@1662
   106
    SDL_free (device);
slouken@167
   107
}
slouken@167
   108
slouken@1662
   109
static SDL_VideoDevice *
slouken@1662
   110
DirectFB_CreateDevice (int devindex)
slouken@167
   111
{
slouken@1662
   112
    SDL_VideoDevice *device;
slouken@167
   113
slouken@1662
   114
    /* Initialize all variables that we clean on shutdown */
slouken@1662
   115
    device = (SDL_VideoDevice *) SDL_malloc (sizeof (SDL_VideoDevice));
slouken@1662
   116
    if (device) {
slouken@1662
   117
        SDL_memset (device, 0, (sizeof *device));
slouken@1662
   118
        device->hidden = (struct SDL_PrivateVideoData *)
slouken@1662
   119
            malloc (sizeof (*device->hidden));
slouken@167
   120
    }
slouken@1662
   121
    if (device == NULL || device->hidden == NULL) {
slouken@1662
   122
        SDL_OutOfMemory ();
slouken@1662
   123
        if (device) {
slouken@1662
   124
            free (device);
slouken@167
   125
        }
slouken@1662
   126
        return (0);
slouken@167
   127
    }
slouken@1662
   128
    SDL_memset (device->hidden, 0, sizeof (*device->hidden));
slouken@167
   129
slouken@1662
   130
    /* Set the function pointers */
slouken@1662
   131
    device->VideoInit = DirectFB_VideoInit;
slouken@1662
   132
    device->ListModes = DirectFB_ListModes;
slouken@1662
   133
    device->SetVideoMode = DirectFB_SetVideoMode;
slouken@1662
   134
    device->SetColors = DirectFB_SetColors;
slouken@1662
   135
    device->UpdateRects = NULL;
slouken@1662
   136
    device->CreateYUVOverlay = DirectFB_CreateYUVOverlay;
slouken@1662
   137
    device->VideoQuit = DirectFB_VideoQuit;
slouken@1662
   138
    device->AllocHWSurface = DirectFB_AllocHWSurface;
slouken@1662
   139
    device->CheckHWBlit = DirectFB_CheckHWBlit;
slouken@1662
   140
    device->FillHWRect = DirectFB_FillHWRect;
slouken@1662
   141
    device->SetHWColorKey = DirectFB_SetHWColorKey;
slouken@1662
   142
    device->SetHWAlpha = DirectFB_SetHWAlpha;
slouken@1662
   143
    device->LockHWSurface = DirectFB_LockHWSurface;
slouken@1662
   144
    device->UnlockHWSurface = DirectFB_UnlockHWSurface;
slouken@1662
   145
    device->FlipHWSurface = DirectFB_FlipHWSurface;
slouken@1662
   146
    device->FreeHWSurface = DirectFB_FreeHWSurface;
slouken@1662
   147
    device->ShowWMCursor = DirectFB_ShowWMCursor;
slouken@1662
   148
    device->SetCaption = NULL;
slouken@1662
   149
    device->SetIcon = NULL;
slouken@1662
   150
    device->IconifyWindow = NULL;
slouken@1662
   151
    device->GrabInput = NULL;
slouken@1662
   152
    device->GetWMInfo = NULL;
slouken@1662
   153
    device->InitOSKeymap = DirectFB_InitOSKeymap;
slouken@1662
   154
    device->PumpEvents = DirectFB_PumpEvents;
slouken@167
   155
slouken@1662
   156
    device->free = DirectFB_DeleteDevice;
slouken@167
   157
slouken@1662
   158
    return device;
slouken@167
   159
}
slouken@167
   160
slouken@167
   161
VideoBootStrap DirectFB_bootstrap = {
slouken@1662
   162
    "directfb", "DirectFB",
slouken@1662
   163
    DirectFB_Available, DirectFB_CreateDevice
slouken@167
   164
};
slouken@167
   165
slouken@1662
   166
static DFBSurfacePixelFormat
slouken@1662
   167
GetFormatForBpp (int bpp, IDirectFBDisplayLayer * layer)
slouken@464
   168
{
slouken@1662
   169
    DFBDisplayLayerConfig dlc;
slouken@1662
   170
    int bytes = (bpp + 7) / 8;
slouken@464
   171
slouken@1662
   172
    layer->GetConfiguration (layer, &dlc);
slouken@464
   173
slouken@1662
   174
    if (bytes == DFB_BYTES_PER_PIXEL (dlc.pixelformat) && bytes > 1)
slouken@1662
   175
        return dlc.pixelformat;
slouken@1662
   176
slouken@1662
   177
    switch (bytes) {
slouken@464
   178
    case 1:
slouken@1662
   179
        return DSPF_LUT8;
slouken@464
   180
    case 2:
slouken@1662
   181
        return DSPF_RGB16;
slouken@464
   182
    case 3:
slouken@1662
   183
        return DSPF_RGB24;
slouken@464
   184
    case 4:
slouken@1662
   185
        return DSPF_RGB32;
slouken@464
   186
    }
slouken@464
   187
slouken@1662
   188
    return DSPF_UNKNOWN;
slouken@464
   189
}
slouken@464
   190
slouken@1662
   191
static DFBEnumerationResult
slouken@1662
   192
EnumModesCallback (int width, int height, int bpp, void *data)
slouken@167
   193
{
slouken@1662
   194
    SDL_VideoDevice *this = (SDL_VideoDevice *) data;
slouken@1662
   195
    struct DirectFBEnumRect *enumrect;
slouken@1662
   196
slouken@1662
   197
    HIDDEN->nummodes++;
slouken@167
   198
slouken@1662
   199
    if (enumlist && enumlist->r.w == width && enumlist->r.h == height)
slouken@1662
   200
        return DFENUM_OK;
slouken@1659
   201
slouken@1662
   202
    enumrect = SDL_calloc (1, sizeof (struct DirectFBEnumRect));
slouken@1662
   203
    if (!enumrect) {
slouken@1662
   204
        SDL_OutOfMemory ();
slouken@1662
   205
        return DFENUM_CANCEL;
slouken@167
   206
    }
slouken@167
   207
slouken@1662
   208
    enumrect->r.w = (Uint16) width;
slouken@1662
   209
    enumrect->r.h = (Uint16) height;
slouken@1662
   210
    enumrect->next = enumlist;
slouken@464
   211
slouken@1662
   212
    enumlist = enumrect;
slouken@464
   213
slouken@1662
   214
    return DFENUM_OK;
slouken@167
   215
}
slouken@167
   216
slouken@1662
   217
struct private_hwdata
slouken@1662
   218
{
slouken@1662
   219
    IDirectFBSurface *surface;
slouken@1662
   220
    IDirectFBPalette *palette;
slouken@167
   221
};
slouken@167
   222
slouken@1662
   223
void
slouken@1662
   224
SetDirectFBerror (const char *function, DFBResult code)
slouken@167
   225
{
slouken@1662
   226
    const char *error = DirectFBErrorString (code);
slouken@167
   227
slouken@1662
   228
    if (error)
slouken@1662
   229
        SDL_SetError ("%s: %s", function, error);
slouken@1662
   230
    else
slouken@1662
   231
        SDL_SetError ("Unknown error code from %s", function);
slouken@167
   232
}
slouken@167
   233
slouken@1662
   234
static DFBSurfacePixelFormat
slouken@1662
   235
SDLToDFBPixelFormat (SDL_PixelFormat * format)
slouken@167
   236
{
slouken@1662
   237
    if (format->Rmask && format->Gmask && format->Bmask) {
slouken@1662
   238
        switch (format->BitsPerPixel) {
slouken@477
   239
        case 8:
slouken@1662
   240
            return DSPF_LUT8;
slouken@1662
   241
slouken@167
   242
        case 16:
slouken@1662
   243
            if (format->Rmask == 0xF800 &&
slouken@1662
   244
                format->Gmask == 0x07E0 && format->Bmask == 0x001F)
slouken@1662
   245
                return DSPF_RGB16;
slouken@1662
   246
            /* fall through */
slouken@1662
   247
slouken@167
   248
        case 15:
slouken@1662
   249
            if (format->Rmask == 0x7C00 &&
slouken@1662
   250
                format->Gmask == 0x03E0 && format->Bmask == 0x001F)
slouken@1662
   251
                return DSPF_ARGB1555;
slouken@1662
   252
            break;
slouken@1662
   253
slouken@167
   254
        case 24:
slouken@1662
   255
            if (format->Rmask == 0xFF0000 &&
slouken@1662
   256
                format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF)
slouken@1662
   257
                return DSPF_RGB24;
slouken@1662
   258
            break;
slouken@464
   259
slouken@167
   260
        case 32:
slouken@1662
   261
            if (format->Rmask == 0xFF0000 &&
slouken@1662
   262
                format->Gmask == 0x00FF00 && format->Bmask == 0x0000FF) {
slouken@1662
   263
                if (format->Amask == 0xFF000000)
slouken@1662
   264
                    return DSPF_ARGB;
slouken@1662
   265
                else
slouken@1662
   266
                    return DSPF_RGB32;
slouken@167
   267
            }
slouken@1662
   268
            break;
slouken@1662
   269
        }
slouken@1662
   270
    } else {
slouken@1662
   271
        switch (format->BitsPerPixel) {
slouken@1662
   272
        case 8:
slouken@1662
   273
            return DSPF_LUT8;
slouken@1662
   274
        case 15:
slouken@1662
   275
            return DSPF_ARGB1555;
slouken@1662
   276
        case 16:
slouken@1662
   277
            return DSPF_RGB16;
slouken@1662
   278
        case 24:
slouken@1662
   279
            return DSPF_RGB24;
slouken@1662
   280
        case 32:
slouken@1662
   281
            return DSPF_RGB32;
slouken@167
   282
        }
slouken@167
   283
    }
slouken@1662
   284
slouken@1662
   285
    return DSPF_UNKNOWN;
slouken@1662
   286
}
slouken@1662
   287
slouken@1662
   288
static SDL_Palette *
slouken@1662
   289
AllocatePalette (int size)
slouken@1662
   290
{
slouken@1662
   291
    SDL_Palette *palette;
slouken@1662
   292
    SDL_Color *colors;
slouken@1662
   293
slouken@1662
   294
    palette = SDL_calloc (1, sizeof (SDL_Palette));
slouken@1662
   295
    if (!palette) {
slouken@1662
   296
        SDL_OutOfMemory ();
slouken@1662
   297
        return NULL;
slouken@167
   298
    }
slouken@167
   299
slouken@1662
   300
    colors = SDL_calloc (size, sizeof (SDL_Color));
slouken@1662
   301
    if (!colors) {
slouken@1662
   302
        SDL_OutOfMemory ();
slouken@1662
   303
        return NULL;
slouken@464
   304
    }
slouken@464
   305
slouken@1662
   306
    palette->ncolors = size;
slouken@1662
   307
    palette->colors = colors;
slouken@464
   308
slouken@1662
   309
    return palette;
slouken@464
   310
}
slouken@464
   311
slouken@1662
   312
static int
slouken@1662
   313
DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat,
slouken@1662
   314
                     SDL_PixelFormat * format)
slouken@167
   315
{
slouken@1662
   316
    format->Amask = format->Rmask = format->Gmask = format->Bmask = 0;
slouken@1662
   317
    format->BitsPerPixel = format->BytesPerPixel = 0;
slouken@167
   318
slouken@1662
   319
    switch (pixelformat) {
slouken@167
   320
    case DSPF_A8:
slouken@1662
   321
        format->Amask = 0x000000FF;
slouken@1662
   322
        break;
slouken@464
   323
slouken@790
   324
    case DSPF_ARGB1555:
slouken@1662
   325
        format->Rmask = 0x00007C00;
slouken@1662
   326
        format->Gmask = 0x000003E0;
slouken@1662
   327
        format->Bmask = 0x0000001F;
slouken@1662
   328
        break;
slouken@464
   329
slouken@167
   330
    case DSPF_RGB16:
slouken@1662
   331
        format->Rmask = 0x0000F800;
slouken@1662
   332
        format->Gmask = 0x000007E0;
slouken@1662
   333
        format->Bmask = 0x0000001F;
slouken@1662
   334
        break;
slouken@464
   335
slouken@167
   336
    case DSPF_ARGB:
slouken@1662
   337
        format->Amask = 0;      /* apps don't seem to like that:  0xFF000000; */
slouken@1662
   338
        /* fall through */
slouken@167
   339
    case DSPF_RGB24:
slouken@167
   340
    case DSPF_RGB32:
slouken@1662
   341
        format->Rmask = 0x00FF0000;
slouken@1662
   342
        format->Gmask = 0x0000FF00;
slouken@1662
   343
        format->Bmask = 0x000000FF;
slouken@1662
   344
        break;
slouken@464
   345
slouken@477
   346
    case DSPF_LUT8:
slouken@1662
   347
        format->Rmask = 0x000000FF;
slouken@1662
   348
        format->Gmask = 0x000000FF;
slouken@1662
   349
        format->Bmask = 0x000000FF;
slouken@464
   350
slouken@1662
   351
        if (!format->palette)
slouken@1662
   352
            format->palette = AllocatePalette (256);
slouken@1662
   353
        break;
slouken@464
   354
slouken@167
   355
    default:
slouken@1662
   356
        fprintf (stderr,
slouken@1662
   357
                 "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n",
slouken@1662
   358
                 pixelformat);
slouken@1662
   359
        return -1;
slouken@167
   360
    }
slouken@167
   361
slouken@1662
   362
    format->BitsPerPixel = DFB_BYTES_PER_PIXEL (pixelformat) * 8;
slouken@1662
   363
    format->BytesPerPixel = DFB_BYTES_PER_PIXEL (pixelformat);
slouken@167
   364
slouken@1662
   365
    return 0;
slouken@167
   366
}
slouken@167
   367
slouken@167
   368
slouken@1662
   369
int
slouken@1662
   370
DirectFB_VideoInit (_THIS, SDL_PixelFormat * vformat)
slouken@167
   371
{
slouken@1662
   372
    int i;
slouken@1662
   373
    DFBResult ret;
icculus@1165
   374
#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
slouken@1662
   375
    DFBCardCapabilities caps;
icculus@1165
   376
#else
slouken@1662
   377
    DFBGraphicsDeviceDescription caps;
icculus@1165
   378
#endif
slouken@1662
   379
    DFBDisplayLayerConfig dlc;
slouken@1662
   380
    struct DirectFBEnumRect *rect;
slouken@1662
   381
    IDirectFB *dfb = NULL;
slouken@1662
   382
    IDirectFBDisplayLayer *layer = NULL;
slouken@1662
   383
    IDirectFBEventBuffer *events = NULL;
slouken@167
   384
slouken@1662
   385
    HIDDEN->c2layer = NULL, HIDDEN->c2frame = NULL;
slouken@1662
   386
    HIDDEN->enable_mga_crtc2 = 0;
slouken@1662
   387
    HIDDEN->mga_crtc2_stretch_overscan = 1;
slouken@167
   388
slouken@1662
   389
    ret = DirectFBInit (NULL, NULL);
slouken@1662
   390
    if (ret) {
slouken@1662
   391
        SetDirectFBerror ("DirectFBInit", ret);
slouken@1662
   392
        goto error;
slouken@167
   393
    }
slouken@167
   394
slouken@1662
   395
    ret = DirectFBCreate (&dfb);
slouken@1662
   396
    if (ret) {
slouken@1662
   397
        SetDirectFBerror ("DirectFBCreate", ret);
slouken@1662
   398
        goto error;
slouken@1662
   399
    }
slouken@1662
   400
slouken@1662
   401
    ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer);
slouken@1662
   402
    if (ret) {
slouken@1662
   403
        SetDirectFBerror ("dfb->GetDisplayLayer", ret);
slouken@1662
   404
        goto error;
slouken@167
   405
    }
slouken@167
   406
slouken@1662
   407
    ret = dfb->CreateInputEventBuffer (dfb, DICAPS_ALL, DFB_FALSE, &events);
slouken@1662
   408
    if (ret) {
slouken@1662
   409
        SetDirectFBerror ("dfb->CreateEventBuffer", ret);
slouken@1662
   410
        goto error;
slouken@1662
   411
    }
slouken@1662
   412
slouken@1662
   413
    layer->EnableCursor (layer, 1);
slouken@1662
   414
slouken@1662
   415
    /* Query layer configuration to determine the current mode and pixelformat */
slouken@1662
   416
    layer->GetConfiguration (layer, &dlc);
slouken@1662
   417
slouken@1662
   418
    /* If current format is not supported use LUT8 as the default */
slouken@1662
   419
    if (DFBToSDLPixelFormat (dlc.pixelformat, vformat))
slouken@1662
   420
        DFBToSDLPixelFormat (DSPF_LUT8, vformat);
slouken@1662
   421
slouken@1662
   422
    /* Enumerate the available fullscreen modes */
slouken@1662
   423
    ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this);
slouken@1662
   424
    if (ret) {
slouken@1662
   425
        SetDirectFBerror ("dfb->EnumVideoModes", ret);
slouken@1662
   426
        goto error;
slouken@167
   427
    }
slouken@167
   428
slouken@1662
   429
    HIDDEN->modelist = SDL_calloc (HIDDEN->nummodes + 1, sizeof (SDL_Rect *));
slouken@1662
   430
    if (!HIDDEN->modelist) {
slouken@1662
   431
        SDL_OutOfMemory ();
slouken@1662
   432
        goto error;
slouken@167
   433
    }
slouken@464
   434
slouken@1662
   435
    for (i = 0, rect = enumlist; rect; ++i, rect = rect->next) {
slouken@1662
   436
        HIDDEN->modelist[i] = &rect->r;
slouken@167
   437
    }
slouken@167
   438
slouken@1662
   439
    HIDDEN->modelist[i] = NULL;
slouken@464
   440
slouken@464
   441
slouken@1662
   442
    /* Query card capabilities to get the video memory size */
icculus@1165
   443
#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
slouken@1662
   444
    dfb->GetCardCapabilities (dfb, &caps);
icculus@1165
   445
#else
slouken@1662
   446
    dfb->GetDeviceDescription (dfb, &caps);
icculus@1165
   447
#endif
slouken@167
   448
slouken@1662
   449
    this->info.wm_available = 1;
slouken@1662
   450
    this->info.hw_available = 1;
slouken@1662
   451
    this->info.blit_hw = 1;
slouken@1662
   452
    this->info.blit_hw_CC = 1;
slouken@1662
   453
    this->info.blit_hw_A = 1;
slouken@1662
   454
    this->info.blit_fill = 1;
slouken@1662
   455
    this->info.video_mem = caps.video_memory / 1024;
slouken@167
   456
slouken@1662
   457
    HIDDEN->initialized = 1;
slouken@1662
   458
    HIDDEN->dfb = dfb;
slouken@1662
   459
    HIDDEN->layer = layer;
slouken@1662
   460
    HIDDEN->eventbuffer = events;
slouken@1662
   461
slouken@1662
   462
    if (SDL_getenv ("SDL_DIRECTFB_MGA_CRTC2") != NULL)
slouken@1662
   463
        HIDDEN->enable_mga_crtc2 = 1;
slouken@1018
   464
slouken@1662
   465
    if (HIDDEN->enable_mga_crtc2) {
slouken@1662
   466
        DFBDisplayLayerConfig dlc;
slouken@1662
   467
        DFBDisplayLayerConfigFlags failed;
slouken@1662
   468
slouken@1662
   469
        ret = dfb->GetDisplayLayer (dfb, 2, &HIDDEN->c2layer);
slouken@1662
   470
        if (ret) {
slouken@1662
   471
            SetDirectFBerror ("dfb->GetDisplayLayer(CRTC2)", ret);
slouken@1662
   472
            goto error;
icculus@728
   473
        }
icculus@728
   474
slouken@1662
   475
        ret =
slouken@1662
   476
            HIDDEN->layer->SetCooperativeLevel (HIDDEN->layer,
slouken@1662
   477
                                                DLSCL_EXCLUSIVE);
slouken@1662
   478
        if (ret) {
slouken@1662
   479
            SetDirectFBerror
slouken@1662
   480
                ("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
slouken@1662
   481
            goto error;
icculus@728
   482
        }
slouken@1662
   483
slouken@1662
   484
        ret =
slouken@1662
   485
            HIDDEN->c2layer->SetCooperativeLevel (HIDDEN->c2layer,
slouken@1662
   486
                                                  DLSCL_EXCLUSIVE);
slouken@1662
   487
        if (ret) {
slouken@1662
   488
            SetDirectFBerror
slouken@1662
   489
                ("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret);
slouken@1662
   490
            goto error;
icculus@728
   491
        }
icculus@728
   492
slouken@1662
   493
        HIDDEN->c2layer->SetOpacity (HIDDEN->c2layer, 0x0);
slouken@1662
   494
slouken@1662
   495
        /* Init the surface here as it got a fixed size */
slouken@1662
   496
        dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
slouken@1662
   497
        dlc.buffermode = DLBM_BACKVIDEO;
slouken@1662
   498
        dlc.pixelformat = DSPF_RGB32;
icculus@728
   499
slouken@1662
   500
        ret =
slouken@1662
   501
            HIDDEN->c2layer->TestConfiguration (HIDDEN->c2layer, &dlc,
slouken@1662
   502
                                                &failed);
slouken@1662
   503
        if (ret) {
slouken@1662
   504
            SetDirectFBerror ("c2layer->TestConfiguration", ret);
slouken@1662
   505
            goto error;
icculus@728
   506
        }
slouken@1662
   507
slouken@1662
   508
        ret = HIDDEN->c2layer->SetConfiguration (HIDDEN->c2layer, &dlc);
slouken@1662
   509
        if (ret) {
slouken@1662
   510
            SetDirectFBerror ("c2layer->SetConfiguration", ret);
slouken@1662
   511
            goto error;
icculus@728
   512
        }
slouken@1662
   513
slouken@1662
   514
        ret = HIDDEN->c2layer->GetSurface (HIDDEN->c2layer, &HIDDEN->c2frame);
slouken@1662
   515
        if (ret) {
slouken@1662
   516
            SetDirectFBerror ("c2layer->GetSurface", ret);
slouken@1662
   517
            goto error;
icculus@728
   518
        }
icculus@728
   519
slouken@1662
   520
        HIDDEN->c2framesize.x = 0;
slouken@1662
   521
        HIDDEN->c2framesize.y = 0;
slouken@1662
   522
        HIDDEN->c2frame->GetSize (HIDDEN->c2frame, &HIDDEN->c2framesize.w,
slouken@1662
   523
                                  &HIDDEN->c2framesize.h);
icculus@728
   524
slouken@1662
   525
        HIDDEN->c2frame->SetBlittingFlags (HIDDEN->c2frame, DSBLIT_NOFX);
slouken@1662
   526
        HIDDEN->c2frame->SetColor (HIDDEN->c2frame, 0, 0, 0, 0xff);
slouken@1662
   527
slouken@1662
   528
        /* Clear CRTC2 */
slouken@1662
   529
        HIDDEN->c2frame->Clear (HIDDEN->c2frame, 0, 0, 0, 0xff);
slouken@1662
   530
        HIDDEN->c2frame->Flip (HIDDEN->c2frame, NULL, 0);
slouken@1662
   531
        HIDDEN->c2frame->Clear (HIDDEN->c2frame, 0, 0, 0, 0xff);
slouken@1662
   532
        HIDDEN->c2frame->Flip (HIDDEN->c2frame, NULL, 0);
slouken@1662
   533
        HIDDEN->c2frame->Clear (HIDDEN->c2frame, 0, 0, 0, 0xff);
icculus@728
   534
slouken@1662
   535
        HIDDEN->c2layer->SetOpacity (HIDDEN->c2layer, 0xFF);
icculus@732
   536
slouken@1662
   537
        /* Check if overscan is possibly set */
slouken@1662
   538
        if (SDL_getenv ("SDL_DIRECTFB_MGA_OVERSCAN") != NULL) {
slouken@1662
   539
            float overscan = 0;
slouken@1662
   540
            if (SDL_sscanf
slouken@1662
   541
                (SDL_getenv ("SDL_DIRECTFB_MGA_OVERSCAN"), "%f",
slouken@1662
   542
                 &overscan) == 1)
slouken@1662
   543
                if (overscan > 0 && overscan < 2)
slouken@1662
   544
                    HIDDEN->mga_crtc2_stretch_overscan = overscan;
slouken@1662
   545
        }
slouken@1662
   546
#ifdef DIRECTFB_CRTC2_DEBUG
slouken@1662
   547
        printf ("CRTC2 overscan: %f\n", HIDDEN->mga_crtc2_stretch_overscan);
slouken@1662
   548
#endif
icculus@728
   549
    }
icculus@728
   550
slouken@1662
   551
    return 0;
slouken@464
   552
slouken@1662
   553
  error:
slouken@1662
   554
    if (events)
slouken@1662
   555
        events->Release (events);
slouken@1662
   556
slouken@1662
   557
    if (HIDDEN->c2frame)
slouken@1662
   558
        HIDDEN->c2frame->Release (HIDDEN->c2frame);
icculus@728
   559
slouken@1662
   560
    if (HIDDEN->c2layer)
slouken@1662
   561
        HIDDEN->c2layer->Release (HIDDEN->c2layer);
icculus@728
   562
slouken@1662
   563
    if (layer)
slouken@1662
   564
        layer->Release (layer);
slouken@464
   565
slouken@1662
   566
    if (dfb)
slouken@1662
   567
        dfb->Release (dfb);
slouken@464
   568
slouken@1662
   569
    return -1;
slouken@167
   570
}
slouken@167
   571
slouken@1662
   572
static SDL_Rect **
slouken@1662
   573
DirectFB_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags)
slouken@167
   574
{
slouken@1662
   575
    if (flags & SDL_FULLSCREEN)
slouken@1662
   576
        return HIDDEN->modelist;
slouken@1662
   577
    else if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN)
slouken@1662
   578
        return (SDL_Rect **) - 1;
slouken@167
   579
slouken@1662
   580
    return NULL;
slouken@167
   581
}
slouken@167
   582
slouken@1662
   583
static SDL_Surface *
slouken@1662
   584
DirectFB_SetVideoMode (_THIS, SDL_Surface * current, int width, int height,
slouken@1662
   585
                       int bpp, Uint32 flags)
slouken@167
   586
{
slouken@1662
   587
    DFBResult ret;
slouken@1662
   588
    DFBSurfaceDescription dsc;
slouken@1662
   589
    DFBSurfacePixelFormat pixelformat;
slouken@1662
   590
    IDirectFBSurface *surface;
slouken@167
   591
slouken@1662
   592
    fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
slouken@1662
   593
             width, height, bpp, flags);
slouken@167
   594
slouken@1662
   595
    flags |= SDL_FULLSCREEN;
slouken@167
   596
slouken@1662
   597
    /* Release previous primary surface */
slouken@1662
   598
    if (current->hwdata && current->hwdata->surface) {
slouken@1662
   599
        current->hwdata->surface->Release (current->hwdata->surface);
slouken@1662
   600
        current->hwdata->surface = NULL;
slouken@477
   601
slouken@1662
   602
        /* And its palette if present */
slouken@1662
   603
        if (current->hwdata->palette) {
slouken@1662
   604
            current->hwdata->palette->Release (current->hwdata->palette);
slouken@1662
   605
            current->hwdata->palette = NULL;
slouken@1662
   606
        }
slouken@1662
   607
    } else if (!current->hwdata) {
slouken@1662
   608
        /* Allocate the hardware acceleration data */
slouken@1662
   609
        current->hwdata =
slouken@1662
   610
            (struct private_hwdata *) SDL_calloc (1,
slouken@1662
   611
                                                  sizeof (*current->hwdata));
slouken@1662
   612
        if (!current->hwdata) {
slouken@1662
   613
            SDL_OutOfMemory ();
slouken@1662
   614
            return NULL;
slouken@477
   615
        }
slouken@167
   616
    }
slouken@167
   617
slouken@1662
   618
    /* Set cooperative level depending on flag SDL_FULLSCREEN */
slouken@1662
   619
    if (flags & SDL_FULLSCREEN) {
slouken@1662
   620
        ret =
slouken@1662
   621
            HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN);
slouken@1662
   622
        if (ret && !HIDDEN->enable_mga_crtc2) {
slouken@1662
   623
            DirectFBError ("dfb->SetCooperativeLevel", ret);
slouken@1662
   624
            flags &= ~SDL_FULLSCREEN;
slouken@167
   625
        }
slouken@1662
   626
    } else
slouken@1662
   627
        HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
slouken@167
   628
slouken@1662
   629
    /* Set video mode */
slouken@1662
   630
    ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
slouken@1662
   631
    if (ret) {
slouken@1662
   632
        if (flags & SDL_FULLSCREEN) {
slouken@1662
   633
            flags &= ~SDL_FULLSCREEN;
slouken@1662
   634
            HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL);
slouken@1662
   635
            ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp);
slouken@167
   636
        }
slouken@167
   637
slouken@1662
   638
        if (ret) {
slouken@1662
   639
            SetDirectFBerror ("dfb->SetVideoMode", ret);
slouken@1662
   640
            return NULL;
slouken@167
   641
        }
slouken@167
   642
    }
slouken@167
   643
slouken@1662
   644
    /* Create primary surface */
slouken@1662
   645
    dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT;
slouken@1662
   646
    dsc.caps =
slouken@1662
   647
        DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0);
slouken@1662
   648
    dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer);
slouken@167
   649
slouken@1662
   650
    ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface);
slouken@1662
   651
    if (ret && (flags & SDL_DOUBLEBUF)) {
slouken@1662
   652
        /* Try without double buffering */
slouken@1662
   653
        dsc.caps &= ~DSCAPS_FLIPPING;
slouken@1662
   654
        ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface);
slouken@167
   655
    }
slouken@1662
   656
    if (ret) {
slouken@1662
   657
        SetDirectFBerror ("dfb->CreateSurface", ret);
slouken@1662
   658
        return NULL;
slouken@167
   659
    }
slouken@167
   660
slouken@1662
   661
    current->w = width;
slouken@1662
   662
    current->h = height;
slouken@1662
   663
    current->flags = SDL_HWSURFACE | SDL_PREALLOC;
slouken@167
   664
slouken@1662
   665
    if (flags & SDL_FULLSCREEN) {
slouken@1662
   666
        current->flags |= SDL_FULLSCREEN;
slouken@1662
   667
        this->UpdateRects = DirectFB_DirectUpdate;
slouken@1662
   668
    } else
slouken@1662
   669
        this->UpdateRects = DirectFB_WindowedUpdate;
slouken@167
   670
slouken@1662
   671
    if (dsc.caps & DSCAPS_FLIPPING)
slouken@1662
   672
        current->flags |= SDL_DOUBLEBUF;
slouken@167
   673
slouken@1662
   674
    surface->GetPixelFormat (surface, &pixelformat);
slouken@167
   675
slouken@1662
   676
    DFBToSDLPixelFormat (pixelformat, current->format);
slouken@477
   677
slouken@1662
   678
    /* Get the surface palette (if supported) */
slouken@1662
   679
    if (DFB_PIXELFORMAT_IS_INDEXED (pixelformat)) {
slouken@1662
   680
        surface->GetPalette (surface, &current->hwdata->palette);
slouken@1662
   681
slouken@1662
   682
        current->flags |= SDL_HWPALETTE;
slouken@477
   683
    }
slouken@477
   684
slouken@1662
   685
    current->hwdata->surface = surface;
slouken@477
   686
slouken@1662
   687
    /* MGA CRTC2 stuff */
slouken@1662
   688
    if (HIDDEN->enable_mga_crtc2) {
slouken@1662
   689
        /* no stretching if c2ssize == c2framesize */
slouken@1662
   690
        HIDDEN->c2ssize.x = 0, HIDDEN->c2ssize.y = 0;
slouken@1662
   691
        HIDDEN->c2ssize.w = width;
slouken@1662
   692
        HIDDEN->c2ssize.h = height;
icculus@728
   693
slouken@1662
   694
        HIDDEN->c2dsize.x = 0, HIDDEN->c2dsize.y = 0;
slouken@1662
   695
        HIDDEN->c2dsize.w = width;
slouken@1662
   696
        HIDDEN->c2dsize.h = height;
slouken@1662
   697
slouken@1662
   698
        HIDDEN->mga_crtc2_stretch = 0;
icculus@728
   699
slouken@1662
   700
        if (SDL_getenv ("SDL_DIRECTFB_MGA_STRETCH") != NULL) {
slouken@1662
   701
            /* Normally assume a picture aspect ratio of 4:3 */
slouken@1662
   702
            int zoom_aspect_x = 4, zoom_aspect_y = 3, i, j;
icculus@728
   703
slouken@1662
   704
            for (i = 1; i < 20; i++) {
slouken@1662
   705
                for (j = 1; j < 10; j++) {
slouken@1662
   706
                    if ((float) width / (float) i * (float) j == height) {
slouken@1662
   707
                        zoom_aspect_x = i;
slouken@1662
   708
                        zoom_aspect_y = j;
icculus@732
   709
slouken@1662
   710
                        /* break the loop */
slouken@1662
   711
                        i = 21;
slouken@1662
   712
                        break;
slouken@1662
   713
                    }
slouken@1662
   714
                }
slouken@1662
   715
            }
slouken@1662
   716
slouken@1662
   717
#ifdef DIRECTFB_CRTC2_DEBUG
slouken@1662
   718
            printf
slouken@1662
   719
                ("Source resolution: X: %d, Y: %d, Aspect ratio: %d:%d\n",
slouken@1662
   720
                 width, height, zoom_aspect_x, zoom_aspect_y);
slouken@1662
   721
            printf ("CRTC2 resolution: X: %d, Y: %d\n",
slouken@1662
   722
                    HIDDEN->c2framesize.w, HIDDEN->c2framesize.h);
slouken@1662
   723
#endif
slouken@1662
   724
slouken@1662
   725
            /* don't stretch only slightly smaller/larger images */
slouken@1662
   726
            if ((float) width < (float) HIDDEN->c2framesize.w * 0.95
slouken@1662
   727
                || (float) height < (float) HIDDEN->c2framesize.h * 0.95) {
slouken@1662
   728
                while ((float) HIDDEN->c2dsize.w <
slouken@1662
   729
                       (float) HIDDEN->c2framesize.w *
slouken@1662
   730
                       HIDDEN->mga_crtc2_stretch_overscan
slouken@1662
   731
                       && (float) HIDDEN->c2dsize.h <
slouken@1662
   732
                       (float) HIDDEN->c2framesize.h *
slouken@1662
   733
                       HIDDEN->mga_crtc2_stretch_overscan) {
slouken@1662
   734
                    HIDDEN->c2dsize.w += zoom_aspect_x;
slouken@1662
   735
                    HIDDEN->c2dsize.h += zoom_aspect_y;
icculus@728
   736
                }
icculus@728
   737
slouken@1662
   738
                /* one step down */
slouken@1662
   739
                HIDDEN->c2dsize.w -= zoom_aspect_x;
slouken@1662
   740
                HIDDEN->c2dsize.h -= zoom_aspect_y;
icculus@728
   741
slouken@1662
   742
#ifdef DIRECTFB_CRTC2_DEBUG
slouken@1662
   743
                printf ("Stretched resolution: X: %d, Y: %d\n",
slouken@1662
   744
                        HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
slouken@1662
   745
#endif
icculus@728
   746
slouken@1662
   747
                HIDDEN->mga_crtc2_stretch = 1;
slouken@1662
   748
            } else if ((float) width > (float) HIDDEN->c2framesize.w * 0.95
slouken@1662
   749
                       || (float) height >
slouken@1662
   750
                       (float) HIDDEN->c2framesize.h * 0.95) {
slouken@1662
   751
                while ((float) HIDDEN->c2dsize.w >
slouken@1662
   752
                       (float) HIDDEN->c2framesize.w *
slouken@1662
   753
                       HIDDEN->mga_crtc2_stretch_overscan
slouken@1662
   754
                       || (float) HIDDEN->c2dsize.h >
slouken@1662
   755
                       (float) HIDDEN->c2framesize.h *
slouken@1662
   756
                       HIDDEN->mga_crtc2_stretch_overscan) {
slouken@1662
   757
                    HIDDEN->c2dsize.w -= zoom_aspect_x;
slouken@1662
   758
                    HIDDEN->c2dsize.h -= zoom_aspect_y;
icculus@728
   759
                }
slouken@1662
   760
slouken@1662
   761
#ifdef DIRECTFB_CRTC2_DEBUG
slouken@1662
   762
                printf ("Down-Stretched resolution: X: %d, Y: %d\n",
slouken@1662
   763
                        HIDDEN->c2dsize.w, HIDDEN->c2dsize.h);
slouken@1662
   764
#endif
icculus@728
   765
slouken@1662
   766
                HIDDEN->mga_crtc2_stretch = 1;
slouken@1662
   767
            } else {
slouken@1662
   768
#ifdef DIRECTFB_CRTC2_DEBUG
slouken@1662
   769
                printf ("Not stretching image\n");
slouken@1662
   770
#endif
slouken@1662
   771
            }
icculus@728
   772
slouken@1662
   773
            /* Panning */
slouken@1662
   774
            if (HIDDEN->c2framesize.w > HIDDEN->c2dsize.w)
slouken@1662
   775
                HIDDEN->c2dsize.x =
slouken@1662
   776
                    (HIDDEN->c2framesize.w - HIDDEN->c2dsize.w) / 2;
slouken@1662
   777
            else
slouken@1662
   778
                HIDDEN->c2dsize.x =
slouken@1662
   779
                    (HIDDEN->c2dsize.w - HIDDEN->c2framesize.w) / 2;
icculus@728
   780
slouken@1662
   781
            if (HIDDEN->c2framesize.h > HIDDEN->c2dsize.h)
slouken@1662
   782
                HIDDEN->c2dsize.y =
slouken@1662
   783
                    (HIDDEN->c2framesize.h - HIDDEN->c2dsize.h) / 2;
slouken@1662
   784
            else
slouken@1662
   785
                HIDDEN->c2dsize.y =
slouken@1662
   786
                    (HIDDEN->c2dsize.h - HIDDEN->c2framesize.h) / 2;
icculus@728
   787
slouken@1662
   788
#ifdef DIRECTFB_CRTC2_DEBUG
slouken@1662
   789
            printf ("CRTC2 position X: %d, Y: %d\n", HIDDEN->c2dsize.x,
slouken@1662
   790
                    HIDDEN->c2dsize.y);
slouken@1662
   791
#endif
slouken@1662
   792
        }
slouken@1662
   793
    }
icculus@728
   794
slouken@1662
   795
    return current;
slouken@167
   796
}
slouken@167
   797
slouken@1662
   798
static int
slouken@1662
   799
DirectFB_AllocHWSurface (_THIS, SDL_Surface * surface)
slouken@167
   800
{
slouken@1662
   801
    DFBResult ret;
slouken@1662
   802
    DFBSurfaceDescription dsc;
slouken@167
   803
slouken@1662
   804
    /*  fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n",
slouken@1662
   805
       surface->w, surface->h, surface->format->BitsPerPixel, surface->flags); */
slouken@167
   806
slouken@1662
   807
    if (surface->w < 8 || surface->h < 8)
slouken@1662
   808
        return -1;
slouken@167
   809
slouken@1662
   810
    /* fill surface description */
slouken@1662
   811
    dsc.flags =
slouken@1662
   812
        DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
slouken@1662
   813
    dsc.width = surface->w;
slouken@1662
   814
    dsc.height = surface->h;
slouken@1662
   815
    dsc.caps = (surface->flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0;
slouken@167
   816
slouken@1662
   817
    /* find the right pixelformat */
slouken@1662
   818
    dsc.pixelformat = SDLToDFBPixelFormat (surface->format);
slouken@1662
   819
    if (dsc.pixelformat == DSPF_UNKNOWN)
slouken@1662
   820
        return -1;
slouken@167
   821
slouken@1662
   822
    /* Allocate the hardware acceleration data */
slouken@1662
   823
    surface->hwdata =
slouken@1662
   824
        (struct private_hwdata *) SDL_calloc (1, sizeof (*surface->hwdata));
slouken@1662
   825
    if (surface->hwdata == NULL) {
slouken@1662
   826
        SDL_OutOfMemory ();
slouken@1662
   827
        return -1;
slouken@167
   828
    }
slouken@167
   829
slouken@1662
   830
    /* Create the surface */
slouken@1662
   831
    ret =
slouken@1662
   832
        HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc,
slouken@1662
   833
                                    &surface->hwdata->surface);
slouken@1662
   834
    if (ret) {
slouken@1662
   835
        SetDirectFBerror ("dfb->CreateSurface", ret);
slouken@1662
   836
        free (surface->hwdata);
slouken@1662
   837
        surface->hwdata = NULL;
slouken@1662
   838
        return -1;
slouken@167
   839
    }
slouken@167
   840
slouken@1662
   841
    surface->flags |= SDL_HWSURFACE | SDL_PREALLOC;
slouken@167
   842
slouken@1662
   843
    return 0;
slouken@167
   844
}
slouken@167
   845
slouken@1662
   846
static void
slouken@1662
   847
DirectFB_FreeHWSurface (_THIS, SDL_Surface * surface)
slouken@167
   848
{
slouken@1662
   849
    if (surface->hwdata && HIDDEN->initialized) {
slouken@1662
   850
        surface->hwdata->surface->Release (surface->hwdata->surface);
slouken@1662
   851
        free (surface->hwdata);
slouken@1662
   852
        surface->hwdata = NULL;
slouken@167
   853
    }
slouken@167
   854
}
slouken@167
   855
slouken@1662
   856
static int
slouken@1662
   857
DirectFB_CheckHWBlit (_THIS, SDL_Surface * src, SDL_Surface * dst)
slouken@167
   858
{
slouken@1662
   859
    /*  fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
slouken@1662
   860
       src->hwdata, dst->hwdata); */
slouken@167
   861
slouken@1662
   862
    if (!src->hwdata || !dst->hwdata)
slouken@1662
   863
        return 0;
slouken@167
   864
slouken@1662
   865
    src->flags |= SDL_HWACCEL;
slouken@1662
   866
    src->map->hw_blit = DirectFB_HWAccelBlit;
slouken@167
   867
slouken@1662
   868
    return 1;
slouken@167
   869
}
slouken@167
   870
slouken@1662
   871
static int
slouken@1662
   872
DirectFB_HWAccelBlit (SDL_Surface * src, SDL_Rect * srcrect,
slouken@1662
   873
                      SDL_Surface * dst, SDL_Rect * dstrect)
slouken@167
   874
{
slouken@1662
   875
    DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
slouken@167
   876
slouken@1662
   877
    DFBRectangle sr = { srcrect->x, srcrect->y, srcrect->w, srcrect->h };
slouken@1662
   878
    DFBRectangle dr = { dstrect->x, dstrect->y, dstrect->w, dstrect->h };
slouken@167
   879
slouken@1662
   880
    IDirectFBSurface *surface = dst->hwdata->surface;
slouken@1662
   881
slouken@1662
   882
    if (src->flags & SDL_SRCCOLORKEY) {
slouken@1662
   883
        flags |= DSBLIT_SRC_COLORKEY;
slouken@1662
   884
        DirectFB_SetHWColorKey (NULL, src, src->format->colorkey);
slouken@167
   885
    }
slouken@167
   886
slouken@1662
   887
    if (src->flags & SDL_SRCALPHA) {
slouken@1662
   888
        flags |= DSBLIT_BLEND_COLORALPHA;
slouken@1662
   889
        surface->SetColor (surface, 0xff, 0xff, 0xff, src->format->alpha);
slouken@167
   890
    }
slouken@167
   891
slouken@1662
   892
    surface->SetBlittingFlags (surface, flags);
slouken@167
   893
slouken@1662
   894
    if (sr.w == dr.w && sr.h == dr.h)
slouken@1662
   895
        surface->Blit (surface, src->hwdata->surface, &sr, dr.x, dr.y);
slouken@1662
   896
    else
slouken@1662
   897
        surface->StretchBlit (surface, src->hwdata->surface, &sr, &dr);
slouken@167
   898
slouken@1662
   899
    return 0;
slouken@167
   900
}
slouken@167
   901
slouken@1662
   902
static int
slouken@1662
   903
DirectFB_FillHWRect (_THIS, SDL_Surface * dst, SDL_Rect * dstrect,
slouken@1662
   904
                     Uint32 color)
slouken@167
   905
{
slouken@1662
   906
    SDL_PixelFormat *fmt = dst->format;
slouken@1662
   907
    IDirectFBSurface *surface = dst->hwdata->surface;
slouken@167
   908
slouken@1662
   909
    /* ugly */
slouken@1662
   910
    surface->SetColor (surface,
slouken@1662
   911
                       (color & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss),
slouken@1662
   912
                       (color & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss),
slouken@1662
   913
                       (color & fmt->Bmask) << (fmt->Bloss - fmt->Bshift),
slouken@1662
   914
                       0xFF);
slouken@1662
   915
    surface->FillRectangle (surface, dstrect->x, dstrect->y, dstrect->w,
slouken@1662
   916
                            dstrect->h);
slouken@167
   917
slouken@1662
   918
    return 0;
slouken@167
   919
}
slouken@167
   920
slouken@1662
   921
static int
slouken@1662
   922
DirectFB_SetHWColorKey (_THIS, SDL_Surface * src, Uint32 key)
slouken@167
   923
{
slouken@1662
   924
    SDL_PixelFormat *fmt = src->format;
slouken@1662
   925
    IDirectFBSurface *surface = src->hwdata->surface;
slouken@219
   926
slouken@1662
   927
    if (fmt->BitsPerPixel == 8)
slouken@1662
   928
        surface->SetSrcColorKeyIndex (surface, key);
slouken@1662
   929
    else
slouken@1662
   930
        /* ugly */
slouken@1662
   931
        surface->SetSrcColorKey (surface,
slouken@1662
   932
                                 (key & fmt->Rmask) >> (fmt->Rshift -
slouken@1662
   933
                                                        fmt->Rloss),
slouken@1662
   934
                                 (key & fmt->Gmask) >> (fmt->Gshift -
slouken@1662
   935
                                                        fmt->Gloss),
slouken@1662
   936
                                 (key & fmt->Bmask) << (fmt->Bloss -
slouken@1662
   937
                                                        fmt->Bshift));
slouken@219
   938
slouken@1662
   939
    return 0;
slouken@167
   940
}
slouken@167
   941
slouken@1662
   942
static int
slouken@1662
   943
DirectFB_SetHWAlpha (_THIS, SDL_Surface * surface, Uint8 alpha)
slouken@167
   944
{
slouken@1662
   945
    return 0;
slouken@167
   946
}
slouken@167
   947
slouken@1662
   948
static int
slouken@1662
   949
DirectFB_FlipHWSurface (_THIS, SDL_Surface * surface)
slouken@167
   950
{
slouken@1662
   951
    if (HIDDEN->enable_mga_crtc2) {
slouken@1662
   952
        int rtn =
slouken@1662
   953
            surface->hwdata->surface->Flip (surface->hwdata->surface, NULL,
slouken@1662
   954
                                            0);
slouken@1662
   955
        if (HIDDEN->mga_crtc2_stretch)
slouken@1662
   956
            HIDDEN->c2frame->StretchBlit (HIDDEN->c2frame,
slouken@1662
   957
                                          surface->hwdata->surface,
slouken@1662
   958
                                          &HIDDEN->c2ssize, &HIDDEN->c2dsize);
slouken@1662
   959
        else
slouken@1662
   960
            HIDDEN->c2frame->Blit (HIDDEN->c2frame,
slouken@1662
   961
                                   surface->hwdata->surface, NULL,
slouken@1662
   962
                                   HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
slouken@1662
   963
slouken@1662
   964
        HIDDEN->c2frame->Flip (HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
slouken@1662
   965
        return rtn;
slouken@1662
   966
    } else
slouken@1662
   967
        return surface->hwdata->surface->Flip (surface->hwdata->surface, NULL,
slouken@1662
   968
                                               DSFLIP_WAITFORSYNC);
slouken@167
   969
}
slouken@167
   970
slouken@1662
   971
static int
slouken@1662
   972
DirectFB_LockHWSurface (_THIS, SDL_Surface * surface)
slouken@167
   973
{
slouken@1662
   974
    DFBResult ret;
slouken@1662
   975
    void *data;
slouken@1662
   976
    int pitch;
slouken@167
   977
slouken@1662
   978
    ret = surface->hwdata->surface->Lock (surface->hwdata->surface,
slouken@1662
   979
                                          DSLF_WRITE, &data, &pitch);
slouken@1662
   980
    if (ret) {
slouken@1662
   981
        SetDirectFBerror ("surface->Lock", ret);
slouken@1662
   982
        return -1;
slouken@167
   983
    }
slouken@167
   984
slouken@1662
   985
    surface->pixels = data;
slouken@1662
   986
    surface->pitch = pitch;
slouken@1662
   987
slouken@1662
   988
    return 0;
slouken@1662
   989
}
slouken@167
   990
slouken@1662
   991
static void
slouken@1662
   992
DirectFB_UnlockHWSurface (_THIS, SDL_Surface * surface)
slouken@1662
   993
{
slouken@1662
   994
    surface->hwdata->surface->Unlock (surface->hwdata->surface);
slouken@1662
   995
    surface->pixels = NULL;
slouken@167
   996
}
slouken@167
   997
slouken@1662
   998
static void
slouken@1662
   999
DirectFB_DirectUpdate (_THIS, int numrects, SDL_Rect * rects)
slouken@167
  1000
{
slouken@1662
  1001
    if (HIDDEN->enable_mga_crtc2) {
slouken@1662
  1002
        if (HIDDEN->mga_crtc2_stretch)
slouken@1662
  1003
            HIDDEN->c2frame->StretchBlit (HIDDEN->c2frame,
slouken@1662
  1004
                                          this->screen->hwdata->surface,
slouken@1662
  1005
                                          &HIDDEN->c2ssize, &HIDDEN->c2dsize);
slouken@1662
  1006
        else
slouken@1662
  1007
            HIDDEN->c2frame->Blit (HIDDEN->c2frame,
slouken@1662
  1008
                                   this->screen->hwdata->surface, NULL,
slouken@1662
  1009
                                   HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
icculus@728
  1010
slouken@1662
  1011
        HIDDEN->c2frame->Flip (HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
icculus@728
  1012
    }
slouken@167
  1013
}
slouken@167
  1014
slouken@1662
  1015
static void
slouken@1662
  1016
DirectFB_WindowedUpdate (_THIS, int numrects, SDL_Rect * rects)
slouken@167
  1017
{
slouken@1662
  1018
    DFBRegion region;
slouken@1662
  1019
    int i;
slouken@1662
  1020
    int region_valid = 0;
slouken@1662
  1021
    IDirectFBSurface *surface = this->screen->hwdata->surface;
slouken@167
  1022
slouken@1662
  1023
    for (i = 0; i < numrects; ++i) {
slouken@1662
  1024
        int x2, y2;
slouken@167
  1025
slouken@1662
  1026
        if (!rects[i].w)        /* Clipped? */
slouken@1662
  1027
            continue;
slouken@167
  1028
slouken@1662
  1029
        x2 = rects[i].x + rects[i].w - 1;
slouken@1662
  1030
        y2 = rects[i].y + rects[i].h - 1;
slouken@167
  1031
slouken@1662
  1032
        if (region_valid) {
slouken@1662
  1033
            if (rects[i].x < region.x1)
slouken@1662
  1034
                region.x1 = rects[i].x;
slouken@167
  1035
slouken@1662
  1036
            if (rects[i].y < region.y1)
slouken@1662
  1037
                region.y1 = rects[i].y;
slouken@167
  1038
slouken@1662
  1039
            if (x2 > region.x2)
slouken@1662
  1040
                region.x2 = x2;
slouken@1662
  1041
slouken@1662
  1042
            if (y2 > region.y2)
slouken@1662
  1043
                region.y2 = y2;
slouken@1662
  1044
        } else {
slouken@286
  1045
            region.x1 = rects[i].x;
slouken@286
  1046
            region.y1 = rects[i].y;
slouken@286
  1047
            region.x2 = x2;
slouken@286
  1048
            region.y2 = y2;
slouken@167
  1049
slouken@286
  1050
            region_valid = 1;
slouken@286
  1051
        }
slouken@167
  1052
    }
slouken@167
  1053
slouken@1662
  1054
    if (region_valid) {
slouken@1662
  1055
        if (HIDDEN->enable_mga_crtc2) {
slouken@1662
  1056
            if (HIDDEN->mga_crtc2_stretch)
slouken@1662
  1057
                HIDDEN->c2frame->StretchBlit (HIDDEN->c2frame, surface,
slouken@1662
  1058
                                              &HIDDEN->c2ssize,
slouken@1662
  1059
                                              &HIDDEN->c2dsize);
slouken@1662
  1060
            else
slouken@1662
  1061
                HIDDEN->c2frame->Blit (HIDDEN->c2frame, surface, NULL,
slouken@1662
  1062
                                       HIDDEN->c2dsize.x, HIDDEN->c2dsize.y);
slouken@1662
  1063
slouken@1662
  1064
            HIDDEN->c2frame->Flip (HIDDEN->c2frame, NULL, DSFLIP_WAITFORSYNC);
slouken@1662
  1065
        } else
slouken@1662
  1066
            surface->Flip (surface, &region, DSFLIP_WAITFORSYNC);
icculus@728
  1067
    }
slouken@167
  1068
}
slouken@167
  1069
slouken@1662
  1070
int
slouken@1662
  1071
DirectFB_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color * colors)
slouken@167
  1072
{
slouken@1662
  1073
    IDirectFBPalette *palette = this->screen->hwdata->palette;
slouken@477
  1074
slouken@1662
  1075
    if (!palette)
slouken@1662
  1076
        return 0;
slouken@477
  1077
slouken@1662
  1078
    if (firstcolor > 255)
slouken@1662
  1079
        return 0;
slouken@477
  1080
slouken@1662
  1081
    if (firstcolor + ncolors > 256)
slouken@1662
  1082
        ncolors = 256 - firstcolor;
slouken@477
  1083
slouken@1662
  1084
    if (ncolors > 0) {
slouken@1662
  1085
        int i;
slouken@1662
  1086
        DFBColor entries[ncolors];
slouken@477
  1087
slouken@1662
  1088
        for (i = 0; i < ncolors; i++) {
slouken@1662
  1089
            entries[i].a = 0xff;
slouken@1662
  1090
            entries[i].r = colors[i].r;
slouken@1662
  1091
            entries[i].g = colors[i].g;
slouken@1662
  1092
            entries[i].b = colors[i].b;
slouken@477
  1093
        }
slouken@477
  1094
slouken@1662
  1095
        palette->SetEntries (palette, entries, ncolors, firstcolor);
slouken@477
  1096
    }
slouken@477
  1097
slouken@1662
  1098
    return 1;
slouken@167
  1099
}
slouken@1662
  1100
slouken@1662
  1101
void
slouken@1662
  1102
DirectFB_VideoQuit (_THIS)
slouken@167
  1103
{
slouken@1662
  1104
    struct DirectFBEnumRect *rect = enumlist;
icculus@759
  1105
slouken@1662
  1106
    if (this->screen && this->screen->hwdata) {
slouken@1662
  1107
        IDirectFBSurface *surface = this->screen->hwdata->surface;
slouken@1662
  1108
        IDirectFBPalette *palette = this->screen->hwdata->palette;
slouken@477
  1109
slouken@1662
  1110
        if (palette)
slouken@1662
  1111
            palette->Release (palette);
slouken@477
  1112
slouken@1662
  1113
        if (surface)
slouken@1662
  1114
            surface->Release (surface);
icculus@759
  1115
slouken@1662
  1116
        this->screen->hwdata->surface = NULL;
slouken@1662
  1117
        this->screen->hwdata->palette = NULL;
icculus@759
  1118
    }
slouken@477
  1119
slouken@1662
  1120
    if (HIDDEN->c2frame) {
slouken@1662
  1121
        HIDDEN->c2frame->Release (HIDDEN->c2frame);
slouken@1662
  1122
        HIDDEN->c2frame = NULL;
slouken@464
  1123
    }
slouken@167
  1124
slouken@1662
  1125
    if (HIDDEN->eventbuffer) {
slouken@1662
  1126
        HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer);
slouken@1662
  1127
        HIDDEN->eventbuffer = NULL;
icculus@728
  1128
    }
icculus@728
  1129
slouken@1662
  1130
    if (HIDDEN->c2layer) {
slouken@1662
  1131
        HIDDEN->c2layer->Release (HIDDEN->c2layer);
slouken@1662
  1132
        HIDDEN->c2layer = NULL;
slouken@464
  1133
    }
slouken@167
  1134
slouken@1662
  1135
    if (HIDDEN->layer) {
slouken@1662
  1136
        HIDDEN->layer->Release (HIDDEN->layer);
slouken@1662
  1137
        HIDDEN->layer = NULL;
slouken@464
  1138
    }
slouken@464
  1139
slouken@1662
  1140
    if (HIDDEN->dfb) {
slouken@1662
  1141
        HIDDEN->dfb->Release (HIDDEN->dfb);
slouken@1662
  1142
        HIDDEN->dfb = NULL;
slouken@167
  1143
    }
slouken@167
  1144
slouken@1662
  1145
    /* Free video mode list */
slouken@1662
  1146
    if (HIDDEN->modelist) {
slouken@1662
  1147
        free (HIDDEN->modelist);
slouken@1662
  1148
        HIDDEN->modelist = NULL;
slouken@464
  1149
    }
slouken@464
  1150
slouken@1662
  1151
    /* Free mode enumeration list */
slouken@1662
  1152
    while (rect) {
slouken@1662
  1153
        struct DirectFBEnumRect *next = rect->next;
slouken@1662
  1154
        free (rect);
slouken@1662
  1155
        rect = next;
slouken@1662
  1156
    }
slouken@1662
  1157
    enumlist = NULL;
slouken@1662
  1158
slouken@1662
  1159
    HIDDEN->initialized = 0;
slouken@167
  1160
}
slouken@167
  1161
slouken@767
  1162
slouken@1662
  1163
int
slouken@1662
  1164
DirectFB_ShowWMCursor (_THIS, WMcursor * cursor)
slouken@767
  1165
{
slouken@1662
  1166
    /* We can only hide or show the default cursor */
slouken@1662
  1167
    if (cursor == NULL) {
slouken@1662
  1168
        HIDDEN->layer->SetCursorOpacity (HIDDEN->layer, 0x00);
slouken@1662
  1169
    } else {
slouken@1662
  1170
        HIDDEN->layer->SetCursorOpacity (HIDDEN->layer, 0xFF);
slouken@767
  1171
    }
slouken@1662
  1172
    return 1;
slouken@767
  1173
}
slouken@767
  1174
slouken@1662
  1175
void
slouken@1662
  1176
DirectFB_FinalQuit (void)
slouken@167
  1177
{
slouken@167
  1178
}
slouken@1662
  1179
slouken@1662
  1180
/* vi: set ts=4 sw=4 expandtab: */