bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions)
{
#if defined(TARGET_RASPBERRY_PI)
  resolutions.clear();

  if(!m_DllBcmHost)
    return false;

  m_fixedMode               = false;

  /* read initial desktop resolution before probe resolutions.
   * probing will replace the desktop resolution when it finds the same one.
   * we raplace it because probing will generate more detailed 
   * resolution flags we don't get with vc_tv_get_state.
   */

  if(m_initDesktopRes)
  {
    TV_DISPLAY_STATE_T tv_state;

    // get current display settings state
    memset(&tv_state, 0, sizeof(TV_DISPLAY_STATE_T));
    m_DllBcmHost->vc_tv_get_display_state(&tv_state);

    if ((tv_state.state & ( VC_HDMI_HDMI | VC_HDMI_DVI )) != 0) // hdtv
    {
      m_desktopRes.iScreen      = 0;
      m_desktopRes.bFullScreen  = true;
      m_desktopRes.iWidth       = tv_state.display.hdmi.width;
      m_desktopRes.iHeight      = tv_state.display.hdmi.height;
      m_desktopRes.iScreenWidth = tv_state.display.hdmi.width;
      m_desktopRes.iScreenHeight= tv_state.display.hdmi.height;
      m_desktopRes.dwFlags      = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode);
      // Also add 3D flags
      if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF)
      {
        m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DSBS;
        m_desktopRes.iWidth       >>= 1;
        m_desktopRes.iScreenWidth >>= 1;
      }
      else if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_TB_HALF)
