aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJon Lund Steffensen <jonlst@gmail.com>2015-01-04 16:35:05 -0500
committerJon Lund Steffensen <jonlst@gmail.com>2015-01-04 16:35:05 -0500
commit6711be464ff2b8e08501d776e57b6f47e29af245 (patch)
tree9df16107d36ac46344fa1866ba957f105b2d5345 /src
parentredshift: Add gamma_is_valid function to check gamma (diff)
parentw32gdi: Add preserve option to windows GDI method (diff)
downloadredshift-ng-6711be464ff2b8e08501d776e57b6f47e29af245.tar.gz
redshift-ng-6711be464ff2b8e08501d776e57b6f47e29af245.tar.bz2
redshift-ng-6711be464ff2b8e08501d776e57b6f47e29af245.tar.xz
Merge branch 'preserve-gamma'
Diffstat (limited to 'src')
-rw-r--r--src/colorramp.c15
-rw-r--r--src/gamma-drm.c10
-rw-r--r--src/gamma-quartz.c156
-rw-r--r--src/gamma-quartz.h14
-rw-r--r--src/gamma-randr.c25
-rw-r--r--src/gamma-randr.h1
-rw-r--r--src/gamma-vidmode.c24
-rw-r--r--src/gamma-vidmode.h1
-rw-r--r--src/gamma-w32gdi.c32
-rw-r--r--src/gamma-w32gdi.h1
10 files changed, 234 insertions, 45 deletions
diff --git a/src/colorramp.c b/src/colorramp.c
index d732a18..fda75f2 100644
--- a/src/colorramp.c
+++ b/src/colorramp.c
@@ -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);
}
}
diff --git a/src/gamma-drm.c b/src/gamma-drm.c
index cbdafe5..d431395 100644
--- a/src/gamma-drm.c
+++ b/src/gamma-drm.c
@@ -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,
diff --git a/src/gamma-quartz.c b/src/gamma-quartz.c
index f28955f..6691c91 100644
--- a/src/gamma-quartz.c
+++ b/src/gamma-quartz.c
@@ -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;
}
diff --git a/src/gamma-quartz.h b/src/gamma-quartz.h
index b5bc213..cd29d54 100644
--- a/src/gamma-quartz.h
+++ b/src/gamma-quartz.h
@@ -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;
diff --git a/src/gamma-randr.c b/src/gamma-randr.c
index 4f6b0f0..0594332 100644
--- a/src/gamma-randr.c
+++ b/src/gamma-randr.c
@@ -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);
diff --git a/src/gamma-randr.h b/src/gamma-randr.h
index e541379..093c41f 100644
--- a/src/gamma-randr.h
+++ b/src/gamma-randr.h
@@ -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;
diff --git a/src/gamma-vidmode.c b/src/gamma-vidmode.c
index 58a552f..254d065 100644
--- a/src/gamma-vidmode.c
+++ b/src/gamma-vidmode.c
@@ -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);
diff --git a/src/gamma-vidmode.h b/src/gamma-vidmode.h
index 05f5919..4b6cecc 100644
--- a/src/gamma-vidmode.h
+++ b/src/gamma-vidmode.h
@@ -29,6 +29,7 @@
typedef struct {
Display *display;
+ int preserve;
int screen_num;
int ramp_size;
uint16_t *saved_ramps;
diff --git a/src/gamma-w32gdi.c b/src/gamma-w32gdi.c
index ee603e6..c518fe6 100644
--- a/src/gamma-w32gdi.c
+++ b/src/gamma-w32gdi.c
@@ -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);
diff --git a/src/gamma-w32gdi.h b/src/gamma-w32gdi.h
index 1f985c8..6e73cd1 100644
--- a/src/gamma-w32gdi.h
+++ b/src/gamma-w32gdi.h
@@ -28,6 +28,7 @@
typedef struct {
WORD *saved_ramps;
+ int preserve;
} w32gdi_state_t;