summaryrefslogtreecommitdiffstats
path: root/src/blueshift_quartz_c.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-04-16 01:12:25 +0200
committerMattias Andrée <maandree@operamail.com>2014-04-16 01:12:25 +0200
commit1752e337c70508b3e0a143934a70e61afdc9daae (patch)
treeec1a002747aa3e0afcc8827f3ccccc3b362fc611 /src/blueshift_quartz_c.c
parentchange quartz functions to utilize that quarts expects floats rather than uint16_t (diff)
downloadblueshift-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.c169
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();
}