diff options
author | Jon Lund Steffensen <jonlst@gmail.com> | 2015-01-04 16:35:05 -0500 |
---|---|---|
committer | Jon Lund Steffensen <jonlst@gmail.com> | 2015-01-04 16:35:05 -0500 |
commit | 6711be464ff2b8e08501d776e57b6f47e29af245 (patch) | |
tree | 9df16107d36ac46344fa1866ba957f105b2d5345 /src | |
parent | redshift: Add gamma_is_valid function to check gamma (diff) | |
parent | w32gdi: Add preserve option to windows GDI method (diff) | |
download | redshift-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.c | 15 | ||||
-rw-r--r-- | src/gamma-drm.c | 10 | ||||
-rw-r--r-- | src/gamma-quartz.c | 156 | ||||
-rw-r--r-- | src/gamma-quartz.h | 14 | ||||
-rw-r--r-- | src/gamma-randr.c | 25 | ||||
-rw-r--r-- | src/gamma-randr.h | 1 | ||||
-rw-r--r-- | src/gamma-vidmode.c | 24 | ||||
-rw-r--r-- | src/gamma-vidmode.h | 1 | ||||
-rw-r--r-- | src/gamma-w32gdi.c | 32 | ||||
-rw-r--r-- | src/gamma-w32gdi.h | 1 |
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; |