Date: Sat, 11 Aug 2007 02:03:16 +0200 (CEST)
From: couriersud arcor.de To: slouken@libsdl.org Subject: Directfb driver for SDL1.3 Hi, the attachment contains a patch for a SDL1.3 directfb driver. It supports: - Renderer "directfb": Hardware acceleration as supported by the underlying directfb driver. With a radeon X850, testsprite2 runs at 50% to 70% of OpenGL (X11, dri) performance. Also supports hardware accelerated yuv overlays. This must be enabled by sett ing: export SDL_DIRECTFB_YUV_DIRECT=1 - Renderer "opengl" Supports software opengl using mesa opengl (make linux-directfb). Some more information may be found in README.DirectFB There will certainly still be some bugs, and there is some debug code around. When I find some time, I will compile against directfb-0.9.25 as distributed with ubuntu 7.04. The diff also contains a fix for SDL_LockYUVOverlay fixing a bug in *pixels and pitches initialization. Kind regards, couriersud --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402588
This commit is contained in:
parent
fa64b7b113
commit
2de3ba209d
12 changed files with 2297 additions and 1506 deletions
45
README.DirectFB
Normal file
45
README.DirectFB
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
SDL on DirectFB
|
||||||
|
|
||||||
|
Supports:
|
||||||
|
|
||||||
|
- Hardware YUV overlays
|
||||||
|
- OpenGL - software only
|
||||||
|
- 2D/3D accelerations (depends on directfb driver)
|
||||||
|
|
||||||
|
What you need:
|
||||||
|
|
||||||
|
DirectFB 1.0.0 - required
|
||||||
|
Kernel-Framebuffer support: required: vesafb, radeonfb ....
|
||||||
|
Mesa 7.0.x - optional for OpenGL
|
||||||
|
|
||||||
|
As of this writing 20070810 you need to pull Mesa from git and do the following:
|
||||||
|
|
||||||
|
------------------------
|
||||||
|
cd mesa
|
||||||
|
make linux-directfb
|
||||||
|
make
|
||||||
|
|
||||||
|
echo Installing - pleaser enter sudo pw.
|
||||||
|
|
||||||
|
sudo make install INSTALL_DIR=/usr/local/dfb_GL
|
||||||
|
cd src/mesa/drivers/directfb
|
||||||
|
make
|
||||||
|
sudo make install INSTALL_DIR=/usr/local/dfb_GL
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
To run the SDL - testprograms:
|
||||||
|
|
||||||
|
export SDL_VIDEODRIVER=directfb
|
||||||
|
export LD_LIBRARY_PATH=/usr/local/dfb_GL/lib
|
||||||
|
export LD_PRELOAD=/usr/local/dfb_GL/libGL.so.7
|
||||||
|
|
||||||
|
./testgl
|
||||||
|
|
||||||
|
To use hardware accelerated YUV-overlays for YUV-textures, use:
|
||||||
|
|
||||||
|
export SDL_DIRECTFB_YUV_DIRECT=1
|
||||||
|
|
||||||
|
This is disabled by default. It will only support one concurrent
|
||||||
|
overlay and may behave strange if not used with SDL_CreateYUvOverlay
|
||||||
|
from SDLcompat.c.
|
||||||
|
|
|
@ -1440,19 +1440,21 @@ SDL_LockYUVOverlay(SDL_Overlay * overlay)
|
||||||
< 0) {
|
< 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
overlay->pixels[0] = (Uint8 *) pixels;
|
||||||
|
overlay->pitches[0] = pitch;
|
||||||
switch (overlay->format) {
|
switch (overlay->format) {
|
||||||
case SDL_YV12_OVERLAY:
|
case SDL_YV12_OVERLAY:
|
||||||
case SDL_IYUV_OVERLAY:
|
case SDL_IYUV_OVERLAY:
|
||||||
overlay->pixels[0] = (Uint8 *) pixels;
|
overlay->pitches[1] = pitch / 2;
|
||||||
|
overlay->pitches[2] = pitch / 2;
|
||||||
overlay->pixels[1] =
|
overlay->pixels[1] =
|
||||||
overlay->pixels[0] + overlay->pitches[0] * overlay->h;
|
overlay->pixels[0] + overlay->pitches[0] * overlay->h;
|
||||||
overlay->pixels[2] =
|
overlay->pixels[2] =
|
||||||
overlay->pixels[1] + overlay->pitches[1] * overlay->h;
|
overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
|
||||||
break;
|
break;
|
||||||
case SDL_YUY2_OVERLAY:
|
case SDL_YUY2_OVERLAY:
|
||||||
case SDL_UYVY_OVERLAY:
|
case SDL_UYVY_OVERLAY:
|
||||||
case SDL_YVYU_OVERLAY:
|
case SDL_YVYU_OVERLAY:
|
||||||
overlay->pixels[0] = (Uint8 *) pixels;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -23,70 +23,97 @@
|
||||||
|
|
||||||
/* Handle the event stream, converting DirectFB input events into SDL events */
|
/* Handle the event stream, converting DirectFB input events into SDL events */
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <termios.h>
|
|
||||||
|
|
||||||
#include <directfb.h>
|
#include <directfb.h>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "../SDL_sysvideo.h"
|
#include "../SDL_sysvideo.h"
|
||||||
#include "../../events/SDL_sysevents.h"
|
#include "../../events/SDL_sysevents.h"
|
||||||
#include "../../events/SDL_events_c.h"
|
#include "../../events/SDL_events_c.h"
|
||||||
#include "SDL_DirectFB_video.h"
|
|
||||||
#include "SDL_DirectFB_events.h"
|
#include "SDL_DirectFB_events.h"
|
||||||
|
|
||||||
/* The translation tables from a DirectFB keycode to a SDL keysym */
|
/* The translation tables from a DirectFB keycode to a SDL keysym */
|
||||||
static SDLKey keymap[256];
|
static SDLKey keymap[256];
|
||||||
static SDL_keysym *DirectFB_TranslateKey(DFBInputEvent * ev,
|
|
||||||
|
static SDL_keysym *DirectFB_TranslateKey(DFBInputDeviceKeyIdentifier key_id,
|
||||||
|
DFBInputDeviceKeySymbol key_symbol,
|
||||||
|
DFBInputDeviceModifierMask key_mod,
|
||||||
SDL_keysym * keysym);
|
SDL_keysym * keysym);
|
||||||
static int DirectFB_TranslateButton(DFBInputEvent * ev);
|
|
||||||
|
|
||||||
static int posted = 0;
|
|
||||||
|
|
||||||
|
static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button);
|
||||||
|
|
||||||
void
|
void
|
||||||
DirectFB_PumpEvents(_THIS)
|
DirectFB_PumpEventsWindow(_THIS)
|
||||||
{
|
{
|
||||||
DFBInputEvent evt;
|
SDL_DFB_DEVICEDATA(_this);
|
||||||
|
DFB_WindowData *p;
|
||||||
|
DFBWindowEvent evt;
|
||||||
|
|
||||||
while (HIDDEN->eventbuffer->GetEvent(HIDDEN->eventbuffer,
|
for (p = devdata->firstwin; p != NULL; p = p->next) {
|
||||||
DFB_EVENT(&evt)) == DFB_OK) {
|
while (p->eventbuffer->GetEvent(p->eventbuffer,
|
||||||
SDL_keysym keysym;
|
DFB_EVENT(&evt)) == DFB_OK) {
|
||||||
|
SDL_keysym keysym;
|
||||||
|
|
||||||
switch (evt.type) {
|
if (evt.clazz = DFEC_WINDOW) {
|
||||||
case DIET_BUTTONPRESS:
|
switch (evt.type) {
|
||||||
posted += SDL_PrivateMouseButton(SDL_PRESSED,
|
case DWET_BUTTONDOWN:
|
||||||
DirectFB_TranslateButton
|
SDL_SendMouseButton(devdata->mouse, SDL_PRESSED,
|
||||||
(&evt), 0, 0);
|
DirectFB_TranslateButton(evt.button));
|
||||||
break;
|
break;
|
||||||
case DIET_BUTTONRELEASE:
|
case DWET_BUTTONUP:
|
||||||
posted += SDL_PrivateMouseButton(SDL_RELEASED,
|
SDL_SendMouseButton(devdata->mouse, SDL_RELEASED,
|
||||||
DirectFB_TranslateButton
|
DirectFB_TranslateButton(evt.button));
|
||||||
(&evt), 0, 0);
|
break;
|
||||||
break;
|
case DWET_MOTION:
|
||||||
case DIET_KEYPRESS:
|
SDL_SendMouseMotion(devdata->mouse, 0, evt.x, evt.y);
|
||||||
posted +=
|
break;
|
||||||
SDL_PrivateKeyboard(SDL_PRESSED,
|
case DWET_KEYDOWN:
|
||||||
DirectFB_TranslateKey(&evt, &keysym));
|
DirectFB_TranslateKey(evt.key_id, evt.key_symbol,
|
||||||
break;
|
evt.modifiers, &keysym);
|
||||||
case DIET_KEYRELEASE:
|
SDL_SendKeyboardKey(devdata->keyboard, SDL_PRESSED,
|
||||||
posted +=
|
keysym.scancode, keysym.sym);
|
||||||
SDL_PrivateKeyboard(SDL_RELEASED,
|
break;
|
||||||
DirectFB_TranslateKey(&evt, &keysym));
|
case DWET_KEYUP:
|
||||||
break;
|
DirectFB_TranslateKey(evt.key_id, evt.key_symbol,
|
||||||
case DIET_AXISMOTION:
|
evt.modifiers, &keysym);
|
||||||
if (evt.flags & DIEF_AXISREL) {
|
SDL_SendKeyboardKey(devdata->keyboard, SDL_RELEASED,
|
||||||
if (evt.axis == DIAI_X)
|
keysym.scancode, keysym.sym);
|
||||||
posted += SDL_PrivateMouseMotion(0, 1, evt.axisrel, 0);
|
break;
|
||||||
else if (evt.axis == DIAI_Y)
|
case DWET_POSITION_SIZE:
|
||||||
posted += SDL_PrivateMouseMotion(0, 1, 0, evt.axisrel);
|
SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED, evt.cx,
|
||||||
|
evt.cy);
|
||||||
|
SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED, evt.w,
|
||||||
|
evt.h);
|
||||||
|
break;
|
||||||
|
case DWET_POSITION:
|
||||||
|
SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_MOVED, evt.cx,
|
||||||
|
evt.cy);
|
||||||
|
break;
|
||||||
|
case DWET_SIZE:
|
||||||
|
SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_RESIZED, evt.w,
|
||||||
|
evt.h);
|
||||||
|
break;
|
||||||
|
case DWET_CLOSE:
|
||||||
|
SDL_SendWindowEvent(p->id, SDL_WINDOWEVENT_CLOSE, 0, 0);
|
||||||
|
break;
|
||||||
|
case DWET_GOTFOCUS:
|
||||||
|
//TODO: Implement for yuv-overlay DirectFB_SwitchOverlayContext(this, evt.window_id);
|
||||||
|
SDL_SetKeyboardFocus(devdata->keyboard, p->id);
|
||||||
|
break;
|
||||||
|
case DWET_LOSTFOCUS:
|
||||||
|
SDL_SetKeyboardFocus(devdata->keyboard, 0);
|
||||||
|
break;
|
||||||
|
case DWET_ENTER:
|
||||||
|
//SDL_DirectFB_ReshowCursor(_this, 0);
|
||||||
|
SDL_SetMouseFocus(devdata->mouse, p->id);
|
||||||
|
break;
|
||||||
|
case DWET_LEAVE:
|
||||||
|
SDL_SetMouseFocus(devdata->mouse, 0);
|
||||||
|
//SDL_DirectFB_ReshowCursor(_this, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,35 +204,80 @@ DirectFB_InitOSKeymap(_THIS)
|
||||||
keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDLK_SCROLLOCK;
|
keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDLK_SCROLLOCK;
|
||||||
keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDLK_PRINT;
|
keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDLK_PRINT;
|
||||||
keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDLK_PAUSE;
|
keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDLK_PAUSE;
|
||||||
|
|
||||||
|
keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDLK_KP_EQUALS;
|
||||||
|
keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDLK_KP_PERIOD;
|
||||||
|
keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDLK_KP0;
|
||||||
|
keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDLK_KP1;
|
||||||
|
keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDLK_KP2;
|
||||||
|
keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDLK_KP3;
|
||||||
|
keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDLK_KP4;
|
||||||
|
keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDLK_KP5;
|
||||||
|
keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDLK_KP6;
|
||||||
|
keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDLK_KP7;
|
||||||
|
keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDLK_KP8;
|
||||||
|
keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDLK_KP9;
|
||||||
keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDLK_KP_DIVIDE;
|
keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDLK_KP_DIVIDE;
|
||||||
keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDLK_KP_MULTIPLY;
|
keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDLK_KP_MULTIPLY;
|
||||||
keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDLK_KP_MINUS;
|
keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDLK_KP_MINUS;
|
||||||
keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDLK_KP_PLUS;
|
keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDLK_KP_PLUS;
|
||||||
keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDLK_KP_ENTER;
|
keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDLK_KP_ENTER;
|
||||||
|
|
||||||
|
keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDLK_BACKQUOTE; /* TLDE */
|
||||||
|
keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDLK_MINUS; /* AE11 */
|
||||||
|
keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDLK_EQUALS; /* AE12 */
|
||||||
|
keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDLK_RIGHTBRACKET; /* AD11 */
|
||||||
|
keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDLK_LEFTBRACKET; /* AD12 */
|
||||||
|
keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDLK_BACKSLASH; /* BKSL */
|
||||||
|
keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDLK_SEMICOLON; /* AC10 */
|
||||||
|
keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDLK_QUOTE; /* AC11 */
|
||||||
|
keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDLK_COMMA; /* AB08 */
|
||||||
|
keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDLK_PERIOD; /* AB09 */
|
||||||
|
keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDLK_SLASH; /* AB10 */
|
||||||
|
keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDLK_LESS; /* 103rd */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SDL_keysym *
|
static SDL_keysym *
|
||||||
DirectFB_TranslateKey(DFBInputEvent * ev, SDL_keysym * keysym)
|
DirectFB_TranslateKey(DFBInputDeviceKeyIdentifier key_id,
|
||||||
|
DFBInputDeviceKeySymbol key_symbol,
|
||||||
|
DFBInputDeviceModifierMask key_mod, SDL_keysym * keysym)
|
||||||
{
|
{
|
||||||
/* Set the keysym information */
|
SDLMod mod = KMOD_NONE;
|
||||||
keysym->scancode = ev->key_id;
|
|
||||||
keysym->mod = KMOD_NONE; /* FIXME */
|
|
||||||
keysym->unicode =
|
|
||||||
(DFB_KEY_TYPE(ev->key_symbol) == DIKT_UNICODE) ? ev->key_symbol : 0;
|
|
||||||
|
|
||||||
if (ev->key_symbol > 0 && ev->key_symbol < 128)
|
/*
|
||||||
keysym->sym = ev->key_symbol;
|
* Set modifier information
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (key_mod & DIMM_SHIFT)
|
||||||
|
mod = mod | KMOD_LSHIFT;
|
||||||
|
if (key_mod & DIMM_CONTROL)
|
||||||
|
mod = mod | KMOD_LCTRL;
|
||||||
|
if (key_mod & DIMM_ALT)
|
||||||
|
mod = mod | KMOD_LALT;
|
||||||
|
if (key_mod & DIMM_ALTGR)
|
||||||
|
mod = mod | KMOD_RALT;
|
||||||
|
if (key_mod & DIMM_META)
|
||||||
|
mod = mod | KMOD_LMETA;
|
||||||
|
|
||||||
|
/* Set the keysym information */
|
||||||
|
keysym->scancode = key_id;
|
||||||
|
|
||||||
|
keysym->mod = mod;
|
||||||
|
keysym->unicode =
|
||||||
|
(DFB_KEY_TYPE(key_symbol) == DIKT_UNICODE) ? key_symbol : 0;
|
||||||
|
|
||||||
|
if (key_symbol > 0 && key_symbol < 255)
|
||||||
|
keysym->sym = key_symbol;
|
||||||
else
|
else
|
||||||
keysym->sym = keymap[ev->key_id - DIKI_UNKNOWN];
|
keysym->sym = keymap[key_id - DIKI_UNKNOWN];
|
||||||
|
|
||||||
return keysym;
|
return keysym;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
DirectFB_TranslateButton(DFBInputEvent * ev)
|
DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)
|
||||||
{
|
{
|
||||||
switch (ev->button) {
|
switch (button) {
|
||||||
case DIBI_LEFT:
|
case DIBI_LEFT:
|
||||||
return 1;
|
return 1;
|
||||||
case DIBI_MIDDLE:
|
case DIBI_MIDDLE:
|
||||||
|
@ -217,4 +289,76 @@ DirectFB_TranslateButton(DFBInputEvent * ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
#if 0
|
||||||
|
void
|
||||||
|
DirectFB_PumpEvents(_THIS)
|
||||||
|
{
|
||||||
|
SDL_DFB_DEVICEDATA(_this);
|
||||||
|
DFBInputEvent evt;
|
||||||
|
static last_x = 0, last_y = 0;
|
||||||
|
|
||||||
|
while (devdata->eventbuffer->GetEvent(devdata->eventbuffer,
|
||||||
|
DFB_EVENT(&evt)) == DFB_OK) {
|
||||||
|
SDL_keysym keysym;
|
||||||
|
DFBInputDeviceModifierMask mod;
|
||||||
|
|
||||||
|
if (evt.clazz = DFEC_INPUT) {
|
||||||
|
if (evt.flags & DIEF_MODIFIERS)
|
||||||
|
mod = evt.modifiers;
|
||||||
|
else
|
||||||
|
mod = 0;
|
||||||
|
|
||||||
|
switch (evt.type) {
|
||||||
|
case DIET_BUTTONPRESS:
|
||||||
|
posted += SDL_PrivateMouseButton(SDL_PRESSED,
|
||||||
|
DirectFB_TranslateButton(evt.
|
||||||
|
button),
|
||||||
|
0, 0);
|
||||||
|
break;
|
||||||
|
case DIET_BUTTONRELEASE:
|
||||||
|
posted += SDL_PrivateMouseButton(SDL_RELEASED,
|
||||||
|
DirectFB_TranslateButton(evt.
|
||||||
|
button),
|
||||||
|
0, 0);
|
||||||
|
break;
|
||||||
|
case DIET_KEYPRESS:
|
||||||
|
posted += SDL_PrivateKeyboard(SDL_PRESSED,
|
||||||
|
DirectFB_TranslateKey(evt.
|
||||||
|
key_id,
|
||||||
|
evt.
|
||||||
|
key_symbol,
|
||||||
|
mod,
|
||||||
|
&keysym));
|
||||||
|
break;
|
||||||
|
case DIET_KEYRELEASE:
|
||||||
|
posted += SDL_PrivateKeyboard(SDL_RELEASED,
|
||||||
|
DirectFB_TranslateKey(evt.
|
||||||
|
key_id,
|
||||||
|
evt.
|
||||||
|
key_symbol,
|
||||||
|
mod,
|
||||||
|
&keysym));
|
||||||
|
break;
|
||||||
|
case DIET_AXISMOTION:
|
||||||
|
if (evt.flags & DIEF_AXISREL) {
|
||||||
|
if (evt.axis == DIAI_X)
|
||||||
|
posted +=
|
||||||
|
SDL_PrivateMouseMotion(0, 1, evt.axisrel, 0);
|
||||||
|
else if (evt.axis == DIAI_Y)
|
||||||
|
posted +=
|
||||||
|
SDL_PrivateMouseMotion(0, 1, 0, evt.axisrel);
|
||||||
|
} else if (evt.flags & DIEF_AXISABS) {
|
||||||
|
if (evt.axis == DIAI_X)
|
||||||
|
last_x = evt.axisabs;
|
||||||
|
else if (evt.axis == DIAI_Y)
|
||||||
|
last_y = evt.axisabs;
|
||||||
|
posted += SDL_PrivateMouseMotion(0, 0, last_x, last_y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -25,5 +25,4 @@
|
||||||
|
|
||||||
/* Functions to be exported */
|
/* Functions to be exported */
|
||||||
extern void DirectFB_InitOSKeymap(_THIS);
|
extern void DirectFB_InitOSKeymap(_THIS);
|
||||||
extern void DirectFB_PumpEvents(_THIS);
|
extern void DirectFB_PumpEventsWindow(_THIS);
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
|
|
||||||
#define SCANCODE_ESCAPE 1
|
|
||||||
|
|
||||||
#define SCANCODE_1 2
|
|
||||||
#define SCANCODE_2 3
|
|
||||||
#define SCANCODE_3 4
|
|
||||||
#define SCANCODE_4 5
|
|
||||||
#define SCANCODE_5 6
|
|
||||||
#define SCANCODE_6 7
|
|
||||||
#define SCANCODE_7 8
|
|
||||||
#define SCANCODE_8 9
|
|
||||||
#define SCANCODE_9 10
|
|
||||||
#define SCANCODE_0 11
|
|
||||||
|
|
||||||
#define SCANCODE_MINUS 12
|
|
||||||
#define SCANCODE_EQUAL 13
|
|
||||||
|
|
||||||
#define SCANCODE_BACKSPACE 14
|
|
||||||
#define SCANCODE_TAB 15
|
|
||||||
|
|
||||||
#define SCANCODE_Q 16
|
|
||||||
#define SCANCODE_W 17
|
|
||||||
#define SCANCODE_E 18
|
|
||||||
#define SCANCODE_R 19
|
|
||||||
#define SCANCODE_T 20
|
|
||||||
#define SCANCODE_Y 21
|
|
||||||
#define SCANCODE_U 22
|
|
||||||
#define SCANCODE_I 23
|
|
||||||
#define SCANCODE_O 24
|
|
||||||
#define SCANCODE_P 25
|
|
||||||
#define SCANCODE_BRACKET_LEFT 26
|
|
||||||
#define SCANCODE_BRACKET_RIGHT 27
|
|
||||||
|
|
||||||
#define SCANCODE_ENTER 28
|
|
||||||
|
|
||||||
#define SCANCODE_LEFTCONTROL 29
|
|
||||||
|
|
||||||
#define SCANCODE_A 30
|
|
||||||
#define SCANCODE_S 31
|
|
||||||
#define SCANCODE_D 32
|
|
||||||
#define SCANCODE_F 33
|
|
||||||
#define SCANCODE_G 34
|
|
||||||
#define SCANCODE_H 35
|
|
||||||
#define SCANCODE_J 36
|
|
||||||
#define SCANCODE_K 37
|
|
||||||
#define SCANCODE_L 38
|
|
||||||
#define SCANCODE_SEMICOLON 39
|
|
||||||
#define SCANCODE_APOSTROPHE 40
|
|
||||||
#define SCANCODE_GRAVE 41
|
|
||||||
|
|
||||||
#define SCANCODE_LEFTSHIFT 42
|
|
||||||
#define SCANCODE_BACKSLASH 43
|
|
||||||
|
|
||||||
#define SCANCODE_Z 44
|
|
||||||
#define SCANCODE_X 45
|
|
||||||
#define SCANCODE_C 46
|
|
||||||
#define SCANCODE_V 47
|
|
||||||
#define SCANCODE_B 48
|
|
||||||
#define SCANCODE_N 49
|
|
||||||
#define SCANCODE_M 50
|
|
||||||
#define SCANCODE_COMMA 51
|
|
||||||
#define SCANCODE_PERIOD 52
|
|
||||||
#define SCANCODE_SLASH 53
|
|
||||||
|
|
||||||
#define SCANCODE_RIGHTSHIFT 54
|
|
||||||
#define SCANCODE_KEYPADMULTIPLY 55
|
|
||||||
|
|
||||||
#define SCANCODE_LEFTALT 56
|
|
||||||
#define SCANCODE_SPACE 57
|
|
||||||
#define SCANCODE_CAPSLOCK 58
|
|
||||||
|
|
||||||
#define SCANCODE_F1 59
|
|
||||||
#define SCANCODE_F2 60
|
|
||||||
#define SCANCODE_F3 61
|
|
||||||
#define SCANCODE_F4 62
|
|
||||||
#define SCANCODE_F5 63
|
|
||||||
#define SCANCODE_F6 64
|
|
||||||
#define SCANCODE_F7 65
|
|
||||||
#define SCANCODE_F8 66
|
|
||||||
#define SCANCODE_F9 67
|
|
||||||
#define SCANCODE_F10 68
|
|
||||||
|
|
||||||
#define SCANCODE_NUMLOCK 69
|
|
||||||
#define SCANCODE_SCROLLLOCK 70
|
|
||||||
|
|
||||||
#define SCANCODE_KEYPAD7 71
|
|
||||||
#define SCANCODE_CURSORUPLEFT 71
|
|
||||||
#define SCANCODE_KEYPAD8 72
|
|
||||||
#define SCANCODE_CURSORUP 72
|
|
||||||
#define SCANCODE_KEYPAD9 73
|
|
||||||
#define SCANCODE_CURSORUPRIGHT 73
|
|
||||||
#define SCANCODE_KEYPADMINUS 74
|
|
||||||
#define SCANCODE_KEYPAD4 75
|
|
||||||
#define SCANCODE_CURSORLEFT 75
|
|
||||||
#define SCANCODE_KEYPAD5 76
|
|
||||||
#define SCANCODE_KEYPAD6 77
|
|
||||||
#define SCANCODE_CURSORRIGHT 77
|
|
||||||
#define SCANCODE_KEYPADPLUS 78
|
|
||||||
#define SCANCODE_KEYPAD1 79
|
|
||||||
#define SCANCODE_CURSORDOWNLEFT 79
|
|
||||||
#define SCANCODE_KEYPAD2 80
|
|
||||||
#define SCANCODE_CURSORDOWN 80
|
|
||||||
#define SCANCODE_KEYPAD3 81
|
|
||||||
#define SCANCODE_CURSORDOWNRIGHT 81
|
|
||||||
#define SCANCODE_KEYPAD0 82
|
|
||||||
#define SCANCODE_KEYPADPERIOD 83
|
|
||||||
|
|
||||||
#define SCANCODE_LESS 86
|
|
||||||
|
|
||||||
#define SCANCODE_F11 87
|
|
||||||
#define SCANCODE_F12 88
|
|
||||||
|
|
||||||
#define SCANCODE_KEYPADENTER 96
|
|
||||||
#define SCANCODE_RIGHTCONTROL 97
|
|
||||||
#define SCANCODE_CONTROL 97
|
|
||||||
#define SCANCODE_KEYPADDIVIDE 98
|
|
||||||
#define SCANCODE_PRINTSCREEN 99
|
|
||||||
#define SCANCODE_RIGHTALT 100
|
|
||||||
#define SCANCODE_BREAK 101 /* Beware: is 119 */
|
|
||||||
#define SCANCODE_BREAK_ALTERNATIVE 119 /* on some keyboards! */
|
|
||||||
|
|
||||||
#define SCANCODE_HOME 102
|
|
||||||
#define SCANCODE_CURSORBLOCKUP 90 /* Cursor key block */
|
|
||||||
#define SCANCODE_PAGEUP 104
|
|
||||||
#define SCANCODE_CURSORBLOCKLEFT 92 /* Cursor key block */
|
|
||||||
#define SCANCODE_CURSORBLOCKRIGHT 94 /* Cursor key block */
|
|
||||||
#define SCANCODE_END 107
|
|
||||||
#define SCANCODE_CURSORBLOCKDOWN 108 /* Cursor key block */
|
|
||||||
#define SCANCODE_PAGEDOWN 109
|
|
||||||
#define SCANCODE_INSERT 110
|
|
||||||
#define SCANCODE_REMOVE 111
|
|
||||||
|
|
||||||
#define SCANCODE_RIGHTWIN 126
|
|
||||||
#define SCANCODE_LEFTWIN 125
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
212
src/video/directfb/SDL_DirectFB_mouse.c
Normal file
212
src/video/directfb/SDL_DirectFB_mouse.c
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2006 Sam Lantinga
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
*/
|
||||||
|
#include "SDL_config.h"
|
||||||
|
|
||||||
|
#include "SDL_DirectFB_video.h"
|
||||||
|
#include "SDL_DirectFB_mouse.h"
|
||||||
|
|
||||||
|
#include "../SDL_sysvideo.h"
|
||||||
|
#include "../../events/SDL_mouse_c.h"
|
||||||
|
|
||||||
|
static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface, int hot_x,
|
||||||
|
int hot_y);
|
||||||
|
static int DirectFB_ShowCursor(SDL_Cursor * cursor);
|
||||||
|
static void DirectFB_MoveCursor(SDL_Cursor * cursor);
|
||||||
|
static void DirectFB_FreeCursor(SDL_Cursor * cursor);
|
||||||
|
static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_WindowID windowID,
|
||||||
|
int x, int y);
|
||||||
|
static void DirectFB_FreeMouse(SDL_Mouse * mouse);
|
||||||
|
|
||||||
|
void
|
||||||
|
DirectFB_InitMouse(_THIS)
|
||||||
|
{
|
||||||
|
SDL_DFB_DEVICEDATA(_this);
|
||||||
|
SDL_Mouse mouse;
|
||||||
|
|
||||||
|
SDL_zero(mouse);
|
||||||
|
mouse.CreateCursor = DirectFB_CreateCursor;
|
||||||
|
mouse.ShowCursor = DirectFB_ShowCursor;
|
||||||
|
mouse.MoveCursor = DirectFB_MoveCursor;
|
||||||
|
mouse.FreeCursor = DirectFB_FreeCursor;
|
||||||
|
mouse.WarpMouse = DirectFB_WarpMouse;
|
||||||
|
mouse.FreeMouse = DirectFB_FreeMouse;
|
||||||
|
devdata->mouse = SDL_AddMouse(&mouse, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DirectFB_QuitMouse(_THIS)
|
||||||
|
{
|
||||||
|
SDL_DFB_DEVICEDATA(_this);
|
||||||
|
|
||||||
|
SDL_DelMouse(devdata->mouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a cursor from a surface */
|
||||||
|
static SDL_Cursor *
|
||||||
|
DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
||||||
|
{
|
||||||
|
SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
||||||
|
|
||||||
|
SDL_DFB_DEVICEDATA(dev);
|
||||||
|
DFB_CursorData *curdata;
|
||||||
|
DFBResult ret;
|
||||||
|
DFBSurfaceDescription dsc;
|
||||||
|
SDL_Cursor *cursor;
|
||||||
|
Uint32 *dest;
|
||||||
|
Uint32 *p;
|
||||||
|
int pitch, i;
|
||||||
|
|
||||||
|
SDL_DFB_CALLOC(cursor, 1, sizeof(*cursor));
|
||||||
|
SDL_DFB_CALLOC(curdata, 1, sizeof(*curdata));
|
||||||
|
|
||||||
|
dsc.flags =
|
||||||
|
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
|
||||||
|
dsc.caps = DSCAPS_NONE; //DSCAPS_SYSTEMONLY;
|
||||||
|
dsc.width = surface->w;
|
||||||
|
dsc.height = surface->h;
|
||||||
|
dsc.pixelformat = DSPF_ARGB;
|
||||||
|
|
||||||
|
SDL_DFB_CHECKERR(devdata->dfb->
|
||||||
|
CreateSurface(devdata->dfb, &dsc, &curdata->surf));
|
||||||
|
curdata->hotx = hot_x;
|
||||||
|
curdata->hoty = hot_y;
|
||||||
|
cursor->driverdata = curdata;
|
||||||
|
|
||||||
|
SDL_DFB_CHECKERR(curdata->surf->
|
||||||
|
Lock(curdata->surf, DSLF_WRITE, (void *) &dest, &pitch));
|
||||||
|
|
||||||
|
//FIXME: Implies a lot of things, e.g. rgba format for SDL_SURFACE ....
|
||||||
|
p = surface->pixels;
|
||||||
|
for (i = 0; i < surface->w * surface->h; i++)
|
||||||
|
if (p[i] == 0x00000000)
|
||||||
|
dest[i] = 0x00000000;
|
||||||
|
else
|
||||||
|
dest[i] = p[i];
|
||||||
|
//memcpy(dest, surface->pixels, surface->w * surface->h * 4);
|
||||||
|
curdata->surf->Unlock(curdata->surf);
|
||||||
|
return cursor;
|
||||||
|
error:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show the specified cursor, or hide if cursor is NULL */
|
||||||
|
static int
|
||||||
|
DirectFB_ShowCursor(SDL_Cursor * cursor)
|
||||||
|
{
|
||||||
|
SDL_DFB_CURSORDATA(cursor);
|
||||||
|
SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
||||||
|
SDL_DFB_DEVICEDATA(dev);
|
||||||
|
#if 0
|
||||||
|
DFB_DisplayData *dispdata =
|
||||||
|
(DFB_DisplayData *) dev->displays[dev->current_display].driverdata;
|
||||||
|
#endif
|
||||||
|
DFBResult ret;
|
||||||
|
SDL_WindowID wid;
|
||||||
|
|
||||||
|
wid = SDL_GetFocusWindow();
|
||||||
|
if (!wid)
|
||||||
|
return -1;
|
||||||
|
else {
|
||||||
|
SDL_Window *window = SDL_GetWindowFromID(wid);
|
||||||
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
||||||
|
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
|
||||||
|
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
|
||||||
|
SDL_DFB_CHECKERR(windata->window->
|
||||||
|
SetCursorShape(windata->window, curdata->surf,
|
||||||
|
curdata->hotx, curdata->hoty));
|
||||||
|
//FIXME: This is somehow a directfb issue
|
||||||
|
SDL_DFB_CHECKERR(dispdata->layer->
|
||||||
|
SetCooperativeLevel(dispdata->layer,
|
||||||
|
DLSCL_ADMINISTRATIVE));
|
||||||
|
SDL_DFB_CHECKERR(dispdata->layer->
|
||||||
|
SetCursorOpacity(dispdata->layer, 0xC0));
|
||||||
|
SDL_DFB_CHECKERR(dispdata->layer->
|
||||||
|
SetCooperativeLevel(dispdata->layer, DLSCL_SHARED));
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
//TODO: Check administrative
|
||||||
|
SDL_DFB_CHECKERR(dispdata->layer->
|
||||||
|
SetCooperativeLevel(dispdata->layer,
|
||||||
|
DLSCL_ADMINISTRATIVE));
|
||||||
|
SDL_DFB_CHECKERR(dispdata->layer->
|
||||||
|
SetCursorShape(dispdata->layer, curdata->surf,
|
||||||
|
curdata->hotx, curdata->hoty));
|
||||||
|
SDL_DFB_CHECKERR(dispdata->layer->
|
||||||
|
SetCursorOpacity(dispdata->layer, 0xC0));
|
||||||
|
SDL_DFB_CHECKERR(dispdata->layer->
|
||||||
|
SetCooperativeLevel(dispdata->layer, DLSCL_SHARED));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is called when a mouse motion event occurs */
|
||||||
|
static void
|
||||||
|
DirectFB_MoveCursor(SDL_Cursor * cursor)
|
||||||
|
{
|
||||||
|
SDL_DFB_CURSORDATA(cursor);
|
||||||
|
/* Do we need to do something here ? */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free a window manager cursor */
|
||||||
|
static void
|
||||||
|
DirectFB_FreeCursor(SDL_Cursor * cursor)
|
||||||
|
{
|
||||||
|
SDL_DFB_CURSORDATA(cursor);
|
||||||
|
|
||||||
|
SDL_DFB_RELEASE(curdata->surf);
|
||||||
|
SDL_DFB_FREE(cursor->driverdata);
|
||||||
|
SDL_DFB_FREE(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Warp the mouse to (x,y) */
|
||||||
|
static void
|
||||||
|
DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_WindowID windowID, int x, int y)
|
||||||
|
{
|
||||||
|
// SDL_DFB_CURSORDATA(cursor);
|
||||||
|
SDL_Window *window = SDL_GetWindowFromID(windowID);
|
||||||
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
||||||
|
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
|
||||||
|
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
|
||||||
|
DFBResult ret;
|
||||||
|
int cx, cy;
|
||||||
|
|
||||||
|
SDL_DFB_CHECKERR(windata->window->GetPosition(windata->window, &cx, &cy));
|
||||||
|
SDL_DFB_CHECKERR(dispdata->layer->
|
||||||
|
WarpCursor(dispdata->layer, cx + x, cy + y));
|
||||||
|
|
||||||
|
error:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the mouse when it's time */
|
||||||
|
static void
|
||||||
|
DirectFB_FreeMouse(SDL_Mouse * mouse)
|
||||||
|
{
|
||||||
|
// nothing yet
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -21,21 +21,23 @@
|
||||||
*/
|
*/
|
||||||
#include "SDL_config.h"
|
#include "SDL_config.h"
|
||||||
|
|
||||||
/* This is the DirectFB implementation of YUV video overlays */
|
#ifndef _SDL_DirectFB_mouse_h
|
||||||
|
#define _SDL_DirectFB_mouse_h
|
||||||
|
|
||||||
#include "SDL_video.h"
|
typedef struct _DFB_CursorData DFB_CursorData;
|
||||||
#include "SDL_DirectFB_video.h"
|
|
||||||
|
|
||||||
extern SDL_Overlay *DirectFB_CreateYUVOverlay(_THIS, int width, int height,
|
struct _DFB_CursorData
|
||||||
Uint32 format,
|
{
|
||||||
SDL_Surface * display);
|
IDirectFBSurface *surf;
|
||||||
|
int hotx;
|
||||||
|
int hoty;
|
||||||
|
};
|
||||||
|
|
||||||
extern int DirectFB_LockYUVOverlay(_THIS, SDL_Overlay * overlay);
|
#define SDL_DFB_CURSORDATA(curs) DFB_CursorData *curdata = (DFB_CursorData *) ((curs)->driverdata)
|
||||||
|
|
||||||
extern void DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay);
|
extern void DirectFB_InitMouse(_THIS);
|
||||||
|
extern void DirectFB_QuitMouse(_THIS);
|
||||||
|
|
||||||
extern int DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay,
|
#endif /* _SDL_DirectFB_mouse_h */
|
||||||
SDL_Rect * src, SDL_Rect * dst);
|
|
||||||
|
|
||||||
extern void DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay * overlay);
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
/* vi: set ts=4 sw=4 expandtab: */
|
737
src/video/directfb/SDL_DirectFB_render.c
Normal file
737
src/video/directfb/SDL_DirectFB_render.c
Normal file
|
@ -0,0 +1,737 @@
|
||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2006 Sam Lantinga
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
|
||||||
|
SDL1.3 implementation by couriersud@arcor.de
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include "SDL_config.h"
|
||||||
|
|
||||||
|
#include "SDL_DirectFB_video.h"
|
||||||
|
#include "SDL_DirectFB_render.h"
|
||||||
|
#include "../SDL_rect_c.h"
|
||||||
|
#include "../SDL_yuv_sw_c.h"
|
||||||
|
|
||||||
|
/* GDI renderer implementation */
|
||||||
|
|
||||||
|
static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window,
|
||||||
|
Uint32 flags);
|
||||||
|
static int DirectFB_DisplayModeChanged(SDL_Renderer * renderer);
|
||||||
|
static int DirectFB_CreateTexture(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture);
|
||||||
|
static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture, void **pixels,
|
||||||
|
int *pitch);
|
||||||
|
static int DirectFB_SetTexturePalette(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture,
|
||||||
|
const SDL_Color * colors,
|
||||||
|
int firstcolor, int ncolors);
|
||||||
|
static int DirectFB_GetTexturePalette(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture,
|
||||||
|
SDL_Color * colors, int firstcolor,
|
||||||
|
int ncolors);
|
||||||
|
static int DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture);
|
||||||
|
static int DirectFB_SetTextureColorMod(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture);
|
||||||
|
static int DirectFB_SetTextureBlendMode(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture);
|
||||||
|
static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture);
|
||||||
|
static int DirectFB_UpdateTexture(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture,
|
||||||
|
const SDL_Rect * rect, const void *pixels,
|
||||||
|
int pitch);
|
||||||
|
static int DirectFB_LockTexture(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture, const SDL_Rect * rect,
|
||||||
|
int markDirty, void **pixels, int *pitch);
|
||||||
|
static void DirectFB_UnlockTexture(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture);
|
||||||
|
static void DirectFB_DirtyTexture(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture, int numrects,
|
||||||
|
const SDL_Rect * rects);
|
||||||
|
static int DirectFB_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g,
|
||||||
|
Uint8 b, Uint8 a, const SDL_Rect * rect);
|
||||||
|
static int DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
|
const SDL_Rect * srcrect,
|
||||||
|
const SDL_Rect * dstrect);
|
||||||
|
static void DirectFB_RenderPresent(SDL_Renderer * renderer);
|
||||||
|
static void DirectFB_DestroyTexture(SDL_Renderer * renderer,
|
||||||
|
SDL_Texture * texture);
|
||||||
|
static void DirectFB_DestroyRenderer(SDL_Renderer * renderer);
|
||||||
|
|
||||||
|
SDL_RenderDriver DirectFB_RenderDriver = {
|
||||||
|
DirectFB_CreateRenderer,
|
||||||
|
{
|
||||||
|
"directfb",
|
||||||
|
(SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
|
||||||
|
SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
|
||||||
|
SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED),
|
||||||
|
(SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
|
||||||
|
SDL_TEXTUREMODULATE_ALPHA),
|
||||||
|
(SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
|
||||||
|
SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_MOD),
|
||||||
|
(SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST),
|
||||||
|
14,
|
||||||
|
{
|
||||||
|
SDL_PIXELFORMAT_INDEX8,
|
||||||
|
SDL_PIXELFORMAT_INDEX4LSB,
|
||||||
|
SDL_PIXELFORMAT_RGB332,
|
||||||
|
SDL_PIXELFORMAT_RGB555,
|
||||||
|
SDL_PIXELFORMAT_RGB565,
|
||||||
|
SDL_PIXELFORMAT_RGB888,
|
||||||
|
SDL_PIXELFORMAT_ARGB8888,
|
||||||
|
SDL_PIXELFORMAT_ARGB4444,
|
||||||
|
SDL_PIXELFORMAT_ARGB1555,
|
||||||
|
SDL_PIXELFORMAT_RGB24,
|
||||||
|
SDL_PIXELFORMAT_YV12,
|
||||||
|
SDL_PIXELFORMAT_IYUV,
|
||||||
|
SDL_PIXELFORMAT_YUY2,
|
||||||
|
SDL_PIXELFORMAT_UYVY},
|
||||||
|
0,
|
||||||
|
0}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
IDirectFBSurface *surface;
|
||||||
|
DFBSurfaceFlipFlags flipflags;
|
||||||
|
int isyuvdirect;
|
||||||
|
} DirectFB_RenderData;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
IDirectFBDisplayLayer *vidlayer;
|
||||||
|
IDirectFBSurface *surface;
|
||||||
|
Uint32 format;
|
||||||
|
void *pixels;
|
||||||
|
int pitch;
|
||||||
|
IDirectFBPalette *palette;
|
||||||
|
} DirectFB_TextureData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
UpdateYUVTextureData(SDL_Texture * texture)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Not needed - directfb supports yuv surfaces
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DirectFB_AddRenderDriver(_THIS)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < _this->num_displays; i++)
|
||||||
|
SDL_AddRenderDriver(i, &DirectFB_RenderDriver);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Renderer *
|
||||||
|
DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
|
{
|
||||||
|
SDL_DFB_WINDOWDATA(window);
|
||||||
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
||||||
|
SDL_DFB_DEVICEDATA(display->device);
|
||||||
|
SDL_Renderer *renderer = NULL;
|
||||||
|
DirectFB_RenderData *data = NULL;
|
||||||
|
DFBResult ret;
|
||||||
|
DFBSurfaceDescription dsc;
|
||||||
|
DFBSurfaceCapabilities scaps;
|
||||||
|
char *p;
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
SDL_DFB_CALLOC(renderer, 1, sizeof(*renderer));
|
||||||
|
SDL_DFB_CALLOC(data, 1, sizeof(*data));
|
||||||
|
|
||||||
|
renderer->DisplayModeChanged = DirectFB_DisplayModeChanged;
|
||||||
|
renderer->CreateTexture = DirectFB_CreateTexture;
|
||||||
|
renderer->QueryTexturePixels = DirectFB_QueryTexturePixels;
|
||||||
|
renderer->SetTexturePalette = DirectFB_SetTexturePalette;
|
||||||
|
renderer->GetTexturePalette = DirectFB_GetTexturePalette;
|
||||||
|
renderer->SetTextureAlphaMod = DirectFB_SetTextureAlphaMod;
|
||||||
|
renderer->SetTextureColorMod = DirectFB_SetTextureColorMod;
|
||||||
|
renderer->SetTextureBlendMode = DirectFB_SetTextureBlendMode;
|
||||||
|
renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode;
|
||||||
|
renderer->UpdateTexture = DirectFB_UpdateTexture;
|
||||||
|
renderer->LockTexture = DirectFB_LockTexture;
|
||||||
|
renderer->UnlockTexture = DirectFB_UnlockTexture;
|
||||||
|
renderer->DirtyTexture = DirectFB_DirtyTexture;
|
||||||
|
renderer->RenderFill = DirectFB_RenderFill;
|
||||||
|
renderer->RenderCopy = DirectFB_RenderCopy;
|
||||||
|
renderer->RenderPresent = DirectFB_RenderPresent;
|
||||||
|
renderer->DestroyTexture = DirectFB_DestroyTexture;
|
||||||
|
renderer->DestroyRenderer = DirectFB_DestroyRenderer;
|
||||||
|
renderer->info = DirectFB_RenderDriver.info;
|
||||||
|
renderer->window = window->id; // SDL window id
|
||||||
|
renderer->driverdata = data;
|
||||||
|
|
||||||
|
renderer->info.flags =
|
||||||
|
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD;
|
||||||
|
|
||||||
|
data->surface = windata->surface;
|
||||||
|
data->flipflags = 0;
|
||||||
|
|
||||||
|
if (flags & SDL_RENDERER_PRESENTVSYNC) {
|
||||||
|
data->flipflags = DSFLIP_ONSYNC;
|
||||||
|
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->surface->GetCapabilities(data->surface, &scaps);
|
||||||
|
if (scaps & DSCAPS_DOUBLE)
|
||||||
|
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
|
||||||
|
else if (scaps & DSCAPS_TRIPLE)
|
||||||
|
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
|
||||||
|
else
|
||||||
|
renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
|
||||||
|
|
||||||
|
data->isyuvdirect = 0;
|
||||||
|
p = getenv("SDL_DIRECTFB_YUV_DIRECT");
|
||||||
|
if (p)
|
||||||
|
data->isyuvdirect = atoi(p);
|
||||||
|
|
||||||
|
return renderer;
|
||||||
|
|
||||||
|
error:
|
||||||
|
SDL_DFB_FREE(renderer);
|
||||||
|
SDL_DFB_FREE(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DFBSurfacePixelFormat
|
||||||
|
SDLToDFBPixelFormat(Uint32 format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case SDL_PIXELFORMAT_INDEX4LSB:
|
||||||
|
return DSPF_ALUT44;
|
||||||
|
case SDL_PIXELFORMAT_INDEX8:
|
||||||
|
return DSPF_LUT8;
|
||||||
|
case SDL_PIXELFORMAT_RGB332:
|
||||||
|
return DSPF_RGB332;
|
||||||
|
case SDL_PIXELFORMAT_RGB555:
|
||||||
|
return DSPF_ARGB1555;
|
||||||
|
case SDL_PIXELFORMAT_ARGB4444:
|
||||||
|
return DSPF_ARGB4444;
|
||||||
|
case SDL_PIXELFORMAT_ARGB1555:
|
||||||
|
return DSPF_ARGB1555;
|
||||||
|
case SDL_PIXELFORMAT_RGB565:
|
||||||
|
return DSPF_RGB16;
|
||||||
|
case SDL_PIXELFORMAT_RGB24:
|
||||||
|
return DSPF_RGB24;
|
||||||
|
case SDL_PIXELFORMAT_RGB888:
|
||||||
|
return DSPF_RGB32;
|
||||||
|
case SDL_PIXELFORMAT_ARGB8888:
|
||||||
|
return DSPF_ARGB;
|
||||||
|
case SDL_PIXELFORMAT_YV12:
|
||||||
|
return DSPF_YV12; /* Planar mode: Y + V + U (3 planes) */
|
||||||
|
case SDL_PIXELFORMAT_IYUV:
|
||||||
|
return DSPF_I420; /* Planar mode: Y + U + V (3 planes) */
|
||||||
|
case SDL_PIXELFORMAT_YUY2:
|
||||||
|
return DSPF_YUY2; /* Packed mode: Y0+U0+Y1+V0 (1 plane) */
|
||||||
|
case SDL_PIXELFORMAT_UYVY:
|
||||||
|
return DSPF_UYVY; /* Packed mode: U0+Y0+V0+Y1 (1 plane) */
|
||||||
|
case SDL_PIXELFORMAT_YVYU:
|
||||||
|
return DSPF_UNKNOWN; /* Packed mode: Y0+V0+Y1+U0 (1 plane) */
|
||||||
|
case SDL_PIXELFORMAT_INDEX1LSB:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
case SDL_PIXELFORMAT_INDEX1MSB:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
case SDL_PIXELFORMAT_INDEX4MSB:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
case SDL_PIXELFORMAT_RGB444:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
case SDL_PIXELFORMAT_BGR24:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
case SDL_PIXELFORMAT_BGR888:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
case SDL_PIXELFORMAT_RGBA8888:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
case SDL_PIXELFORMAT_ABGR8888:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
case SDL_PIXELFORMAT_BGRA8888:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
case SDL_PIXELFORMAT_ARGB2101010:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
default:
|
||||||
|
return DSPF_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_DisplayModeChanged(SDL_Renderer * renderer)
|
||||||
|
{
|
||||||
|
SDL_DFB_RENDERERDATA(renderer);
|
||||||
|
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
||||||
|
SDL_DFB_WINDOWDATA(window);
|
||||||
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
||||||
|
SDL_DFB_DEVICEDATA(display->device);
|
||||||
|
DFBResult ret;
|
||||||
|
DFBSurfaceDescription dsc;
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nothing to do here
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
|
{
|
||||||
|
SDL_DFB_RENDERERDATA(renderer);
|
||||||
|
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
||||||
|
SDL_DFB_WINDOWDATA(window);
|
||||||
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
||||||
|
SDL_DFB_DEVICEDATA(display->device);
|
||||||
|
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
|
||||||
|
DirectFB_TextureData *data;
|
||||||
|
DFBResult ret;
|
||||||
|
DFBSurfaceDescription dsc;
|
||||||
|
DFBDisplayLayerDescription laydsc;
|
||||||
|
DFBDisplayLayerConfig layconf;
|
||||||
|
|
||||||
|
SDL_DFB_CALLOC(data, 1, sizeof(*data));
|
||||||
|
texture->driverdata = data;
|
||||||
|
|
||||||
|
data->format = texture->format;
|
||||||
|
data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
|
||||||
|
data->vidlayer = NULL;
|
||||||
|
if (renddata->isyuvdirect && (dispdata->vidID >= 0)
|
||||||
|
&& SDL_ISPIXELFORMAT_FOURCC(data->format)) {
|
||||||
|
SDL_DFB_CHECKERR(devdata->dfb->
|
||||||
|
GetDisplayLayer(devdata->dfb, dispdata->vidID,
|
||||||
|
&data->vidlayer));
|
||||||
|
layconf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
|
||||||
|
layconf.width = texture->w;
|
||||||
|
layconf.height = texture->h;
|
||||||
|
layconf.pixelformat = SDLToDFBPixelFormat(data->format);
|
||||||
|
|
||||||
|
SDL_DFB_CHECKERR(data->vidlayer->
|
||||||
|
SetCooperativeLevel(data->vidlayer,
|
||||||
|
DLSCL_EXCLUSIVE));
|
||||||
|
SDL_DFB_CHECKERR(data->vidlayer->
|
||||||
|
SetConfiguration(data->vidlayer, &layconf));
|
||||||
|
SDL_DFB_CHECKERR(data->vidlayer->
|
||||||
|
GetSurface(data->vidlayer, &data->surface));
|
||||||
|
SDL_DFB_CHECKERR(data->vidlayer->
|
||||||
|
GetDescription(data->vidlayer, &laydsc));
|
||||||
|
SDL_DFB_DEBUG("Created HW YUV surface\n");
|
||||||
|
}
|
||||||
|
if (!data->vidlayer) {
|
||||||
|
/* fill surface description */
|
||||||
|
dsc.flags =
|
||||||
|
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
|
||||||
|
dsc.width = texture->w;
|
||||||
|
dsc.height = texture->h;
|
||||||
|
/* Never use DSCAPS_VIDEOONLY here. It kills performance
|
||||||
|
* No DSCAPS_SYSTEMONLY either - let dfb decide
|
||||||
|
*/
|
||||||
|
dsc.caps = 0; //DSCAPS_PREMULTIPLIED;
|
||||||
|
|
||||||
|
/* find the right pixelformat */
|
||||||
|
|
||||||
|
dsc.pixelformat = SDLToDFBPixelFormat(data->format);
|
||||||
|
if (dsc.pixelformat == DSPF_UNKNOWN) {
|
||||||
|
SDL_SetError("Unknown pixel format %d\n", data->format);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->pixels = NULL;
|
||||||
|
|
||||||
|
/* Create the surface */
|
||||||
|
SDL_DFB_CHECKERR(devdata->dfb->
|
||||||
|
CreateSurface(devdata->dfb, &dsc, &data->surface));
|
||||||
|
if (SDL_ISPIXELFORMAT_INDEXED(data->format)
|
||||||
|
&& !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
|
||||||
|
SDL_DFB_CHECKERR(data->surface->
|
||||||
|
GetPalette(data->surface, &data->palette));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
SDL_DFB_RELEASE(data->palette);
|
||||||
|
SDL_DFB_RELEASE(data->surface);
|
||||||
|
SDL_DFB_FREE(texture->driverdata);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
|
void **pixels, int *pitch)
|
||||||
|
{
|
||||||
|
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Always fail here so in compat mode SDL_HWSURFACE is set !
|
||||||
|
*/
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
|
const SDL_Color * colors, int firstcolor,
|
||||||
|
int ncolors)
|
||||||
|
{
|
||||||
|
DirectFB_RenderData *renderdata =
|
||||||
|
(DirectFB_RenderData *) renderer->driverdata;
|
||||||
|
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
|
||||||
|
DFBResult ret;
|
||||||
|
|
||||||
|
if (SDL_ISPIXELFORMAT_INDEXED(data->format)
|
||||||
|
&& !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
|
||||||
|
DFBColor entries[256];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ncolors; ++i) {
|
||||||
|
entries[i].r = colors[i].r;
|
||||||
|
entries[i].g = colors[i].g;
|
||||||
|
entries[i].b = colors[i].b;
|
||||||
|
entries[i].a = 0xFF;
|
||||||
|
}
|
||||||
|
SDL_DFB_CHECKERR(data->palette->
|
||||||
|
SetEntries(data->palette, entries, ncolors,
|
||||||
|
firstcolor));
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
SDL_SetError("YUV textures don't have a palette");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
|
SDL_Color * colors, int firstcolor, int ncolors)
|
||||||
|
{
|
||||||
|
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
|
||||||
|
DFBResult ret;
|
||||||
|
|
||||||
|
if (SDL_ISPIXELFORMAT_INDEXED(data->format)
|
||||||
|
&& !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
|
||||||
|
DFBColor entries[256];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
SDL_DFB_CHECKERR(data->palette->
|
||||||
|
GetEntries(data->palette, entries, ncolors,
|
||||||
|
firstcolor));
|
||||||
|
|
||||||
|
for (i = 0; i < ncolors; ++i) {
|
||||||
|
colors[i].r = entries[i].r;
|
||||||
|
colors[i].g = entries[i].g;
|
||||||
|
colors[i].b = entries[i].b;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
SDL_SetError("YUV textures don't have a palette");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
|
{
|
||||||
|
switch (texture->blendMode) {
|
||||||
|
case SDL_TEXTUREBLENDMODE_NONE:
|
||||||
|
case SDL_TEXTUREBLENDMODE_MASK:
|
||||||
|
case SDL_TEXTUREBLENDMODE_BLEND:
|
||||||
|
case SDL_TEXTUREBLENDMODE_MOD:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
SDL_Unsupported();
|
||||||
|
texture->blendMode = SDL_TEXTUREBLENDMODE_NONE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
|
{
|
||||||
|
switch (texture->scaleMode) {
|
||||||
|
case SDL_TEXTURESCALEMODE_NONE:
|
||||||
|
case SDL_TEXTURESCALEMODE_FAST:
|
||||||
|
return 0;
|
||||||
|
case SDL_TEXTURESCALEMODE_SLOW:
|
||||||
|
case SDL_TEXTURESCALEMODE_BEST:
|
||||||
|
SDL_Unsupported();
|
||||||
|
texture->scaleMode = SDL_TEXTURESCALEMODE_FAST;
|
||||||
|
return -1;
|
||||||
|
default:
|
||||||
|
SDL_Unsupported();
|
||||||
|
texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
|
const SDL_Rect * rect, const void *pixels, int pitch)
|
||||||
|
{
|
||||||
|
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
|
||||||
|
DirectFB_RenderData *renderdata =
|
||||||
|
(DirectFB_RenderData *) renderer->driverdata;
|
||||||
|
|
||||||
|
if (data->pixels) {
|
||||||
|
Uint8 *src, *dst;
|
||||||
|
int row;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
src = (Uint8 *) pixels;
|
||||||
|
dst =
|
||||||
|
(Uint8 *) data->pixels + rect->y * data->pitch +
|
||||||
|
rect->x * SDL_BYTESPERPIXEL(texture->format);
|
||||||
|
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
|
||||||
|
for (row = 0; row < rect->h; ++row) {
|
||||||
|
SDL_memcpy(dst, src, length);
|
||||||
|
src += pitch;
|
||||||
|
dst += data->pitch;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SDL_SetError("FIXME: Update without lock!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
|
const SDL_Rect * rect, int markDirty, void **pixels,
|
||||||
|
int *pitch)
|
||||||
|
{
|
||||||
|
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
|
||||||
|
DFBResult ret;
|
||||||
|
void *fdata;
|
||||||
|
int fpitch;
|
||||||
|
|
||||||
|
SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
|
||||||
|
DSLF_WRITE | DSLF_READ, &fdata,
|
||||||
|
&fpitch));
|
||||||
|
data->pixels = fdata;
|
||||||
|
data->pitch = fpitch;
|
||||||
|
|
||||||
|
switch (texture->format) {
|
||||||
|
case SDL_PIXELFORMAT_YV12:
|
||||||
|
case SDL_PIXELFORMAT_IYUV:
|
||||||
|
if (rect
|
||||||
|
&& (rect->x != 0 || rect->y != 0 || rect->w != texture->w
|
||||||
|
|| rect->h != texture->h)) {
|
||||||
|
SDL_SetError
|
||||||
|
("YV12 and IYUV textures only support full surface locks");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Only one plane, no worries */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pitch = data->pitch;
|
||||||
|
*pixels = data->pixels;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
|
{
|
||||||
|
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
|
||||||
|
|
||||||
|
data->surface->Unlock(data->surface);
|
||||||
|
data->pixels = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
|
int numrects, const SDL_Rect * rects)
|
||||||
|
{
|
||||||
|
//TODO: DirtyTexture
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_RenderFill(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b,
|
||||||
|
Uint8 a, const SDL_Rect * rect)
|
||||||
|
{
|
||||||
|
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
|
||||||
|
DFBResult ret;
|
||||||
|
|
||||||
|
SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, r, g, b, a));
|
||||||
|
SDL_DFB_CHECKERR(data->surface->
|
||||||
|
FillRectangle(data->surface, rect->x, rect->y, rect->w,
|
||||||
|
rect->h));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
|
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
|
||||||
|
{
|
||||||
|
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
|
||||||
|
DirectFB_TextureData *texturedata =
|
||||||
|
(DirectFB_TextureData *) texture->driverdata;
|
||||||
|
DFBResult ret;
|
||||||
|
|
||||||
|
if (texturedata->vidlayer) {
|
||||||
|
int px, py;
|
||||||
|
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
||||||
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
||||||
|
SDL_DFB_DEVICEDATA(display->device);
|
||||||
|
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
|
||||||
|
SDL_DFB_WINDOWDATA(window);
|
||||||
|
|
||||||
|
SDL_DFB_CHECKERR(texturedata->vidlayer->
|
||||||
|
SetSourceRectangle(texturedata->vidlayer, srcrect->x,
|
||||||
|
srcrect->y, srcrect->w,
|
||||||
|
srcrect->h));
|
||||||
|
windata->window->GetPosition(windata->window, &px, &py);
|
||||||
|
SDL_DFB_CHECKERR(texturedata->vidlayer->
|
||||||
|
SetScreenRectangle(texturedata->vidlayer,
|
||||||
|
px + dstrect->x, py + dstrect->y,
|
||||||
|
dstrect->w, dstrect->h));
|
||||||
|
} else {
|
||||||
|
DFBRectangle sr, dr;
|
||||||
|
DFBSurfaceBlittingFlags flags = 0;
|
||||||
|
|
||||||
|
sr.x = srcrect->x;
|
||||||
|
sr.y = srcrect->y;
|
||||||
|
sr.w = srcrect->w;
|
||||||
|
sr.h = srcrect->h;
|
||||||
|
|
||||||
|
dr.x = dstrect->x;
|
||||||
|
dr.y = dstrect->y;
|
||||||
|
dr.w = dstrect->w;
|
||||||
|
dr.h = dstrect->h;
|
||||||
|
|
||||||
|
if (texture->
|
||||||
|
modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))
|
||||||
|
{
|
||||||
|
u8 alpha = 0xFF;
|
||||||
|
if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA)
|
||||||
|
alpha = texture->a;
|
||||||
|
if (texture->modMode & SDL_TEXTUREMODULATE_COLOR)
|
||||||
|
SDL_DFB_CHECKERR(data->surface->
|
||||||
|
SetColor(data->surface, texture->r,
|
||||||
|
texture->g, texture->b, alpha));
|
||||||
|
else
|
||||||
|
SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF,
|
||||||
|
0xFF, 0xFF, alpha));
|
||||||
|
// Only works together ....
|
||||||
|
flags |= DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->
|
||||||
|
blendMode & (SDL_TEXTUREBLENDMODE_MASK |
|
||||||
|
SDL_TEXTUREBLENDMODE_BLEND)) {
|
||||||
|
flags |= DSBLIT_BLEND_ALPHACHANNEL;
|
||||||
|
} else {
|
||||||
|
flags |= DSBLIT_NOFX;
|
||||||
|
}
|
||||||
|
SDL_DFB_CHECKERR(data->surface->
|
||||||
|
SetBlittingFlags(data->surface, flags));
|
||||||
|
if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
|
||||||
|
SDL_DFB_CHECKERR(data->surface->
|
||||||
|
Blit(data->surface, texturedata->surface, &sr,
|
||||||
|
dr.x, dr.y));
|
||||||
|
} else {
|
||||||
|
SDL_DFB_CHECKERR(data->surface->
|
||||||
|
StretchBlit(data->surface, texturedata->surface,
|
||||||
|
&sr, &dr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DirectFB_RenderPresent(SDL_Renderer * renderer)
|
||||||
|
{
|
||||||
|
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
|
||||||
|
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
||||||
|
|
||||||
|
SDL_DirtyRect *dirty;
|
||||||
|
DFBRectangle sr;
|
||||||
|
DFBResult ret;
|
||||||
|
|
||||||
|
sr.x = 0;
|
||||||
|
sr.y = 0;
|
||||||
|
sr.w = window->w;
|
||||||
|
sr.h = window->h;
|
||||||
|
|
||||||
|
/* Send the data to the display */
|
||||||
|
SDL_DFB_CHECKERR(data->surface->
|
||||||
|
Flip(data->surface, NULL, data->flipflags));
|
||||||
|
|
||||||
|
return;
|
||||||
|
error:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
|
{
|
||||||
|
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SDL_DFB_RELEASE(data->palette);
|
||||||
|
SDL_DFB_RELEASE(data->surface);
|
||||||
|
SDL_DFB_RELEASE(data->vidlayer);
|
||||||
|
SDL_free(data);
|
||||||
|
texture->driverdata = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
DirectFB_DestroyRenderer(SDL_Renderer * renderer)
|
||||||
|
{
|
||||||
|
DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
data->surface = NULL;
|
||||||
|
SDL_free(data);
|
||||||
|
}
|
||||||
|
SDL_free(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
30
src/video/directfb/SDL_DirectFB_render.h
Normal file
30
src/video/directfb/SDL_DirectFB_render.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
SDL - Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2006 Sam Lantinga
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Sam Lantinga
|
||||||
|
slouken@libsdl.org
|
||||||
|
*/
|
||||||
|
#include "SDL_config.h"
|
||||||
|
|
||||||
|
/* SDL surface based renderer implementation */
|
||||||
|
|
||||||
|
#define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL)
|
||||||
|
|
||||||
|
extern void DirectFB_AddRenderDriver(_THIS);
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
File diff suppressed because it is too large
Load diff
|
@ -25,39 +25,155 @@
|
||||||
#define _SDL_DirectFB_video_h
|
#define _SDL_DirectFB_video_h
|
||||||
|
|
||||||
#include <directfb.h>
|
#include <directfb.h>
|
||||||
|
#include <directfb_version.h>
|
||||||
|
|
||||||
|
#define LOG_CHANNEL stdout
|
||||||
|
|
||||||
|
#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23)
|
||||||
|
#error "SDL_DIRECTFB: Please compile against libdirectfb version >=0.9.24"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (DIRECTFB_MAJOR_VERSION >= 1) && (DIRECTFB_MINOR_VERSION >= 0) && (DIRECTFB_MICRO_VERSION >= 0 )
|
||||||
|
#define SDL_DIRECTFB_OPENGL 1
|
||||||
|
#include <directfbgl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SDL_DIRECTFB_OPENGL
|
||||||
|
#include "SDL_loadso.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "SDL_mouse.h"
|
#include "SDL_mouse.h"
|
||||||
#include "../SDL_sysvideo.h"
|
#include "../SDL_sysvideo.h"
|
||||||
|
|
||||||
#define _THIS SDL_VideoDevice *this
|
#define DEBUG 1
|
||||||
|
|
||||||
|
#define SDL_DFB_RELEASE(x) do { if ( x ) { x->Release(x); x = NULL; } } while (0)
|
||||||
|
#define SDL_DFB_FREE(x) do { if ( x ) { SDL_free(x); x = NULL; } } while (0)
|
||||||
|
#define SDL_DFB_UNLOCK(x) do { if ( x ) { x->Unlock(x); } } while (0)
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#define SDL_DFB_DEBUG(x...) do { fprintf(LOG_CHANNEL, "%s:", __FUNCTION__); fprintf(LOG_CHANNEL, x); } while (0)
|
||||||
|
#define SDL_DFB_DEBUGC(x...) do { fprintf(LOG_CHANNEL, x); } while (0)
|
||||||
|
#else
|
||||||
|
#define SDL_DFB_DEBUG(x...) do { } while (0)
|
||||||
|
#define SDL_DFB_DEBUGC(x...) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SDL_DFB_CONTEXT "SDL_DirectFB"
|
||||||
|
|
||||||
|
#define SDL_DFB_ERR(x...) \
|
||||||
|
do { \
|
||||||
|
fprintf(LOG_CHANNEL, "%s: %s <%d>:\n\t", \
|
||||||
|
SDL_DFB_CONTEXT, __FILE__, __LINE__ ); \
|
||||||
|
fprintf(LOG_CHANNEL, x ); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SDL_DFB_CHECK(x...) \
|
||||||
|
do { \
|
||||||
|
ret = x; \
|
||||||
|
if (ret != DFB_OK) { \
|
||||||
|
fprintf(LOG_CHANNEL, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
|
||||||
|
SDL_SetError( #x, DirectFBErrorString (ret) ); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SDL_DFB_CHECKERR(x...) \
|
||||||
|
do { \
|
||||||
|
ret = x; \
|
||||||
|
if (ret != DFB_OK) { \
|
||||||
|
fprintf(LOG_CHANNEL, "%s <%d>:\n", __FILE__, __LINE__ ); \
|
||||||
|
fprintf(LOG_CHANNEL, "\t%s\n", #x ); \
|
||||||
|
fprintf(LOG_CHANNEL, "\t%s\n", DirectFBErrorString (ret) ); \
|
||||||
|
SDL_SetError( #x, DirectFBErrorString (ret) ); \
|
||||||
|
goto error; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SDL_DFB_CALLOC(r, n, s) \
|
||||||
|
do { \
|
||||||
|
r = SDL_calloc (n, s); \
|
||||||
|
if (!(r)) { \
|
||||||
|
fprintf( LOG_CHANNEL, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
|
||||||
|
SDL_OutOfMemory(); \
|
||||||
|
goto error; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* Private display data */
|
/* Private display data */
|
||||||
|
|
||||||
struct SDL_PrivateVideoData
|
#define SDL_DFB_DEVICEDATA(dev) DFB_DeviceData *devdata = (DFB_DeviceData *) ((dev)->driverdata)
|
||||||
|
#define SDL_DFB_WINDOWDATA(win) DFB_WindowData *windata = ((win) ? (DFB_WindowData *) ((win)->driverdata) : NULL)
|
||||||
|
#define SDL_DFB_DISPLAYDATA(dev, win) DFB_DisplayData *dispdata = ((win && dev) ? (DFB_DisplayData *) (dev)->displays[(win)->display].driverdata : NULL)
|
||||||
|
|
||||||
|
typedef struct _DFB_DisplayData DFB_DisplayData;
|
||||||
|
|
||||||
|
#define DFB_MAX_SCREENS 10
|
||||||
|
#define DFB_MAX_MODES 50
|
||||||
|
|
||||||
|
struct _DFB_DisplayData
|
||||||
|
{
|
||||||
|
IDirectFBDisplayLayer *layer;
|
||||||
|
DFBSurfacePixelFormat pixelformat;
|
||||||
|
DFBDisplayLayerID vidID;
|
||||||
|
|
||||||
|
int cw;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
int nummodes;
|
||||||
|
SDL_DisplayMode *modelist;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
WMcursor *last_cursor;
|
||||||
|
WMcursor *blank_cursor;
|
||||||
|
WMcursor *default_cursor;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _DFB_WindowData DFB_WindowData;
|
||||||
|
struct _DFB_WindowData
|
||||||
|
{
|
||||||
|
IDirectFBSurface *surface;
|
||||||
|
IDirectFBPalette *palette;
|
||||||
|
IDirectFBWindow *window;
|
||||||
|
IDirectFBGL *gl_context;
|
||||||
|
IDirectFBEventBuffer *eventbuffer;
|
||||||
|
DFBWindowID windowID;
|
||||||
|
int id; // SDL window id
|
||||||
|
DFB_WindowData *next;
|
||||||
|
u8 opacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _DFB_DeviceData DFB_DeviceData;
|
||||||
|
struct _DFB_DeviceData
|
||||||
{
|
{
|
||||||
int initialized;
|
int initialized;
|
||||||
|
|
||||||
IDirectFB *dfb;
|
IDirectFB *dfb;
|
||||||
IDirectFBDisplayLayer *layer;
|
int mouse;
|
||||||
IDirectFBEventBuffer *eventbuffer;
|
int keyboard;
|
||||||
|
DFB_WindowData *firstwin;
|
||||||
|
|
||||||
int nummodes;
|
int numscreens;
|
||||||
SDL_Rect **modelist;
|
DFBScreenID screenid[DFB_MAX_SCREENS];
|
||||||
|
DFBDisplayLayerID gralayer[DFB_MAX_SCREENS];
|
||||||
|
DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS];
|
||||||
|
|
||||||
/* MGA CRTC2 support */
|
// auxiliary integer for callbacks
|
||||||
int enable_mga_crtc2;
|
int aux;
|
||||||
int mga_crtc2_stretch;
|
|
||||||
float mga_crtc2_stretch_overscan;
|
// OpenGL
|
||||||
IDirectFBDisplayLayer *c2layer;
|
void (*glFinish) (void);
|
||||||
IDirectFBSurface *c2frame;
|
void (*glFlush) (void);
|
||||||
DFBRectangle c2ssize; /* Real screen size */
|
|
||||||
DFBRectangle c2dsize; /* Stretched screen size */
|
|
||||||
DFBRectangle c2framesize; /* CRTC2 screen size */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HIDDEN (this->hidden)
|
struct SDL_GLDriverData
|
||||||
|
{
|
||||||
|
int gl_active; /* to stop switching drivers while we have a valid context */
|
||||||
|
|
||||||
void SetDirectFBerror(const char *function, DFBResult code);
|
#if SDL_DIRECTFB_OPENGL
|
||||||
|
IDirectFBGL *gl_context;
|
||||||
|
#endif /* SDL_DIRECTFB_OPENGL */
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _SDL_DirectFB_video_h */
|
#endif /* _SDL_DirectFB_video_h */
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
||||||
|
|
|
@ -1,290 +0,0 @@
|
||||||
/*
|
|
||||||
SDL - Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2006 Sam Lantinga
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Sam Lantinga
|
|
||||||
slouken@libsdl.org
|
|
||||||
*/
|
|
||||||
#include "SDL_config.h"
|
|
||||||
|
|
||||||
/* This is the DirectFB implementation of YUV video overlays */
|
|
||||||
|
|
||||||
#include "SDL_video.h"
|
|
||||||
#include "SDL_DirectFB_yuv.h"
|
|
||||||
#include "../SDL_yuvfuncs.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* The functions used to manipulate software video overlays */
|
|
||||||
static struct private_yuvhwfuncs directfb_yuvfuncs = {
|
|
||||||
DirectFB_LockYUVOverlay,
|
|
||||||
DirectFB_UnlockYUVOverlay,
|
|
||||||
DirectFB_DisplayYUVOverlay,
|
|
||||||
DirectFB_FreeYUVOverlay
|
|
||||||
};
|
|
||||||
|
|
||||||
struct private_yuvhwdata
|
|
||||||
{
|
|
||||||
DFBDisplayLayerID layer_id;
|
|
||||||
|
|
||||||
IDirectFBDisplayLayer *layer;
|
|
||||||
IDirectFBSurface *surface;
|
|
||||||
|
|
||||||
/* These are just so we don't have to allocate them separately */
|
|
||||||
Uint16 pitches[3];
|
|
||||||
Uint8 *planes[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
static DFBEnumerationResult
|
|
||||||
enum_layers_callback(DFBDisplayLayerID id,
|
|
||||||
DFBDisplayLayerDescription desc, void *data)
|
|
||||||
{
|
|
||||||
struct private_yuvhwdata *hwdata = (struct private_yuvhwdata *) data;
|
|
||||||
|
|
||||||
/* we don't want the primary */
|
|
||||||
if (id == DLID_PRIMARY)
|
|
||||||
return DFENUM_OK;
|
|
||||||
|
|
||||||
/* take the one with a surface for video */
|
|
||||||
if ((desc.caps & DLCAPS_SURFACE) && (desc.type & DLTF_VIDEO)) {
|
|
||||||
hwdata->layer_id = id;
|
|
||||||
|
|
||||||
return DFENUM_CANCEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DFENUM_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static DFBResult
|
|
||||||
CreateYUVSurface(_THIS, struct private_yuvhwdata *hwdata,
|
|
||||||
int width, int height, Uint32 format)
|
|
||||||
{
|
|
||||||
DFBResult ret;
|
|
||||||
IDirectFB *dfb = HIDDEN->dfb;
|
|
||||||
IDirectFBDisplayLayer *layer;
|
|
||||||
DFBDisplayLayerConfig conf;
|
|
||||||
|
|
||||||
ret = dfb->EnumDisplayLayers(dfb, enum_layers_callback, hwdata);
|
|
||||||
if (ret) {
|
|
||||||
SetDirectFBerror("IDirectFB::EnumDisplayLayers", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hwdata->layer_id)
|
|
||||||
return DFB_UNSUPPORTED;
|
|
||||||
|
|
||||||
ret = dfb->GetDisplayLayer(dfb, hwdata->layer_id, &layer);
|
|
||||||
if (ret) {
|
|
||||||
SetDirectFBerror("IDirectFB::GetDisplayLayer", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
conf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
|
|
||||||
conf.width = width;
|
|
||||||
conf.height = height;
|
|
||||||
|
|
||||||
switch (format) {
|
|
||||||
case SDL_YV12_OVERLAY:
|
|
||||||
conf.pixelformat = DSPF_YV12;
|
|
||||||
break;
|
|
||||||
case SDL_IYUV_OVERLAY:
|
|
||||||
conf.pixelformat = DSPF_I420;
|
|
||||||
break;
|
|
||||||
case SDL_YUY2_OVERLAY:
|
|
||||||
conf.pixelformat = DSPF_YUY2;
|
|
||||||
break;
|
|
||||||
case SDL_UYVY_OVERLAY:
|
|
||||||
conf.pixelformat = DSPF_UYVY;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "SDL_DirectFB: Unsupported YUV format (0x%08x)!\n",
|
|
||||||
format);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need to set coop level or newer DirectFB versions will fail here. */
|
|
||||||
ret = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
|
|
||||||
if (ret) {
|
|
||||||
SetDirectFBError
|
|
||||||
("IDirectFBDisplayLayer::SetCooperativeLevel() failed", ret);
|
|
||||||
layer->Release(layer);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = layer->SetConfiguration(layer, &conf);
|
|
||||||
if (ret) {
|
|
||||||
SetDirectFBerror("IDirectFBDisplayLayer::SetConfiguration", ret);
|
|
||||||
layer->Release(layer);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = layer->GetSurface(layer, &hwdata->surface);
|
|
||||||
if (ret) {
|
|
||||||
SetDirectFBerror("IDirectFBDisplayLayer::GetSurface", ret);
|
|
||||||
layer->Release(layer);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
hwdata->layer = layer;
|
|
||||||
|
|
||||||
return DFB_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Overlay *
|
|
||||||
DirectFB_CreateYUVOverlay(_THIS, int width, int height, Uint32 format,
|
|
||||||
SDL_Surface * display)
|
|
||||||
{
|
|
||||||
SDL_Overlay *overlay;
|
|
||||||
struct private_yuvhwdata *hwdata;
|
|
||||||
|
|
||||||
/* Create the overlay structure */
|
|
||||||
overlay = SDL_calloc(1, sizeof(SDL_Overlay));
|
|
||||||
if (!overlay) {
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in the basic members */
|
|
||||||
overlay->format = format;
|
|
||||||
overlay->w = width;
|
|
||||||
overlay->h = height;
|
|
||||||
|
|
||||||
/* Set up the YUV surface function structure */
|
|
||||||
overlay->hwfuncs = &directfb_yuvfuncs;
|
|
||||||
|
|
||||||
/* Create the pixel data and lookup tables */
|
|
||||||
hwdata = SDL_calloc(1, sizeof(struct private_yuvhwdata));
|
|
||||||
overlay->hwdata = hwdata;
|
|
||||||
if (!hwdata) {
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
SDL_FreeYUVOverlay(overlay);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CreateYUVSurface(this, hwdata, width, height, format)) {
|
|
||||||
SDL_FreeYUVOverlay(overlay);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
overlay->hw_overlay = 1;
|
|
||||||
|
|
||||||
/* Set up the plane pointers */
|
|
||||||
overlay->pitches = hwdata->pitches;
|
|
||||||
overlay->pixels = hwdata->planes;
|
|
||||||
switch (format) {
|
|
||||||
case SDL_YV12_OVERLAY:
|
|
||||||
case SDL_IYUV_OVERLAY:
|
|
||||||
overlay->planes = 3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
overlay->planes = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We're all done.. */
|
|
||||||
return overlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
DirectFB_LockYUVOverlay(_THIS, SDL_Overlay * overlay)
|
|
||||||
{
|
|
||||||
DFBResult ret;
|
|
||||||
void *data;
|
|
||||||
int pitch;
|
|
||||||
IDirectFBSurface *surface = overlay->hwdata->surface;
|
|
||||||
|
|
||||||
ret = surface->Lock(surface, DSLF_READ | DSLF_WRITE, &data, &pitch);
|
|
||||||
if (ret) {
|
|
||||||
SetDirectFBerror("IDirectFBSurface::Lock", ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the pitch and offset values for the overlay */
|
|
||||||
overlay->pitches[0] = (Uint16) pitch;
|
|
||||||
overlay->pixels[0] = (Uint8 *) data;
|
|
||||||
|
|
||||||
switch (overlay->format) {
|
|
||||||
case SDL_YV12_OVERLAY:
|
|
||||||
case SDL_IYUV_OVERLAY:
|
|
||||||
/* Add the two extra planes */
|
|
||||||
overlay->pitches[1] = overlay->pitches[0] / 2;
|
|
||||||
overlay->pitches[2] = overlay->pitches[0] / 2;
|
|
||||||
overlay->pixels[1] =
|
|
||||||
overlay->pixels[0] + overlay->pitches[0] * overlay->h;
|
|
||||||
overlay->pixels[2] =
|
|
||||||
overlay->pixels[1] + overlay->pitches[1] * overlay->h / 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Only one plane, no worries */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DirectFB_UnlockYUVOverlay(_THIS, SDL_Overlay * overlay)
|
|
||||||
{
|
|
||||||
IDirectFBSurface *surface = overlay->hwdata->surface;
|
|
||||||
|
|
||||||
overlay->pixels[0] = overlay->pixels[1] = overlay->pixels[2] = NULL;
|
|
||||||
|
|
||||||
surface->Unlock(surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
DirectFB_DisplayYUVOverlay(_THIS, SDL_Overlay * overlay, SDL_Rect * src,
|
|
||||||
SDL_Rect * dst)
|
|
||||||
{
|
|
||||||
DFBResult ret;
|
|
||||||
DFBDisplayLayerConfig conf;
|
|
||||||
IDirectFBDisplayLayer *primary = HIDDEN->layer;
|
|
||||||
IDirectFBDisplayLayer *layer = overlay->hwdata->layer;
|
|
||||||
|
|
||||||
primary->GetConfiguration(primary, &conf);
|
|
||||||
|
|
||||||
ret = layer->SetScreenLocation(layer,
|
|
||||||
dst->x / (float) conf.width,
|
|
||||||
dst->y / (float) conf.height,
|
|
||||||
dst->w / (float) conf.width,
|
|
||||||
dst->h / (float) conf.height);
|
|
||||||
if (ret) {
|
|
||||||
SetDirectFBerror("IDirectFBDisplayLayer::SetScreenLocation", ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DirectFB_FreeYUVOverlay(_THIS, SDL_Overlay * overlay)
|
|
||||||
{
|
|
||||||
struct private_yuvhwdata *hwdata;
|
|
||||||
|
|
||||||
hwdata = overlay->hwdata;
|
|
||||||
if (hwdata) {
|
|
||||||
if (hwdata->surface)
|
|
||||||
hwdata->surface->Release(hwdata->surface);
|
|
||||||
|
|
||||||
if (hwdata->layer)
|
|
||||||
hwdata->layer->Release(hwdata->layer);
|
|
||||||
|
|
||||||
free(hwdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
Loading…
Add table
Add a link
Reference in a new issue