diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/blueshift_quartz.pyx | 14 | ||||
-rw-r--r-- | src/blueshift_quartz_c.c | 169 | ||||
-rw-r--r-- | src/blueshift_quartz_c.h | 11 | ||||
-rw-r--r-- | src/fake_quartz.c | 21 | ||||
-rw-r--r-- | src/fake_quartz.h | 2 |
5 files changed, 201 insertions, 16 deletions
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); |