diff options
author | Mattias Andrée <maandree@operamail.com> | 2014-04-16 01:12:25 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2014-04-16 01:12:25 +0200 |
commit | 1752e337c70508b3e0a143934a70e61afdc9daae (patch) | |
tree | ec1a002747aa3e0afcc8827f3ccccc3b362fc611 /src/blueshift_quartz_c.c | |
parent | change quartz functions to utilize that quarts expects floats rather than uint16_t (diff) | |
download | blueshift-1752e337c70508b3e0a143934a70e61afdc9daae.tar.gz blueshift-1752e337c70508b3e0a143934a70e61afdc9daae.tar.bz2 blueshift-1752e337c70508b3e0a143934a70e61afdc9daae.tar.xz |
finish quartz
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src/blueshift_quartz_c.c')
-rw-r--r-- | src/blueshift_quartz_c.c | 169 |
1 files changed, 164 insertions, 5 deletions
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(); } |