Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c80d58f
Add hidden non-git files and .gch and .su (can be generated when comp…
maandree May 12, 2014
e3f9cb9
Add fake-w32gdi (./configure --enable-fakegdi) that enabled the w32gd…
maandree May 12, 2014
e5ad5a1
Printing gamma in verbose mode is not necessary and causes complicati…
maandree May 12, 2014
84fe440
Separate out adjustment methods from redshift.c into adjustments.h so…
maandree May 12, 2014
fa0c50a
Move coordinate and elevation constants from redshift.c to redshift.h…
maandree May 12, 2014
bba1834
Use separate arguments instead of colon for option delimiting in -l a…
maandree May 16, 2014
d8dd370
Add adjustment datastructures to adjustments.h and prepare colorramp_…
maandree May 13, 2014
1751578
Add adjustment method common states
maandree May 12, 2014
9bf932f
Adjustment method common state initialisation and destruction
maandree May 12, 2014
addf271
Add adjustment method commit CRTC iterator
maandree May 16, 2014
f70127e
Add a function to find the alreadly loaded, if any, site (e.g. X disp…
maandree May 16, 2014
ada4fba
Implement adjustment method common CRTC selection logic
maandree May 16, 2014
062c997
Add adjustment method common gamma ramp update function and restore f…
maandree May 12, 2014
b59ece3
Add adjustment method common option parsing
maandree May 12, 2014
68b2b10
Add functions for updating adjustment settings
maandree May 12, 2014
96f1561
Add function to config-ini that gets multiple sections with the same …
maandree May 12, 2014
b8b58dc
Rewrite gamma-dummy to use gamma-common and update redshift.c to use …
maandree May 12, 2014
04df1b4
Rewrite gamma-randr to use gamma-common
maandree May 12, 2014
c17850a
Rewrite gamma-vidmode to use gamma-common
maandree May 12, 2014
e105abb
Rewrite gramma-drm to use gamma-common
maandree May 12, 2014
50c66f8
Rewrite gamma-w32gdi to use gamma-common
maandree May 12, 2014
64d2f47
Remove the old colorramp_fill
maandree May 12, 2014
a18884f
Some code reduce
maandree Apr 11, 2014
289c886
Minor documentation edits
maandree Apr 11, 2014
ce39556
Update configure.ac and src/Makefile.am for gamma-quartz and fake-quartz
maandree Apr 16, 2014
a3d3c3e
Add fake Mac OS X Quartz library
maandree Apr 16, 2014
99d818c
Add Quartz method
maandree Apr 16, 2014
32c647f
updated to compile with osx
shawnrice May 8, 2014
8cbd93d
Simplify systemtime_get_time
maandree May 8, 2014
2a0ca01
Allocate the clock service on OS X once rather than everytime the clo…
maandree May 8, 2014
418eeba
Fix return type
maandree May 8, 2014
ceef794
Fix framwork linking for Quartz support
maandree May 9, 2014
5520798
Update quartz_set_option to use the new signature
maandree May 27, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add Quartz method
Signed-off-by: Mattias Andrée <maandree@operamail.com>
  • Loading branch information
maandree committed May 27, 2014
commit 99d818c7c0c488453adb475088570c7480590ea4
4 changes: 3 additions & 1 deletion src/fake-quartz.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ CGGetOnlineDisplayList(uint32_t max_size, CGDirectDisplayID *displays_out, uint3
}
}

for (uint32_t i = 0; (i < max_size) && (i < crtc_count); i++)
uint32_t i;
for (i = 0; (i < max_size) && (i < crtc_count); i++)
*(displays_out + i) = (CGDirectDisplayID)i;

*count_out = i;
Expand Down Expand Up @@ -253,6 +254,7 @@ CGGetDisplayTransferByTable(CGDirectDisplayID display, uint32_t gamma_size, CGGa
blue[i] = (CGGammaValue)(b_int[i]) / UINT16_MAX;
}

free(gamma_reply);
return kCGErrorSuccess;
}

Expand Down
273 changes: 273 additions & 0 deletions src/gamma-quartz.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
/* gamma-quartz.c -- Mac OS X Quartz gamma adjustment source
This file is part of Redshift.

Redshift is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Redshift is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Redshift. If not, see <http://www.gnu.org/licenses/>.

Copyright (c) 2014 Mattias Andrée <maandree@member.fsf.org>
*/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef ENABLE_NLS
# include <libintl.h>
# define _(s) gettext(s)
#else
# define _(s) s
#endif

#include "gamma-quartz.h"


static void
quartz_free_crtc(void *data)
{
free(data);
}

