2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2006 Sam Lantinga
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 MGA CRTC2 support by Thomas Jarosch - tomj@simonv.com
23 CRTC2 support is inspired by mplayer's dfbmga driver
24 written by Ville Syrj��<syrjala@sci.fi>
26 #include "SDL_config.h"
28 /* DirectFB video driver implementation.
36 #include <directfb_version.h>
38 #include "SDL_video.h"
39 #include "SDL_mouse.h"
40 #include "../SDL_sysvideo.h"
41 #include "../SDL_pixels_c.h"
42 #include "../../events/SDL_events_c.h"
43 #include "SDL_DirectFB_video.h"
44 #include "SDL_DirectFB_events.h"
45 #include "SDL_DirectFB_yuv.h"
47 /* The implementation dependent data for the window manager cursor */
53 /* Initialization/Query functions */
54 static int DirectFB_VideoInit(_THIS
, SDL_PixelFormat
*vformat
);
55 static SDL_Rect
**DirectFB_ListModes(_THIS
, SDL_PixelFormat
*format
, Uint32 flags
);
56 static SDL_Surface
*DirectFB_SetVideoMode(_THIS
, SDL_Surface
*current
, int width
, int height
, int bpp
, Uint32 flags
);
57 static int DirectFB_SetColors(_THIS
, int firstcolor
, int ncolors
,
59 static void DirectFB_VideoQuit(_THIS
);
61 /* Hardware surface functions */
62 static int DirectFB_AllocHWSurface(_THIS
, SDL_Surface
*surface
);
63 static int DirectFB_FillHWRect(_THIS
, SDL_Surface
*dst
, SDL_Rect
*dstrect
, Uint32 color
);
64 static int DirectFB_LockHWSurface(_THIS
, SDL_Surface
*surface
);
65 static void DirectFB_UnlockHWSurface(_THIS
, SDL_Surface
*surface
);
66 static void DirectFB_FreeHWSurface(_THIS
, SDL_Surface
*surface
);
67 static int DirectFB_CheckHWBlit(_THIS
, SDL_Surface
*src
, SDL_Surface
*dst
);
68 static int DirectFB_HWAccelBlit(SDL_Surface
*src
, SDL_Rect
*srcrect
,
69 SDL_Surface
*dst
, SDL_Rect
*dstrect
);
70 static int DirectFB_SetHWColorKey(_THIS
, SDL_Surface
*surface
, Uint32 key
);
71 static int DirectFB_SetHWAlpha(_THIS
, SDL_Surface
*surface
, Uint8 alpha
);
72 static int DirectFB_FlipHWSurface(_THIS
, SDL_Surface
*surface
);
73 static int DirectFB_ShowWMCursor(_THIS
, WMcursor
*cursor
);
75 /* Various screen update functions available */
76 static void DirectFB_DirectUpdate(_THIS
, int numrects
, SDL_Rect
*rects
);
77 static void DirectFB_WindowedUpdate(_THIS
, int numrects
, SDL_Rect
*rects
);
79 /* This is the rect EnumModes2 uses */
80 struct DirectFBEnumRect
{
82 struct DirectFBEnumRect
* next
;
85 static struct DirectFBEnumRect
*enumlist
= NULL
;
88 /* DirectFB driver bootstrap functions */
90 static int DirectFB_Available(void)
95 static void DirectFB_DeleteDevice(SDL_VideoDevice
*device
)
97 SDL_free(device
->hidden
);
101 static SDL_VideoDevice
*DirectFB_CreateDevice(int devindex
)
103 SDL_VideoDevice
*device
;
105 /* Initialize all variables that we clean on shutdown */
106 device
= (SDL_VideoDevice
*)SDL_malloc(sizeof(SDL_VideoDevice
));
109 SDL_memset (device
, 0, (sizeof *device
));
110 device
->hidden
= (struct SDL_PrivateVideoData
*) malloc (sizeof (*device
->hidden
));
112 if (device
== NULL
|| device
->hidden
== NULL
)
121 SDL_memset (device
->hidden
, 0, sizeof (*device
->hidden
));
123 /* Set the function pointers */
124 device
->VideoInit
= DirectFB_VideoInit
;
125 device
->ListModes
= DirectFB_ListModes
;
126 device
->SetVideoMode
= DirectFB_SetVideoMode
;
127 device
->SetColors
= DirectFB_SetColors
;
128 device
->UpdateRects
= NULL
;
129 device
->CreateYUVOverlay
= DirectFB_CreateYUVOverlay
;
130 device
->VideoQuit
= DirectFB_VideoQuit
;
131 device
->AllocHWSurface
= DirectFB_AllocHWSurface
;
132 device
->CheckHWBlit
= DirectFB_CheckHWBlit
;
133 device
->FillHWRect
= DirectFB_FillHWRect
;
134 device
->SetHWColorKey
= DirectFB_SetHWColorKey
;
135 device
->SetHWAlpha
= DirectFB_SetHWAlpha
;
136 device
->LockHWSurface
= DirectFB_LockHWSurface
;
137 device
->UnlockHWSurface
= DirectFB_UnlockHWSurface
;
138 device
->FlipHWSurface
= DirectFB_FlipHWSurface
;
139 device
->FreeHWSurface
= DirectFB_FreeHWSurface
;
140 device
->ShowWMCursor
= DirectFB_ShowWMCursor
;
141 device
->SetCaption
= NULL
;
142 device
->SetIcon
= NULL
;
143 device
->IconifyWindow
= NULL
;
144 device
->GrabInput
= NULL
;
145 device
->GetWMInfo
= NULL
;
146 device
->InitOSKeymap
= DirectFB_InitOSKeymap
;
147 device
->PumpEvents
= DirectFB_PumpEvents
;
149 device
->free
= DirectFB_DeleteDevice
;
154 VideoBootStrap DirectFB_bootstrap
= {
155 "directfb", "DirectFB",
156 DirectFB_Available
, DirectFB_CreateDevice
159 static DFBSurfacePixelFormat
GetFormatForBpp (int bpp
, IDirectFBDisplayLayer
*layer
)
161 DFBDisplayLayerConfig dlc
;
162 int bytes
= (bpp
+ 7) / 8;
164 layer
->GetConfiguration (layer
, &dlc
);
166 if (bytes
== DFB_BYTES_PER_PIXEL(dlc
.pixelformat
) && bytes
> 1)
167 return dlc
.pixelformat
;
184 static DFBEnumerationResult
EnumModesCallback (int width
,
189 SDL_VideoDevice
*this = (SDL_VideoDevice
*)data
;
190 struct DirectFBEnumRect
*enumrect
;
194 if (enumlist
&& enumlist
->r
.w
== width
&& enumlist
->r
.h
== height
)
197 enumrect
= SDL_calloc(1, sizeof(struct DirectFBEnumRect
));
201 return DFENUM_CANCEL
;
204 enumrect
->r
.w
= (Uint16
)width
;
205 enumrect
->r
.h
= (Uint16
)height
;
206 enumrect
->next
= enumlist
;
213 struct private_hwdata
{
214 IDirectFBSurface
*surface
;
215 IDirectFBPalette
*palette
;
218 void SetDirectFBerror (const char *function
, DFBResult code
)
220 const char *error
= DirectFBErrorString (code
);
223 SDL_SetError("%s: %s", function
, error
);
225 SDL_SetError("Unknown error code from %s", function
);
228 static DFBSurfacePixelFormat
SDLToDFBPixelFormat (SDL_PixelFormat
*format
)
230 if (format
->Rmask
&& format
->Gmask
&& format
->Bmask
)
232 switch (format
->BitsPerPixel
)
238 if (format
->Rmask
== 0xF800 &&
239 format
->Gmask
== 0x07E0 &&
240 format
->Bmask
== 0x001F)
245 if (format
->Rmask
== 0x7C00 &&
246 format
->Gmask
== 0x03E0 &&
247 format
->Bmask
== 0x001F)
248 return DSPF_ARGB1555
;
252 if (format
->Rmask
== 0xFF0000 &&
253 format
->Gmask
== 0x00FF00 &&
254 format
->Bmask
== 0x0000FF)
259 if (format
->Rmask
== 0xFF0000 &&
260 format
->Gmask
== 0x00FF00 &&
261 format
->Bmask
== 0x0000FF)
263 if (format
->Amask
== 0xFF000000)
273 switch (format
->BitsPerPixel
)
278 return DSPF_ARGB1555
;
291 static SDL_Palette
*AllocatePalette(int size
)
293 SDL_Palette
*palette
;
296 palette
= SDL_calloc (1, sizeof(SDL_Palette
));
303 colors
= SDL_calloc (size
, sizeof(SDL_Color
));
310 palette
->ncolors
= size
;
311 palette
->colors
= colors
;
316 static int DFBToSDLPixelFormat (DFBSurfacePixelFormat pixelformat
, SDL_PixelFormat
*format
)
318 format
->Amask
= format
->Rmask
= format
->Gmask
= format
->Bmask
= 0;
319 format
->BitsPerPixel
= format
->BytesPerPixel
= 0;
324 format
->Amask
= 0x000000FF;
328 format
->Rmask
= 0x00007C00;
329 format
->Gmask
= 0x000003E0;
330 format
->Bmask
= 0x0000001F;
334 format
->Rmask
= 0x0000F800;
335 format
->Gmask
= 0x000007E0;
336 format
->Bmask
= 0x0000001F;
340 format
->Amask
= 0; /* apps don't seem to like that: 0xFF000000; */
344 format
->Rmask
= 0x00FF0000;
345 format
->Gmask
= 0x0000FF00;
346 format
->Bmask
= 0x000000FF;
350 format
->Rmask
= 0x000000FF;
351 format
->Gmask
= 0x000000FF;
352 format
->Bmask
= 0x000000FF;
354 if (!format
->palette
)
355 format
->palette
= AllocatePalette(256);
359 fprintf (stderr
, "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n", pixelformat
);
363 format
->BitsPerPixel
= DFB_BYTES_PER_PIXEL(pixelformat
) * 8;
364 format
->BytesPerPixel
= DFB_BYTES_PER_PIXEL(pixelformat
);
370 int DirectFB_VideoInit(_THIS
, SDL_PixelFormat
*vformat
)
374 #if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
375 DFBCardCapabilities caps
;
377 DFBGraphicsDeviceDescription caps
;
379 DFBDisplayLayerConfig dlc
;
380 struct DirectFBEnumRect
*rect
;
381 IDirectFB
*dfb
= NULL
;
382 IDirectFBDisplayLayer
*layer
= NULL
;
383 IDirectFBEventBuffer
*events
= NULL
;
385 HIDDEN
->c2layer
= NULL
, HIDDEN
->c2frame
= NULL
;
386 HIDDEN
->enable_mga_crtc2
= 0;
387 HIDDEN
->mga_crtc2_stretch_overscan
= 1;
389 ret
= DirectFBInit (NULL
, NULL
);
392 SetDirectFBerror ("DirectFBInit", ret
);
396 ret
= DirectFBCreate (&dfb
);
399 SetDirectFBerror ("DirectFBCreate", ret
);
403 ret
= dfb
->GetDisplayLayer (dfb
, DLID_PRIMARY
, &layer
);
406 SetDirectFBerror ("dfb->GetDisplayLayer", ret
);
410 ret
= dfb
->CreateInputEventBuffer (dfb
, DICAPS_ALL
, DFB_FALSE
, &events
);
413 SetDirectFBerror ("dfb->CreateEventBuffer", ret
);
417 layer
->EnableCursor (layer
, 1);
419 /* Query layer configuration to determine the current mode and pixelformat */
420 layer
->GetConfiguration (layer
, &dlc
);
422 /* If current format is not supported use LUT8 as the default */
423 if (DFBToSDLPixelFormat (dlc
.pixelformat
, vformat
))
424 DFBToSDLPixelFormat (DSPF_LUT8
, vformat
);
426 /* Enumerate the available fullscreen modes */
427 ret
= dfb
->EnumVideoModes (dfb
, EnumModesCallback
, this);
430 SetDirectFBerror ("dfb->EnumVideoModes", ret
);
434 HIDDEN
->modelist
= SDL_calloc (HIDDEN
->nummodes
+ 1, sizeof(SDL_Rect
*));
435 if (!HIDDEN
->modelist
)
441 for (i
= 0, rect
= enumlist
; rect
; ++i
, rect
= rect
->next
)
443 HIDDEN
->modelist
[i
] = &rect
->r
;
446 HIDDEN
->modelist
[i
] = NULL
;
449 /* Query card capabilities to get the video memory size */
450 #if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
451 dfb
->GetCardCapabilities (dfb
, &caps
);
453 dfb
->GetDeviceDescription (dfb
, &caps
);
456 this->info
.wm_available
= 1;
457 this->info
.hw_available
= 1;
458 this->info
.blit_hw
= 1;
459 this->info
.blit_hw_CC
= 1;
460 this->info
.blit_hw_A
= 1;
461 this->info
.blit_fill
= 1;
462 this->info
.video_mem
= caps
.video_memory
/ 1024;
463 this->info
.current_w
= dlc
.width
;
464 this->info
.current_h
= dlc
.height
;
466 HIDDEN
->initialized
= 1;
468 HIDDEN
->layer
= layer
;
469 HIDDEN
->eventbuffer
= events
;
471 if (SDL_getenv("SDL_DIRECTFB_MGA_CRTC2") != NULL
)
472 HIDDEN
->enable_mga_crtc2
= 1;
474 if (HIDDEN
->enable_mga_crtc2
)
476 DFBDisplayLayerConfig dlc
;
477 DFBDisplayLayerConfigFlags failed
;
479 ret
= dfb
->GetDisplayLayer (dfb
, 2, &HIDDEN
->c2layer
);
482 SetDirectFBerror ("dfb->GetDisplayLayer(CRTC2)", ret
);
486 ret
= HIDDEN
->layer
->SetCooperativeLevel(HIDDEN
->layer
, DLSCL_EXCLUSIVE
);
489 SetDirectFBerror ("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret
);
493 ret
= HIDDEN
->c2layer
->SetCooperativeLevel(HIDDEN
->c2layer
, DLSCL_EXCLUSIVE
);
496 SetDirectFBerror ("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret
);
500 HIDDEN
->c2layer
->SetOpacity(HIDDEN
->c2layer
, 0x0);
502 /* Init the surface here as it got a fixed size */
503 dlc
.flags
= DLCONF_PIXELFORMAT
| DLCONF_BUFFERMODE
;
504 dlc
.buffermode
= DLBM_BACKVIDEO
;
505 dlc
.pixelformat
= DSPF_RGB32
;
507 ret
= HIDDEN
->c2layer
->TestConfiguration( HIDDEN
->c2layer
, &dlc
, &failed
);
510 SetDirectFBerror ("c2layer->TestConfiguration", ret
);
514 ret
= HIDDEN
->c2layer
->SetConfiguration( HIDDEN
->c2layer
, &dlc
);
517 SetDirectFBerror ("c2layer->SetConfiguration", ret
);
521 ret
= HIDDEN
->c2layer
->GetSurface( HIDDEN
->c2layer
, &HIDDEN
->c2frame
);
524 SetDirectFBerror ("c2layer->GetSurface", ret
);
528 HIDDEN
->c2framesize
.x
= 0;
529 HIDDEN
->c2framesize
.y
= 0;
530 HIDDEN
->c2frame
->GetSize( HIDDEN
->c2frame
, &HIDDEN
->c2framesize
.w
, &HIDDEN
->c2framesize
.h
);
532 HIDDEN
->c2frame
->SetBlittingFlags( HIDDEN
->c2frame
, DSBLIT_NOFX
);
533 HIDDEN
->c2frame
->SetColor( HIDDEN
->c2frame
, 0, 0, 0, 0xff );
536 HIDDEN
->c2frame
->Clear(HIDDEN
->c2frame
, 0, 0, 0, 0xff );
537 HIDDEN
->c2frame
->Flip(HIDDEN
->c2frame
, NULL
, 0 );
538 HIDDEN
->c2frame
->Clear(HIDDEN
->c2frame
, 0, 0, 0, 0xff );
539 HIDDEN
->c2frame
->Flip(HIDDEN
->c2frame
, NULL
, 0 );
540 HIDDEN
->c2frame
->Clear(HIDDEN
->c2frame
, 0, 0, 0, 0xff );
542 HIDDEN
->c2layer
->SetOpacity(HIDDEN
->c2layer
, 0xFF );
544 /* Check if overscan is possibly set */
545 if (SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN") != NULL
)
548 if (SDL_sscanf(SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN"), "%f", &overscan
) == 1)
549 if (overscan
> 0 && overscan
< 2)
550 HIDDEN
->mga_crtc2_stretch_overscan
= overscan
;
553 #ifdef DIRECTFB_CRTC2_DEBUG
554 printf("CRTC2 overscan: %f\n", HIDDEN
->mga_crtc2_stretch_overscan
);
562 events
->Release (events
);
565 HIDDEN
->c2frame
->Release (HIDDEN
->c2frame
);
568 HIDDEN
->c2layer
->Release (HIDDEN
->c2layer
);
571 layer
->Release (layer
);
579 static SDL_Rect
**DirectFB_ListModes(_THIS
, SDL_PixelFormat
*format
, Uint32 flags
)
581 if (flags
& SDL_FULLSCREEN
)
582 return HIDDEN
->modelist
;
584 if (SDLToDFBPixelFormat (format
) != DSPF_UNKNOWN
)
585 return (SDL_Rect
**) -1;
590 static SDL_Surface
*DirectFB_SetVideoMode(_THIS
, SDL_Surface
*current
, int width
, int height
, int bpp
, Uint32 flags
)
593 DFBSurfaceDescription dsc
;
594 DFBSurfacePixelFormat pixelformat
;
595 IDirectFBSurface
*surface
;
597 fprintf (stderr
, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n",
598 width
, height
, bpp
, flags
);
600 flags
|= SDL_FULLSCREEN
;
602 /* Release previous primary surface */
603 if (current
->hwdata
&& current
->hwdata
->surface
)
605 current
->hwdata
->surface
->Release (current
->hwdata
->surface
);
606 current
->hwdata
->surface
= NULL
;
608 /* And its palette if present */
609 if (current
->hwdata
->palette
)
611 current
->hwdata
->palette
->Release (current
->hwdata
->palette
);
612 current
->hwdata
->palette
= NULL
;
615 else if (!current
->hwdata
)
617 /* Allocate the hardware acceleration data */
618 current
->hwdata
= (struct private_hwdata
*) SDL_calloc (1, sizeof(*current
->hwdata
));
619 if (!current
->hwdata
)
626 /* Set cooperative level depending on flag SDL_FULLSCREEN */
627 if (flags
& SDL_FULLSCREEN
)
629 ret
= HIDDEN
->dfb
->SetCooperativeLevel (HIDDEN
->dfb
, DFSCL_FULLSCREEN
);
630 if (ret
&& !HIDDEN
->enable_mga_crtc2
)
632 DirectFBError ("dfb->SetCooperativeLevel", ret
);
633 flags
&= ~SDL_FULLSCREEN
;
637 HIDDEN
->dfb
->SetCooperativeLevel (HIDDEN
->dfb
, DFSCL_NORMAL
);
640 ret
= HIDDEN
->dfb
->SetVideoMode (HIDDEN
->dfb
, width
, height
, bpp
);
643 if (flags
& SDL_FULLSCREEN
)
645 flags
&= ~SDL_FULLSCREEN
;
646 HIDDEN
->dfb
->SetCooperativeLevel (HIDDEN
->dfb
, DFSCL_NORMAL
);
647 ret
= HIDDEN
->dfb
->SetVideoMode (HIDDEN
->dfb
, width
, height
, bpp
);
652 SetDirectFBerror ("dfb->SetVideoMode", ret
);
657 /* Create primary surface */
658 dsc
.flags
= DSDESC_CAPS
| DSDESC_PIXELFORMAT
;
659 dsc
.caps
= DSCAPS_PRIMARY
| ((flags
& SDL_DOUBLEBUF
) ? DSCAPS_FLIPPING
: 0);
660 dsc
.pixelformat
= GetFormatForBpp (bpp
, HIDDEN
->layer
);
662 ret
= HIDDEN
->dfb
->CreateSurface (HIDDEN
->dfb
, &dsc
, &surface
);
663 if (ret
&& (flags
& SDL_DOUBLEBUF
))
665 /* Try without double buffering */
666 dsc
.caps
&= ~DSCAPS_FLIPPING
;
667 ret
= HIDDEN
->dfb
->CreateSurface (HIDDEN
->dfb
, &dsc
, &surface
);
671 SetDirectFBerror ("dfb->CreateSurface", ret
);
677 current
->flags
= SDL_HWSURFACE
| SDL_PREALLOC
;
679 if (flags
& SDL_FULLSCREEN
)
681 current
->flags
|= SDL_FULLSCREEN
;
682 this->UpdateRects
= DirectFB_DirectUpdate
;
685 this->UpdateRects
= DirectFB_WindowedUpdate
;
687 if (dsc
.caps
& DSCAPS_FLIPPING
)
688 current
->flags
|= SDL_DOUBLEBUF
;
690 surface
->GetPixelFormat (surface
, &pixelformat
);
692 DFBToSDLPixelFormat (pixelformat
, current
->format
);
694 /* Get the surface palette (if supported) */
695 if (DFB_PIXELFORMAT_IS_INDEXED( pixelformat
))
697 surface
->GetPalette (surface
, ¤t
->hwdata
->palette
);
699 current
->flags
|= SDL_HWPALETTE
;
702 current
->hwdata
->surface
= surface
;
704 /* MGA CRTC2 stuff */
705 if (HIDDEN
->enable_mga_crtc2
)
707 /* no stretching if c2ssize == c2framesize */
708 HIDDEN
->c2ssize
.x
= 0, HIDDEN
->c2ssize
.y
= 0;
709 HIDDEN
->c2ssize
.w
= width
;
710 HIDDEN
->c2ssize
.h
= height
;
712 HIDDEN
->c2dsize
.x
= 0, HIDDEN
->c2dsize
.y
= 0;
713 HIDDEN
->c2dsize
.w
= width
;
714 HIDDEN
->c2dsize
.h
= height
;
716 HIDDEN
->mga_crtc2_stretch
= 0;
718 if (SDL_getenv("SDL_DIRECTFB_MGA_STRETCH") != NULL
)
720 /* Normally assume a picture aspect ratio of 4:3 */
721 int zoom_aspect_x
= 4, zoom_aspect_y
= 3, i
, j
;
723 for (i
= 1; i
< 20; i
++)
725 for (j
= 1; j
< 10; j
++)
727 if ((float)width
/(float)i
*(float)j
== height
)
739 #ifdef DIRECTFB_CRTC2_DEBUG
740 printf("Source resolution: X: %d, Y: %d, Aspect ratio: %d:%d\n", width
, height
, zoom_aspect_x
, zoom_aspect_y
);
741 printf("CRTC2 resolution: X: %d, Y: %d\n", HIDDEN
->c2framesize
.w
, HIDDEN
->c2framesize
.h
);
744 /* don't stretch only slightly smaller/larger images */
745 if ((float)width
< (float)HIDDEN
->c2framesize
.w
*0.95 || (float)height
< (float)HIDDEN
->c2framesize
.h
*0.95)
747 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
)
749 HIDDEN
->c2dsize
.w
+=zoom_aspect_x
;
750 HIDDEN
->c2dsize
.h
+=zoom_aspect_y
;
754 HIDDEN
->c2dsize
.w
-=zoom_aspect_x
;
755 HIDDEN
->c2dsize
.h
-=zoom_aspect_y
;
757 #ifdef DIRECTFB_CRTC2_DEBUG
758 printf("Stretched resolution: X: %d, Y: %d\n", HIDDEN
->c2dsize
.w
, HIDDEN
->c2dsize
.h
);
761 HIDDEN
->mga_crtc2_stretch
= 1;
763 else if ((float)width
> (float)HIDDEN
->c2framesize
.w
*0.95 || (float)height
> (float)HIDDEN
->c2framesize
.h
*0.95)
765 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
)
767 HIDDEN
->c2dsize
.w
-=zoom_aspect_x
;
768 HIDDEN
->c2dsize
.h
-=zoom_aspect_y
;
771 #ifdef DIRECTFB_CRTC2_DEBUG
772 printf("Down-Stretched resolution: X: %d, Y: %d\n", HIDDEN
->c2dsize
.w
, HIDDEN
->c2dsize
.h
);
775 HIDDEN
->mga_crtc2_stretch
= 1;
777 #ifdef DIRECTFB_CRTC2_DEBUG
778 printf("Not stretching image\n");
783 if (HIDDEN
->c2framesize
.w
> HIDDEN
->c2dsize
.w
)
784 HIDDEN
->c2dsize
.x
= (HIDDEN
->c2framesize
.w
- HIDDEN
->c2dsize
.w
) / 2;
786 HIDDEN
->c2dsize
.x
= (HIDDEN
->c2dsize
.w
- HIDDEN
->c2framesize
.w
) / 2;
788 if (HIDDEN
->c2framesize
.h
> HIDDEN
->c2dsize
.h
)
789 HIDDEN
->c2dsize
.y
= (HIDDEN
->c2framesize
.h
- HIDDEN
->c2dsize
.h
) / 2;
791 HIDDEN
->c2dsize
.y
= (HIDDEN
->c2dsize
.h
- HIDDEN
->c2framesize
.h
) / 2;
793 #ifdef DIRECTFB_CRTC2_DEBUG
794 printf("CRTC2 position X: %d, Y: %d\n", HIDDEN
->c2dsize
.x
, HIDDEN
->c2dsize
.y
);
802 static int DirectFB_AllocHWSurface(_THIS
, SDL_Surface
*surface
)
805 DFBSurfaceDescription dsc
;
807 /* fprintf(stderr, "SDL: DirectFB_AllocHWSurface (%dx%d@%d, flags: 0x%08x)\n",
808 surface->w, surface->h, surface->format->BitsPerPixel, surface->flags);*/
810 if (surface
->w
< 8 || surface
->h
< 8)
813 /* fill surface description */
814 dsc
.flags
= DSDESC_WIDTH
| DSDESC_HEIGHT
| DSDESC_PIXELFORMAT
| DSDESC_CAPS
;
815 dsc
.width
= surface
->w
;
816 dsc
.height
= surface
->h
;
817 dsc
.caps
= (surface
->flags
& SDL_DOUBLEBUF
) ? DSCAPS_FLIPPING
: 0;
819 /* find the right pixelformat */
820 dsc
.pixelformat
= SDLToDFBPixelFormat (surface
->format
);
821 if (dsc
.pixelformat
== DSPF_UNKNOWN
)
824 /* Allocate the hardware acceleration data */
825 surface
->hwdata
= (struct private_hwdata
*) SDL_calloc (1, sizeof(*surface
->hwdata
));
826 if (surface
->hwdata
== NULL
)
832 /* Create the surface */
833 ret
= HIDDEN
->dfb
->CreateSurface (HIDDEN
->dfb
, &dsc
, &surface
->hwdata
->surface
);
836 SetDirectFBerror ("dfb->CreateSurface", ret
);
837 free (surface
->hwdata
);
838 surface
->hwdata
= NULL
;
842 surface
->flags
|= SDL_HWSURFACE
| SDL_PREALLOC
;
847 static void DirectFB_FreeHWSurface(_THIS
, SDL_Surface
*surface
)
849 if (surface
->hwdata
&& HIDDEN
->initialized
)
851 surface
->hwdata
->surface
->Release (surface
->hwdata
->surface
);
852 free (surface
->hwdata
);
853 surface
->hwdata
= NULL
;
857 static int DirectFB_CheckHWBlit(_THIS
, SDL_Surface
*src
, SDL_Surface
*dst
)
859 /* fprintf(stderr, "SDL: DirectFB_CheckHWBlit (src->hwdata: %p, dst->hwdata: %p)\n",
860 src->hwdata, dst->hwdata);*/
862 if (!src
->hwdata
|| !dst
->hwdata
)
865 src
->flags
|= SDL_HWACCEL
;
866 src
->map
->hw_blit
= DirectFB_HWAccelBlit
;
871 static int DirectFB_HWAccelBlit(SDL_Surface
*src
, SDL_Rect
*srcrect
,
872 SDL_Surface
*dst
, SDL_Rect
*dstrect
)
874 DFBSurfaceBlittingFlags flags
= DSBLIT_NOFX
;
876 DFBRectangle sr
= { srcrect
->x
, srcrect
->y
, srcrect
->w
, srcrect
->h
};
877 DFBRectangle dr
= { dstrect
->x
, dstrect
->y
, dstrect
->w
, dstrect
->h
};
879 IDirectFBSurface
*surface
= dst
->hwdata
->surface
;
881 if (src
->flags
& SDL_SRCCOLORKEY
)
883 flags
|= DSBLIT_SRC_COLORKEY
;
884 DirectFB_SetHWColorKey (NULL
, src
, src
->format
->colorkey
);
887 if (src
->flags
& SDL_SRCALPHA
)
889 flags
|= DSBLIT_BLEND_COLORALPHA
;
890 surface
->SetColor (surface
, 0xff, 0xff, 0xff, src
->format
->alpha
);
893 surface
->SetBlittingFlags (surface
, flags
);
895 if (sr
.w
== dr
.w
&& sr
.h
== dr
.h
)
896 surface
->Blit (surface
, src
->hwdata
->surface
, &sr
, dr
.x
, dr
.y
);
898 surface
->StretchBlit (surface
, src
->hwdata
->surface
, &sr
, &dr
);
903 static int DirectFB_FillHWRect(_THIS
, SDL_Surface
*dst
, SDL_Rect
*dstrect
, Uint32 color
)
905 SDL_PixelFormat
*fmt
= dst
->format
;
906 IDirectFBSurface
*surface
= dst
->hwdata
->surface
;
909 surface
->SetColor (surface
,
910 (color
& fmt
->Rmask
) >> (fmt
->Rshift
- fmt
->Rloss
),
911 (color
& fmt
->Gmask
) >> (fmt
->Gshift
- fmt
->Gloss
),
912 (color
& fmt
->Bmask
) << (fmt
->Bloss
- fmt
->Bshift
), 0xFF);
913 surface
->FillRectangle (surface
, dstrect
->x
, dstrect
->y
, dstrect
->w
, dstrect
->h
);
918 static int DirectFB_SetHWColorKey(_THIS
, SDL_Surface
*src
, Uint32 key
)
920 SDL_PixelFormat
*fmt
= src
->format
;
921 IDirectFBSurface
*surface
= src
->hwdata
->surface
;
923 if (fmt
->BitsPerPixel
== 8)
924 surface
->SetSrcColorKeyIndex (surface
, key
);
927 surface
->SetSrcColorKey (surface
,
928 (key
& fmt
->Rmask
) >> (fmt
->Rshift
- fmt
->Rloss
),
929 (key
& fmt
->Gmask
) >> (fmt
->Gshift
- fmt
->Gloss
),
930 (key
& fmt
->Bmask
) << (fmt
->Bloss
- fmt
->Bshift
));
935 static int DirectFB_SetHWAlpha(_THIS
, SDL_Surface
*surface
, Uint8 alpha
)
940 static int DirectFB_FlipHWSurface(_THIS
, SDL_Surface
*surface
)
942 if (HIDDEN
->enable_mga_crtc2
)
944 int rtn
= surface
->hwdata
->surface
->Flip (surface
->hwdata
->surface
, NULL
, 0);
945 if (HIDDEN
->mga_crtc2_stretch
)
946 HIDDEN
->c2frame
->StretchBlit(HIDDEN
->c2frame
, surface
->hwdata
->surface
, &HIDDEN
->c2ssize
, &HIDDEN
->c2dsize
);
948 HIDDEN
->c2frame
->Blit(HIDDEN
->c2frame
, surface
->hwdata
->surface
, NULL
, HIDDEN
->c2dsize
.x
, HIDDEN
->c2dsize
.y
);
950 HIDDEN
->c2frame
->Flip(HIDDEN
->c2frame
, NULL
, DSFLIP_WAITFORSYNC
);
954 return surface
->hwdata
->surface
->Flip (surface
->hwdata
->surface
, NULL
, DSFLIP_WAITFORSYNC
);
957 static int DirectFB_LockHWSurface(_THIS
, SDL_Surface
*surface
)
963 ret
= surface
->hwdata
->surface
->Lock (surface
->hwdata
->surface
,
964 DSLF_WRITE
, &data
, &pitch
);
967 SetDirectFBerror ("surface->Lock", ret
);
971 surface
->pixels
= data
;
972 surface
->pitch
= pitch
;
977 static void DirectFB_UnlockHWSurface(_THIS
, SDL_Surface
*surface
)
979 surface
->hwdata
->surface
->Unlock (surface
->hwdata
->surface
);
980 surface
->pixels
= NULL
;
983 static void DirectFB_DirectUpdate(_THIS
, int numrects
, SDL_Rect
*rects
)
985 if (HIDDEN
->enable_mga_crtc2
)
987 if (HIDDEN
->mga_crtc2_stretch
)
988 HIDDEN
->c2frame
->StretchBlit(HIDDEN
->c2frame
, this->screen
->hwdata
->surface
, &HIDDEN
->c2ssize
, &HIDDEN
->c2dsize
);
990 HIDDEN
->c2frame
->Blit(HIDDEN
->c2frame
, this->screen
->hwdata
->surface
, NULL
, HIDDEN
->c2dsize
.x
, HIDDEN
->c2dsize
.y
);
992 HIDDEN
->c2frame
->Flip(HIDDEN
->c2frame
, NULL
, DSFLIP_WAITFORSYNC
);
996 static void DirectFB_WindowedUpdate(_THIS
, int numrects
, SDL_Rect
*rects
)
1000 int region_valid
= 0;
1001 IDirectFBSurface
*surface
= this->screen
->hwdata
->surface
;
1003 for (i
=0; i
<numrects
; ++i
)
1007 if ( ! rects
[i
].w
) /* Clipped? */
1010 x2
= rects
[i
].x
+ rects
[i
].w
- 1;
1011 y2
= rects
[i
].y
+ rects
[i
].h
- 1;
1015 if (rects
[i
].x
< region
.x1
)
1016 region
.x1
= rects
[i
].x
;
1018 if (rects
[i
].y
< region
.y1
)
1019 region
.y1
= rects
[i
].y
;
1029 region
.x1
= rects
[i
].x
;
1030 region
.y1
= rects
[i
].y
;
1040 if (HIDDEN
->enable_mga_crtc2
)
1042 if (HIDDEN
->mga_crtc2_stretch
)
1043 HIDDEN
->c2frame
->StretchBlit(HIDDEN
->c2frame
, surface
, &HIDDEN
->c2ssize
, &HIDDEN
->c2dsize
);
1045 HIDDEN
->c2frame
->Blit(HIDDEN
->c2frame
, surface
, NULL
, HIDDEN
->c2dsize
.x
, HIDDEN
->c2dsize
.y
);
1047 HIDDEN
->c2frame
->Flip(HIDDEN
->c2frame
, NULL
, DSFLIP_WAITFORSYNC
);
1050 surface
->Flip (surface
, ®ion
, DSFLIP_WAITFORSYNC
);
1054 int DirectFB_SetColors(_THIS
, int firstcolor
, int ncolors
, SDL_Color
*colors
)
1056 IDirectFBPalette
*palette
= this->screen
->hwdata
->palette
;
1061 if (firstcolor
> 255)
1064 if (firstcolor
+ ncolors
> 256)
1065 ncolors
= 256 - firstcolor
;
1070 DFBColor entries
[ncolors
];
1072 for (i
=0; i
<ncolors
; i
++)
1074 entries
[i
].a
= 0xff;
1075 entries
[i
].r
= colors
[i
].r
;
1076 entries
[i
].g
= colors
[i
].g
;
1077 entries
[i
].b
= colors
[i
].b
;
1080 palette
->SetEntries (palette
, entries
, ncolors
, firstcolor
);
1086 void DirectFB_VideoQuit(_THIS
)
1088 struct DirectFBEnumRect
*rect
= enumlist
;
1090 if (this->screen
&& this->screen
->hwdata
)
1092 IDirectFBSurface
*surface
= this->screen
->hwdata
->surface
;
1093 IDirectFBPalette
*palette
= this->screen
->hwdata
->palette
;
1096 palette
->Release (palette
);
1099 surface
->Release (surface
);
1101 this->screen
->hwdata
->surface
= NULL
;
1102 this->screen
->hwdata
->palette
= NULL
;
1105 if (HIDDEN
->c2frame
)
1107 HIDDEN
->c2frame
->Release (HIDDEN
->c2frame
);
1108 HIDDEN
->c2frame
= NULL
;
1111 if (HIDDEN
->eventbuffer
)
1113 HIDDEN
->eventbuffer
->Release (HIDDEN
->eventbuffer
);
1114 HIDDEN
->eventbuffer
= NULL
;
1117 if (HIDDEN
->c2layer
)
1119 HIDDEN
->c2layer
->Release (HIDDEN
->c2layer
);
1120 HIDDEN
->c2layer
= NULL
;
1125 HIDDEN
->layer
->Release (HIDDEN
->layer
);
1126 HIDDEN
->layer
= NULL
;
1131 HIDDEN
->dfb
->Release (HIDDEN
->dfb
);
1135 /* Free video mode list */
1136 if (HIDDEN
->modelist
)
1138 free (HIDDEN
->modelist
);
1139 HIDDEN
->modelist
= NULL
;
1142 /* Free mode enumeration list */
1145 struct DirectFBEnumRect
*next
= rect
->next
;
1151 HIDDEN
->initialized
= 0;
1155 int DirectFB_ShowWMCursor(_THIS
, WMcursor
*cursor
)
1157 /* We can only hide or show the default cursor */
1158 if ( cursor
== NULL
)
1160 HIDDEN
->layer
->SetCursorOpacity(HIDDEN
->layer
, 0x00);
1164 HIDDEN
->layer
->SetCursorOpacity(HIDDEN
->layer
, 0xFF);
1169 void DirectFB_FinalQuit(void)