diff options
author | Mattias Andrée <m@maandree.se> | 2025-03-23 18:54:07 +0100 |
---|---|---|
committer | Mattias Andrée <m@maandree.se> | 2025-03-23 18:54:07 +0100 |
commit | 3388beadc3ae38f9bca59165640feb285e8a3c12 (patch) | |
tree | b2260aed07775d8f98c1d400445582331895bc66 | |
parent | Add support for output selection by EDID (diff) | |
download | redshift-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-- | README | 26 | ||||
-rw-r--r-- | TODO | 4 | ||||
-rw-r--r-- | redshift.1 | 33 | ||||
-rw-r--r-- | src/backend-direct.c | 86 |
4 files changed, 119 insertions, 30 deletions
@@ -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. @@ -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 @@ -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.")); |