Merge branch 'preserve-gamma'

This commit is contained in:
Jon Lund Steffensen
2015-01-04 16:35:05 -05:00
10 changed files with 234 additions and 45 deletions
+9 -6
View File
@@ -297,9 +297,12 @@ colorramp_fill(uint16_t *gamma_r, uint16_t *gamma_g, uint16_t *gamma_b,
&blackbody_color[temp_index+3], white_point);
for (int i = 0; i < size; i++) {
gamma_r[i] = F((float)i/size, 0) * (UINT16_MAX+1);
gamma_g[i] = F((float)i/size, 1) * (UINT16_MAX+1);
gamma_b[i] = F((float)i/size, 2) * (UINT16_MAX+1);
gamma_r[i] = F((double)gamma_r[i]/(UINT16_MAX+1), 0) *
(UINT16_MAX+1);
gamma_g[i] = F((double)gamma_g[i]/(UINT16_MAX+1), 1) *
(UINT16_MAX+1);
gamma_b[i] = F((double)gamma_b[i]/(UINT16_MAX+1), 2) *
(UINT16_MAX+1);
}
}
@@ -315,9 +318,9 @@ colorramp_fill_float(float *gamma_r, float *gamma_g, float *gamma_b,
&blackbody_color[temp_index+3], white_point);
for (int i = 0; i < size; i++) {
gamma_r[i] = F((float)i/size, 0);
gamma_g[i] = F((float)i/size, 1);
gamma_b[i] = F((float)i/size, 2);
gamma_r[i] = F((double)gamma_r[i], 0);
gamma_g[i] = F((double)gamma_g[i], 1);
gamma_b[i] = F((double)gamma_b[i], 2);
}
}
+10
View File
@@ -268,6 +268,16 @@ drm_set_temperature(drm_state_t *state, const color_setting_t *setting)
}
last_gamma_size = crtcs->gamma_size;
}
/* Initialize gamma ramps to pure state */
int ramp_size = crtcs->gamma_size;
for (int i = 0; i < ramp_size; i++) {
uint16_t value = (double)i/ramp_size * (UINT16_MAX+1);
r_gamma[i] = value;
g_gamma[i] = value;
b_gamma[i] = value;
}
colorramp_fill(r_gamma, g_gamma, b_gamma, crtcs->gamma_size,
setting);
drmModeCrtcSetGamma(state->fd, crtcs->crtc_id, crtcs->gamma_size,
+122 -34
View File
@@ -40,12 +40,95 @@
int
quartz_init(quartz_state_t *state)
{
state->preserve = 0;
state->displays = NULL;
return 0;
}
int
quartz_start(quartz_state_t *state)
{
int r;
CGError error;
uint32_t display_count;
/* Get display count */
error = CGGetOnlineDisplayList(0, NULL, &display_count);
if (error != kCGErrorSuccess) return -1;
state->display_count = display_count;
CGDirectDisplayID* displays =
malloc(sizeof(CGDirectDisplayID)*display_count);
if (displays == NULL) {
perror("malloc");
return -1;
}
/* Get list of displays */
error = CGGetOnlineDisplayList(display_count, displays,
&display_count);
if (error != kCGErrorSuccess) {
free(displays);
return -1;
}
/* Allocate list of display state */
state->displays = malloc(display_count *
sizeof(quartz_display_state_t));
if (state->displays == NULL) {
perror("malloc");
free(displays);
return -1;
}
/* Copy display indentifiers to display state */
for (int i = 0; i < display_count; i++) {
state->displays[i].display = displays[i];
state->displays[i].saved_ramps = NULL;
}
free(displays);
/* Save gamma ramps for all displays in display state */
for (int i = 0; i < display_count; i++) {
CGDirectDisplayID display = state->displays[i].display;
uint32_t ramp_size = CGDisplayGammaTableCapacity(display);
if (ramp_size == 0) {
fprintf(stderr, _("Gamma ramp size too small: %i\n"),
ramp_size);
return -1;
}
state->displays[i].ramp_size = ramp_size;
/* Allocate space for saved ramps */
state->displays[i].saved_ramps =
malloc(3 * ramp_size * sizeof(float));
if (state->displays[i].saved_ramps == NULL) {
perror("malloc");
return -1;
}
float *gamma_r = &state->displays[i].saved_ramps[0*ramp_size];
float *gamma_g = &state->displays[i].saved_ramps[1*ramp_size];
float *gamma_b = &state->displays[i].saved_ramps[2*ramp_size];
/* Copy the ramps to allocated space */
uint32_t sample_count;
error = CGGetDisplayTransferByTable(display, ramp_size,
gamma_r, gamma_g, gamma_b,
&sample_count);
if (error != kCGErrorSuccess ||
sample_count != ramp_size) {
fputs(_("Unable to save current gamma ramp.\n"),
stderr);
return -1;
}
}
return 0;
}
@@ -58,6 +141,12 @@ quartz_restore(quartz_state_t *state)
void
quartz_free(quartz_state_t *state)
{
if (state->displays != NULL) {
for (int i = 0; i < state->display_count; i++) {
free(state->displays[i].saved_ramps);
}
}
free(state->displays);
}
void
@@ -65,25 +154,33 @@ quartz_print_help(FILE *f)
{
fputs(_("Adjust gamma ramps on OSX using Quartz.\n"), f);
fputs("\n", f);
/* TRANSLATORS: Quartz help output
left column must not be translated */
fputs(_(" preserve={0,1}\tWhether existing gamma should be"
" preserved\n"),
f);
fputs("\n", f);
}
int
quartz_set_option(quartz_state_t *state, const char *key, const char *value)
{
fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
return -1;
if (strcasecmp(key, "preserve") == 0) {
state->preserve = atoi(value);
} else {
fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
return -1;
}
return 0;
}
static void
quartz_set_temperature_for_display(CGDirectDisplayID display,
quartz_set_temperature_for_display(quartz_state_t *state, int display,
const color_setting_t *setting)
{
uint32_t ramp_size = CGDisplayGammaTableCapacity(display);
if (ramp_size == 0) {
fprintf(stderr, _("Gamma ramp size too small: %i\n"),
ramp_size);
return;
}
uint32_t ramp_size = state->displays[display].ramp_size;
/* Create new gamma ramps */
float *gamma_ramps = malloc(3*ramp_size*sizeof(float));
@@ -96,6 +193,20 @@ quartz_set_temperature_for_display(CGDirectDisplayID display,
float *gamma_g = &gamma_ramps[1*ramp_size];
float *gamma_b = &gamma_ramps[2*ramp_size];
if (state->preserve) {
/* Initialize gamma ramps from saved state */
memcpy(gamma_ramps, state->displays[display].saved_ramps,
3*ramp_size*sizeof(float));
} else {
/* Initialize gamma ramps to pure state */
for (int i = 0; i < ramp_size; i++) {
float value = (double)i/ramp_size;
gamma_r[i] = value;
gamma_g[i] = value;
gamma_b[i] = value;
}
}
colorramp_fill_float(gamma_r, gamma_g, gamma_b, ramp_size,
setting);
@@ -114,32 +225,9 @@ int
quartz_set_temperature(quartz_state_t *state,
const color_setting_t *setting)
{
int r;
CGError error;
uint32_t display_count;
error = CGGetOnlineDisplayList(0, NULL, &display_count);
if (error != kCGErrorSuccess) return -1;
CGDirectDisplayID* displays =
malloc(sizeof(CGDirectDisplayID)*display_count);
if (displays == NULL) {
perror("malloc");
return -1;
for (int i = 0; i < state->display_count; i++) {
quartz_set_temperature_for_display(state, i, setting);
}
error = CGGetOnlineDisplayList(display_count, displays,
&display_count);
if (error != kCGErrorSuccess) {
free(displays);
return -1;
}
for (int i = 0; i < display_count; i++) {
quartz_set_temperature_for_display(displays[i], setting);
}
free(displays);
return 0;
}
+13 -1
View File
@@ -20,11 +20,23 @@
#ifndef REDSHIFT_GAMMA_QUARTZ_H
#define REDSHIFT_GAMMA_QUARTZ_H
#include <stdint.h>
#include <ApplicationServices/ApplicationServices.h>
#include "redshift.h"
typedef struct {
int dummy;
CGDirectDisplayID display;
uint32_t ramp_size;
float *saved_ramps;
} quartz_display_state_t;
typedef struct {
quartz_display_state_t *displays;
uint32_t display_count;
int preserve;
} quartz_state_t;
+23 -2
View File
@@ -51,6 +51,8 @@ randr_init(randr_state_t *state)
state->crtc_count = 0;
state->crtcs = NULL;
state->preserve = 0;
xcb_generic_error_t *error;
/* Open X server connection */
@@ -274,8 +276,11 @@ randr_print_help(FILE *f)
/* TRANSLATORS: RANDR help output
left column must not be translated */
fputs(_(" screen=N\tX screen to apply adjustments to\n"
" crtc=N\tCRTC to apply adjustments to\n"), f);
fputs(_(" screen=N\t\tX screen to apply adjustments to\n"
" crtc=N\t\tCRTC to apply adjustments to\n"
" preserve={0,1}\tWhether existing gamma should be"
" preserved\n"),
f);
fputs("\n", f);
}
@@ -286,6 +291,8 @@ randr_set_option(randr_state_t *state, const char *key, const char *value)
state->screen_num = atoi(value);
} else if (strcasecmp(key, "crtc") == 0) {
state->crtc_num = atoi(value);
} else if (strcasecmp(key, "preserve") == 0) {
state->preserve = atoi(value);
} else {
fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
return -1;
@@ -327,6 +334,20 @@ randr_set_temperature_for_crtc(randr_state_t *state, int crtc_num,
uint16_t *gamma_g = &gamma_ramps[1*ramp_size];
uint16_t *gamma_b = &gamma_ramps[2*ramp_size];
if (state->preserve) {
/* Initialize gamma ramps from saved state */
memcpy(gamma_ramps, state->crtcs[crtc_num].saved_ramps,
3*ramp_size*sizeof(uint16_t));
} else {
/* Initialize gamma ramps to pure state */
for (int i = 0; i < ramp_size; i++) {
uint16_t value = (double)i/ramp_size * (UINT16_MAX+1);
gamma_r[i] = value;
gamma_g[i] = value;
gamma_b[i] = value;
}
}
colorramp_fill(gamma_r, gamma_g, gamma_b, ramp_size,
setting);
+1
View File
@@ -39,6 +39,7 @@ typedef struct {
xcb_connection_t *conn;
xcb_screen_t *screen;
int preferred_screen;
int preserve;
int screen_num;
int crtc_num;
unsigned int crtc_count;
+23 -1
View File
@@ -43,6 +43,8 @@ vidmode_init(vidmode_state_t *state)
state->screen_num = -1;
state->saved_ramps = NULL;
state->preserve = 0;
/* Open display */
state->display = XOpenDisplay(NULL);
if (state->display == NULL) {
@@ -129,7 +131,10 @@ vidmode_print_help(FILE *f)
/* TRANSLATORS: VidMode help output
left column must not be translated */
fputs(_(" screen=N\tX screen to apply adjustments to\n"), f);
fputs(_(" screen=N\t\tX screen to apply adjustments to\n"
" preserve={0,1}\tWhether existing gamma should be"
" preserved\n"),
f);
fputs("\n", f);
}
@@ -138,6 +143,8 @@ vidmode_set_option(vidmode_state_t *state, const char *key, const char *value)
{
if (strcasecmp(key, "screen") == 0) {
state->screen_num = atoi(value);
} else if (strcasecmp(key, "preserve") == 0) {
state->preserve = atoi(value);
} else {
fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
return -1;
@@ -180,6 +187,21 @@ vidmode_set_temperature(vidmode_state_t *state,
uint16_t *gamma_g = &gamma_ramps[1*state->ramp_size];
uint16_t *gamma_b = &gamma_ramps[2*state->ramp_size];
if (state->preserve) {
/* Initialize gamma ramps from saved state */
memcpy(gamma_ramps, state->saved_ramps,
3*state->ramp_size*sizeof(uint16_t));
} else {
/* Initialize gamma ramps to pure state */
for (int i = 0; i < state->ramp_size; i++) {
uint16_t value = (double)i/state->ramp_size *
(UINT16_MAX+1);
gamma_r[i] = value;
gamma_g[i] = value;
gamma_b[i] = value;
}
}
colorramp_fill(gamma_r, gamma_g, gamma_b, state->ramp_size,
setting);
+1
View File
@@ -29,6 +29,7 @@
typedef struct {
Display *display;
int preserve;
int screen_num;
int ramp_size;
uint16_t *saved_ramps;
+31 -1
View File
@@ -43,6 +43,7 @@ int
w32gdi_init(w32gdi_state_t *state)
{
state->saved_ramps = NULL;
state->preserve = 0;
return 0;
}
@@ -102,12 +103,26 @@ w32gdi_print_help(FILE *f)
{
fputs(_("Adjust gamma ramps with the Windows GDI.\n"), f);
fputs("\n", f);
/* TRANSLATORS: Windows GDI help output
left column must not be translated */
fputs(_(" preserve={0,1}\tWhether existing gamma should be"
" preserved\n"),
f);
fputs("\n", f);
}
int
w32gdi_set_option(w32gdi_state_t *state, const char *key, const char *value)
{
return -1;
if (strcasecmp(key, "preserve") == 0) {
state->preserve = atoi(value);
} else {
fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
return -1;
}
return 0;
}
void
@@ -153,6 +168,21 @@ w32gdi_set_temperature(w32gdi_state_t *state,
WORD *gamma_g = &gamma_ramps[1*GAMMA_RAMP_SIZE];
WORD *gamma_b = &gamma_ramps[2*GAMMA_RAMP_SIZE];
if (state->preserve) {
/* Initialize gamma ramps from saved state */
memcpy(gamma_ramps, state->saved_ramps,
3*GAMMA_RAMP_SIZE*sizeof(WORD));
} else {
/* Initialize gamma ramps to pure state */
for (int i = 0; i < GAMMA_RAMP_SIZE; i++) {
WORD value = (double)i/GAMMA_RAMP_SIZE *
(UINT16_MAX+1);
gamma_r[i] = value;
gamma_g[i] = value;
gamma_b[i] = value;
}
}
colorramp_fill(gamma_r, gamma_g, gamma_b, GAMMA_RAMP_SIZE,
setting);
+1
View File
@@ -28,6 +28,7 @@
typedef struct {
WORD *saved_ramps;
int preserve;
} w32gdi_state_t;