1/*
2cc -g -o /tmp/probe probe.c -framework ApplicationServices -framework IOKit -Wall
3cc -g -o /tmp/rotate probe.c -framework ApplicationServices -framework IOKit -Wall
4*/
5
6#include <CoreFoundation/CoreFoundation.h>
7#include <ApplicationServices/ApplicationServices.h>
8#include <IOKit/graphics/IOGraphicsLib.h>
9#include <IOKit/graphics/IOGraphicsTypesPrivate.h>
10#include <stdlib.h>
11#include <stdio.h>
12
13
14int main(int argc, char * argv[])
15{
16    io_service_t        service;
17    CGError             err;
18    int                 i;
19    CGDisplayCount      max;
20    CGDirectDisplayID   displayIDs[8];
21    uint32_t            mask;
22    IOOptionBits        options;
23    CFNumberRef         num;
24    SInt32              value;
25
26    err = CGGetOnlineDisplayList(8, displayIDs, &max);
27    if(err != kCGErrorSuccess)
28        exit(1);
29    if(max > 8)
30        max = 8;
31
32    if( argc < 2)
33        options = kIOFBUserRequestProbe;
34    else
35        options = strtol( argv[1], 0, 0 );
36
37    if (strstr(argv[0], "rotate"))
38    {
39        switch (options)
40        {
41            case 90:
42              options = kIOFBSetTransform | (kIOScaleRotate90 << 16);
43              break;
44            case 180:
45              options = kIOFBSetTransform | (kIOScaleRotate180 << 16);
46              break;
47            case 270:
48              options = kIOFBSetTransform | (kIOScaleRotate270 << 16);
49              break;
50            case 0:
51            default:
52              options = kIOFBSetTransform | (kIOScaleRotate0 << 16);
53              break;
54        }
55    }
56
57    if( argc < 3)
58        mask = 0xffffffff;
59    else
60        mask = strtol( argv[2], 0, 0 );
61
62    for(i = 0; i < max; i++ )
63    {
64        if (!(mask & (1 << i)))
65            continue;
66
67        service = CGDisplayIOServicePort(displayIDs[i]);
68
69
70        num = (CFNumberRef) IORegistryEntryCreateCFProperty( service,
71                                                                CFSTR(kIOFBTransformKey),
72                                                                kCFAllocatorDefault, kNilOptions);
73        if (num)
74          CFNumberGetValue( num, kCFNumberSInt32Type, (SInt32 *) &value );
75        else
76          value = 0;
77
78        value &= kIOScaleRotateFlags;
79
80        printf("Display %p: current transform: ", displayIDs[i]);
81
82        switch (value)
83        {
84            case kIOScaleRotate90:
85              printf("90\n");
86              break;
87
88            case kIOScaleRotate180:
89              printf("180\n");
90              break;
91
92            case kIOScaleRotate270:
93              printf("270\n");
94              break;
95
96            case kIOScaleRotate0:
97            default:
98              printf("0\n");
99              break;
100        }
101
102
103        num = (CFNumberRef) IORegistryEntryCreateCFProperty( service,
104                                                                CFSTR(kIOFBProbeOptionsKey),
105                                                                kCFAllocatorDefault, kNilOptions);
106        if (num)
107          CFNumberGetValue( num, kCFNumberSInt32Type, (SInt32 *) &value );
108        else
109          value = 0;
110        printf("Display %p: does %ssupport kIOFBSetTransform\n", displayIDs[i], value & kIOFBSetTransform ? "" : "not ");
111
112        if (value & kIOFBSetTransform)
113        {
114          err = IOServiceRequestProbe(service, options );
115          printf("Display %p: IOServiceRequestProbe(%d)\n", displayIDs[i], err);
116        }
117    }
118
119    exit(0);
120    return(0);
121}
122
123