Module Name: xsrc
Committed By: mrg
Date: Sat Aug 14 09:14:01 UTC 2010
Modified Files:
xsrc/external/mit/xrandr/dist: xrandr.c
Removed Files:
xsrc/external/mit/xrandr/dist: AUTHORS NEWS
Log Message:
merge xrandr 1.3.3.
To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1 -r0 xsrc/external/mit/xrandr/dist/AUTHORS \
xsrc/external/mit/xrandr/dist/NEWS
cvs rdiff -u -r1.3 -r1.4 xsrc/external/mit/xrandr/dist/xrandr.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: xsrc/external/mit/xrandr/dist/xrandr.c
diff -u xsrc/external/mit/xrandr/dist/xrandr.c:1.3 xsrc/external/mit/xrandr/dist/xrandr.c:1.4
--- xsrc/external/mit/xrandr/dist/xrandr.c:1.3 Sun Nov 8 11:40:22 2009
+++ xsrc/external/mit/xrandr/dist/xrandr.c Sat Aug 14 09:14:01 2010
@@ -41,10 +41,6 @@
#include "config.h"
#endif
-#if RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 2)
-#define HAS_RANDR_1_2 1
-#endif
-
static char *program_name;
static Display *dpy;
static Window root;
@@ -113,15 +109,10 @@
fprintf(stderr, " --verbose\n");
fprintf(stderr, " --dryrun\n");
fprintf(stderr, " --nograb\n");
-#if HAS_RANDR_1_2
fprintf(stderr, " --prop or --properties\n");
fprintf(stderr, " --fb <width>x<height>\n");
fprintf(stderr, " --fbmm <width>x<height>\n");
fprintf(stderr, " --dpi <dpi>/<output>\n");
-#if 0
- fprintf(stderr, " --clone\n");
- fprintf(stderr, " --extend\n");
-#endif
fprintf(stderr, " --output <output>\n");
fprintf(stderr, " --auto\n");
fprintf(stderr, " --mode <mode>\n");
@@ -151,7 +142,6 @@
fprintf(stderr, " --rmmode <name>\n");
fprintf(stderr, " --addmode <output> <name>\n");
fprintf(stderr, " --delmode <output> <name>\n");
-#endif
exit(1);
/*NOTREACHED*/
@@ -181,6 +171,12 @@
va_end (ap);
}
+/* Because fmin requires C99 suppport */
+static inline double dmin (double x, double y)
+{
+ return x < y ? x : y;
+}
+
static char *
rotation_name (Rotation rotation)
{
@@ -211,13 +207,12 @@
return "invalid reflection";
}
-#if HAS_RANDR_1_2
-typedef enum _policy {
- clone, extend
-} policy_t;
-
typedef enum _relation {
- left_of, right_of, above, below, same_as,
+ relation_left_of,
+ relation_right_of,
+ relation_above,
+ relation_below,
+ relation_same_as,
} relation_t;
typedef struct {
@@ -335,6 +330,8 @@
float blue;
} gamma;
+ float brightness;
+
Bool primary;
Bool found;
@@ -637,6 +634,7 @@
fatal ("out of memory\n");
output->next = NULL;
output->found = False;
+ output->brightness = 1.0;
*outputs_tail = output;
outputs_tail = &output->next;
return output;
@@ -947,6 +945,96 @@
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)
{
@@ -1059,6 +1147,10 @@
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))
{
@@ -1101,9 +1193,7 @@
for (c = 0; c < res->ncrtc; c++)
{
XRRCrtcInfo *crtc_info = XRRGetCrtcInfo (dpy, res, res->crtcs[c]);
-#if RANDR_MAJOR > 1 || RANDR_MINOR >= 3
XRRCrtcTransformAttributes *attr;
-#endif
XRRPanning *panning_info = NULL;
if (has_1_3) {
@@ -1129,7 +1219,6 @@
crtcs[c].y = 0;
crtcs[c].rotation = RR_Rotate_0;
}
-#if RANDR_MAJOR > 1 || RANDR_MINOR >= 3
if (XRRGetCrtcTransform (dpy, res->crtcs[c], &attr) && attr) {
set_transform (&crtcs[c].current_transform,
&attr->currentTransform,
@@ -1139,7 +1228,6 @@
XFree (attr);
}
else
-#endif
{
init_transform (&crtcs[c].current_transform);
}
@@ -1228,24 +1316,30 @@
continue;
}
+ if(output->gamma.red == 0.0 && output->gamma.green == 0.0 && output->gamma.blue == 0.0)
+ output->gamma.red = output->gamma.green = output->gamma.blue = 1.0;
+
for (i = 0; i < size; i++) {
- if (output->gamma.red == 1.0)
- gamma->red[i] = i << 8;
+ if (output->gamma.red == 1.0 && output->brightness == 1.0)
+ gamma->red[i] = (i << 8) + i;
else
- gamma->red[i] = (CARD16)(pow((double)i/(double)(size - 1),
- (double)output->gamma.red) * (double)(size - 1) * 256);
+ gamma->red[i] = dmin(pow((double)i/(double)(size - 1),
+ output->gamma.red) * output->brightness,
+ 1.0) * 65535.0;
- if (output->gamma.green == 1.0)
- gamma->green[i] = i << 8;
+ if (output->gamma.green == 1.0 && output->brightness == 1.0)
+ gamma->green[i] = (i << 8) + i;
else
- gamma->green[i] = (CARD16)(pow((double)i/(double)(size - 1),
- (double)output->gamma.green) * (double)(size - 1) * 256);
+ gamma->green[i] = dmin(pow((double)i/(double)(size - 1),
+ output->gamma.green) * output->brightness,
+ 1.0) * 65535.0;
- if (output->gamma.blue == 1.0)
- gamma->blue[i] = i << 8;
+ if (output->gamma.blue == 1.0 && output->brightness == 1.0)
+ gamma->blue[i] = (i << 8) + i;
else
- gamma->blue[i] = (CARD16)(pow((double)i/(double)(size - 1),
- (double)output->gamma.blue) * (double)(size - 1) * 256);
+ gamma->blue[i] = dmin(pow((double)i/(double)(size - 1),
+ output->gamma.blue) * output->brightness,
+ 1.0) * 65535.0;
}
XRRSetCrtcGamma(dpy, crtc->crtc.xid, gamma);
@@ -1771,23 +1865,23 @@
}
switch (output->relation) {
- case left_of:
+ case relation_left_of:
output->y = relation->y;
output->x = relation->x - mode_width (output->mode_info, output->rotation);
break;
- case right_of:
+ case relation_right_of:
output->y = relation->y;
output->x = relation->x + mode_width (relation->mode_info, relation->rotation);
break;
- case above:
+ case relation_above:
output->x = relation->x;
output->y = relation->y - mode_height (output->mode_info, output->rotation);
break;
- case below:
+ case relation_below:
output->x = relation->x;
output->y = relation->y + mode_height (relation->mode_info, relation->rotation);
break;
- case same_as:
+ case relation_same_as:
output->x = relation->x;
output->y = relation->y;
}
@@ -1888,7 +1982,6 @@
}
}
-#endif
static void
disable_outputs (output_t *outputs)
@@ -2024,7 +2117,7 @@
return result;
}
-static int
+static double
check_strtod(char *s)
{
char *endptr;
@@ -2044,7 +2137,8 @@
short *rates;
Status status = RRSetConfigFailed;
int rot = -1;
- int query = 0;
+ int query = False;
+ int action_requested = False;
Rotation rotation, current_rotation, rotations;
XEvent event;
XRRScreenChangeNotifyEvent *sce;
@@ -2062,9 +2156,7 @@
int width = 0, height = 0;
Bool have_pixel_size = False;
int ret = 0;
-#if HAS_RANDR_1_2
output_t *output = NULL;
- policy_t policy = clone;
Bool setit_1_2 = False;
Bool query_1_2 = False;
Bool modeit = False;
@@ -2072,10 +2164,8 @@
Bool query_1 = False;
int major, minor;
Bool current = False;
-#endif
program_name = argv[0];
- if (argc == 1) query = True;
for (i = 1; i < argc; i++) {
if (!strcmp ("-display", argv[i]) || !strcmp ("-d", argv[i])) {
if (++i>=argc) usage ();
@@ -2084,6 +2174,7 @@
}
if (!strcmp("-help", argv[i])) {
usage();
+ action_requested = True;
continue;
}
if (!strcmp ("--verbose", argv[i])) {
@@ -2101,8 +2192,6 @@
}
if (!strcmp("--current", argv[i])) {
current = True;
- /* if --current was the only arg, then query */
- if (argc == 2) query = True;
continue;
}
@@ -2115,6 +2204,7 @@
if (size < 0) usage();
}
setit = True;
+ action_requested = True;
continue;
}
@@ -2125,30 +2215,32 @@
if (++i>=argc) usage ();
rate = check_strtod(argv[i]);
setit = True;
-#if HAS_RANDR_1_2
if (output)
{
output->refresh = rate;
output->changes |= changes_refresh;
setit_1_2 = True;
}
-#endif
+ action_requested = True;
continue;
}
if (!strcmp ("-v", argv[i]) || !strcmp ("--version", argv[i])) {
version = True;
+ action_requested = True;
continue;
}
if (!strcmp ("-x", argv[i])) {
reflection |= RR_Reflect_X;
setit = True;
+ action_requested = True;
continue;
}
if (!strcmp ("-y", argv[i])) {
reflection |= RR_Reflect_Y;
setit = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--screen", argv[i])) {
@@ -2173,9 +2265,9 @@
}
rot = dirind;
setit = True;
+ action_requested = True;
continue;
}
-#if HAS_RANDR_1_2
if (!strcmp ("--prop", argv[i]) ||
!strcmp ("--props", argv[i]) ||
!strcmp ("--madprops", argv[i]) ||
@@ -2183,6 +2275,7 @@
{
query_1_2 = True;
properties = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--output", argv[i])) {
@@ -2195,6 +2288,7 @@
}
setit_1_2 = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--crtc", argv[i])) {
@@ -2255,7 +2349,7 @@
if (!strcmp ("--left-of", argv[i])) {
if (++i>=argc) usage ();
if (!output) usage();
- output->relation = left_of;
+ output->relation = relation_left_of;
output->relative_to = argv[i];
output->changes |= changes_relation;
continue;
@@ -2263,7 +2357,7 @@
if (!strcmp ("--right-of", argv[i])) {
if (++i>=argc) usage ();
if (!output) usage();
- output->relation = right_of;
+ output->relation = relation_right_of;
output->relative_to = argv[i];
output->changes |= changes_relation;
continue;
@@ -2271,7 +2365,7 @@
if (!strcmp ("--above", argv[i])) {
if (++i>=argc) usage ();
if (!output) usage();
- output->relation = above;
+ output->relation = relation_above;
output->relative_to = argv[i];
output->changes |= changes_relation;
continue;
@@ -2279,7 +2373,7 @@
if (!strcmp ("--below", argv[i])) {
if (++i>=argc) usage ();
if (!output) usage();
- output->relation = below;
+ output->relation = relation_below;
output->relative_to = argv[i];
output->changes |= changes_relation;
continue;
@@ -2287,7 +2381,7 @@
if (!strcmp ("--same-as", argv[i])) {
if (++i>=argc) usage ();
if (!output) usage();
- output->relation = same_as;
+ output->relation = relation_same_as;
output->relative_to = argv[i];
output->changes |= changes_relation;
continue;
@@ -2332,6 +2426,15 @@
setit_1_2 = True;
continue;
}
+ if (!strcmp ("--brightness", argv[i])) {
+ if (!output) usage();
+ if (++i>=argc) usage();
+ if (sscanf(argv[i], "%f", &output->brightness) != 1)
+ usage ();
+ output->changes |= changes_gamma;
+ setit_1_2 = True;
+ continue;
+ }
if (!strcmp ("--primary", argv[i])) {
if (!output) usage();
output->changes |= changes_primary;
@@ -2362,6 +2465,7 @@
if (!strcmp ("--scale", argv[i]))
{
double sx, sy;
+ if (!output) usage();
if (++i>=argc) usage();
if (sscanf (argv[i], "%lfx%lf", &sx, &sy) != 2)
usage ();
@@ -2381,6 +2485,7 @@
if (!strcmp ("--transform", argv[i])) {
double transform[3][3];
int k, l;
+ if (!output) usage();
if (++i>=argc) usage ();
init_transform (&output->transform);
if (strcmp (argv[i], "none") != 0)
@@ -2416,6 +2521,7 @@
&fb_width, &fb_height) != 2)
usage ();
setit_1_2 = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--fbmm", argv[i])) {
@@ -2424,6 +2530,7 @@
&fb_width_mm, &fb_height_mm) != 2)
usage ();
setit_1_2 = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--dpi", argv[i])) {
@@ -2436,16 +2543,7 @@
dpi_output = argv[i];
}
setit_1_2 = True;
- continue;
- }
- if (!strcmp ("--clone", argv[i])) {
- policy = clone;
- setit_1_2 = True;
- continue;
- }
- if (!strcmp ("--extend", argv[i])) {
- policy = extend;
- setit_1_2 = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--auto", argv[i])) {
@@ -2457,6 +2555,7 @@
else
automatic = True;
setit_1_2 = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--q12", argv[i]))
@@ -2507,6 +2606,7 @@
m->action = umode_create;
umodes = m;
modeit = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--rmmode", argv[i]))
@@ -2519,6 +2619,7 @@
m->next = umodes;
umodes = m;
modeit = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--addmode", argv[i]))
@@ -2533,6 +2634,7 @@
m->next = umodes;
umodes = m;
modeit = True;
+ action_requested = True;
continue;
}
if (!strcmp ("--delmode", argv[i]))
@@ -2547,11 +2649,13 @@
m->next = umodes;
umodes = m;
modeit = True;
+ action_requested = True;
continue;
}
-#endif
usage();
}
+ if (!action_requested)
+ query = True;
if (verbose)
{
query = True;
@@ -2577,7 +2681,6 @@
root = RootWindow (dpy, screen);
-#if HAS_RANDR_1_2
if (!XRRQueryVersion (dpy, &major, &minor))
{
fprintf (stderr, "RandR extension missing\n");
@@ -2912,6 +3015,11 @@
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++)
{
@@ -3129,7 +3237,6 @@
}
exit (0);
}
-#endif
sc = XRRGetScreenInfo (dpy, root);