1// cc -o /tmp/mlist -g mlist.c -framework ApplicationServices -framework IOKit -Wall
2
3
4#include <mach/mach.h>
5#include <unistd.h>
6#include <string.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <assert.h>
10
11#include <IOKit/IOKitLib.h>
12#include <IOKit/graphics/IOGraphicsTypesPrivate.h>
13#include <IOKit/graphics/IOFramebufferShared.h>
14#include <ApplicationServices/ApplicationServices.h>
15
16int main(int argc, char * argv[])
17{
18    kern_return_t 				kr;
19    io_iterator_t 				iter;
20    io_service_t  				framebuffer;
21    io_string_t   				path;
22    uint32_t                    index;
23    CFIndex						idx;
24    IODisplayModeInformation *  modeInfo;
25    IODetailedTimingInformationV2 *timingInfo;
26
27    CFDictionaryRef             dict;
28    CFArrayRef                  modes;
29    CFIndex                     count;
30    CFDictionaryRef             mode;
31    CFDataRef                   data;
32    CFNumberRef                 num;
33
34    kr = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(
35                IOFRAMEBUFFER_CONFORMSTO), &iter);
36    assert( KERN_SUCCESS == kr );
37
38    for ( index = 0;
39            index++, (framebuffer = IOIteratorNext(iter));
40            IOObjectRelease(framebuffer))
41    {
42        kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path);
43        assert( KERN_SUCCESS == kr );
44        fprintf(stderr, "\n%s\n", path);
45
46        dict = IORegistryEntryCreateCFProperty(framebuffer, CFSTR(kIOFBConfigKey),
47                                                kCFAllocatorDefault, kNilOptions);
48		if (!dict) continue;
49
50        modes = CFDictionaryGetValue(dict, CFSTR(kIOFBModesKey));
51        assert(modes);
52
53        count = CFArrayGetCount(modes);
54        for (idx = 0; idx < count; idx++)
55        {
56            mode = CFArrayGetValueAtIndex(modes, idx);
57
58            data = CFDictionaryGetValue(mode, CFSTR(kIOFBModeDMKey));
59            if (!data)
60                continue;
61            modeInfo = (IODisplayModeInformation *) CFDataGetBytePtr(data);
62
63            data = CFDictionaryGetValue(mode, CFSTR(kIOFBModeTMKey));
64            if (!data)
65                continue;
66            timingInfo = (IODetailedTimingInformationV2 *) CFDataGetBytePtr(data);
67
68			IODisplayModeID modeID = 0;
69            num = CFDictionaryGetValue(mode, CFSTR(kIOFBModeIDKey));
70            if (num) CFNumberGetValue(num, kCFNumberSInt32Type, &modeID );
71
72            printf("0x%x: %d x %d %d Hz - %d x %d - flags 0x%x\n",
73            		modeID,
74            		modeInfo->nominalWidth, modeInfo->nominalHeight,
75            		((modeInfo->refreshRate + 0x8000) >> 16),
76            		modeInfo->imageWidth, modeInfo->imageHeight,
77            		modeInfo->flags);
78
79			if (argc > 1)
80			{
81				printf("  horizontalScaledInset    %d\n", timingInfo->horizontalScaledInset);
82				printf("  verticalScaledInset      %d\n", timingInfo->verticalScaledInset);
83				printf("  scalerFlags              0x%x\n", timingInfo->scalerFlags);
84				printf("  horizontalScaled         %d\n", timingInfo->horizontalScaled);
85				printf("  verticalScaled           %d\n", timingInfo->verticalScaled);
86				printf("  pixelClock               %lld\n", timingInfo->pixelClock);
87				printf("  minPixelClock            %lld\n", timingInfo->minPixelClock);
88				printf("  maxPixelClock            %lld\n", timingInfo->maxPixelClock);
89				printf("  horizontalActive         %d\n", timingInfo->horizontalActive);
90				printf("  horizontalBlanking       %d\n", timingInfo->horizontalBlanking);
91				printf("  horizontalSyncOffset     %d\n", timingInfo->horizontalSyncOffset);
92				printf("  horizontalSyncPulseWidth %d\n", timingInfo->horizontalSyncPulseWidth);
93				printf("  verticalActive           %d\n", timingInfo->verticalActive);
94				printf("  verticalBlanking         %d\n", timingInfo->verticalBlanking);
95				printf("  verticalSyncOffset       %d\n", timingInfo->verticalSyncOffset);
96				printf("  verticalSyncPulseWidth   %d\n", timingInfo->verticalSyncPulseWidth);
97				printf("  horizontalBorderLeft     %d\n", timingInfo->horizontalBorderLeft);
98				printf("  horizontalBorderRight    %d\n", timingInfo->horizontalBorderRight);
99				printf("  verticalBorderTop        %d\n", timingInfo->verticalBorderTop);
100				printf("  verticalBorderBottom     %d\n", timingInfo->verticalBorderBottom);
101				printf("  horizontalSyncConfig     %d\n", timingInfo->horizontalSyncConfig);
102				printf("  horizontalSyncLevel      %d\n", timingInfo->horizontalSyncLevel);
103				printf("  verticalSyncConfig       0x%x\n", timingInfo->verticalSyncConfig);
104				printf("  verticalSyncLevel        %d\n", timingInfo->verticalSyncLevel);
105				printf("  signalConfig             0x%x\n", timingInfo->signalConfig);
106				printf("  signalLevels             %d\n", timingInfo->signalLevels);
107				printf("  numLinks                 %d\n", timingInfo->numLinks);
108			}
109		}
110		CFRelease(dict);
111    }
112    IOObjectRelease(iter);
113    exit(0);
114    return(0);
115}
116