From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/src/display/idirectfbscreen.c | 722 ++++++++++++++++++++++++++ 1 file changed, 722 insertions(+) create mode 100755 Source/DirectFB/src/display/idirectfbscreen.c (limited to 'Source/DirectFB/src/display/idirectfbscreen.c') diff --git a/Source/DirectFB/src/display/idirectfbscreen.c b/Source/DirectFB/src/display/idirectfbscreen.c new file mode 100755 index 0000000..9fcebdc --- /dev/null +++ b/Source/DirectFB/src/display/idirectfbscreen.c @@ -0,0 +1,722 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + 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 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include "idirectfbscreen.h" + +/* + * private data struct of IDirectFBScreen + */ +typedef struct { + int ref; /* reference counter */ + + CoreScreen *screen; + + DFBScreenID id; + DFBScreenDescription description; +} IDirectFBScreen_data; + +/******************************************************************************/ + +static DFBResult PatchMixerConfig ( DFBScreenMixerConfig *patched, + const DFBScreenMixerConfig *patch ); +static DFBResult PatchEncoderConfig( DFBScreenEncoderConfig *patched, + const DFBScreenEncoderConfig *patch ); +static DFBResult PatchOutputConfig ( DFBScreenOutputConfig *patched, + const DFBScreenOutputConfig *patch ); + +/******************************************************************************/ + +typedef struct { + CoreScreen *screen; + + DFBDisplayLayerCallback callback; + void *callback_ctx; +} EnumDisplayLayers_Context; + +static DFBEnumerationResult EnumDisplayLayers_Callback( CoreLayer *layer, + void *ctx ); + +/******************************************************************************/ + +static void +IDirectFBScreen_Destruct( IDirectFBScreen *thiz ) +{ +// IDirectFBScreen_data *data = (IDirectFBScreen_data*)thiz->priv; + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DirectResult +IDirectFBScreen_AddRef( IDirectFBScreen *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + data->ref++; + + return DFB_OK; +} + +static DirectResult +IDirectFBScreen_Release( IDirectFBScreen *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (--data->ref == 0) + IDirectFBScreen_Destruct( thiz ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetID( IDirectFBScreen *thiz, + DFBScreenID *id ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!id) + return DFB_INVARG; + + *id = data->id; + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetDescription( IDirectFBScreen *thiz, + DFBScreenDescription *desc ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!desc) + return DFB_INVARG; + + *desc = data->description; + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetSize( IDirectFBScreen *thiz, + int *ret_width, + int *ret_height ) +{ + DFBResult ret; + int width = 0; + int height = 0; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!ret_width && !ret_height) + return DFB_INVARG; + + ret = dfb_screen_get_screen_size( data->screen, &width, &height ); + + if (ret_width) + *ret_width = width; + + if (ret_height) + *ret_height = height; + + return ret; +} + +static DFBResult +IDirectFBScreen_EnumDisplayLayers( IDirectFBScreen *thiz, + DFBDisplayLayerCallback callbackfunc, + void *callbackdata ) +{ + EnumDisplayLayers_Context context; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!callbackfunc) + return DFB_INVARG; + + context.screen = data->screen; + context.callback = callbackfunc; + context.callback_ctx = callbackdata; + + dfb_layers_enumerate( EnumDisplayLayers_Callback, &context ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_SetPowerMode( IDirectFBScreen *thiz, + DFBScreenPowerMode mode ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + switch (mode) { + case DSPM_ON: + case DSPM_STANDBY: + case DSPM_SUSPEND: + case DSPM_OFF: + break; + + default: + return DFB_INVARG; + } + + return dfb_screen_set_powermode( data->screen, mode ); +} + +static DFBResult +IDirectFBScreen_WaitForSync( IDirectFBScreen *thiz ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + return dfb_screen_wait_vsync( data->screen ); +} + +static DFBResult +IDirectFBScreen_GetMixerDescriptions( IDirectFBScreen *thiz, + DFBScreenMixerDescription *descriptions ) +{ + int i; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!descriptions) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_MIXERS)) + return DFB_UNSUPPORTED; + + for (i=0; idescription.mixers; i++) + dfb_screen_get_mixer_info( data->screen, i, &descriptions[i] ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetMixerConfiguration( IDirectFBScreen *thiz, + int mixer, + DFBScreenMixerConfig *config ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_MIXERS)) + return DFB_UNSUPPORTED; + + if (mixer < 0 || mixer >= data->description.mixers) + return DFB_INVARG; + + return dfb_screen_get_mixer_config( data->screen, mixer, config ); +} + +static DFBResult +IDirectFBScreen_TestMixerConfiguration( IDirectFBScreen *thiz, + int mixer, + const DFBScreenMixerConfig *config, + DFBScreenMixerConfigFlags *failed ) +{ + DFBResult ret; + DFBScreenMixerConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSMCONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_MIXERS)) + return DFB_UNSUPPORTED; + + if (mixer < 0 || mixer >= data->description.mixers) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_mixer_config( data->screen, mixer, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchMixerConfig( &patched, config ); + if (ret) + return ret; + + /* Test the patched configuration. */ + return dfb_screen_test_mixer_config( data->screen, + mixer, &patched, failed ); +} + +static DFBResult +IDirectFBScreen_SetMixerConfiguration( IDirectFBScreen *thiz, + int mixer, + const DFBScreenMixerConfig *config ) +{ + DFBResult ret; + DFBScreenMixerConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSMCONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_MIXERS)) + return DFB_UNSUPPORTED; + + if (mixer < 0 || mixer >= data->description.mixers) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_mixer_config( data->screen, mixer, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchMixerConfig( &patched, config ); + if (ret) + return ret; + + /* Set the patched configuration. */ + return dfb_screen_set_mixer_config( data->screen, mixer, &patched ); +} + +static DFBResult +IDirectFBScreen_GetEncoderDescriptions( IDirectFBScreen *thiz, + DFBScreenEncoderDescription *descriptions ) +{ + int i; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!descriptions) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_ENCODERS)) + return DFB_UNSUPPORTED; + + for (i=0; idescription.encoders; i++) + dfb_screen_get_encoder_info( data->screen, i, &descriptions[i] ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetEncoderConfiguration( IDirectFBScreen *thiz, + int encoder, + DFBScreenEncoderConfig *config ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_ENCODERS)) + return DFB_UNSUPPORTED; + + if (encoder < 0 || encoder >= data->description.encoders) + return DFB_INVARG; + + return dfb_screen_get_encoder_config( data->screen, encoder, config ); +} + +static DFBResult +IDirectFBScreen_TestEncoderConfiguration( IDirectFBScreen *thiz, + int encoder, + const DFBScreenEncoderConfig *config, + DFBScreenEncoderConfigFlags *failed ) +{ + DFBResult ret; + DFBScreenEncoderConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSECONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_ENCODERS)) + return DFB_UNSUPPORTED; + + if (encoder < 0 || encoder >= data->description.encoders) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_encoder_config( data->screen, encoder, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchEncoderConfig( &patched, config ); + if (ret) + return ret; + + /* Test the patched configuration. */ + return dfb_screen_test_encoder_config( data->screen, + encoder, &patched, failed ); +} + +static DFBResult +IDirectFBScreen_SetEncoderConfiguration( IDirectFBScreen *thiz, + int encoder, + const DFBScreenEncoderConfig *config ) +{ + DFBResult ret; + DFBScreenEncoderConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSECONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_ENCODERS)) + return DFB_UNSUPPORTED; + + if (encoder < 0 || encoder >= data->description.encoders) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_encoder_config( data->screen, encoder, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchEncoderConfig( &patched, config ); + if (ret) + return ret; + + /* Set the patched configuration. */ + return dfb_screen_set_encoder_config( data->screen, encoder, &patched ); +} + +static DFBResult +IDirectFBScreen_GetOutputDescriptions( IDirectFBScreen *thiz, + DFBScreenOutputDescription *descriptions ) +{ + int i; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!descriptions) + return DFB_INVARG; + + if (!data->description.caps & DSCCAPS_OUTPUTS) + return DFB_UNSUPPORTED; + + for (i=0; idescription.outputs; i++) + dfb_screen_get_output_info( data->screen, i, &descriptions[i] ); + + return DFB_OK; +} + +static DFBResult +IDirectFBScreen_GetOutputConfiguration( IDirectFBScreen *thiz, + int output, + DFBScreenOutputConfig *config ) +{ + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_OUTPUTS)) + return DFB_UNSUPPORTED; + + if (output < 0 || output >= data->description.outputs) + return DFB_INVARG; + + return dfb_screen_get_output_config( data->screen, output, config ); +} + +static DFBResult +IDirectFBScreen_TestOutputConfiguration( IDirectFBScreen *thiz, + int output, + const DFBScreenOutputConfig *config, + DFBScreenOutputConfigFlags *failed ) +{ + DFBResult ret; + DFBScreenOutputConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSOCONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_OUTPUTS)) + return DFB_UNSUPPORTED; + + if (output < 0 || output >= data->description.outputs) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_output_config( data->screen, output, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchOutputConfig( &patched, config ); + if (ret) + return ret; + + /* Test the patched configuration. */ + return dfb_screen_test_output_config( data->screen, + output, &patched, failed ); +} + +static DFBResult +IDirectFBScreen_SetOutputConfiguration( IDirectFBScreen *thiz, + int output, + const DFBScreenOutputConfig *config ) +{ + DFBResult ret; + DFBScreenOutputConfig patched; + + DIRECT_INTERFACE_GET_DATA(IDirectFBScreen) + + if (!config || (config->flags & ~DSOCONF_ALL)) + return DFB_INVARG; + + if (! (data->description.caps & DSCCAPS_OUTPUTS)) + return DFB_UNSUPPORTED; + + if (output < 0 || output >= data->description.outputs) + return DFB_INVARG; + + /* Get the current configuration. */ + ret = dfb_screen_get_output_config( data->screen, output, &patched ); + if (ret) + return ret; + + /* Patch the configuration. */ + ret = PatchOutputConfig( &patched, config ); + if (ret) + return ret; + + /* Set the patched configuration. */ + return dfb_screen_set_output_config( data->screen, output, &patched ); +} + +/******************************************************************************/ + +DFBResult +IDirectFBScreen_Construct( IDirectFBScreen *thiz, + CoreScreen *screen ) +{ + DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBScreen) + + data->ref = 1; + data->screen = screen; + + dfb_screen_get_info( screen, NULL, &data->description ); + data->id = dfb_screen_id_translated( data->screen ); + + thiz->AddRef = IDirectFBScreen_AddRef; + thiz->Release = IDirectFBScreen_Release; + thiz->GetID = IDirectFBScreen_GetID; + thiz->GetDescription = IDirectFBScreen_GetDescription; + thiz->GetSize = IDirectFBScreen_GetSize; + thiz->EnumDisplayLayers = IDirectFBScreen_EnumDisplayLayers; + thiz->SetPowerMode = IDirectFBScreen_SetPowerMode; + thiz->WaitForSync = IDirectFBScreen_WaitForSync; + thiz->GetMixerDescriptions = IDirectFBScreen_GetMixerDescriptions; + thiz->GetMixerConfiguration = IDirectFBScreen_GetMixerConfiguration; + thiz->TestMixerConfiguration = IDirectFBScreen_TestMixerConfiguration; + thiz->SetMixerConfiguration = IDirectFBScreen_SetMixerConfiguration; + thiz->GetEncoderDescriptions = IDirectFBScreen_GetEncoderDescriptions; + thiz->GetEncoderConfiguration = IDirectFBScreen_GetEncoderConfiguration; + thiz->TestEncoderConfiguration = IDirectFBScreen_TestEncoderConfiguration; + thiz->SetEncoderConfiguration = IDirectFBScreen_SetEncoderConfiguration; + thiz->GetOutputDescriptions = IDirectFBScreen_GetOutputDescriptions; + thiz->GetOutputConfiguration = IDirectFBScreen_GetOutputConfiguration; + thiz->TestOutputConfiguration = IDirectFBScreen_TestOutputConfiguration; + thiz->SetOutputConfiguration = IDirectFBScreen_SetOutputConfiguration; + + return DFB_OK; +} + +/******************************************************************************/ + +static DFBResult +PatchMixerConfig( DFBScreenMixerConfig *patched, + const DFBScreenMixerConfig *patch ) +{ + /* Check for unsupported flags. */ + if (patch->flags & ~patched->flags) + return DFB_UNSUPPORTED; + + if (patch->flags & DSMCONF_TREE) + patched->tree = patch->tree; + + if (patch->flags & DSMCONF_LEVEL) + patched->level = patch->level; + + if (patch->flags & DSMCONF_LAYERS) + patched->layers = patch->layers; + + if (patch->flags & DSMCONF_BACKGROUND) + patched->background = patch->background; + + return DFB_OK; +} + +static DFBResult +PatchEncoderConfig( DFBScreenEncoderConfig *patched, + const DFBScreenEncoderConfig *patch ) +{ + /* Check for unsupported flags. */ + if (patch->flags & ~patched->flags) + return DFB_UNSUPPORTED; + + if (patch->flags & DSECONF_RESOLUTION) + patched->resolution = patch->resolution; + + if (patch->flags & DSECONF_FREQUENCY) + patched->frequency = patch->frequency; + + /** + * Need to be backwards compatible with these so that + * they specify resolution and frequency as well. + * If you have set a TV_STANDARD + * (and set the flag) it will override the resolution and + * frequency chosen above.*/ + if (patch->flags & DSECONF_TV_STANDARD) { + patched->tv_standard = patch->tv_standard; + switch (patched->tv_standard) { + case DSETV_PAL: + case DSETV_PAL_BG: + case DSETV_PAL_I: + case DSETV_PAL_N: + case DSETV_PAL_NC: + patched->resolution = DSOR_720_576; + patched->frequency = DSEF_50HZ; + break; + + case DSETV_PAL_60: + case DSETV_PAL_M: + patched->resolution = DSOR_720_480; + patched->frequency = DSEF_60HZ; + break; + + case DSETV_SECAM: + patched->resolution = DSOR_720_576; + patched->frequency = DSEF_50HZ; + break; + + case DSETV_NTSC: + case DSETV_NTSC_M_JPN: + case DSETV_NTSC_443: + patched->resolution = DSOR_720_480; + patched->frequency = DSEF_60HZ; + break; + + default: + break; + } + } + if (patch->flags & DSECONF_TEST_PICTURE) + patched->test_picture = patch->test_picture; + + if (patch->flags & DSECONF_MIXER) + patched->mixer = patch->mixer; + + if (patch->flags & DSECONF_OUT_SIGNALS) + patched->out_signals = patch->out_signals; + + if (patch->flags & DSECONF_SCANMODE) + patched->scanmode = patch->scanmode; + + if (patch->flags & DSECONF_ADJUSTMENT) + patched->adjustment = patch->adjustment; + + if (patch->flags & DSECONF_CONNECTORS) + patched->out_connectors = patch->out_connectors; + + if (patch->flags & DSECONF_SLOW_BLANKING) + patched->slow_blanking = patch->slow_blanking; + + return DFB_OK; +} + +static DFBResult +PatchOutputConfig( DFBScreenOutputConfig *patched, + const DFBScreenOutputConfig *patch ) +{ + /* Check for unsupported flags. */ + if (patch->flags & ~patched->flags) + return DFB_UNSUPPORTED; + + if (patch->flags & DSOCONF_RESOLUTION) + patched->resolution = patch->resolution; + + if (patch->flags & DSOCONF_ENCODER) + patched->encoder = patch->encoder; + + if (patch->flags & DSOCONF_SIGNALS) + patched->out_signals = patch->out_signals; + + if (patch->flags & DSOCONF_CONNECTORS) + patched->out_connectors = patch->out_connectors; + + if (patch->flags & DSOCONF_SLOW_BLANKING) + patched->slow_blanking = patch->slow_blanking; + + return DFB_OK; +} + +static DFBEnumerationResult +EnumDisplayLayers_Callback( CoreLayer *layer, void *ctx ) +{ + DFBDisplayLayerDescription desc; + DFBDisplayLayerID id; + EnumDisplayLayers_Context *context = (EnumDisplayLayers_Context*) ctx; + + if (dfb_layer_screen( layer ) != context->screen) + return DFENUM_OK; + + id = dfb_layer_id_translated( layer ); + + if (dfb_config->primary_only && id != DLID_PRIMARY) + return DFENUM_OK; + + dfb_layer_get_description( layer, &desc ); + + return context->callback( id, desc, context->callback_ctx ); +} + -- cgit