aboutsummaryrefslogtreecommitdiffstats
path: root/src/gamma-randr.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/gamma-randr.c (renamed from src/randr.c)170
1 files changed, 125 insertions, 45 deletions
diff --git a/src/randr.c b/src/gamma-randr.c
index 7c05b26..66d5c48 100644
--- a/src/randr.c
+++ b/src/gamma-randr.c
@@ -1,4 +1,4 @@
-/* randr.c -- X RandR gamma adjustment source
+/* gamma-randr.c -- X RANDR gamma adjustment source
This file is part of Redshift.
Redshift is free software: you can redistribute it and/or modify
@@ -19,15 +19,20 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
-#include <libintl.h>
-#define _(s) gettext(s)
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(s) gettext(s)
+#else
+# define _(s) s
+#endif
#include <xcb/xcb.h>
#include <xcb/randr.h>
-#include "randr.h"
+#include "gamma-randr.h"
#include "colorramp.h"
@@ -36,15 +41,19 @@
int
-randr_init(randr_state_t *state, int screen_num)
+randr_init(randr_state_t *state)
{
+ /* Initialize state. */
+ state->screen_num = -1;
+ state->crtc_num = -1;
+
+ state->crtc_count = 0;
+ state->crtcs = NULL;
+
xcb_generic_error_t *error;
/* Open X server connection */
- int preferred_screen;
- state->conn = xcb_connect(NULL, &preferred_screen);
-
- if (screen_num < 0) screen_num = preferred_screen;
+ state->conn = xcb_connect(NULL, &state->preferred_screen);
/* Query RandR version */
xcb_randr_query_version_cookie_t ver_cookie =
@@ -71,6 +80,17 @@ randr_init(randr_state_t *state, int screen_num)
free(ver_reply);
+ return 0;
+}
+
+int
+randr_start(randr_state_t *state)
+{
+ xcb_generic_error_t *error;
+
+ int screen_num = state->screen_num;
+ if (screen_num < 0) screen_num = state->preferred_screen;
+
/* Get screen */
const xcb_setup_t *setup = xcb_get_setup(state->conn);
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
@@ -87,7 +107,6 @@ randr_init(randr_state_t *state, int screen_num)
if (state->screen == NULL) {
fprintf(stderr, _("Screen %i could not be found.\n"),
screen_num);
- xcb_disconnect(state->conn);
return -1;
}
@@ -104,15 +123,14 @@ randr_init(randr_state_t *state, int screen_num)
fprintf(stderr, _("`%s' returned error %d\n"),
"RANDR Get Screen Resources Current",
error->error_code);
- xcb_disconnect(state->conn);
return -1;
}
state->crtc_count = res_reply->num_crtcs;
- state->crtcs = malloc(state->crtc_count * sizeof(randr_crtc_state_t));
+ state->crtcs = calloc(state->crtc_count, sizeof(randr_crtc_state_t));
if (state->crtcs == NULL) {
perror("malloc");
- xcb_disconnect(state->conn);
+ state->crtc_count = 0;
return -1;
}
@@ -144,7 +162,6 @@ randr_init(randr_state_t *state, int screen_num)
fprintf(stderr, _("`%s' returned error %d\n"),
"RANDR Get CRTC Gamma Size",
error->error_code);
- xcb_disconnect(state->conn);
return -1;
}
@@ -156,7 +173,6 @@ randr_init(randr_state_t *state, int screen_num)
if (ramp_size == 0) {
fprintf(stderr, _("Gamma ramp size too small: %i\n"),
ramp_size);
- xcb_disconnect(state->conn);
return -1;
}
@@ -171,7 +187,6 @@ randr_init(randr_state_t *state, int screen_num)
if (error) {
fprintf(stderr, _("`%s' returned error %d\n"),
"RANDR Get CRTC Gamma", error->error_code);
- xcb_disconnect(state->conn);
return -1;
}
@@ -188,7 +203,6 @@ randr_init(randr_state_t *state, int screen_num)
if (state->crtcs[i].saved_ramps == NULL) {
perror("malloc");
free(gamma_get_reply);
- xcb_disconnect(state->conn);
return -1;
}
@@ -248,45 +262,111 @@ randr_free(randr_state_t *state)
xcb_disconnect(state->conn);
}
+void
+randr_print_help(FILE *f)
+{
+ fputs(_("Adjust gamma ramps with the X RANDR extension.\n"), f);
+ fputs("\n", 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("\n", f);
+}
+
int
-randr_set_temperature(randr_state_t *state, int temp, float gamma[3])
+randr_set_option(randr_state_t *state, const char *key, const char *value)
{
- xcb_generic_error_t *error;
+ if (key == NULL) {
+ fprintf(stderr, _("Missing value for parameter: `%s'.\n"),
+ value);
+ return -1;
+ }
- /* Set temperature on all CRTCs */
- for (int i = 0; i < state->crtc_count; i++) {
- xcb_randr_crtc_t crtc = state->crtcs[i].crtc;
- unsigned int ramp_size = state->crtcs[i].ramp_size;
+ if (strcasecmp(key, "screen") == 0) {
+ state->screen_num = atoi(value);
+ } else if (strcasecmp(key, "crtc") == 0) {
+ state->crtc_num = atoi(value);
+ } else {
+ fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
+ return -1;
+ }
- /* Create new gamma ramps */
- uint16_t *gamma_ramps = malloc(3*ramp_size*sizeof(uint16_t));
- if (gamma_ramps == NULL) {
- perror("malloc");
- return -1;
+ return 0;
+}
+
+static int
+randr_set_temperature_for_crtc(randr_state_t *state, int crtc_num, int temp,
+ float gamma[3])
+{
+ xcb_generic_error_t *error;
+
+ if (crtc_num >= state->crtc_count || crtc_num < 0) {
+ fprintf(stderr, _("CRTC %d does not exist. "),
+ state->crtc_num);
+ if (state->crtc_count > 1) {
+ fprintf(stderr, _("Valid CRTCs are [0-%d].\n"),
+ state->crtc_count-1);
+ } else {
+ fprintf(stderr, _("Only CRTC 0 exists.\n"));
}
- uint16_t *gamma_r = &gamma_ramps[0*ramp_size];
- uint16_t *gamma_g = &gamma_ramps[1*ramp_size];
- uint16_t *gamma_b = &gamma_ramps[2*ramp_size];
+ return -1;
+ }
- colorramp_fill(gamma_r, gamma_g, gamma_b, ramp_size,
- temp, gamma);
+ xcb_randr_crtc_t crtc = state->crtcs[crtc_num].crtc;
+ unsigned int ramp_size = state->crtcs[crtc_num].ramp_size;
- /* Set new gamma ramps */
- xcb_void_cookie_t gamma_set_cookie =
- xcb_randr_set_crtc_gamma_checked(state->conn, crtc,
- ramp_size, gamma_r,
- gamma_g, gamma_b);
- error = xcb_request_check(state->conn, gamma_set_cookie);
+ /* Create new gamma ramps */
+ uint16_t *gamma_ramps = malloc(3*ramp_size*sizeof(uint16_t));
+ if (gamma_ramps == NULL) {
+ perror("malloc");
+ return -1;
+ }
- if (error) {
- fprintf(stderr, _("`%s' returned error %d\n"),
- "RANDR Set CRTC Gamma", error->error_code);
- free(gamma_ramps);
- return -1;
- }
+ uint16_t *gamma_r = &gamma_ramps[0*ramp_size];
+ uint16_t *gamma_g = &gamma_ramps[1*ramp_size];
+ uint16_t *gamma_b = &gamma_ramps[2*ramp_size];
+
+ colorramp_fill(gamma_r, gamma_g, gamma_b, ramp_size,
+ temp, gamma);
+ /* Set new gamma ramps */
+ xcb_void_cookie_t gamma_set_cookie =
+ xcb_randr_set_crtc_gamma_checked(state->conn, crtc,
+ ramp_size, gamma_r,
+ gamma_g, gamma_b);
+ error = xcb_request_check(state->conn, gamma_set_cookie);
+
+ if (error) {
+ fprintf(stderr, _("`%s' returned error %d\n"),
+ "RANDR Set CRTC Gamma", error->error_code);
free(gamma_ramps);
+ return -1;
+ }
+
+ free(gamma_ramps);
+
+ return 0;
+}
+
+int
+randr_set_temperature(randr_state_t *state, int temp, float gamma[3])
+{
+ int r;
+
+ /* If no CRTC number has been specified,
+ set temperature on all CRTCs. */
+ if (state->crtc_num < 0) {
+ for (int i = 0; i < state->crtc_count; i++) {
+ r = randr_set_temperature_for_crtc(state, i,
+ temp, gamma);
+ if (r < 0) return -1;
+ }
+ } else {
+ return randr_set_temperature_for_crtc(state, state->crtc_num,
+ temp, gamma);
}
return 0;