how to read monitor's EDID information?

Discussion in 'Windows Vista Drivers' started by lucy, Aug 5, 2004.

  1. lucy

    lucy Guest

    Does anybody know how to read monitor's EDID information on Windows XP. I
    have found some source code that basically calls int 10h. But I cannot call
    int 10h on Windows XP. I did search DDK document and found some APIs to read
    the EDID information. But I just don't know how to do that. Is there any
    sample code showing how to do that? Please help me!

    By the way, does anybody know the relationship between the Gamma value in
    EDID (one byte) and the real gamma value... I could not figure how to
    convert that BYTE value into real gamma value...

    Thanks a lot,

    -Lucy
     
    lucy, Aug 5, 2004
    #1
    1. Advertisements

  2. Windows only provides you with a PnP ID of the monitor, which is derived
    from EDID.
    The rest can be done only by videocard-specific hackery, no standard ways.
     
    Maxim S. Shatskih, Aug 5, 2004
    #2
    1. Advertisements

  3. lucy

    Calvin Guan Guest

    ways.

    There you go.

    #include "windows.h"
    #include "setupapi.h"
    #include "initguid.h"
    #include "stdio.h"

    #define NAME_SIZE 128
    #define PRINT(_x_) printf _x_

    DEFINE_GUID (GUID_CLASS_MONITOR,
    0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1,
    0x03, 0x18);

    static void
    PlayWithDeviceInfo(
    IN HDEVINFO devInfo,
    IN PSP_DEVINFO_DATA devInfoData
    )
    {
    HKEY hDevRegKey;
    DWORD uniID[123];

    if (SetupDiGetDeviceRegistryProperty(
    devInfo,
    devInfoData,
    SPDRP_DEVICEDESC,//SPDRP_UI_NUMBER,
    NULL,
    (PBYTE)(&uniID),
    sizeof(uniID),
    NULL))
    {
    printf("UID: %s\n",uniID);
    }
    else {
    printf("ERROR: %d\n",GetLastError());
    }



    hDevRegKey = SetupDiOpenDevRegKey(
    devInfo,
    devInfoData,
    DICS_FLAG_GLOBAL,
    0,
    DIREG_DEV,
    KEY_ALL_ACCESS);

    if (hDevRegKey) {
    LONG retValue,i;
    DWORD dwType, AcutalValueNameLength= NAME_SIZE;

    CHAR valueName[NAME_SIZE];

    for (i = 0, retValue = ERROR_SUCCESS; retValue !=
    ERROR_NO_MORE_ITEMS; i++)
    {
    unsigned char EDIDdata[1024];
    DWORD j,edidsize=sizeof(EDIDdata);

    retValue = RegEnumValue (
    hDevRegKey,
    i,
    &valueName[0],
    &AcutalValueNameLength,
    NULL,//reserved
    &dwType,
    EDIDdata, // buffer
    &edidsize); // buffer size

    if (retValue == ERROR_SUCCESS )
    {
    if (!strcmp(valueName,"EDID")) {
    printf("Found value EDID\n");
    {

    for (j=0;j<edidsize;j++) {
    if (j %16 == 0) printf("\n");
    printf("%02x ",EDIDdata[j]);
    }
    printf("\n");
    }

    break;
    }
    }
    }

    RegCloseKey(hDevRegKey);
    }
    else {
    printf("ERROR:%d\n",GetLastError());
    }

    }
    int EnumDevices()
    {
    HDEVINFO devInfo = NULL;
    SP_DEVINFO_DATA devInfoData;
    SP_DEVINFO_LIST_DETAIL_DATA devInfoSetDetailData;
    ULONG i;

    do
    {

    devInfo = SetupDiGetClassDevsEx(
    &GUID_CLASS_MONITOR, //class GUID
    NULL, //enumerator
    NULL, //HWND
    DIGCF_PRESENT, // Flags //DIGCF_ALLCLASSES|
    NULL, // device info, create a new one.
    NULL, // machine name, local machine
    NULL);// reserved

    if (NULL == devInfo)
    {
    //PrintWin32Error("SetupDiGetClassDevsEx");
    break;
    }

    for (i=0;ERROR_NO_MORE_ITEMS != GetLastError();i++)
    {

    memset(&devInfoData,0,sizeof(devInfoData));
    devInfoData.cbSize = sizeof(devInfoData);

    if (SetupDiEnumDeviceInfo(devInfo,i,&devInfoData))
    {
    PlayWithDeviceInfo(devInfo,&devInfoData);
    }
    }

    } while (FALSE);

    return i;
    }

    int __cdecl main()
    {
    EnumDevices();
    return 0;
    }

    -
    Calvin Guan Software Engineer
    ATI Technologies Inc. www.ati.com
     
    Calvin Guan, Aug 5, 2004
    #3
  4. lucy

    Calvin Guan Guest

    Ouch! I forgot to put "Copyleft Calvin Guan"-:)
    -
    Calvin Guan Software Engineer
    ATI Technologies Inc. www.ati.com

     
    Calvin Guan, Aug 5, 2004
    #4
  5. lucy

    lucy Guest


    Dear Calvin,

    Thank you so much. I did read out the EDID with your code. I really don't
    understand your code. But anyway, here is the result after running it:

    UID: StudioWorks 995E
    Found value EDID

    00 ff ff ff ff ff ff 00 1e 6d 4c 4a 01 01 01 01
    00 0a 01 01 7e 25 1b aa e8 e0 59 a3 54 46 9b 24
    10 48 4c ff ff 80 31 59 45 59 61 59 81 99 a9 4f
    01 01 01 01 01 01 1a 4f 40 30 62 b0 32 40 40 c0
    10 00 5e 06 11 00 00 1e 00 00 00 fd 00 32 a0 1e
    60 15 00 0a 20 20 20 20 20 20 00 00 00 fc 00 53
    74 75 64 69 6f 57 6f 72 6b 73 20 39 00 00 00 fc
    00 39 35 45 0a 20 20 20 20 20 20 20 20 20 00 4c
    00 00 00 00 ff ff ff ff ff 00 1e 6d 4c 4a 01 01
    01 01 00 0a 01 01 7e 25 1b aa e8 e0 59 a3 54 46
    9b 24 10 48 4c ff ff 80 31 59 45 59 61 59 81 99
    a9 4f 01 01 01 01 01 01 1a 4f 40 30 62 b0 32 40
    40 c0 10 00 5e 06 11 00 00 1e 00 00 00 fd 00 32
    a0 1e 60 15 00 0a 20 20 20 20 20 20 00 00 00 fc
    00 53 74 75 64 69 6f 57 6f 72 6b 73 20 39 00 00
    00 fc 00 39 35 45 0a 20 20 20 20 20 20 20 20 20
    Press any key to continue

    But this is really not what I want, it is a whole screen of strange numbers.
    From my understanding the EDID should have some manufactorer information,
    Gamma value, display modes, etc. Do you mean I should find some detailed
    specifications of these numbers and do some translation? I think I can find
    some specifications if they are available to the public somewhere on the
    Internet.

    This is a great program and provides a nice start. Thank you so much. I
    really apreciate that.

    -Lucy

    btw, did you use any DDK function in your above code?
     
    lucy, Aug 6, 2004
    #5
  6. lucy

    Calvin Guan Guest

    Thank you so much. I did read out the EDID with your code. I really don't
    Each time a child PDO (monitor) is enumerated by the videoport/miniport
    combo, the port driver stores the Edid data into child's device registry
    key, (Actually, it took me sometime to figure out in windbg) so that app can
    use SetupAPI to read it.
    It also contains standard/extended timing info, pixel clock, display
    PhySize(not for projector though) and many other.
    See this:
    http://www.vesa.org/standards_faqs.html#EDID

    I'm not sure if you have to be a member to access the doc. I bet you may
    find the definition of EDID struct in open source community?

    EDID can have extension block, i.e. CEA861 block in many plasma TV which is
    not governed by VESA.
    SetupDiXxx is documented in DDK.
    You are very welcome.

    Calvin
    -
    Calvin Guan Software Engineer
    ATI Technologies Inc. www.ati.com
     
    Calvin Guan, Aug 6, 2004
    #6
  7. lucy

    poltrone Guest

    poltrone, Aug 6, 2004
    #7
  8. Instead of RegEnumValue, why not just RegQueryValue(Ex) ("EDID") ?

     
    Alexander Grigoriev, Aug 6, 2004
    #8
  9. lucy

    Calvin Guan Guest

    Points taken! I've very limited programming experience in user mode;)

    Thanks,
    Calvin
    -
    Calvin Guan Software Engineer
    ATI Technologies Inc. www.ati.com
     
    Calvin Guan, Aug 6, 2004
    #9
  10. lucy

    lucy Guest

    Thank you very much! Now I understand. Have a nice weekend!
     
    lucy, Aug 7, 2004
    #10
  11. lucy

    lucy Guest

    Hi poltrone,

    This is a smart solution. That's great. Thank you very much. Yet after some
    reading, I still could not find the interepreation for Gamma value which is
    one BYTE in EDID...

    I read 120 from my EDID of DELL 2001FP. But how does that 120 relate to
    real-world Gamma value?

    1.2? 2.2? etc.?

    anybody has an idea?

    Thank you
     
    lucy, Aug 7, 2004
    #11
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.