summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--src/blueshift_quartz.pyx14
-rw-r--r--src/blueshift_quartz_c.c169
-rw-r--r--src/blueshift_quartz_c.h11
-rw-r--r--src/fake_quartz.c21
-rw-r--r--src/fake_quartz.h2
6 files changed, 203 insertions, 16 deletions
diff --git a/TODO b/TODO
index 80791dd..2f3f52e 100644
--- a/TODO
+++ b/TODO
@@ -23,6 +23,8 @@ Low priority:
CRTC count function for W32 GDI should be documented
W32 GDI support should be documented
Quartz support should be documented
+ CRTC count function for Quartz should be documented
+ Gamma restore function for Quartz should be documented
Future stuff:
How is it looking on the DirectFB front?
diff --git a/src/blueshift_quartz.pyx b/src/blueshift_quartz.pyx
index e9d424e..528c08f 100644
--- a/src/blueshift_quartz.pyx
+++ b/src/blueshift_quartz.pyx
@@ -60,6 +60,12 @@ cdef extern void blueshift_quartz_close()
Resource freeing stage of colour curve control
'''
+cdef extern void blueshift_quartz_restore()
+'''
+Restore all gamma curves (on each and every CRTC on the system)
+to the settings on ColorSync
+'''
+
cdef float* r_c
@@ -165,3 +171,11 @@ def quartz_close():
# Close free all resources in the native code
blueshift_quartz_close()
+
+def quartz_restore():
+ '''
+ Restore all gamma curves (on each and every CRTC on the system)
+ to the settings on ColorSync
+ '''
+ blueshift_quartz_restore()
+
diff --git a/src/blueshift_quartz_c.c b/src/blueshift_quartz_c.c
index a74b219..d4e0bf7 100644
--- a/src/blueshift_quartz_c.c
+++ b/src/blueshift_quartz_c.c
@@ -19,13 +19,80 @@
/**
+ * The number of CRTC:s on the system
+ */
+static uint32_t crtc_count = 0;
+
+/**
+ * The CRTC:s on the system
+ */
+static CGDirectDisplayID* crtcs = NULL;
+
+/**
+ */
+static uint32_t* gamma_sizes = NULL;
+
+
+
+/**
* Start stage of colour curve control
*
* @return Zero on success
*/
int blueshift_quartz_open(void)
{
- return -1,
+ uint32_t cap = 4;
+ CGError r;
+
+ crtcs = malloc((size_t)cap * sizeof(CGDirectDisplayID));
+ if (crtcs == NULL)
+ {
+ perror("malloc");
+ return -1;
+ }
+
+ for (;;)
+ {
+ r = CGGetOnlineDisplayList(cap, crtcs, &crtc_count);
+ if (r != kCGErrorSuccess)
+ {
+ free(crtcs);
+ crtcs = NULL;
+ close_fake_quartz();
+ }
+ if (crtc_count == cap)
+ {
+ cap <<= 1;
+ if (cap == 0) /* We could also test ~0, but it is still too many. */
+ {
+ fprintf(stderr, "A impossible number of CRTC:s are avaiable according to Quartz\n");
+ free(crtcs);
+ close_fake_quartz();
+ return -1;
+ }
+ crtcs = realloc(crtcs, (size_t)cap * sizeof(CGDirectDisplayID));
+ if (crtcs == NULL)
+ {
+ perror("realloc");
+ close_fake_quartz();
+ return -1;
+ }
+ }
+ }
+
+ if (crtc_count > 0)
+ {
+ gamma_sizes = malloc((size_t)crtc_count * sizeof(uint32_t));
+ if (gamma_sizes == NULL)
+ {
+ perror("malloc");
+ free(crtcs);
+ close_fake_quartz();
+ return -1;
+ }
+ }
+
+ return 0;
}
@@ -36,7 +103,7 @@ int blueshift_quartz_open(void)
*/
int blueshift_quartz_crtc_count(void)
{
- return 0;
+ return (int)crtc_count;
}
@@ -50,7 +117,69 @@ int blueshift_quartz_crtc_count(void)
*/
uint16_t* blueshift_quartz_read(int use_crtc)
{
- return NULL;
+ if ((use_crtc < 0) || (use_crtc >= (int)crtc_count))
+ {
+ fprintf(stderr, "CRTC %i does not exist\n", use_crtc);
+ return NULL;
+ }
+ else
+ {
+ uint32_t gamma_size = gamma_sizes[use_crtc];
+ uint16_t* rc = malloc((1 + 3 * (size_t)(gamma_size)) * sizeof(uint16_t));
+ uint32_t i;
+ CGGammaValue* red;
+ CGGammaValue* green;
+ CGGammaValue* blue;
+ CGError r;
+ uint32_t _;
+
+ if (rc == NULL)
+ {
+ perror("malloc");
+ return NULL;
+ }
+
+ red = malloc((3 * (size_t)gamma_size) * sizeof(CGGammaValue));
+ green = red + (size_t)gamma_size;
+ blue = green + (size_t)gamma_size;
+
+ if (red == NULL)
+ {
+ perror("malloc");
+ free(rc);
+ return NULL;
+ }
+
+ r = CGGetDisplayTransferByTable(crtcs[use_crtc], gamma_size, red, green, blue, &_);
+ if (r != kCGErrorSuccess)
+ {
+ fprintf(stderr, "Failed to get gamma ramps for CRTC %i\n", use_crtc);
+ free(red);
+ free(rc);
+ return 0;
+ }
+
+ *rc++ = gamma_sizes[use_crtc];
+ for (i = 0; i < gamma_size; i++)
+ {
+ int32_t v = red[i] * UINT16_MAX;
+ rc[i] = (uint16_t)(v < 0 ? 0 : v > UINT16_MAX ? UINT16_MAX : v);
+ }
+ rc += gamma_size;
+ for (i = 0; i < gamma_size; i++)
+ {
+ int32_t v = blue[i] * UINT16_MAX;
+ rc[i] = (uint16_t)(v < 0 ? 0 : v > UINT16_MAX ? UINT16_MAX : v);
+ }
+ rc += gamma_size;
+ for (i = 0; i < gamma_size; i++)
+ {
+ int32_t v = blue[i] * UINT16_MAX;
+ rc[i] = (uint16_t)(v < 0 ? 0 : v > UINT16_MAX ? UINT16_MAX : v);
+ }
+
+ return rc - (1 + 2 * gamma_size);
+ }
}
@@ -65,6 +194,24 @@ uint16_t* blueshift_quartz_read(int use_crtc)
*/
int blueshift_quartz_apply(int use_crtc, float* r_curves, float* g_curves, float* b_curves)
{
+ if (use_crtc < (int)crtc_count)
+ {
+ int c = use_crtc < 0 ? 0 : use_crtc;
+ int n = use_crtc < 0 ? (int)crtc_count : (use_crtc + 1);
+ CGError r = kCGErrorSuccess;
+
+ for (; c < n; c++)
+ {
+ r = CGSetDisplayTransferByTable(crtcs[c], gamma_sizes[c], r_curves, g_curves, b_curves);
+ if (r != kCGErrorSuccess)
+ {
+ fprintf(stderr, "Failed to set gamma ramps for CRTC %i\n", c);
+ break;
+ }
+ }
+ return r != kCGErrorSuccess;
+ }
+ fprintf(stderr, "CRTC %i does not exist\n", use_crtc);
return -1;
}
@@ -74,8 +221,20 @@ int blueshift_quartz_apply(int use_crtc, float* r_curves, float* g_curves, float
*/
void blueshift_quartz_close(void)
{
-#ifdef FAKE_QUARTZ
+ if (crtcs != NULL)
+ free(crtcs);
+ if (gamma_sizes != NULL)
+ free(gamma_sizes);
close_fake_quartz();
-#endif
+}
+
+
+/**
+ * Restore all gamma curves (on each and every CRTC on the system)
+ * to the settings on ColorSync
+ */
+void blueshift_quartz_restore(void)
+{
+ CGDisplayRestoreColorSyncSettings();
}
diff --git a/src/blueshift_quartz_c.h b/src/blueshift_quartz_c.h
index f8ea783..d21ef02 100644
--- a/src/blueshift_quartz_c.h
+++ b/src/blueshift_quartz_c.h
@@ -25,9 +25,14 @@
# include "fake_quartz.h"
#else
# include <CoreGraphics/CGDirectDisplay.h>
+# include <CoreGraphics/CGError.h>
#endif
+#ifndef FAKE_QUARTZ
+# define close_fake_quartz() /* Do nothing */
+#endif
+
/**
* Start stage of colour curve control
@@ -69,6 +74,12 @@ int blueshift_quartz_apply(int use_crtc, float* r_curves, float* g_curves, float
*/
void blueshift_quartz_close(void);
+/**
+ * Restore all gamma curves (on each and every CRTC on the system)
+ * to the settings on ColorSync
+ */
+void blueshift_quartz_restore(void);
+
#endif
diff --git a/src/fake_quartz.c b/src/fake_quartz.c
index 92f75df..6508860 100644
--- a/src/fake_quartz.c
+++ b/src/fake_quartz.c
@@ -123,14 +123,14 @@ CGError CGSetDisplayTransferByTable(CGDirectDisplayID display, uint32_t gamma_si
for (i = 0; i < 256; i++)
{
- v = red[i] * (UINT16_MAX - 1);
- r_int[i] = v < 0 ? 0 : v >= UINT16_MAX : (UINT16_MAX - 1) : v;
+ v = red[i] * UINT16_MAX;
+ r_int[i] = v < 0 ? 0 : v > UINT16_MAX ? UINT16_MAX : v;
- v = green[i] * (UINT16_MAX - 1);
- g_int[i] = v < 0 ? 0 : v >= UINT16_MAX : (UINT16_MAX - 1) : v;
+ v = green[i] * UINT16_MAX;
+ g_int[i] = v < 0 ? 0 : v > UINT16_MAX ? UINT16_MAX : v;
- v = blue[i] * (UINT16_MAX - 1);
- b_int[i] = v < 0 ? 0 : v >= UINT16_MAX : (UINT16_MAX - 1) : v;
+ v = blue[i] * UINT16_MAX;
+ b_int[i] = v < 0 ? 0 : v > UINT16_MAX ? UINT16_MAX : v;
}
gamma_cookie = xcb_randr_set_crtc_gamma_checked(conn, crtcs[display], gamma_size, r_int, g_int, b_int);
@@ -147,6 +147,7 @@ CGError CGGetDisplayTransferByTable(CGDirectDisplayID display, uint32_t gamma_si
uint16_t* r_int;
uint16_t* g_int;
uint16_t* b_int;
+ long i;
if (gamma_size != 256)
{
@@ -156,7 +157,7 @@ CGError CGGetDisplayTransferByTable(CGDirectDisplayID display, uint32_t gamma_si
*gamma_size_out = 256;
- gamma_cookie = xcb_randr_get_crtc_gamma(conn, crtcs[i]);
+ gamma_cookie = xcb_randr_get_crtc_gamma(conn, crtcs[display]);
gamma_reply = xcb_randr_get_crtc_gamma_reply(conn, gamma_cookie, &error);
if (error)
@@ -171,9 +172,9 @@ CGError CGGetDisplayTransferByTable(CGDirectDisplayID display, uint32_t gamma_si
for (i = 0; i < 256; i++)
{
- red[i] = (CGGammaValue)(r_int[i]) / (UINT16_MAX - 1);
- green[i] = (CGGammaValue)(g_int[i]) / (UINT16_MAX - 1);
- blue[i] = (CGGammaValue)(b_int[i]) / (UINT16_MAX - 1);
+ red[i] = (CGGammaValue)(r_int[i]) / UINT16_MAX;
+ green[i] = (CGGammaValue)(g_int[i]) / UINT16_MAX;
+ blue[i] = (CGGammaValue)(b_int[i]) / UINT16_MAX;
}
return kCGErrorSuccess;
diff --git a/src/fake_quartz.h b/src/fake_quartz.h
index 24935e8..ee6d065 100644
--- a/src/fake_quartz.h
+++ b/src/fake_quartz.h
@@ -47,7 +47,7 @@ CGError CGSetDisplayTransferByTable(CGDirectDisplayID display, uint32_t gamma_si
const CGGammaValue* green, const CGGammaValue* blue);
CGError CGGetDisplayTransferByTable(CGDirectDisplayID display, uint32_t gamma_size, CGGammaValue* red,
- CGGammaValue* green, CGGammaValue* blue, uint32_t *gamma_size_out);
+ CGGammaValue* green, CGGammaValue* blue, uint32_t* gamma_size_out);
void CGDisplayRestoreColorSyncSettings(void);