This source file includes following definitions.
- DirectFBVid_GetCtxSizeOf
- DirectFBVid_DrawHLineWrapper
- DirectFBVid_DrawHLineAlphaWrapper
- DirectFBVid_DrawRectangleWrapper
- DirectFBVid_CtxPrimaryLock
- enum_input_device
- DirectFBVid_InitAndCreateSurface
- DirectFBVid_CtxPrimaryUnlock
- DirectFBVid_CtxGetWidth
- DirectFBVid_CtxGetHeight
- DirectFBVid_CtxGetPrimary
- DirectFBVid_CtxGetPixelFormat
- DirectFBVid_CtxIsHwMemory
- DirectFBVid_CtxPrimaryFlip
- DirectFBVid_CtxSetDisableDisplay
- DirectFBVid_CtxGetDisableDisplay
- DirectFBVid_CtxSetDisableAcceleration
- DirectFBVid_CtxGetDisableAcceleration
- DirectFBVid_CtxSetIsInit
- DirectFBVid_CtxSetFlipMode
- DirectFBVid_CtxPrimaryProcessGetAccelerationMask
- DirectFBVid_ShutdownWrapper
- DirectFBVid_BlitWrapper
- DirectFBVid_ProcessMessageQueueWrapper
- DirectFBVid_TranslatePixelFormatToGPAC
- DirectFBVid_TranslatePixelFormatFromGPAC
- directfb_translate_key
#include <directfb.h>
#include <directfb_strings.h>
#include <directfb_util.h>
#include <direct/util.h>
#include <gpac/constants.h>
#include <gpac/events_constants.h>
#include <gpac/events.h>
#include "directfb_out.h"
static int do_xor = 0;
#define DFBCHECK(x...) \
do { \
err = x; \
if (err != DFB_OK) { \
fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
DirectFBErrorFatal( #x, err ); \
} \
} while (0)
#define SET_DRAWING_FLAGS( flags ) \
ctx->primary->SetDrawingFlags( ctx->primary, (flags) | (do_xor ? DSDRAW_XOR : 0) )
struct __DirectFBVidCtx
{
IDirectFB *dfb;
IDirectFBSurface *primary;
u32 width, height, pixel_format;
Bool use_systems_memory, disable_acceleration, disable_aa, is_init, disable_display;
int accel_drawline, accel_fillrect;
DFBSurfaceFlipFlags flip_mode;
IDirectFBEventBuffer *events;
IDirectFBInputDevice *mouse;
IDirectFBWindow *window;
IDirectFBDisplayLayer *layer;
};
size_t DirectFBVid_GetCtxSizeOf(void)
{
return sizeof(DirectFBVidCtx);
}
typedef struct _DeviceInfo DeviceInfo;
struct _DeviceInfo {
DFBInputDeviceID device_id;
DFBInputDeviceDescription desc;
DeviceInfo *next;
};
void DirectFBVid_DrawHLineWrapper(DirectFBVidCtx *ctx, u32 x, u32 y, u32 length, u8 r, u8 g, u8 b)
{
SET_DRAWING_FLAGS( DSDRAW_NOFX );
ctx->primary->SetColor(ctx->primary, r, g, b, 0xFF);
ctx->primary->FillRectangle(ctx->primary, x, y,length, 1);
}
void DirectFBVid_DrawHLineAlphaWrapper(DirectFBVidCtx *ctx, u32 x, u32 y, u32 length, u8 r, u8 g, u8 b, u8 alpha)
{
SET_DRAWING_FLAGS( DSDRAW_BLEND );
ctx->primary->SetColor(ctx->primary, r, g, b, alpha);
ctx->primary->FillRectangle(ctx->primary, x, y, length, 1);
}
void DirectFBVid_DrawRectangleWrapper(DirectFBVidCtx *ctx, u32 x, u32 y, u32 width, u32 height, u8 r, u8 g, u8 b, u8 a)
{
SET_DRAWING_FLAGS( DSDRAW_NOFX );
ctx->primary->SetColor(ctx->primary, r, g, b, a);
ctx->primary->FillRectangle(ctx->primary, x, y, width, height);
}
u32 DirectFBVid_CtxPrimaryLock(DirectFBVidCtx *ctx, void **buf, u32 *pitch)
{
DFBResult ret = ctx->primary->Lock(ctx->primary, DSLF_READ | DSLF_WRITE, buf, pitch);
if (ret != DFB_OK) return 1;
return 0;
}
static DFBEnumerationResult enum_input_device(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, void *data )
{
DeviceInfo **devices = data;
DeviceInfo *device = malloc(sizeof(DeviceInfo) );
device->device_id = device_id;
device->desc = desc;
device->next = *devices;
*devices = device;
return 0;
}
u32 DirectFBVid_TranslatePixelFormatToGPAC(u32 dfbpf);
void DirectFBVid_InitAndCreateSurface(DirectFBVidCtx *ctx, u32 window_mode)
{
DFBResult err;
DFBSurfaceDescription dsc;
DFBSurfacePixelFormat dfbpf;
DeviceInfo *devices = NULL;
{
int i, argc=2, argc_ro=2;
char **argv = malloc(argc*sizeof(char*));
char *argv_ro[2];
argv_ro[0]=argv[0]=strdup("gpac");
if (window_mode == WINDOW_SDL) {
argv_ro[1]=argv[1]=strdup("--dfb:system=sdl");
} else {
argv_ro[1]=argv[1]=strdup("--dfb:system=x11");
}
DFBCHECK(DirectFBInit(&argc, &argv));
for (i=0; i<argc_ro; i++)
free(argv_ro[i]);
free(argv);
}
DFBCHECK(DirectFBSetOption ("bg-none", NULL));
DFBCHECK(DirectFBSetOption ("no-init-layer", NULL));
DFBCHECK(DirectFBCreate( &(ctx->dfb) ));
ctx->dfb->EnumInputDevices(ctx->dfb, enum_input_device, &devices );
if (devices->desc.type & DIDTF_JOYSTICK) {
DFBCHECK(ctx->dfb->GetInputDevice(ctx->dfb, devices->device_id, &(ctx->mouse)));
}
DFBCHECK(ctx->dfb->CreateInputEventBuffer(ctx->dfb, DICAPS_KEYS, DFB_FALSE, &(ctx->events) ));
DFBCHECK(ctx->dfb->SetCooperativeLevel( ctx->dfb, DFSCL_FULLSCREEN ));
dsc.flags = DSDESC_CAPS;
dsc.caps = DSCAPS_PRIMARY | DSCAPS_DOUBLE;
if (ctx->use_systems_memory) dsc.caps |= DSCAPS_SYSTEMONLY;
DFBCHECK(ctx->dfb->CreateSurface( ctx->dfb, &dsc, &(ctx->primary) ));
ctx->primary->GetPixelFormat( ctx->primary, &dfbpf );
ctx->pixel_format = DirectFBVid_TranslatePixelFormatToGPAC(dfbpf);
ctx->primary->GetSize( ctx->primary, &(ctx->width), &(ctx->height) );
ctx->primary->Clear( ctx->primary, 0, 0, 0, 0xFF);
}
void DirectFBVid_CtxPrimaryUnlock(DirectFBVidCtx *ctx)
{
ctx->primary->Unlock(ctx->primary);
}
u32 DirectFBVid_CtxGetWidth(DirectFBVidCtx *ctx)
{
return ctx->width;
}
u32 DirectFBVid_CtxGetHeight(DirectFBVidCtx *ctx)
{
return ctx->height;
}
void *DirectFBVid_CtxGetPrimary(DirectFBVidCtx *ctx)
{
return ctx->primary;
}
u32 DirectFBVid_CtxGetPixelFormat(DirectFBVidCtx *ctx)
{
return ctx->pixel_format;
}
Bool DirectFBVid_CtxIsHwMemory(DirectFBVidCtx *ctx)
{
return ctx->use_systems_memory;
}
u32 DirectFBVid_CtxPrimaryFlip(DirectFBVidCtx *ctx)
{
return ctx->primary->Flip(ctx->primary, NULL, ctx->flip_mode);
}
void DirectFBVid_CtxSetDisableDisplay(DirectFBVidCtx *ctx, Bool val)
{
ctx->disable_display = val;
}
Bool DirectFBVid_CtxGetDisableDisplay(DirectFBVidCtx *ctx)
{
return ctx->disable_display;
}
void DirectFBVid_CtxSetDisableAcceleration(DirectFBVidCtx *ctx, Bool val)
{
ctx->disable_acceleration = val;
}
Bool DirectFBVid_CtxGetDisableAcceleration(DirectFBVidCtx *ctx)
{
return ctx->disable_acceleration;
}
void DirectFBVid_CtxSetIsInit(DirectFBVidCtx *ctx, Bool val)
{
ctx->is_init = val;
}
void DirectFBVid_CtxSetFlipMode(DirectFBVidCtx *ctx, u32 flip_mode)
{
ctx->flip_mode = DSFLIP_BLIT;
switch(flip_mode) {
case FLIP_WAITFORSYNC:
ctx->flip_mode |= DSFLIP_WAITFORSYNC;
break;
case FLIP_WAIT:
ctx->flip_mode |= DSFLIP_WAIT;
break;
case FLIP_ONSYNC:
ctx->flip_mode |= DSFLIP_ONSYNC;
break;
case FLIP_SWAP:
ctx->flip_mode &= ~DSFLIP_BLIT;
break;
}
}
void DirectFBVid_CtxPrimaryProcessGetAccelerationMask(DirectFBVidCtx *ctx)
{
DFBAccelerationMask mask;
ctx->primary->GetAccelerationMask( ctx->primary, NULL, &mask );
if (mask & DFXL_DRAWLINE )
ctx->accel_drawline = 1;
if (mask & DFXL_FILLRECTANGLE)
ctx->accel_fillrect = 1;
}
u32 DirectFBVid_ShutdownWrapper(DirectFBVidCtx *ctx)
{
if (!ctx->is_init) return 1;
ctx->primary->Release( ctx->primary );
ctx->events->Release( ctx->events );
ctx->dfb->Release( ctx->dfb );
ctx->is_init = 0;
return 0;
}
u32 DirectFBVid_TranslatePixelFormatFromGPAC(u32 gpacpf);
u32 DirectFBVid_BlitWrapper(DirectFBVidCtx *ctx, u32 video_src_width, u32 video_src_height, u32 video_src_pixel_format, char *video_src_buffer, s32 video_src_pitch_y, u32 src_wnd_x, u32 src_wnd_y, u32 src_wnd_w, u32 src_wnd_h, u32 dst_wnd_x, u32 dst_wnd_y, u32 dst_wnd_w, u32 dst_wnd_h, u32 overlay_type)
{
DFBResult res;
DFBSurfaceDescription srcdesc;
IDirectFBSurface *src;
DFBRectangle dfbsrc, dfbdst;
if (overlay_type != 0) return 1;
if (ctx->disable_display) return 0;
memset(&srcdesc, 0, sizeof(srcdesc));
srcdesc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_PREALLOCATED;
srcdesc.width = video_src_width;
srcdesc.height = video_src_height;
srcdesc.pixelformat = DirectFBVid_TranslatePixelFormatFromGPAC(video_src_pixel_format);
srcdesc.preallocated[0].data = video_src_buffer;
srcdesc.preallocated[0].pitch = video_src_pitch_y;
switch (video_src_pixel_format) {
case GF_PIXEL_ARGB:
case GF_PIXEL_RGBA:
ctx->primary->SetBlittingFlags(ctx->primary, DSBLIT_BLEND_ALPHACHANNEL);
break;
default:
ctx->primary->SetBlittingFlags(ctx->primary, DSBLIT_NOFX);
}
res = ctx->dfb->CreateSurface(ctx->dfb, &srcdesc, &src);
if (res != DFB_OK) {
return 1;
}
dfbsrc.x = src_wnd_x;
dfbsrc.y = src_wnd_y;
dfbsrc.w = src_wnd_w;
dfbsrc.h = src_wnd_h;
if (!src_wnd_x && !src_wnd_y && (dst_wnd_w==src_wnd_w) && (dst_wnd_h==src_wnd_h)) {
ctx->primary->Blit(ctx->primary, src, &dfbsrc, dst_wnd_x, dst_wnd_y);
} else {
dfbdst.x = dst_wnd_x;
dfbdst.y = dst_wnd_y;
dfbdst.w = dst_wnd_w;
dfbdst.h = dst_wnd_h;
ctx->primary->StretchBlit(ctx->primary, src, &dfbsrc, &dfbdst);
}
src->Release(src);
return 0;
}
void directfb_translate_key(DFBInputDeviceKeyIdentifier DirectFBkey, u32 *flags, u32 *key_code);
u32 DirectFBVid_ProcessMessageQueueWrapper(DirectFBVidCtx *ctx, u8 *type, u32 *flags, u32 *key_code, s32 *x, s32 *y, u32 *button)
{
DFBInputEvent directfb_evt;
if (ctx->events->GetEvent( ctx->events, DFB_EVENT(&directfb_evt) ) == DFB_OK)
{
switch (directfb_evt.type) {
case DIET_KEYPRESS:
case DIET_KEYRELEASE:
directfb_translate_key(directfb_evt.key_id, flags, key_code);
*type = (directfb_evt.type == DIET_KEYPRESS) ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP;
break;
case DIET_BUTTONPRESS:
case DIET_BUTTONRELEASE:
*type = (directfb_evt.type == DIET_BUTTONPRESS) ? GF_EVENT_MOUSEUP : GF_EVENT_MOUSEDOWN;
switch(directfb_evt.button) {
case DIBI_LEFT:
*button = GF_MOUSE_LEFT;
break;
case DIBI_RIGHT:
*button = GF_MOUSE_RIGHT;
break;
case DIBI_MIDDLE:
*button = GF_MOUSE_MIDDLE;
break;
default:
break;
}
break;
case DIET_AXISMOTION:
*type = GF_EVENT_MOUSEMOVE;
ctx->mouse->GetXY(ctx->mouse, x, y);
default:
break;
}
return 0;
}
return 1;
}
u32 DirectFBVid_TranslatePixelFormatToGPAC(u32 dfbpf)
{
switch (dfbpf) {
case DSPF_RGB16:
return GF_PIXEL_RGB_565;
case DSPF_RGB555:
return GF_PIXEL_RGB_555;
case DSPF_RGB24:
return GF_PIXEL_RGB_24;
case DSPF_RGB32:
return GF_PIXEL_RGB_32;
case DSPF_ARGB:
return GF_PIXEL_ARGB;
default:
return 0;
}
}
u32 DirectFBVid_TranslatePixelFormatFromGPAC(u32 gpacpf)
{
switch (gpacpf) {
case GF_PIXEL_RGB_565:
return DSPF_RGB16;
case GF_PIXEL_RGB_555 :
return DSPF_RGB555;
case GF_PIXEL_BGR_24 :
return DSPF_RGB24;
case GF_PIXEL_RGB_24 :
return DSPF_RGB24;
case GF_PIXEL_RGB_32 :
return DSPF_RGB32;
case GF_PIXEL_ARGB:
return DSPF_ARGB;
case GF_PIXEL_RGBA:
return DSPF_ARGB;
case GF_PIXEL_YUY2 :
return DSPF_YUY2;
case GF_PIXEL_YV12 :
return DSPF_YV12;
default:
;
}
return 0;
}
void directfb_translate_key(DFBInputDeviceKeyIdentifier DirectFBkey, u32 *flags, u32 *key_code)
{
switch (DirectFBkey) {
case DIKI_BACKSPACE:
*key_code = GF_KEY_BACKSPACE;
break;
case DIKI_TAB:
*key_code = GF_KEY_TAB;
break;
case DIKI_ENTER:
*key_code = GF_KEY_ENTER;
break;
case DIKI_ESCAPE:
*key_code = GF_KEY_ESCAPE;
break;
case DIKI_SPACE:
*key_code = GF_KEY_SPACE;
break;
case DIKI_SHIFT_L:
case DIKI_SHIFT_R:
*key_code = GF_KEY_SHIFT;
break;
case DIKI_CONTROL_L:
case DIKI_CONTROL_R:
*key_code = GF_KEY_CONTROL;
break;
case DIKI_ALT_L:
case DIKI_ALT_R:
*key_code = GF_KEY_ALT;
break;
case DIKI_CAPS_LOCK:
*key_code = GF_KEY_CAPSLOCK;
break;
case DIKI_META_L:
case DIKI_META_R:
*key_code = GF_KEY_META;
break;
case DIKI_KP_EQUAL:
*key_code = GF_KEY_EQUALS;
break;
case DIKI_SUPER_L:
case DIKI_SUPER_R:
*key_code = GF_KEY_WIN;
break;
case DIKI_A:
*key_code = GF_KEY_A;
break;
case DIKI_B:
*key_code = GF_KEY_B;
break;
case DIKI_C:
*key_code = GF_KEY_C;
break;
case DIKI_D:
*key_code = GF_KEY_D;
break;
case DIKI_E:
*key_code = GF_KEY_E;
break;
case DIKI_F:
*key_code = GF_KEY_F;
break;
case DIKI_G:
*key_code = GF_KEY_G;
break;
case DIKI_H:
*key_code = GF_KEY_H;
break;
case DIKI_I:
*key_code = GF_KEY_I;
break;
case DIKI_J:
*key_code = GF_KEY_J;
break;
case DIKI_K:
*key_code = GF_KEY_K;
break;
case DIKI_L:
*key_code = GF_KEY_L;
break;
case DIKI_M:
*key_code = GF_KEY_M;
break;
case DIKI_N:
*key_code = GF_KEY_N;
break;
case DIKI_O:
*key_code = GF_KEY_O;
break;
case DIKI_P:
*key_code = GF_KEY_P;
break;
case DIKI_Q:
*key_code = GF_KEY_Q;
break;
case DIKI_R:
*key_code = GF_KEY_R;
break;
case DIKI_S:
*key_code = GF_KEY_S;
break;
case DIKI_T:
*key_code = GF_KEY_T;
break;
case DIKI_U:
*key_code = GF_KEY_U;
break;
case DIKI_V:
*key_code = GF_KEY_V;
break;
case DIKI_W:
*key_code = GF_KEY_W;
break;
case DIKI_X:
*key_code = GF_KEY_X;
break;
case DIKI_Y:
*key_code = GF_KEY_Y;
break;
case DIKI_Z:
*key_code = GF_KEY_Z;
break;
case DIKI_PRINT:
*key_code = GF_KEY_PRINTSCREEN;
break;
case DIKI_SCROLL_LOCK:
*key_code = GF_KEY_SCROLL;
break;
case DIKI_PAUSE:
*key_code = GF_KEY_PAUSE;
break;
case DIKI_INSERT:
*key_code = GF_KEY_INSERT;
break;
case DIKI_DELETE:
*key_code = GF_KEY_DEL;
break;
case DIKI_HOME:
*key_code = GF_KEY_HOME;
break;
case DIKI_END:
*key_code = GF_KEY_END;
break;
case DIKI_PAGE_UP:
*key_code = GF_KEY_PAGEUP;
break;
case DIKI_PAGE_DOWN:
*key_code = GF_KEY_PAGEDOWN;
break;
case DIKI_UP:
*key_code = GF_KEY_UP;
break;
case DIKI_DOWN:
*key_code = GF_KEY_DOWN;
break;
case DIKI_RIGHT:
*key_code = GF_KEY_RIGHT;
break;
case DIKI_LEFT:
*key_code = GF_KEY_LEFT;
break;
case DIKI_NUM_LOCK:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_NUMLOCK;
break;
case DIKI_KP_DIV:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_SLASH;
break;
case DIKI_KP_MULT:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_STAR;
break;
case DIKI_KP_MINUS:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_HYPHEN;
break;
case DIKI_KP_PLUS:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_PLUS;
break;
case DIKI_KP_ENTER:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_ENTER;
break;
case DIKI_KP_DECIMAL:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_FULLSTOP;
break;
case DIKI_KP_0:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_0;
break;
case DIKI_KP_1:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_1;
break;
case DIKI_KP_2:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_2;
break;
case DIKI_KP_3:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_3;
break;
case DIKI_KP_4:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_4;
break;
case DIKI_KP_5:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_5;
break;
case DIKI_KP_6:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_6;
break;
case DIKI_KP_7:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_7;
break;
case DIKI_KP_8:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_8;
break;
case DIKI_KP_9:
*flags = GF_KEY_EXT_NUMPAD;
*key_code = GF_KEY_9;
break;
case DIKI_F1:
*key_code = GF_KEY_F1;
break;
case DIKI_F2:
*key_code = GF_KEY_F2;
break;
case DIKI_F3:
*key_code = GF_KEY_F3;
break;
case DIKI_F4:
*key_code = GF_KEY_F4;
break;
case DIKI_F5:
*key_code = GF_KEY_F5;
break;
case DIKI_F6:
*key_code = GF_KEY_F6;
break;
case DIKI_F7:
*key_code = GF_KEY_F7;
break;
case DIKI_F8:
*key_code = GF_KEY_F8;
break;
case DIKI_F9:
*key_code = GF_KEY_F9;
break;
case DIKI_F10:
*key_code = GF_KEY_F10;
break;
case DIKI_F11:
*key_code = GF_KEY_F11;
break;
case DIKI_F12:
*key_code = GF_KEY_F12;
break;
default:
*key_code = GF_KEY_UNIDENTIFIED;
break;
}
}