void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::vector<RESOLUTION_INFO> &resolutions)
{
  if(!m_DllBcmHost)
    return;

  //Supported HDMI CEA/DMT resolutions, preferred resolution will be returned
  int32_t num_modes = 0;
  HDMI_RES_GROUP_T prefer_group;
  uint32_t prefer_mode;
  int i;
  TV_SUPPORTED_MODE_NEW_T *supported_modes = NULL;
  // query the number of modes first
  int max_supported_modes = m_DllBcmHost->vc_tv_hdmi_get_supported_modes_new(group, NULL, 0, &prefer_group, &prefer_mode);

  if (max_supported_modes > 0)
    supported_modes = new TV_SUPPORTED_MODE_NEW_T[max_supported_modes];

  if (supported_modes)
  {
    num_modes = m_DllBcmHost->vc_tv_hdmi_get_supported_modes_new(group,
        supported_modes, max_supported_modes, &prefer_group, &prefer_mode);

    CLog::Log(LOGDEBUG, "EGL get supported modes (%d) = %d, prefer_group=%x, prefer_mode=%x\n",
        group, num_modes, prefer_group, prefer_mode);
  }

  if (num_modes > 0 && prefer_group != HDMI_RES_GROUP_INVALID)
  {
    TV_SUPPORTED_MODE_NEW_T *tv = supported_modes;
    for (i=0; i < num_modes; i++, tv++)
    {
      RESOLUTION_INFO res;

      res.iScreen       = 0;
      res.bFullScreen   = true;
      res.dwFlags       = MAKEFLAGS(group, tv->code, tv->scan_mode);
      res.fRefreshRate  = (float)tv->frame_rate;
      res.iWidth        = tv->width;
      res.iHeight       = tv->height;
      res.iScreenWidth  = tv->width;
      res.iScreenHeight = tv->height;
      res.fPixelRatio   = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res.iScreenWidth / (float)res.iScreenHeight);
      res.iSubtitles    = (int)(0.965 * res.iHeight);

      if (!m_desktopRes.dwFlags && prefer_group == group && prefer_mode == tv->code)
        m_desktopRes = res;

      AddUniqueResolution(res, resolutions);
      CLog::Log(LOGDEBUG, "EGL mode %d: %s (%.2f) %s%s:%x\n", i, res.strMode.c_str(), res.fPixelRatio,
          tv->native ? "N" : "", tv->scan_mode ? "I" : "", tv->code);

      if (tv->frame_rate == 24 || tv->frame_rate == 30 || tv->frame_rate == 48 || tv->frame_rate == 60 || tv->frame_rate == 72)
      {
        RESOLUTION_INFO res2 = res;
        res2.fRefreshRate  = (float)tv->frame_rate * (1000.0f/1001.0f);
        AddUniqueResolution(res2, resolutions);
      }
    }
  }
  if (supported_modes)
    delete [] supported_modes;
}
bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions)
{
#if defined(TARGET_RASPBERRY_PI)
  resolutions.clear();

  if(!m_DllBcmHost)
    return false;

  /* read initial desktop resolution before probe resolutions.
   * probing will replace the desktop resolution when it finds the same one.
   * we raplace it because probing will generate more detailed 
   * resolution flags we don't get with vc_tv_get_state.
   */

  if(m_initDesktopRes)
  {
    TV_DISPLAY_STATE_T tv_state;

    // get current display settings state
    memset(&tv_state, 0, sizeof(TV_DISPLAY_STATE_T));
    m_DllBcmHost->vc_tv_get_display_state(&tv_state);

    if ((tv_state.state & ( VC_HDMI_HDMI | VC_HDMI_DVI )) != 0) // hdtv
    {
      m_desktopRes.iScreen      = 0;
      m_desktopRes.bFullScreen  = true;
      m_desktopRes.iWidth       = tv_state.display.hdmi.width;
      m_desktopRes.iHeight      = tv_state.display.hdmi.height;
      m_desktopRes.iScreenWidth = tv_state.display.hdmi.width;
      m_desktopRes.iScreenHeight= tv_state.display.hdmi.height;
      m_desktopRes.dwFlags      = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode);
      m_desktopRes.fPixelRatio  = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight);
      HDMI_PROPERTY_PARAM_T property;
      property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE;
      vc_tv_hdmi_get_property(&property);
      m_desktopRes.fRefreshRate = property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? tv_state.display.hdmi.frame_rate * (1000.0f/1001.0f) : tv_state.display.hdmi.frame_rate;
    }
    else if ((tv_state.state & ( VC_SDTV_NTSC | VC_SDTV_PAL )) != 0) // sdtv
    {
      m_desktopRes.iScreen      = 0;
      m_desktopRes.bFullScreen  = true;
      m_desktopRes.iWidth       = tv_state.display.sdtv.width;
      m_desktopRes.iHeight      = tv_state.display.sdtv.height;
      m_desktopRes.iScreenWidth = tv_state.display.sdtv.width;
      m_desktopRes.iScreenHeight= tv_state.display.sdtv.height;
      m_desktopRes.dwFlags      = MAKEFLAGS(HDMI_RES_GROUP_INVALID, tv_state.display.sdtv.mode, 1);
      m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate;
      m_desktopRes.fPixelRatio  = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight);
    }
    else if ((tv_state.state & VC_LCD_ATTACHED_DEFAULT) != 0) // lcd
    {
      m_desktopRes.iScreen      = 0;
      m_desktopRes.bFullScreen  = true;
      m_desktopRes.iWidth       = tv_state.display.sdtv.width;
      m_desktopRes.iHeight      = tv_state.display.sdtv.height;
      m_desktopRes.iScreenWidth = tv_state.display.sdtv.width;
      m_desktopRes.iScreenHeight= tv_state.display.sdtv.height;
      m_desktopRes.dwFlags      = MAKEFLAGS(HDMI_RES_GROUP_INVALID, 0, 0);
      m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate;
      m_desktopRes.fPixelRatio  = tv_state.display.hdmi.display_options.aspect == 0 ? 1.0f : get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight);
    }

    SetResolutionString(m_desktopRes);

    m_initDesktopRes = false;

    m_desktopRes.iSubtitles   = (int)(0.965 * m_desktopRes.iHeight);

    CLog::Log(LOGDEBUG, "EGL initial desktop resolution %s (%.2f)\n", m_desktopRes.strMode.c_str(), m_desktopRes.fPixelRatio);
  }

  if(GETFLAGS_GROUP(m_desktopRes.dwFlags) && GETFLAGS_MODE(m_desktopRes.dwFlags))
  {
    GetSupportedModes(HDMI_RES_GROUP_DMT, resolutions);
    GetSupportedModes(HDMI_RES_GROUP_CEA, resolutions);
  }
  {
    AddUniqueResolution(m_desktopRes, resolutions, true);
    CLog::Log(LOGDEBUG, "EGL probe resolution %s:%x\n", m_desktopRes.strMode.c_str(), m_desktopRes.dwFlags);
  }

  DLOG("CEGLNativeTypeRaspberryPI::ProbeResolutions\n");
  return true;
#else
  return false;
