aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2025-03-23 18:54:07 +0100
committerMattias Andrée <m@maandree.se>2025-03-23 18:54:07 +0100
commit3388beadc3ae38f9bca59165640feb285e8a3c12 (patch)
treeb2260aed07775d8f98c1d400445582331895bc66
parentAdd support for output selection by EDID (diff)
downloadredshift-ng-3388beadc3ae38f9bca59165640feb285e8a3c12.tar.gz
redshift-ng-3388beadc3ae38f9bca59165640feb285e8a3c12.tar.bz2
redshift-ng-3388beadc3ae38f9bca59165640feb285e8a3c12.tar.xz
Add ability to select screen in crtc option
Signed-off-by: Mattias Andrée <m@maandree.se>
-rw-r--r--README26
-rw-r--r--TODO4
-rw-r--r--redshift.133
-rw-r--r--src/backend-direct.c86
4 files changed, 119 insertions, 30 deletions
diff --git a/README b/README
index d75353a..976764b 100644
--- a/README
+++ b/README
@@ -613,15 +613,21 @@ EXTENDED DESCRIPTION
X display to apply adjustments to. Default is determined
by the environment variable DISPLAY.
- screen = integer
+ screen = ordinal
X screen to apply adjustments to. All will be used if not
specified.
- crtc = integer list or all
- Comma-separated (,) list of CRTC indices for monitors to
+ crtc = number list or all
+ Comma-separated (,) list of CRTC numbers for monitors to
apply adjustments to. All available CRTCs are used if the
list is empty or if the setting is omitted.
+ A CRTC number may either be specified as an overall ordinal
+ for all selected X screens, or the index of the X screen
+ followed by a dot (.) and the index of the CRTC within the
+ specified X screen. The specified X screen is automatically
+ included in the screen selection.
+
"all" may be specified as a synonym for an empty list.
The index of the first CRTC is 0.
@@ -642,21 +648,27 @@ EXTENDED DESCRIPTION
X display to apply adjustments to. Default is determined
by the environment variable DISPLAY.
- screen = integer
+ screen = ordinal
X screen to apply adjustments to. All will be used if not
specified.
Options for the location provider "drm" (method for Linux without
display server) are:
- card = integer
+ card = ordinal
Index of graphics card to apply adjustments to.
- crtc = integer list or all
- Comma-separated (,) list of CRTC indices for monitors to
+ crtc = number list or all
+ Comma-separated (,) list of CRTC numbers for monitors to
apply adjustments to. All available CRTCs are used if the
list is empty or if the setting is omitted.
+ A CRTC number may either be specified as an overall ordinal
+ for all selected graphics card, or the index of the graphics
+ card followed by a dot (.) and the index of the CRTC within
+ the specified graphics card. The specified graphics card is
+ automatically included in the card selection.
+
"all" may be specified as a synonym for an empty list.
The index of the first CRTC is 0.
diff --git a/TODO b/TODO
index 27a9418..1b0748c 100644
--- a/TODO
+++ b/TODO
@@ -142,11 +142,9 @@ Add support for solar time.
When disabled, redshift should be periodically set the gamma ramps
Add signals for setting location
Add signals for responding with sigqueue the state of redshift
-Document option delimiter for -l and -m
Add support for selecting multiple screens
-Add support for prefixing CRTC with screen/card number (e.g. "1.2" for CRTC 2 on screen 1)
-Properly document how provider/method options are separated
+Document option delimiter for -l and -m
The method option "display" requires support for ":", use ";" delimit after "display"
":" cannot be changed to ";" for all options are this would break backwards
compatibility; however ";" could be supported in addition to ":" for all options
diff --git a/redshift.1 b/redshift.1
index 54a971c..bd9b1bc 100644
--- a/redshift.1
+++ b/redshift.1
@@ -956,17 +956,26 @@ X display to apply adjustments to. Default is determined
by the environment variable
.IR DISPLAY .
.TP
-.BI screen\fR\ =\ integer
+.BI screen\fR\ =\ ordinal
X screen to apply adjustments to. All will be used if not
specified.
.TP
-.BI crtc\fR\ =\ "integer list or " all
+.BI crtc\fR\ =\ "number list or " all
Comma-separated
.RB ( , )
-list of CRTC indices for monitors to
+list of CRTC numbers for monitors to
apply adjustments to. All available CRTCs are used if the
list is empty or if the setting is omitted.
+A CRTC number may either be specified as an overall
+ordinal for all selected X screens, or the index of
+the X screen followed by a dot
+.RB ( . )
+and the index of the CRTC within the specified X screen.
+The specified X screen is automatically included in the
+.B screen
+selection.
+
.B all
may be specified as a synonym for an empty list.
@@ -995,7 +1004,7 @@ X display to apply adjustments to. Default is determined
by the environment variable
.IR DISPLAY .
.TP
-.BI screen\fR\ =\ integer
+.BI screen\fR\ =\ ordinal
X screen to apply adjustments to. All will be used if not
specified.
.PP
@@ -1003,16 +1012,26 @@ Options for the location provider
.B drm
(method for Linux without display server) are:
.TP
-.BI card\fR\ =\ integer
+.BI card\fR\ =\ ordinal
Index of graphics card to apply adjustments to.
.TP
-.BI crtc\fR\ =\ "integer list or " all
+.BI crtc\fR\ =\ "number list or " all
Comma-separated
.RB ( , )
-list of CRTC indices for monitors to
+list of CRTC numbers for monitors to
apply adjustments to. All available CRTCs are used if the
list is empty or if the setting is omitted.
+A CRTC number may either be specified as an overall
+ordinal for all selected graphics card, or the index of
+the graphics card followed by a dot
+.RB ( . )
+and the index of
+the CRTC within the specified graphics card. The specified
+graphics card is automatically included in the
+.B card
+selection.
+
.B all
may be specified as a synonym for an empty list.
diff --git a/src/backend-direct.c b/src/backend-direct.c
index 62fe2fa..de58548 100644
--- a/src/backend-direct.c
+++ b/src/backend-direct.c
@@ -86,6 +86,22 @@ struct crtc_state {
};
+/**
+ * CRTC number, either overall number or partion and number within partition
+ */
+struct crtc_number {
+ /**
+ * The partition of the EDID, -1 if using overall ordinal
+ */
+ ssize_t partition;
+
+ /**
+ * CRTC number within the partition, or overall if no partition is specified
+ */
+ size_t crtc;
+};
+
+
struct gamma_state {
/**
* libgamma state for the site (e.g. X display)
@@ -162,11 +178,11 @@ struct gamma_state {
size_t npartitions;
/**
- * Indices of selected CRTCs
+ * Selected CRTC numbers
*
* Deallocated by when no longer needed
*/
- size_t *selected_crtcs;
+ struct crtc_number *selected_crtcs;
/**
* Selected EDIDs
@@ -253,17 +269,22 @@ direct_print_help(FILE *f, int method)
if (caps.multiple_sites)
fprintf(f, " display=%s %s\n", _("NAME "), _("Display server instance to apply adjustments to"));
- if (caps.multiple_partitions && caps.partitions_are_graphics_cards)
+ if (caps.multiple_partitions && caps.partitions_are_graphics_cards) {
/* TRANSLATORS: "N" represents "ordinal"; right-pad with spaces to preserve display width */
fprintf(f, " card=%s %s\n", _("N "), _("Graphics card to apply adjustments to"));
- else if (caps.multiple_partitions)
+ } else if (caps.multiple_partitions) {
+ /* TRANSLATORS: "N" represents "ordinal"; right-pad with spaces to preserve display width */
fprintf(f, " screen=%s %s\n", _("N "), _("X screen to apply adjustments to"));
+ }
- if (caps.multiple_crtcs)
+ if (caps.multiple_crtcs) {
+ /* TRANSLATORS: "N" represents "number"; right-pad with spaces to preserve display width */
fprintf(f, " crtc=%s %s\n", _("N "), _("List of comma-separated CRTCs to apply adjustments to"));
- if (caps.multiple_crtcs && (caps.crtc_information & LIBGAMMA_CRTC_INFO_EDID))
+ }
+ if (caps.multiple_crtcs && (caps.crtc_information & LIBGAMMA_CRTC_INFO_EDID)) {
fprintf(f, " edid=%s %s\n", _("EDID "), _("List of comma-separated EDIDS of monitors to apply "
"adjustments to, enter `list' to list available monitors"));
+ }
if (caps.multiple_sites || caps.multiple_partitions || caps.multiple_crtcs)
fprintf(f, "\n");
@@ -356,12 +377,25 @@ direct_set_crtcs(struct gamma_state *state, const char *key, const char *value)
errno = 0;
for (p = value; *p; p = end) {
num = strtoumax(p, (void *)&end, 10);
- state->selected_crtcs[state->ncrtcs++] = (size_t)num;
- if (num > (uintmax_t)SIZE_MAX || (*end && *end != ',') || !isdigit(*p) || errno) {
+ state->selected_crtcs[state->ncrtcs].partition = -1;
+ state->selected_crtcs[state->ncrtcs].crtc = (size_t)num;
+ if (num > (uintmax_t)SIZE_MAX || (*end && *end != ',' && *end != '.') || !isdigit(*p) || errno) {
+ invalid:
weprintf(_("Invalid value of `%s' option: `%s'."), key, value);
return -1;
}
+ if (*end == '.') {
+ if (!state->multiple_partitions || num > (uintmax_t)SSIZE_MAX)
+ goto invalid;
+ state->selected_crtcs[state->ncrtcs].partition = (ssize_t)num;
+ p = &end[1];
+ num = strtoumax(p, (void *)&end, 10);
+ state->selected_crtcs[state->ncrtcs].crtc = (size_t)num;
+ if (num > (uintmax_t)SIZE_MAX || (*end && *end != ',') || !isdigit(*p) || errno)
+ goto invalid;
+ }
end = &end[*end == ','];
+ state->ncrtcs++;
}
return 0;
@@ -464,6 +498,25 @@ direct_start(struct gamma_state *state)
}
}
+ /* Map the partition indices in CRTC numbers from indices of selected
+ * partitions, and allocate partitions specified via CRTC numbers */
+ for (i = 0; i < state->ncrtcs; i++) {
+ if (state->selected_crtcs[i].partition < 0)
+ continue;
+ for (j = 0; j < state->npartitions; j++) {
+ if ((size_t)state->selected_crtcs[i].partition == state->partitions[j].state.partition) {
+ state->selected_crtcs[i].partition = (ssize_t)j;
+ break;
+ }
+ }
+ if (j == state->npartitions) {
+ state->partitions = realloc(state->partitions, (state->npartitions + 1U) * sizeof(*state->partitions));
+ state->partitions[state->npartitions].state.partition = (size_t)state->selected_crtcs[i].partition;
+ state->partitions[state->npartitions].state.data = NULL;
+ state->npartitions++;
+ }
+ }
+
/* Initialise partitions */
for (i = 0; i < state->npartitions; i++) {
num = state->partitions[i].state.partition;
@@ -522,10 +575,11 @@ direct_start(struct gamma_state *state)
resolved_edids[i].edid, resolved_edids[i].crtc,
resolved_edids[i].partition);
}
- num = state->ncrtcs + 1U;
- state->selected_crtcs = erealloc(state->selected_crtcs, num * sizeof(*state->crtcs));
- num = state->partitions[resolved_edids[i].partition].crtc_num_offset;
- state->selected_crtcs[state->ncrtcs++] = num + resolved_edids[i].crtc;
+ count = state->ncrtcs + 1U;
+ state->selected_crtcs = erealloc(state->selected_crtcs, count * sizeof(*state->crtcs));
+ state->selected_crtcs[state->ncrtcs].partition = (ssize_t)resolved_edids[i].partition;
+ state->selected_crtcs[state->ncrtcs].crtc = resolved_edids[i].crtc;
+ state->ncrtcs++;
goto next_edid;
}
}
@@ -546,13 +600,19 @@ direct_start(struct gamma_state *state)
state->crtcs = ecalloc(state->ncrtcs, sizeof(*state->crtcs));
for (i = 0; i < state->ncrtcs; i++) {
state->crtcs[i].state.data = NULL;
- state->crtcs[i].state.crtc = state->selected_crtcs[i];
+ state->crtcs[i].state.partition = NULL;
+ if (state->selected_crtcs[i].partition >= 0)
+ state->crtcs[i].state.partition = &state->partitions[state->selected_crtcs[i].partition].state;
+ state->crtcs[i].state.crtc = state->selected_crtcs[i].crtc;
}
for (i = 0; i < state->ncrtcs; i++) {
+ if (state->crtcs[i].state.partition)
+ continue;
for (j = 1; j < state->npartitions; j++)
if (state->crtcs[i].state.crtc < state->partitions[j].crtc_num_offset)
break;
state->crtcs[i].state.partition = &state->partitions[j - 1U].state;
+ state->crtcs[i].state.crtc -= state->partitions[j - 1U].crtc_num_offset;
}
} else if (!crtc_num_offset) {
weprintf(_("No CRTCs found."));