src/video/directfb/SDL_DirectFB_video.c
author Ryan C. Gordon
Mon, 17 Jan 2005 19:38:28 +0000
changeset 1029 f87f87efd45a
parent 1018 012af0b7e8e6
child 1165 4fa705cdecb9
permissions -rw-r--r--
Date: Mon, 17 Jan 2005 20:54:50 +0200
From: Ville [snip]
Subject: [PATCH] SDL/DirectFB: remove Matrox CRTC2 flicker filter

Hi,

This patch removes the flicker filter option from the DirectFB backend's
Matrox CRTC2 code in SDL. I will be removing the option from DirectFB
(because it doesn't actually work) and that would cause the SDL code to
fail without this fix.

I was going to send this to some SDL list directly but libsdl.org is down
so I'm not sure what if any lists there are. Thomas Jarosch (the guy who
wrote the code) said you would accept SDL patches. Let me know if I should
send this somewhere else.

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