/*****************************************************************************/
/* Copyright (c) 2008 NXP B.V.                                               */
/*                                                                           */
/* 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, using               */
/* version 2.1 of the License.                                               */
/*                                                                           */
/* 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   */
/*                                                                           */
/*****************************************************************************/
/*
   NXP STB22X Driver

   Code is derived from TI Davinci driver.

   TI Davinci driver

   (c) Copyright 2007  Telio AG

   Written by Denis Oliver Kropp <dok@directfb.org>

   Code is derived from VMWare driver.

   (c) Copyright 2001-2007  The DirectFB Organization (directfb.org)
   (c) Copyright 2000-2004  Convergence (integrated media) GmbH

   All rights reserved.

   Written by Denis Oliver Kropp <dok@directfb.org>,
              Andreas Hundt <andi@fischlustig.de>,
              Sven Neumann <neo@directfb.org>,
              Ville Syrjälä <syrjala@sci.fi> and
              Claudio Ciccani <klan@users.sf.net>.

   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.
*//**
    @file   phStbDFB_screen.c
    @brief  Screen Implementation for DirectFB.

@b  Component:  phStbDFB.

*//*

Rev Date        Author      Comments
--------------------------------------------------------------------------------
  1 20080103    laird       New version for DirectFB 1.1.1
  2 20080716    laird       Rework.
  3 20080716    laird       Adding support for video layers.
  4 20080826    laird       Remove unneeded assignment.
  5 20080902    laird       Update Copyright headers.
  6 20080904    laird       Cleaning up.
  7 20081021    neill       Add wait for vsync
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/

/***********************************************
* INCLUDE FILES                                *
************************************************/
#include "phStbDFB_screen.h"
#include "phStbDFB_utils.h"

/***********************************************
* LOCAL MACROS                                 *
* recommendation only: <MODULE><_WORD>+        *
************************************************/

/******************************************************************
* LOCAL TYPEDEFS                                                  *
* recommendation only:                [p]phStbTemplate_<Word>+_t  *
*******************************************************************/
D_DEBUG_DOMAIN( phStbDFB_Screen, "NXP/STB22X/Screen", "NXP 22X Screen" );

/******************************************************************
* STATIC FUNCTION PROTOTYPES                  <Module>_<Word>+    *
*******************************************************************/

/******************************************************************
* STATIC DATA                  g[k|p|kp|pk|kpk]<Module>_<Word>+   *
*******************************************************************/
/**
 * @brief Name the Outputs.
 */
static Char *gphStbDFB_ScreenName[PH_STBVIDEORENDERER_MAX_INSTANCES] =
{
    "Main",
    "FrontPanel"
};

/**
 * @brief This is used to indicate what screen is being initialised.
 *        Once Initscreen has been used we can work out the screen number
 *        using dfb_screen_at.
 */
int32_t phStbDFB_screen_idx = DSCID_PRIMARY;

/**************************************************************************
* EXPORTED DATA                     g[k|p|kp|pk|kpk]phStbTemplate_<Word>+ *
***************************************************************************/

/*******************************************************************************
* FUNCTION IMPLEMENTATION  <Module>[_<Word>+] for static functions             *
*                          tm[<screen>]<Module>[_<Word>+] for exported functions*
********************************************************************************/
/******************************************************************************/
extern int
phStbDFB_ScreenDataSize(void)
{
    return sizeof(phStbDFB_ScreenData_t);
}

/**********************************************************************************************************************/
static DFBResult
phStbDFB_GetScreenSize( CoreScreen *screen,
                        void       *driver_data,
                        void       *screen_data,
                        int        *ret_width,
                        int        *ret_height )
{
     tmErrorCode_t err = TM_OK;
     DFBResult result = DFB_FAILURE;

     D_ASSERT( ret_width != NULL );
     D_ASSERT( ret_height != NULL );

     D_DEBUG_ENTER( phStbDFB_Screen, "");

     err = phStbVideoRenderer_GetOutputResolution(phStbVideoRenderer_DisplayChain_Main,
                                                  (unsigned int *)ret_width,
                                                  (unsigned int *)ret_height);

     result = DFB_OK;

     D_DEBUG_EXIT( phStbDFB_Screen, "(%d*%d) => 0x%x", *ret_width, *ret_height, result);
     return result;
}

