Skip to content

Commit

Permalink
Added display events
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiasebsen committed Aug 11, 2014
1 parent 04e94e6 commit 338a367
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.DS_Store

# Compiled Object files
*.slo
*.lo
Expand Down
127 changes: 127 additions & 0 deletions src/ofxDisplay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* ofxDisplay.cpp
* displayExample
*
* Created by Tobias Ebsen on 10/1/12.
* Copyright 2012 Tobias Ebsen. All rights reserved.
*
*/

#include "ofxDisplay.h"

ofEvent<ofxDisplayArgs> ofxDisplay::displayEvents;

#ifdef TARGET_OSX
ofxDisplay::ofxDisplay(uint32_t displayId) {
this->displayId = displayId;
}
#endif

ofxDisplay* ofxDisplay::getMainDisplay() {
#ifdef TARGET_OSX
uint32_t displayId = CGMainDisplayID();
return new ofxDisplay(displayId);
#endif
}

vector<ofxDisplay*> ofxDisplay::getActiveDisplays() {
vector<ofxDisplay*> displays;
#ifdef TARGET_OSX
uint32_t count = 0;
CGGetActiveDisplayList(0, NULL, &count);
CGDirectDisplayID* ids = (CGDirectDisplayID*)malloc(count * sizeof(CGDirectDisplayID));
CGGetActiveDisplayList(count, ids, &count);
for (int i=0; i<count; i++) {
ofxDisplay* display = new ofxDisplay(ids[i]);
displays.push_back(display);
}
free(ids);
#endif
return displays;
}

ofPoint ofxDisplay::getSize() {
#ifdef TARGET_OSX
CGSize size = CGDisplayScreenSize(displayId);
return ofPoint(size.width, size.height);
#endif
}

ofRectangle ofxDisplay::getBounds() {
#ifdef TARGET_OSX
CGRect bounds = CGDisplayBounds(displayId);
return ofRectangle(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
#endif
}

bool ofxDisplay::isAsleep() {
#ifdef TARGET_OSX
return CGDisplayIsAsleep(displayId);
#endif
}

void ofxDisplay::grabImage(ofImage& image) {
ofRectangle rect = getBounds();
grabImage(image, rect);
}

void ofxDisplay::grabImage(ofImage& image, ofRectangle& rect) {
#ifdef TARGET_OSX
CGRect r = {rect.x, rect.y, rect.width, rect.height};
CGImageRef imgr = CGDisplayCreateImageForRect(displayId, r);
int width = CGImageGetWidth(imgr);
int height = CGImageGetHeight(imgr);
int row = CGImageGetBytesPerRow(imgr);
CGColorSpaceRef csr = CGImageGetColorSpace(imgr);

CGDataProviderRef dpr = CGImageGetDataProvider(imgr);
CFDataRef dr = CGDataProviderCopyData(dpr);
const unsigned char* spixels = (const unsigned char*)CFDataGetBytePtr(dr);

if (CGColorSpaceGetModel(csr) == kCGColorSpaceModelRGB) {
CGBitmapInfo info = CGImageGetBitmapInfo(imgr);
CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imgr);

if (!(info & kCGBitmapFloatComponents)) {

if ((info & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Big && alpha & kCGImageAlphaLast) {
image.setFromPixels(spixels, width, height, OF_IMAGE_COLOR_ALPHA);
}
if ((info & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Little && alpha & kCGImageAlphaLast) {
unsigned char* dpixels = image.getPixels();
int dwidth = image.getWidth() * 4;
int dheight = image.getHeight();
int srow = 0;
int drow = 0;
for (int y=0; y<dheight; y++) {
for (int x=0; x<dwidth; x+=4) {
dpixels[drow+x+0] = spixels[srow+x+2];
dpixels[drow+x+1] = spixels[srow+x+1];
dpixels[drow+x+2] = spixels[srow+x+0];
dpixels[drow+x+3] = spixels[srow+x+3];
}
srow += row;
drow += dwidth;
}
image.update();
}
}
CFRelease(dr);
}

CGImageRelease(imgr);
#endif
}

void ofxDisplay::registerCallbacks() {
CGDisplayRegisterReconfigurationCallback(&ofxDisplay::displayCallBack, NULL);
}

void ofxDisplay::displayCallBack(uint32_t display, uint32_t flags, void *userInfo) {

ofxDisplayArgs args;
args.id = display;
args.flags = flags;

ofNotifyEvent(displayEvents, args);
}
49 changes: 49 additions & 0 deletions src/ofxDisplay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* ofxDisplay.h
* displayExample
*
* Created by Tobias Ebsen on 10/1/12.
* Copyright 2012 Tobias Ebsen. All rights reserved.
*
*/

#pragma once

#include "ofMain.h"

#ifdef TARGET_OSX
#include <Carbon/Carbon.h>
#endif

typedef struct _ofxDisplayArgs {
uint32_t id;
uint32_t flags;
} ofxDisplayArgs;

class ofxDisplay {
public:
ofxDisplay(uint32_t displayId);

static ofxDisplay* getMainDisplay();
static vector<ofxDisplay*> getActiveDisplays();

// Get size in millimeters
ofPoint getSize();
// Get pixel bounds
ofRectangle getBounds();
// Is the display sleeping?
bool isAsleep();

// Grab entire screen
void grabImage(ofImage& image);
// Grab a specified rectagle of the screen
void grabImage(ofImage& image, ofRectangle& rect);

static void registerCallbacks();
static ofEvent<ofxDisplayArgs> displayEvents;

private:
uint32_t displayId;

static void displayCallBack(uint32_t display, uint32_t flags, void *userInfo);
};

0 comments on commit 338a367

Please sign in to comment.