summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Piel <eric@triangle.(none)>2010-01-10 00:08:53 +0100
committerMatthias Hopf <mhopf@suse.de>2010-04-07 14:25:04 +0200
commit61fc9cc04e1ac179ac5e2cc4ff861bb362f0b801 (patch)
treedc31f2ced075cf0da1284f090374e1b0a5867701
parentb5627bb72b3ca2c7f5a702b7134a5c6dd4f83687 (diff)
xrandr: get gamma and brightness
Even in verbose query mode, gamma and brigthness were not displayed. That's because they are not stored in the server the same way they are specified on the command line: they are stored as 256 * 3 u16 while the command line is 3 + 1 floats. Still, this is useful info for the users, and they don't care about how it's stored in the server. So we do a regression over the values stored to recover info in the same way as on the command line: gamma and brightness. Signed-off-by: Éric Piel <eric.piel@tremplin-utc.net> Reviewed-By: Matthias Hopf <mhopf@suse.de>
-rw-r--r--xrandr.c99
-rw-r--r--xrandr.man10
2 files changed, 106 insertions, 3 deletions
diff --git a/xrandr.c b/xrandr.c
index 76c1342..5858813 100644
--- a/xrandr.c
+++ b/xrandr.c
@@ -943,6 +943,96 @@ output_is_primary(output_t *output)
return False;
}
+/* Returns the index of the last value in an array < 0xffff */
+static int
+find_last_non_clamped(CARD16 array[], int size) {
+ int i;
+ for (i = size - 1; i > 0; i--) {
+ if (array[i] < 0xffff)
+ return i;
+ }
+ return 0;
+}
+
+static void
+set_gamma_info(output_t *output)
+{
+ XRRCrtcGamma *gamma;
+ double i1, v1, i2, v2;
+ int size, middle, last_best, last_red, last_green, last_blue;
+ CARD16 *best_array;
+
+ if (!output->crtc_info)
+ return;
+
+ size = XRRGetCrtcGammaSize(dpy, output->crtc_info->crtc.xid);
+ if (!size) {
+ warning("Failed to get size of gamma for output %s\n", output->output.string);
+ return;
+ }
+
+ gamma = XRRGetCrtcGamma(dpy, output->crtc_info->crtc.xid);
+ if (!gamma) {
+ warning("Failed to get gamma for output %s\n", output->output.string);
+ return;
+ }
+
+ /*
+ * Here is a bit tricky because gamma is a whole curve for each
+ * color. So, typically, we need to represent 3 * 256 values as 3 + 1
+ * values. Therefore, we approximate the gamma curve (v) by supposing
+ * it always follows the way we set it: a power function (i^g)
+ * multiplied by a brightness (b).
+ * v = i^g * b
+ * so g = (ln(v) - ln(b))/ln(i)
+ * and b can be found using two points (v1,i1) and (v2, i2):
+ * b = e^((ln(v2)*ln(i1) - ln(v1)*ln(i2))/ln(i1/i2))
+ * For the best resolution, we select i2 at the highest place not
+ * clamped and i1 at i2/2. Note that if i2 = 1 (as in most normal
+ * cases), then b = v2.
+ */
+ last_red = find_last_non_clamped(gamma->red, size);
+ last_green = find_last_non_clamped(gamma->green, size);
+ last_blue = find_last_non_clamped(gamma->blue, size);
+ best_array = gamma->red;
+ last_best = last_red;
+ if (last_green > last_best) {
+ last_best = last_green;
+ best_array = gamma->green;
+ }
+ if (last_blue > last_best) {
+ last_best = last_blue;
+ best_array = gamma->blue;
+ }
+ if (last_best == 0)
+ last_best = 1;
+
+ middle = last_best / 2;
+ i1 = (double)(middle + 1) / size;
+ v1 = (double)(best_array[middle]) / 65535;
+ i2 = (double)(last_best + 1) / size;
+ v2 = (double)(best_array[last_best]) / 65535;
+ if (v2 < 0.0001) { /* The screen is black */
+ output->brightness = 0;
+ output->gamma.red = 1;
+ output->gamma.green = 1;
+ output->gamma.blue = 1;
+ } else {
+ if ((last_best + 1) == size)
+ output->brightness = v2;
+ else
+ output->brightness = exp((log(v2)*log(i1) - log(v1)*log(i2))/log(i1/i2));
+ output->gamma.red = log((double)(gamma->red[last_red / 2]) / output->brightness
+ / 65535) / log((double)((last_red / 2) + 1) / size);
+ output->gamma.green = log((double)(gamma->green[last_green / 2]) / output->brightness
+ / 65535) / log((double)((last_green / 2) + 1) / size);
+ output->gamma.blue = log((double)(gamma->blue[last_blue / 2]) / output->brightness
+ / 65535) / log((double)((last_blue / 2) + 1) / size);
+ }
+
+ XRRFreeGamma(gamma);
+}
+
static void
set_output_info (output_t *output, RROutput xid, XRROutputInfo *output_info)
{
@@ -1055,6 +1145,10 @@ set_output_info (output_t *output, RROutput xid, XRROutputInfo *output_info)
rotation_name (output->rotation),
reflection_name (output->rotation));
+ /* set gamma */
+ if (!(output->changes & changes_gamma))
+ set_gamma_info(output);
+
/* set transformation */
if (!(output->changes & changes_transform))
{
@@ -2919,6 +3013,11 @@ main (int argc, char **argv)
printf ("\tIdentifier: 0x%x\n", (int)output->output.xid);
printf ("\tTimestamp: %d\n", (int)output_info->timestamp);
printf ("\tSubpixel: %s\n", order[output_info->subpixel_order]);
+ if (output->gamma.red != 0.0 && output->gamma.green != 0.0 && output->gamma.blue != 0.0) {
+ printf ("\tGamma: %#.2g:%#.2g:%#.2g\n",
+ output->gamma.red, output->gamma.green, output->gamma.blue);
+ printf ("\tBrightness: %#.2g\n", output->brightness);
+ }
printf ("\tClones: ");
for (j = 0; j < output_info->nclone; j++)
{
diff --git a/xrandr.man b/xrandr.man
index 335b7c0..aa1d9c5 100644
--- a/xrandr.man
+++ b/xrandr.man
@@ -105,7 +105,9 @@ Print out a summary of the usage and exit.
Print out the RandR version reported by the X server and exit.
.IP \-\-verbose
Causes xrandr to be more verbose. When used with \-q (or without other
-options), xrandr will display more information about the server state. When
+options), xrandr will display more information about the server state. Please
+note that the gamma and brightness informations are only approximations of the
+complete color profile stored in the server. When
used along with options that reconfigure the system, progress will be
reported while executing the configuration changes.
.IP "\-q, \-\-query"
@@ -287,11 +289,13 @@ for some reason, this option can override the normal selection.
.IP "\-\-gamma \fIred\fP:\fIgreen\fP:\fIblue\fP"
Set the specified floating point values as gamma correction on the crtc
currently attached to this output. Note that you cannot get two different values
-for cloned outputs and that switching an output to another crtc doesn't change
+for cloned outputs (i.e.: which share the same crtc) and that switching an output to another crtc doesn't change
the crtc gamma corrections at all.
.IP "\-\-brightness \fIbrightness\fP"
Multiply the gamma values on the crtc currently attached to the output to
specified floating value. Useful for overly bright or overly dim outputs.
+However, this is a software only modification, if your hardware has support to
+actually change the brightness, you will probably prefer to use \fBxbacklight\fR.
.PP
.SH "RandR version 1.1 options"
These options are available for X servers supporting RandR version 1.1 or
@@ -342,7 +346,7 @@ when the projector is slightly above the screen:
xrandr --fb 1024x768 --output VGA --transform 1.24,0.16,-124,0,1.24,0,0,0.000316,1
.RE
.SH "SEE ALSO"
-Xrandr(3), cvt(1), xkeystone(1)
+Xrandr(3), cvt(1), xkeystone(1), xbacklight(1)
.SH AUTHORS
Keith Packard,
Open Source Technology Center, Intel Corporation.