2012-12-20 12 views
6

Ich arbeite derzeit an einem Remotedesktop-Projekt, insbesondere versuche ich Ersatzcode für die alten depreceated Methoden, die zuvor verwendet wurden, bereitzustellen. Ich habe das zum größten Teil erfolgreich geschafft, aber ich habe anscheinend einen Stolperstein erreicht.Zugriff auf Framebuffer OSX 10.7

Ab OSX 10.7 wurde der Methodenaufruf CGDisplayBaseAddress herabgesetzt (1). Zuvor gab mir das die Basisadresse des Framebuffers im Speicher, die woanders verwendet wurde, um zu sehen, welche Teile des Bildschirms sich geändert hatten und um zu bestimmen, was an das entfernte Display gesendet werden musste. Jetzt gibt es NULL zurück.

Meine aktuelle Lösung war CGDisplayCreateImage (2), die mir eine CGImageRef gibt, die ich dann verwenden kann, um einen Zeiger auf die Rohdaten (über ein CFDataRef-Objekt - für Code siehe unten) für das Bild zu erhalten.

Ist dies der beste Weg? Sicherlich müssen sie ein besserer Weg sein!

Zusammenfassend: Ich möchte keine Zeichnung auf den Bildschirm oder irgendetwas, ich versuche nur einen Zeiger auf das erste Byte im Speicher, die entweder den Desktop Framebuffer oder (wie ich gerade mache) die Bilddaten.

Danke für jede Hilfe, die Sie geben können! :)

Aktuelle Lösungscode:

CFDataRef copy_image_pixels(CGImageRef inImage) { 
    return CGDataProviderCopyData(CGImageGetDataProvider(inImage)); 
} 

/** 
ret_byte_buffer is the byte buffer containing the pixel data for the image **/ 
void *getPixelDataForImage (CGImageRef image) 
{ 
    //Check image ref is not null 
    if (!image){ 
     NSLog(@"Error - image was null"); 
     return -1; 
    } 

    //Gets a CFData reference for the specified image reference 
    CFDataRef pixelData = copy_image_pixels(image); 
    //Gets a readonly pointer to the image data 
    const UInt8 *pointerToData = CFDataGetBytePtr(pixelData); //This returns a read only version 
    //Casting to a void pointer to return, expected to be cast to a byte_t * 
    CFIndex length_of_buffer = CFDataGetLength(pixelData); 
    printf("Size of buffer is %zu\n",length_of_buffer); 
    return (void *)pointerToData; 

} 

Code-Schnipsel für die CGImageRef bekommen -

osx_disp= main_screen_details->main_screenid; //Returns CGDirectDisplayID 
CGImageRef screenShot = CGDisplayCreateImage(osx_disp); 
byte_t *image_byte_data = getPixelDataForImage(screenShot); 

byte_t ist typedef'd ein unsigned char

+0

'CGRegisterScreenRefreshCallback' ist etwas besser, aber es ist immer noch in 10.8 veraltet. Nicht sicher, ob es Ersatz gibt ... – duskwuff

+0

Ja, es hätte nützlich sein können :) Ich weiß nicht, warum sie es so schwer machen, den Frambuffer zu benutzen, es sei denn, es gab einige seltsame Sicherheitsprobleme oder sie planen etwas Magisches einzuführen Abstraktion, um es zu ersetzen: P Danke für den Kommentar! – andrewktmeikle

Antwort

2

Aus meiner Forschung zu sein scheint dass Sie nicht mehr auf den Framebuffer zugreifen müssen.

Sie Art und Weise habe ich es oben getan vielleicht nicht die beste Art und Weise sein, aber es funktioniert auf jeden Fall für das, was ich brauche es :)

Bisher tun würden Sie die Anzeige sperren, haben tun, was man damit tun wollte dann lassen Sie es los, was manchmal zu Bildschirmflackern führen könnte, wenn Sie den Bildschirm losließen.

Die neue Art und Weise, über das Bild zu schaffen, bedeutet, Sie müssen nicht mit jedem damit umgehen nur das Bild erstellen und Ihre goldenen :)

Eine Sache, die ich zu meinem bestehenden Code hinzufügen würde, ist, dass Sie müssen Denken Sie daran, das CGImageRef oder ein MAJOR-Speicherleck freizugeben.

Um aufrufen, dies zu tun einfach:

CFRelease(screenShot); 

Wir müssen auch auf die gleiche Weise die Pixeldata-Objekt freigeben.

CFRelease(pixelData);