]> source.dussan.org Git - tigervnc.git/commitdiff
Use correct color space for current monitor
authorPierre Ossman <ossman@cendio.se>
Fri, 28 Apr 2017 09:37:12 +0000 (11:37 +0200)
committerPierre Ossman <ossman@cendio.se>
Fri, 28 Apr 2017 10:58:57 +0000 (12:58 +0200)
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)

tests/CMakeLists.txt
vncviewer/Surface_OSX.cxx
vncviewer/cocoa.h
vncviewer/cocoa.mm

index 8ea99255a9daccea0c7d224cfe4209894c4cbb4b..60edb0139531d791bbf1ff0aff6fa5e8b7fa2931 100644 (file)
@@ -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()
index 10d1e3e2c69a3a174ba094ca3b1adaad8a5fbe5e..3313ae3bd5ef546b57e45bed7d9d569324fbbcb9 100644 (file)
 
 #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);
index e9101f34ca30e0f87e3a2535b0c2f14f4a3a7a05..0c3ac82f57225fe3552442e9ac99bd2102808d11 100644 (file)
 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);
index fc3b5bcfe3367650900f319ebe1fa7404e26deb5..85b736bad2ca522742a942fd94762956d84397be 100644 (file)
@@ -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;