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);
 

Reply via email to