#include "env.h"
#include "adl-edid.h"
#if defined(HAVE_ADL_EDID_PARSER)
#if defined(__WINDOWS__)
#include "p8-platform/windows/dlfcn-win32.h"
#endif
using namespace P8PLATFORM;
CADLEdidParser::CADLEdidParser(void) :
m_bOpen(false),
m_handle(NULL)
{
Initialise();
}
CADLEdidParser::~CADLEdidParser(void)
{
CloseLibrary();
}
bool CADLEdidParser::OpenLibrary(void)
{
CloseLibrary();
#if !defined(__WINDOWS__)
m_handle = dlopen("libatiadlxx.so", RTLD_LAZY|RTLD_GLOBAL);
#else
m_handle = LoadLibrary("atiadlxx.dll");
if (!m_handle)
m_handle = LoadLibrary("atiadlxy.dll");
#endif
return m_handle != NULL;
}
void CADLEdidParser::CloseLibrary(void)
{
if (LibOpen())
ADL_Main_Control_Destroy();
if (m_handle)
dlclose(m_handle);
m_handle = NULL;
}
void *__stdcall ADL_AllocMemory(int iSize)
{
void* lpBuffer = malloc(iSize);
return lpBuffer;
}
void CADLEdidParser::Initialise(void)
{
if (OpenLibrary())
{
ADL_Main_Control_Create = (ADL_MAIN_CONTROL_CREATE) dlsym(m_handle, "ADL_Main_Control_Create");
ADL_Main_Control_Destroy = (ADL_MAIN_CONTROL_DESTROY) dlsym(m_handle, "ADL_Main_Control_Destroy");
ADL_Adapter_NumberOfAdapters_Get = (ADL_ADAPTER_NUMBEROFADAPTERS_GET) dlsym(m_handle, "ADL_Adapter_NumberOfAdapters_Get");
ADL_Adapter_AdapterInfo_Get = (ADL_ADAPTER_ADAPTERINFO_GET) dlsym(m_handle, "ADL_Adapter_AdapterInfo_Get");
ADL_Display_DisplayInfo_Get = (ADL_DISPLAY_DISPLAYINFO_GET) dlsym(m_handle, "ADL_Display_DisplayInfo_Get");
ADL_Display_EdidData_Get = (ADL_DISPLAY_EDIDDATA_GET) dlsym(m_handle, "ADL_Display_EdidData_Get");
if (ADL_Main_Control_Create &&
ADL_Main_Control_Destroy &&
ADL_Adapter_NumberOfAdapters_Get &&
ADL_Adapter_AdapterInfo_Get &&
ADL_Display_DisplayInfo_Get &&
ADL_Display_EdidData_Get)
{
m_bOpen = (ADL_OK == ADL_Main_Control_Create(ADL_AllocMemory, 1));
}
}
}
int CADLEdidParser::GetNumAdapters(void)
{
int iNumAdapters(0);
if (!LibOpen() || ADL_OK != ADL_Adapter_NumberOfAdapters_Get(&iNumAdapters))
iNumAdapters = 0;
return iNumAdapters;
}
LPAdapterInfo CADLEdidParser::GetAdapterInfo(int iNumAdapters)
{
if (iNumAdapters <= 0)
return NULL;
LPAdapterInfo adapterInfo = (LPAdapterInfo)malloc(sizeof(AdapterInfo) * iNumAdapters);
memset(adapterInfo, 0, sizeof(AdapterInfo) * iNumAdapters);
ADL_Adapter_AdapterInfo_Get(adapterInfo, sizeof(AdapterInfo) * iNumAdapters);
return adapterInfo;
}
bool CADLEdidParser::GetAdapterEDID(int iAdapterIndex, int iDisplayIndex, ADLDisplayEDIDData *data)
{
if (iAdapterIndex < 0 || iDisplayIndex < 0)
return false;
memset(data, 0, sizeof(ADLDisplayEDIDData));
data->iSize = sizeof(ADLDisplayEDIDData);
data->iBlockIndex = 1;
return (ADL_Display_EdidData_Get(iAdapterIndex, iDisplayIndex, data) == ADL_OK);
}
uint16_t CADLEdidParser::GetPhysicalAddress(void)
{
uint16_t iPA(0);
int iNumAdapters = GetNumAdapters();
if (iNumAdapters <= 0)
return 0;
LPAdapterInfo adapterInfo = GetAdapterInfo(iNumAdapters);
if (!adapterInfo)
return 0;
for (int iAdapterPtr = 0; iAdapterPtr < iNumAdapters; iAdapterPtr++)
{
int iNumDisplays(-1);
LPADLDisplayInfo displayInfo(NULL);
int iAdapterIndex = adapterInfo[iAdapterPtr].iAdapterIndex;
if (ADL_OK != ADL_Display_DisplayInfo_Get(iAdapterIndex, &iNumDisplays, &displayInfo, 0))
continue;
for (int iDisplayPtr = 0; iDisplayPtr < iNumDisplays; iDisplayPtr++)
{
if ((displayInfo[iDisplayPtr].iDisplayInfoValue & ADL_DISPLAY_CONNECTED) != ADL_DISPLAY_CONNECTED)
continue;
int iDisplayIndex = displayInfo[iDisplayPtr].displayID.iDisplayLogicalIndex;
ADLDisplayEDIDData edidData;
if (GetAdapterEDID(iAdapterIndex, iDisplayIndex, &edidData))
{
iPA = CEDIDParser::GetPhysicalAddressFromEDID(edidData.cEDIDData, edidData.iEDIDSize);
if (iPA != 0)
break;
}
}
free(displayInfo);
}
free(adapterInfo);
return iPA;
}
#endif