#endif
}
void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::vector<RESOLUTION_INFO> &resolutions)
{
  if(!m_DllBcmHost)
    return;

  //Supported HDMI CEA/DMT resolutions, preferred resolution will be returned
  int32_t num_modes = 0;
  HDMI_RES_GROUP_T prefer_group;
  uint32_t prefer_mode;
  int i;
  TV_SUPPORTED_MODE_NEW_T *supported_modes = NULL;
  // query the number of modes first
  int max_supported_modes = m_DllBcmHost->vc_tv_hdmi_get_supported_modes_new(group, NULL, 0, &prefer_group, &prefer_mode);

  if (max_supported_modes > 0)
    supported_modes = new TV_SUPPORTED_MODE_NEW_T[max_supported_modes];

  if (supported_modes)
  {
    num_modes = m_DllBcmHost->vc_tv_hdmi_get_supported_modes_new(group,
        supported_modes, max_supported_modes, &prefer_group, &prefer_mode);

    CLog::Log(LOGDEBUG, "EGL get supported modes (%d) = %d, prefer_group=%x, prefer_mode=%x\n",
        group, num_modes, prefer_group, prefer_mode);
  }

  if (num_modes > 0 && prefer_group != HDMI_RES_GROUP_INVALID)
  {
    TV_SUPPORTED_MODE_NEW_T *tv = supported_modes;
    for (i=0; i < num_modes; i++, tv++)
    {
      RESOLUTION_INFO res;

      res.iScreen       = 0;
      res.bFullScreen   = true;
      res.dwFlags       = MAKEFLAGS(group, tv->code, tv->scan_mode);
      res.fRefreshRate  = (float)tv->frame_rate;
      res.iWidth        = tv->width;
      res.iHeight       = tv->height;
      res.iScreenWidth  = tv->width;
      res.iScreenHeight = tv->height;
      res.fPixelRatio   = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res.iScreenWidth / (float)res.iScreenHeight);

      int gui_width  = res.iWidth;
      int gui_height = res.iHeight;

      ClampToGUIDisplayLimits(gui_width, gui_height);

      res.iWidth = gui_width;
      res.iHeight = gui_height;

      res.strMode = StringUtils::Format("%dx%d @ %.2f%s - Full Screen", res.iScreenWidth, res.iScreenHeight, res.fRefreshRate,
        res.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");

      CLog::Log(LOGDEBUG, "EGL mode %d: %s (%.2f) %s%s:%x\n", i, res.strMode.c_str(), res.fPixelRatio,
          tv->native ? "N" : "", tv->scan_mode ? "I" : "", tv->code);

      res.iSubtitles    = (int)(0.965 * res.iHeight);

      AddUniqueResolution(res, resolutions);

      // Also add 3D versions of modes
      if (tv->struct_3d_mask & HDMI_3D_STRUCT_SIDE_BY_SIDE_HALF_HORIZONTAL)
      {
        RESOLUTION_INFO res2 = res;
        res2.dwFlags |= D3DPRESENTFLAG_MODE3DSBS;
        res2.fPixelRatio    = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res2.iScreenWidth / (float)res2.iScreenHeight);
        res2.fPixelRatio   *= 2.0f;
        res2.strMode = StringUtils::Format("%dx%d @ %.2f%s - Full Screen", res2.iScreenWidth, res2.iScreenHeight, res2.fRefreshRate,
            res2.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
        CLog::Log(LOGDEBUG, "EGL mode %d: %s (%.2f) SBS\n", i, res2.strMode.c_str(), res2.fPixelRatio);

        res2.iSubtitles    = (int)(0.965 * res2.iHeight);

        AddUniqueResolution(res2, resolutions);
      }
      if (tv->struct_3d_mask & HDMI_3D_STRUCT_TOP_AND_BOTTOM)
      {
        RESOLUTION_INFO res2 = res;
        res2.dwFlags |= D3DPRESENTFLAG_MODE3DTB;
        res2.fPixelRatio    = get_display_aspect_ratio((HDMI_ASPECT_T)tv->aspect_ratio) / ((float)res2.iScreenWidth / (float)res2.iScreenHeight);
        res2.fPixelRatio   *= 0.5f;
        res2.strMode = StringUtils::Format("%dx%d @ %.2f%s - Full Screen", res2.iScreenWidth, res2.iScreenHeight, res2.fRefreshRate,
            res2.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
        CLog::Log(LOGDEBUG, "EGL mode %d: %s (%.2f) TAB\n", i, res2.strMode.c_str(), res2.fPixelRatio);

        res2.iSubtitles    = (int)(0.965 * res2.iHeight);

        AddUniqueResolution(res2, resolutions);
      }
    }
  }
  if (supported_modes)
    delete [] supported_modes;
}
bool CEGLNativeTypeRaspberryPI::ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions)
{
#if defined(TARGET_RASPBERRY_PI)
  resolutions.clear();

  if(!m_DllBcmHost)
    return false;

  m_fixedMode               = false;

  /* read initial desktop resolution before probe resolutions.
   * probing will replace the desktop resolution when it finds the same one.
   * we raplace it because probing will generate more detailed 
   * resolution flags we don't get with vc_tv_get_state.
   */

  if(m_initDesktopRes)
  {
    TV_DISPLAY_STATE_T tv_state;

    // get current display settings state
    memset(&tv_state, 0, sizeof(TV_DISPLAY_STATE_T));
    m_DllBcmHost->vc_tv_get_display_state(&tv_state);

    if ((tv_state.state & ( VC_HDMI_HDMI | VC_HDMI_DVI )) != 0) // hdtv
    {
      m_desktopRes.iScreen      = 0;
      m_desktopRes.bFullScreen  = true;
      m_desktopRes.iWidth       = tv_state.display.hdmi.width;
      m_desktopRes.iHeight      = tv_state.display.hdmi.height;
      m_desktopRes.iScreenWidth = tv_state.display.hdmi.width;
      m_desktopRes.iScreenHeight= tv_state.display.hdmi.height;
      m_desktopRes.dwFlags      = MAKEFLAGS(tv_state.display.hdmi.group, tv_state.display.hdmi.mode, tv_state.display.hdmi.scan_mode);
      m_desktopRes.fPixelRatio  = get_display_aspect_ratio((HDMI_ASPECT_T)tv_state.display.hdmi.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight);
      // Also add 3D flags
      if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_SBS_HALF)
      {
        m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DSBS;
        m_desktopRes.fPixelRatio *= 2.0;
      }
      else if (tv_state.display.hdmi.format_3d == HDMI_3D_FORMAT_TB_HALF)
      {
        m_desktopRes.dwFlags |= D3DPRESENTFLAG_MODE3DTB;
        m_desktopRes.fPixelRatio *= 0.5;
      }
      m_desktopRes.fRefreshRate = (float)tv_state.display.hdmi.frame_rate;
    }
    else // sdtv
    {
      m_desktopRes.iScreen      = 0;
      m_desktopRes.bFullScreen  = true;
      m_desktopRes.iWidth       = tv_state.display.sdtv.width;
      m_desktopRes.iHeight      = tv_state.display.sdtv.height;
      m_desktopRes.iScreenWidth = tv_state.display.sdtv.width;
      m_desktopRes.iScreenHeight= tv_state.display.sdtv.height;
      m_desktopRes.dwFlags      = D3DPRESENTFLAG_INTERLACED;
      m_desktopRes.fRefreshRate = (float)tv_state.display.sdtv.frame_rate;
      m_desktopRes.fPixelRatio  = get_display_aspect_ratio((SDTV_ASPECT_T)tv_state.display.sdtv.display_options.aspect) / ((float)m_desktopRes.iScreenWidth / (float)m_desktopRes.iScreenHeight);
    }

    m_desktopRes.strMode = StringUtils::Format("%dx%d", m_desktopRes.iScreenWidth, m_desktopRes.iScreenHeight);

    if((int)m_desktopRes.fRefreshRate > 1)
    {
      m_desktopRes.strMode = StringUtils::Format("%dx%d @ %.2f%s - Full Screen", m_desktopRes.iScreenWidth, m_desktopRes.iScreenHeight, m_desktopRes.fRefreshRate,
        m_desktopRes.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
    }
    m_initDesktopRes = false;

    int gui_width  = m_desktopRes.iWidth;
    int gui_height = m_desktopRes.iHeight;

    ClampToGUIDisplayLimits(gui_width, gui_height);

    m_desktopRes.iWidth = gui_width;
    m_desktopRes.iHeight = gui_height;

    m_desktopRes.iSubtitles   = (int)(0.965 * m_desktopRes.iHeight);

    CLog::Log(LOGDEBUG, "EGL initial desktop resolution %s (%.2f)\n", m_desktopRes.strMode.c_str(), m_desktopRes.fPixelRatio);
  }

  GetSupportedModes(HDMI_RES_GROUP_CEA, resolutions);
  GetSupportedModes(HDMI_RES_GROUP_DMT, resolutions);

  if(resolutions.size() == 0)
  {
    RESOLUTION_INFO res;
    CLog::Log(LOGDEBUG, "EGL probe resolution %s:%x\n", m_desktopRes.strMode.c_str(), m_desktopRes.dwFlags);

    AddUniqueResolution(m_desktopRes, resolutions);
  }

  if(resolutions.size() < 2)
    m_fixedMode = true;

  DLOG("CEGLNativeTypeRaspberryPI::ProbeResolutions\n");
  return true;
#else
  return false;
#endif
}
void CEGLNativeTypeRaspberryPI::GetSupportedModes(HDMI_RES_GROUP_T group, std::vector<RESOLUTION_INFO> &resolutions)
{
  if(!m_DllBcmHost)
    return;

  //Supported HDMI CEA/DMT resolutions, first one will be preferred resolution
  TV_SUPPORTED_MODE_T supported_modes[TV_MAX_SUPPORTED_MODES];
  int32_t num_modes;
  HDMI_RES_GROUP_T prefer_group;
  uint32_t prefer_mode;
  int i;

  num_modes = m_DllBcmHost->vc_tv_hdmi_get_supported_modes(group,
      supported_modes, TV_MAX_SUPPORTED_MODES, &prefer_group, &prefer_mode);

  CLog::Log(LOGDEBUG, "EGL get supported modes (%d) = %d, prefer_group=%x, prefer_mode=%x\n",
      group, num_modes, prefer_group, prefer_mode);

  if (num_modes > 0 && prefer_group != HDMI_RES_GROUP_INVALID)
  {
    TV_SUPPORTED_MODE_T *tv = supported_modes;
    for (i=0; i < num_modes; i++, tv++)
    {
      // treat 3D modes as half-width SBS
      unsigned int width = (group == HDMI_RES_GROUP_CEA_3D) ? tv->width>>1 : tv->width;
      RESOLUTION_INFO res;
      CLog::Log(LOGDEBUG, "EGL mode %d: %dx%d@%d %s%s:%x\n", i, width, tv->height, tv->frame_rate,
          tv->native ? "N" : "", tv->scan_mode ? "I" : "", tv->code);

      res.iScreen       = 0;
      res.bFullScreen   = true;
      res.dwFlags       = MAKEFLAGS(group, tv->code, tv->scan_mode, group==HDMI_RES_GROUP_CEA_3D);
      res.fRefreshRate  = (float)tv->frame_rate;
      res.fPixelRatio   = 1.0f;
      res.iWidth        = width;
      res.iHeight       = tv->height;
      res.iScreenWidth  = width;
      res.iScreenHeight = tv->height;
      res.strMode.Format("%dx%d", width, tv->height);
      if((float)tv->frame_rate > 1)
      {
        res.strMode.Format("%dx%d @ %.2f%s - Full Screen", res.iScreenWidth, res.iScreenHeight, res.fRefreshRate,
          res.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
      }

      int gui_width  = res.iWidth;
      int gui_height = res.iHeight;

      ClampToGUIDisplayLimits(gui_width, gui_height);

      res.iWidth = gui_width;
      res.iHeight = gui_height;

      res.iSubtitles    = (int)(0.965 * res.iHeight);

      resolutions.push_back(res);

      /* replace initial desktop resolution with probed hdmi resolution */
      if(m_desktopRes.iWidth == res.iWidth && m_desktopRes.iHeight == res.iHeight &&
          m_desktopRes.iScreenWidth == res.iScreenWidth && m_desktopRes.iScreenHeight == res.iScreenHeight &&
          m_desktopRes.fRefreshRate == res.fRefreshRate)
      {
        m_desktopRes = res;
        CLog::Log(LOGDEBUG, "EGL desktop replacement resolution %dx%d@%d %s%s:%x\n",
            width, tv->height, tv->frame_rate, tv->native ? "N" : "", tv->scan_mode ? "I" : "", tv->code);
      }

      m_res.push_back(res);
    }
  }