aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2017-04-28 11:37:12 +0200
committerPierre Ossman <ossman@cendio.se>2017-04-28 12:58:57 +0200
commit5da019ad6bc54e10930b846f796851200e662783 (patch)
treeb865c44de82bace3ea9ae321bbe1398343521749
parentee234fe36a4d8be3baea010b22fe3019518625ce (diff)
downloadtigervnc-5da019ad6bc54e10930b846f796851200e662783.tar.gz
tigervnc-5da019ad6bc54e10930b846f796851200e662783.zip
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)
-rw-r--r--tests/CMakeLists.txt5
-rw-r--r--vncviewer/Surface_OSX.cxx46
-rw-r--r--vncviewer/cocoa.h4
-rw-r--r--vncviewer/cocoa.mm22
4 files changed, 50 insertions, 27 deletions
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 <rdr/Exception.h>
+#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;