static void
quartz_free_partition(void *data)
{
close_fake_quartz();
free(data);
}

static int
quartz_open_site(gamma_server_state_t *state, char *site, gamma_site_state_t *site_out)
{
(void) state;
(void) site;
site_out->data = NULL;
site_out->partitions_available = 1;
return 0;
}

static int
quartz_open_partition(gamma_server_state_t *state, gamma_site_state_t *site,
size_t partition, gamma_partition_state_t *partition_out)
{
(void) state;
(void) site;
(void) partition;

partition_out->data = NULL;
partition_out->crtcs_available = 0;

uint32_t cap = 4;
CGDirectDisplayID *crtcs = malloc((size_t)cap * sizeof(CGDirectDisplayID));
if (crtcs == NULL) {
perror("malloc");
return -1;
}

/* Count number of displays. */
CGError r;
uint32_t crtc_count;
while (1) {
r = CGGetOnlineDisplayList(cap, crtcs, &crtc_count);
if (r != kCGErrorSuccess) {
fputs(_("Cannot get list of online displays.\n"), stderr);
free(crtcs);
close_fake_quartz();
}
if (crtc_count < cap)
break;
cap <<= 1;
if (cap == 0) { /* We could also test ~0, but it is still too many. */
fprintf(stderr,
_("An impossible number of CRTCs are available 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;
}
}

partition_out->data = crtcs;
partition_out->crtcs_available = (size_t)crtc_count;

return 0;
}

static int
quartz_open_crtc(gamma_server_state_t *state, gamma_site_state_t *site,
gamma_partition_state_t *partition, size_t crtc, gamma_crtc_state_t *crtc_out)
{
(void) state;
(void) site;

CGDirectDisplayID *crtcs = partition->data;
CGDirectDisplayID crtc_id = crtcs[crtc];

crtc_out->data = NULL;
crtc_out->saved_ramps.red = NULL;

size_t gamma_size = CGDisplayGammaTableCapacity(crtc_id);
if (gamma_size < 2) {
fprintf(stderr,
_("Quartz reported an impossibly small gamma ramp size for CRTC %ld.\n"),
crtc);
return -1;
}

/* Specify gamma ramp dimensions. */
crtc_out->saved_ramps.red_size = gamma_size;
crtc_out->saved_ramps.green_size = gamma_size;
crtc_out->saved_ramps.blue_size = gamma_size;

/* Allocate space for saved gamma ramps. */
crtc_out->saved_ramps.red = malloc(3 * gamma_size * sizeof(uint16_t));
if (crtc_out->saved_ramps.red == NULL) {
perror("malloc");
return -1;
}
crtc_out->saved_ramps.green = crtc_out->saved_ramps.red + gamma_size;
crtc_out->saved_ramps.blue = crtc_out->saved_ramps.green + gamma_size;

/* Allocate space for gamma ramps reading. */
crtc_out->data = malloc(3 * gamma_size * sizeof(CGGammaValue));
if (crtc_out->data == NULL) {
perror("malloc");
return -1;
}

/* Read current gamma ramps. */
CGError r;
uint32_t gamma_size_out;
CGGammaValue *red_green_blue = crtc_out->data;
CGGammaValue *red = red_green_blue + 0 * gamma_size;
CGGammaValue *green = red_green_blue + 1 * gamma_size;
CGGammaValue *blue = red_green_blue + 2 * gamma_size;
r = CGGetDisplayTransferByTable(crtc_id, gamma_size, red, green, blue, &gamma_size_out);
if (r != kCGErrorSuccess) {
fprintf(stderr, _("Cannot read gamma ramps for CRTC %ld.\n"), crtc);
return -1;
}
if (gamma_size_out != gamma_size) {
fprintf(stderr, _("Quartz changed its mind about gamma ramp sizes,\n"
"I do not know what is real anymore.\n"));
return -1;
}

/* Convert current gamma ramps to integer format. */
for (size_t c = 0; c < 3; c++) {
uint16_t *ramp_int = crtc_out->saved_ramps.red + c * gamma_size;
CGGammaValue *ramp_float = red_green_blue + c * gamma_size;
for (uint32_t i = 0; i < gamma_size; i++) {
int32_t value = (int32_t)(ramp_float[i] * UINT16_MAX);
ramp_int[i] = (uint16_t)(value < 0 ? 0 : value > UINT16_MAX ? UINT16_MAX : value);
}
}

return 0;
}

static int
quartz_set_ramps(gamma_server_state_t *state, gamma_crtc_state_t *crtc, gamma_ramps_t ramps)
{
CGDirectDisplayID *crtcs = state->sites->partitions->data;
CGDirectDisplayID crtc_id = crtcs[crtc->crtc];
size_t gamma_size = ramps.red_size;

CGGammaValue *red_green_blue = crtc->data;
CGGammaValue *red = red_green_blue + 0 * gamma_size;
CGGammaValue *green = red_green_blue + 1 * gamma_size;
CGGammaValue *blue = red_green_blue + 2 * gamma_size;

/* Convert pending gamma ramps to float format. */
for (size_t c = 0; c < 3; c++) {
uint16_t *ramp_int = crtc->current_ramps.red + c * gamma_size;
CGGammaValue *ramp_float = red_green_blue + c * gamma_size;
for (uint32_t i = 0; i < gamma_size; i++)
ramp_float[i] = (CGGammaValue)(ramp_int[i]) / UINT16_MAX;
}

/* Apply gamma ramps. */
CGError r = CGSetDisplayTransferByTable(crtc_id, (uint32_t)gamma_size, red, green, blue);
if (r != kCGErrorSuccess) {
fprintf(stderr, _("Cannot set gamma ramps for CRTC %ld.\n"), crtc->crtc);
return -1;
}

return 0;
}

static int
quartz_set_option(gamma_server_state_t *state, const char *key, const char *value, ssize_t section)
{
if (strcasecmp(key, "crtc") == 0) {
ssize_t crtc = strcasecmp(value, "all") ? (ssize_t)atoi(value) : -1;
if (crtc < 0 && strcasecmp(value, "all")) {
/* TRANSLATORS: `all' must not be translated. */
fprintf(stderr, _("CRTC must be `all' or a non-negative integer.\n"));
return -1;
}
if (section >= 0) {
state->selections[section].crtc = crtc;
} else {
for (size_t i = 0; i < state->selections_made; i++)
state->selections[i].crtc = crtc;
}
return 0;
}
return 1;
}


int
quartz_init(gamma_server_state_t *state)
{
int r;
r = gamma_init(state);
if (r != 0) return r;

state->free_partition_data = quartz_free_partition;
state->free_crtc_data = quartz_free_crtc;
state->open_site = quartz_open_site;
state->open_partition = quartz_open_partition;
state->open_crtc = quartz_open_crtc;
state->set_ramps = quartz_set_ramps;
state->set_option = quartz_set_option;

return 0;
}

int
quartz_start(gamma_server_state_t *state)
{
return gamma_resolve_selections(state);
}

void
quartz_print_help(FILE *f)
{
fputs(_("Adjust gamma ramps with Quartz.\n"), f);
fputs("\n", f);

/* TRANSLATORS: Mac OS X Quartz help output
left column must not be translated. */
fputs(_(" crtc=N\tX monitor to apply adjustments to\n"), f);
fputs("\n", f);
}

47 changes: 47 additions & 0 deletions src/gamma-quartz.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* gamma-quartz.h -- Mac OS X Quartz gamma adjustment header
This file is part of Redshift.

Redshift is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Redshift is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Redshift. If not, see <http://www.gnu.org/licenses/>.

Copyright (c) 2014 Mattias Andrée <maandree@member.fsf.org>
*/

#ifndef REDSHIFT_GAMMA_QUARTZ_H
#define REDSHIFT_GAMMA_QUARTZ_H

#include "gamma-common.h"

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#ifdef FAKE_QUARTZ
# include "fake-quartz.h"
#else
# include <CoreGraphics/CGDirectDisplay.h>
# define close_fake_quartz() /* for compatibility with "fake-quartz.h" */
#endif


int quartz_init(gamma_server_state_t *state);
int quartz_start(gamma_server_state_t *state);

void quartz_print_help(FILE *f);


/* TODO: It should be possible to use CGDisplayRestoreColorSyncSettings. */


#endif /* ! REDSHIFT_GAMMA_QUARTZ_H */

12 changes: 12 additions & 0 deletions src/redshift.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
# include "gamma-drm.h"
#endif

#ifdef ENABLE_QUARTZ
# include "gamma-quartz.h"
#endif

#ifdef ENABLE_RANDR
# include "gamma-randr.h"
#endif
Expand Down Expand Up @@ -93,6 +97,14 @@ static const gamma_method_t gamma_methods[] = {
(gamma_method_print_help_func *)drm_print_help
},
#endif
#ifdef ENABLE_QUARTZ
{
"quartz", 1,
(gamma_method_init_func *)quartz_init,
(gamma_method_start_func *)quartz_start,
(gamma_method_print_help_func *)quartz_print_help
},
#endif
#ifdef ENABLE_RANDR
{
"randr", 1,
Expand Down