static void retrace_CGLDestroyPixelFormat(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    trace::Value & pix = call.argByName("pix");

    PixelFormat *pixelFormat = retrace::asObjPointer<PixelFormat>(call, pix);
    delete pixelFormat;

    retrace::delObj(pix);
}
static void retrace_CGLCreateContext(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    trace::Value & pix = call.argByName("pix");
    const PixelFormat *pixelFormat = retrace::asObjPointer<PixelFormat>(call, pix);
    glprofile::Profile profile = pixelFormat ? pixelFormat->profile : glretrace::defaultProfile;

    unsigned long long share = call.arg(1).toUIntPtr();
    Context *sharedContext = getContext(share);

    const trace::Array *ctx_ptr = call.arg(2).toArray();
    assert(ctx_ptr);
    unsigned long long ctx = ctx_ptr->values[0]->toUIntPtr();

    Context *context = glretrace::createContext(sharedContext, profile);
    context_map[ctx] = context;
}
static void retrace_CGLChoosePixelFormat(trace::Call &call) {
    if (call.ret->toUInt() != kCGLNoError) {
        return;
    }

    bool singleBuffer = true;
    int profile = 0;

    const trace::Array * attribs = call.arg(0).toArray();
    if (attribs) {
        size_t i = 0;
        while (i < attribs->values.size()) {
            int param = attribs->values[i++]->toSInt();
            if (param == 0) {
                break;
            }

            switch (param) {

            // Boolean attributes

            case kCGLPFAAllRenderers:
            case kCGLPFAStereo:
            case kCGLPFAMinimumPolicy:
            case kCGLPFAMaximumPolicy:
            case kCGLPFAOffScreen:
            case kCGLPFAFullScreen:
            case kCGLPFAAuxDepthStencil:
            case kCGLPFAColorFloat:
            case kCGLPFAMultisample:
            case kCGLPFASupersample:
            case kCGLPFASampleAlpha:
            case kCGLPFASingleRenderer:
            case kCGLPFANoRecovery:
            case kCGLPFAAccelerated:
            case kCGLPFAClosestPolicy:
            case kCGLPFARobust:
            case kCGLPFABackingStore:
            case kCGLPFABackingVolatile:
            case kCGLPFAMPSafe:
            case kCGLPFAWindow:
            case kCGLPFAMultiScreen:
            case kCGLPFACompliant:
            case kCGLPFAPBuffer:
            case kCGLPFARemotePBuffer:
            case kCGLPFAAllowOfflineRenderers:
            case kCGLPFAAcceleratedCompute:
            case kCGLPFASupportsAutomaticGraphicsSwitching:
                break;

            case kCGLPFADoubleBuffer:
            case kCGLPFATripleBuffer:
                singleBuffer = false;
                break;

            // Valued attributes

            case kCGLPFAColorSize:
            case kCGLPFAAlphaSize:
            case kCGLPFADepthSize:
            case kCGLPFAStencilSize:
            case kCGLPFAAuxBuffers:
            case kCGLPFAAccumSize:
            case kCGLPFASampleBuffers:
            case kCGLPFASamples:
            case kCGLPFARendererID:
            case kCGLPFADisplayMask:
            case kCGLPFAVirtualScreenCount:
                ++i;
                break;

            case kCGLPFAOpenGLProfile:
                profile = attribs->values[i++]->toSInt();
                break;

            default:
                retrace::warning(call) << "unexpected attribute " << param << "\n";
                break;
            }
        }
    }

    trace::Value & pix = call.argByName("pix")[0];

    PixelFormat *pixelFormat = new PixelFormat;

    // TODO: Do this on a per visual basis
    switch (profile) {
    case 0:
        break;
    case kCGLOGLPVersion_Legacy:
        pixelFormat->profile = glprofile::Profile(glprofile::API_GL, 1, 0);
        break;
    case kCGLOGLPVersion_GL3_Core:
        pixelFormat->profile = glprofile::Profile(glprofile::API_GL, 3, 2, true, true);
        break;
    case kCGLOGLPVersion_GL4_Core:
        pixelFormat->profile = glprofile::Profile(glprofile::API_GL, 4, 1, true, true);
        break;
    default:
        retrace::warning(call) << "unexpected opengl profile " << std::hex << profile << std::dec << "\n";
        break;
    }

    // XXX: Generalize this, don't override command line options.
    retrace::doubleBuffer = !singleBuffer;

    retrace::addObj(call, pix, pixelFormat);
}