From: Pierre Ossman Date: Fri, 28 Apr 2017 09:37:12 +0000 (+0200) Subject: Use correct color space for current monitor X-Git-Tag: v1.8.0~18 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=5da019ad6bc54e10930b846f796851200e662783;p=tigervnc.git Use correct color space for current monitor We won't always be on the primary monitor, so check which color space we're actually using right now. For offscreen stuff we assume a standard sRGB color space. (cherry picked from commit 1669a2d5a15aa39313cb74eff4f62dfe14d136cd) --- diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8ea99255..60edb013 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -27,7 +27,10 @@ set(FBPERF_SOURCES if(WIN32) set(FBPERF_SOURCES ${FBPERF_SOURCES} ../vncviewer/Surface_Win32.cxx) elseif(APPLE) - set(FBPERF_SOURCES ${FBPERF_SOURCES} ../vncviewer/Surface_OSX.cxx) + set(FBPERF_SOURCES + ${FBPERF_SOURCES} ../vncviewer/Surface_OSX.cxx + ${FBPERF_SOURCES} ../vncviewer/keysym2ucs.c + ${FBPERF_SOURCES} ../vncviewer/cocoa.mm) else() set(FBPERF_SOURCES ${FBPERF_SOURCES} ../vncviewer/Surface_X11.cxx) endif() diff --git a/vncviewer/Surface_OSX.cxx b/vncviewer/Surface_OSX.cxx index 10d1e3e2..3313ae3b 100644 --- a/vncviewer/Surface_OSX.cxx +++ b/vncviewer/Surface_OSX.cxx @@ -26,23 +26,19 @@ #include +#include "cocoa.h" #include "Surface.h" -static CGImageRef create_image(const unsigned char* data, +static CGColorSpaceRef srgb = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + +static CGImageRef create_image(CGColorSpaceRef lut, + const unsigned char* data, int w, int h) { - CGColorSpaceRef lut; CGDataProviderRef provider; CGImageRef image; - lut = CGDisplayCopyColorSpace(kCGDirectMainDisplay); - if (!lut) { - lut = CGColorSpaceCreateDeviceRGB(); - if (!lut) - throw rdr::Exception("CGColorSpaceCreateDeviceRGB"); - } - provider = CGDataProviderCreateWithData(NULL, data, w * h * 4, NULL); if (!provider) @@ -51,7 +47,6 @@ static CGImageRef create_image(const unsigned char* data, image = CGImageCreate(w, h, 8, 32, w * 4, lut, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little, provider, NULL, false, kCGRenderingIntentDefault); - CGColorSpaceRelease(lut); CGDataProviderRelease(provider); if (!image) throw rdr::Exception("CGImageCreate"); @@ -59,7 +54,7 @@ static CGImageRef create_image(const unsigned char* data, return image; } -static void render(CGContextRef gc, +static void render(CGContextRef gc, CGColorSpaceRef lut, const unsigned char* data, CGBlendMode mode, CGFloat alpha, int src_x, int src_y, int src_w, int src_h, @@ -68,7 +63,7 @@ static void render(CGContextRef gc, CGRect rect; CGImageRef image, subimage; - image = create_image(data, src_w, src_h); + image = create_image(lut, data, src_w, src_h); rect.origin.x = src_x; rect.origin.y = src_y; @@ -99,19 +94,10 @@ static void render(CGContextRef gc, static CGContextRef make_bitmap(int width, int height, unsigned char* data) { - CGColorSpaceRef lut; CGContextRef bitmap; - lut = CGDisplayCopyColorSpace(kCGDirectMainDisplay); - if (!lut) { - lut = CGColorSpaceCreateDeviceRGB(); - if (!lut) - throw rdr::Exception("CGColorSpaceCreateDeviceRGB"); - } - - bitmap = CGBitmapContextCreate(data, width, height, 8, width*4, lut, + bitmap = CGBitmapContextCreate(data, width, height, 8, width*4, srgb, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); - CGColorSpaceRelease(lut); if (!bitmap) throw rdr::Exception("CGBitmapContextCreate"); @@ -140,6 +126,8 @@ void Surface::clear(unsigned char r, unsigned char g, unsigned char b, unsigned void Surface::draw(int src_x, int src_y, int x, int y, int w, int h) { + CGColorSpaceRef lut; + CGContextSaveGState(fl_gc); // Reset the transformation matrix back to the default identity @@ -149,8 +137,10 @@ void Surface::draw(int src_x, int src_y, int x, int y, int w, int h) // macOS Coordinates are from bottom left, not top left y = Fl_Window::current()->h() - (y + h); - render(fl_gc, data, kCGBlendModeCopy, 1.0, + lut = cocoa_win_color_space(Fl_Window::current()); + render(fl_gc, lut, data, kCGBlendModeCopy, 1.0, src_x, src_y, width(), height(), x, y, w, h); + CGColorSpaceRelease(lut); CGContextRestoreGState(fl_gc); } @@ -164,7 +154,7 @@ void Surface::draw(Surface* dst, int src_x, int src_y, int x, int y, int w, int // macOS Coordinates are from bottom left, not top left y = dst->height() - (y + h); - render(bitmap, data, kCGBlendModeCopy, 1.0, + render(bitmap, srgb, data, kCGBlendModeCopy, 1.0, src_x, src_y, width(), height(), x, y, w, h); CGContextRelease(bitmap); @@ -172,6 +162,8 @@ void Surface::draw(Surface* dst, int src_x, int src_y, int x, int y, int w, int void Surface::blend(int src_x, int src_y, int x, int y, int w, int h, int a) { + CGColorSpaceRef lut; + CGContextSaveGState(fl_gc); // Reset the transformation matrix back to the default identity @@ -181,8 +173,10 @@ void Surface::blend(int src_x, int src_y, int x, int y, int w, int h, int a) // macOS Coordinates are from bottom left, not top left y = Fl_Window::current()->h() - (y + h); - render(fl_gc, data, kCGBlendModeNormal, (CGFloat)a/255.0, + lut = cocoa_win_color_space(Fl_Window::current()); + render(fl_gc, lut, data, kCGBlendModeNormal, (CGFloat)a/255.0, src_x, src_y, width(), height(), x, y, w, h); + CGColorSpaceRelease(lut); CGContextRestoreGState(fl_gc); } @@ -196,7 +190,7 @@ void Surface::blend(Surface* dst, int src_x, int src_y, int x, int y, int w, int // macOS Coordinates are from bottom left, not top left y = dst->height() - (y + h); - render(bitmap, data, kCGBlendModeNormal, (CGFloat)a/255.0, + render(bitmap, srgb, data, kCGBlendModeNormal, (CGFloat)a/255.0, src_x, src_y, width(), height(), x, y, w, h); CGContextRelease(bitmap); diff --git a/vncviewer/cocoa.h b/vncviewer/cocoa.h index e9101f34..0c3ac82f 100644 --- a/vncviewer/cocoa.h +++ b/vncviewer/cocoa.h @@ -22,6 +22,10 @@ int cocoa_capture_display(Fl_Window *win, bool all_displays); void cocoa_release_display(Fl_Window *win); +typedef struct CGColorSpace *CGColorSpaceRef; + +CGColorSpaceRef cocoa_win_color_space(Fl_Window *win); + int cocoa_is_keyboard_event(const void *event); int cocoa_is_key_press(const void *event); diff --git a/vncviewer/cocoa.mm b/vncviewer/cocoa.mm index fc3b5bcf..85b736ba 100644 --- a/vncviewer/cocoa.mm +++ b/vncviewer/cocoa.mm @@ -110,6 +110,28 @@ void cocoa_release_display(Fl_Window *win) [nsw setLevel:newlevel]; } +CGColorSpaceRef cocoa_win_color_space(Fl_Window *win) +{ + NSWindow *nsw; + NSColorSpace *nscs; + + nsw = (NSWindow*)fl_xid(win); + + nscs = [nsw colorSpace]; + if (nscs == nil) { + // Offscreen, so return standard SRGB color space + assert(false); + return CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + } + + CGColorSpaceRef lut = [nscs CGColorSpace]; + + // We want a permanent reference, not an autorelease + CGColorSpaceRetain(lut); + + return lut; +} + int cocoa_is_keyboard_event(const void *event) { NSEvent *nsevent;