/**********************************************************************************************************************/
static DFBResult
phStbDFB_InitScreen( CoreScreen           *screen,
                     CoreGraphicsDevice   *device,
                     void                 *driver_data,
                     void                 *screen_data,
                     DFBScreenDescription *description )
{
     phStbDFB_ScreenData_t *pScreenData = (phStbDFB_ScreenData_t*)screen_data;

     D_DEBUG_ENTER( phStbDFB_Screen, "screen_idx is %d name is %s", phStbDFB_screen_idx, gphStbDFB_ScreenName[phStbDFB_screen_idx]);

     /* Set the screen capabilities. */
     pScreenData->unitId = phStbDFB_screen_idx;
     description->caps = PH_STBDFB_SCREEN_CAPABILITIES;

     /* Set the screen name. */
     snprintf( description->name, DFB_SCREEN_DESC_NAME_LENGTH, "NXP 22X %s Screen", gphStbDFB_ScreenName[pScreenData->unitId] );

     /* Number of mixers depends on screen_idx.*/
     description->mixers = ((pScreenData->unitId == DSCID_PRIMARY) ? 2 : 0);

     /* Get pScreenData->screenWidth and pScreenData->screenHeight */
     phStbDFB_GetScreenSize(screen,
                            device,
                            screen_data,
                            (int *)&(pScreenData->screenWidth),
                            (int *)&(pScreenData->screenHeight));
     /**
      * We just get the number of encoders for each renderer.
      * If the number is greater than 0 then set the number of outputs to 1.
      */
     description->encoders = phStbDFB_GetNumberVideoDencs(0);
     pScreenData->numberEncoders = description->encoders;

     /* Store the number of Encoders. */
     if(description->encoders > 0)
     {
         description->caps |= (DSCCAPS_ENCODERS | DSCCAPS_OUTPUTS);
         /* TODO: Must work out number of outputs*/
         description->outputs = 1;
     }

     /** Increment screen idx.*/
     phStbDFB_screen_idx++;

     D_DEBUG_EXIT( phStbDFB_Screen, "");
     return DFB_OK;
}

static DFBResult
phStbDFB_WaitVSync( CoreScreen *screen,
                    void       *driver_data,
                    void       *screen_data )
{
    tmErrorCode_t err = TM_OK;
    DFBResult result = DFB_FAILURE;
    uint32_t red;
    uint32_t green;
    uint32_t blue;
    phStbVideoRenderer_t *pVideoRenderer;

    D_DEBUG_ENTER( phStbDFB_Screen, "");

    /* Use a non-destructive way to wait for vsync */
    err = phStbVideoRenderer_GetInstance(phStbVideoRenderer_DisplayChain_Main, &pVideoRenderer);

    /* Setting the background colour will wait for vsync! */
    err = phStbVideoRenderer_GetBackgroundColour(pVideoRenderer, &red, &green, &blue);
    err = phStbVideoRenderer_SetBackgroundColour(pVideoRenderer, red, green, blue);

    result = DFB_OK;

    D_DEBUG_EXIT( phStbDFB_Screen, "");
    return result;
}

/**********************************************************************************************************************/
ScreenFuncs phStbDFB_ScreenFuncs =
{
    .ScreenDataSize    = phStbDFB_ScreenDataSize,
    .InitScreen        = phStbDFB_InitScreen,
    .GetScreenSize     = phStbDFB_GetScreenSize,
    .InitMixer         = phStbDFB_InitMixer,
    .InitEncoder       = phStbDFB_InitEncoder,
    .InitOutput        = phStbDFB_InitOutput,
    .SetPowerMode      = phStbDFB_SetPowerMode,
    .TestMixerConfig   = phStbDFB_TestMixerConfig,
    .SetMixerConfig    = phStbDFB_SetMixerConfig,
    .TestEncoderConfig = phStbDFB_TestEncoderConfig,
    .SetEncoderConfig  = phStbDFB_SetEncoderConfig,
    .TestOutputConfig  = phStbDFB_TestOutputConfig,
    .SetOutputConfig   = phStbDFB_SetOutputConfig,
    .WaitVSync         = phStbDFB_WaitVSync
};

