Merge branch 'preserve-gamma'
This commit is contained in:
+9
-6
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
typedef struct {
|
||||
Display *display;
|
||||
int preserve;
|
||||
int screen_num;
|
||||
int ramp_size;
|
||||
uint16_t *saved_ramps;
|
||||
|
||||
+31
-1
@@ -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);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
typedef struct {
|
||||
WORD *saved_ramps;
|
||||
int preserve;
|
||||
} w32gdi_state_t;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user