Skip to content

CGDirectDisplay

The CGDirectDisplay API is designed to provide direct access to display modes, cursor position, gamma tables, and other low-level functionality. It is intended to replace and extend DrawSprocket, the Display Manager, and other similar APIs with one single, coherent, integrated API.

Definitions

Types used by the CGDirectDisplay API:

  • CGDirectDisplayID: An opaque reference to a display (kCGDirectMainDisplay refers to the main display as a convenience)
  • CGDirectPaletteRef: An opaque reference to a palette
  • CGDisplayCount: An unsigned 32 bit value
  • CGTableCount: An unsigned 32 bit value
  • CGDisplayCoord: A signed 32 bit value representing a coordinate on a display (The display origin is in the upper left corner)
  • CGByteValue: An unsigned 8 bit value used by the gamma/palette functions
  • CGOpenGLDisplayMask: An unsigned 32 bit value holding OpenGL display mask bits (Each bit represents a different display)
  • CGBeamPosition: An unsigned 32 bit value representing the position of the refresh beam on the display (0 is at the top)
  • CGMouseDelta: A signed 32 bit value representing the change in the mouse position
  • CGDisplayErr: A signed 32 bit error value

Typical Usage

Simple

In the simple case, you want to take over the main display and set it to the mode that most closely matches your required bit depth and resolution. You can then do any drawing you need to directly to the base address of the display. Once you are done, restore the display mode and release the display.

CFDictionaryRef mode;
CFDictionaryRef originalMode;
size_t desiredBitDepth = 16;
size_t desiredWidth = 1024;
size_t desiredHeight = 768;
boolean_t exactMatch;

originalMode = CGDisplayCurrentMode( kCGDirectMainDisplay );

mode = CGDisplayBestModeForParameters(
    kCGDirectMainDisplay,
    desiredBitDepth, desiredWidth,
    desiredHeight, &exactMatch );

if ( NULL != mode ) {
        /* If it is important to have an
        exact match, check exactMatch here */

    CGDisplayCapture( kCGDirectMainDisplay );
    CGDisplaySwitchToMode( kCGDirectMainDisplay, mode );
    CGDisplayHideCursor( kCGDirectMainDisplay );

        /* Do your drawing/game loop here Use
        CGDisplayBaseAddress() to get the base
        address of the display */

    CGDisplayShowCursor( kCGDirectMainDisplay );
    CGDisplaySwitchToMode( kCGDirectMainDisplay, originalMode );
    CGDisplayRelease( kCGDirectMainDisplay );
}

Complex

In the complex case, you need more control over which display you use or want to determine for yourself what "best mode" means. In this case, you get an array of active displays, iterate over that list examining the modes that each display supports, and choose the most appropriate display/mode combination for your application.

CFDictionaryRef originalMode;
CGDirectDisplayID displays[kMaxDisplays];
CGDisplayCount numDisplays;
CGDisplayCount i;
CGDisplayErr err;
CFDictionaryRef bestMode = NULL;
CGDirectDisplayID bestDisplay = kCGDirectMainDisplay;

err = CGGetActiveDisplayList(
    kMaxDisplays,
    displays,
    &numDisplays);
if ( err != kCGDisplayNoErr )
{
    printf("Cannot get displays (%d)\n", err);
    exit( 1 );
}

for ( i = 0; i < numDisplays; i++ )
{
    CFDictionaryRef mode;
    CFIndex i, cnt;
    CGDirectDisplayID dspy;
    CFArrayRef modeList;

    dspy = displays[i];

    modeList = CGDisplayAvailableModes(dspy);
    if ( NULL != modeList )
    {
        //  Examine each mode
        cnt = CFArrayGetCount( modeList );

        for ( i = 0; i < cnt; i++ )
        {
            //  Pull the mode dictionary out of the CFArray
            mode = CFArrayGetValueAtIndex( modeList, i );

            /* Examine the mode here thisModeIsTheBest( mode )
            is a user supplied function that evaluates each
            mode and picks the best one (returning true) */
            if ( thisModeIsTheBest( mode ) )
            {
                bestMode = mode;
                bestDisplay = dspy;
            }
        }
    }
}

//  At this point, you have identified the best mode
//      and its corresponding display ID
if ( NULL != bestMode )
{
    originalMode = CGDisplayCurrentMode( bestDisplay );

    CGDisplayCapture( bestDisplay );
    CGDisplaySwitchToMode( bestDisplay, bestMode );
    CGDisplayHideCursor( bestDisplay );

    //  Do your drawing/game loop here
    //  Use CGDisplayBaseAddress() to get the base address of the display

    CGDisplayShowCursor( bestDisplay );
    CGDisplaySwitchToMode( bestDisplay, originalMode );
    CGDisplayRelease( bestDisplay );
    }
    // ...
}

See also

Favorite site

References


  1. Technical_Note_TN_2007_-_The_CGDirectDisplay_API.pdf