[PATCH xrandr] Add a --scale-from option

Aaron Plattner aplattner at nvidia.com
Tue Apr 24 07:36:40 PDT 2012


A typical case for wanting to specify a scale on an output is making your
framebuffer be one size and scaling it to fill an output of a different size.
Instead of making the user calculate the scaling factors to be specified by
--scale, add a new option, --scale-from, that lets the user specify the
framebuffer size directly.  Compute the appropriate transform to achieve the
desired target size.

Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
Reviewed-by: Andy Ritger <aritger at nvidia.com>
---
 man/xrandr.man |    5 +++++
 xrandr.c       |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/man/xrandr.man b/man/xrandr.man
index ba36ae3..ddc2804 100644
--- a/man/xrandr.man
+++ b/man/xrandr.man
@@ -41,6 +41,7 @@ xrandr \- primitive command line interface to RandR extension
 .br
 [\-\-panning \fIwidth\fPx\fIheight\fP[+\fIx\fP+\fIy\fP[/\fItrack_width\fPx\fItrack_height\fP+\fItrack_x\fP+\fItrack_y\fP[/\fIborder_left\fP/\fIborder_top\fP/\fIborder_right\fP/\fIborder_bottom\fP]]]]
 [\-\-scale \fIx\fPx\fIy\fP]
+[\-\-scale-from \fIw\fPx\fIh\fP]
 [\-\-transform \fIa\fP,\fIb\fP,\fIc\fP,\fId\fP,\fIe\fP,\fIf\fP,\fIg\fP,\fIh\fP,\fIi\fP]
 [\-\-primary]
 .br
@@ -199,6 +200,10 @@ Changes the dimensions of the output picture. Values superior to 1 will lead to
 a compressed screen (screen dimension bigger than the dimension of the output
 mode), and values below 1 leads to a zoom in on the output. This option is
 actually a shortcut version of the \fI\-\-transform\fP option.
+.IP "\-\-scale-from \fIw\fPx\fIh\fP"
+Specifies the size in pixels of the area of the framebuffer to be displayed on
+this output.
+This option is actually a shortcut version of the \fI\-\-transform\fP option.
 .IP \-\-primary
 Set the output as primary.
 It will be sorted first in Xinerama and RANDR geometry requests.
diff --git a/xrandr.c b/xrandr.c
index b7f468b..6683ceb 100644
--- a/xrandr.c
+++ b/xrandr.c
@@ -128,6 +128,7 @@ usage(void)
     fprintf(stderr, "      --same-as <output>\n");
     fprintf(stderr, "      --set <property> <value>\n");
     fprintf(stderr, "      --scale <x>x<y>\n");
+    fprintf(stderr, "      --scale-from <w>x<h>\n");
     fprintf(stderr, "      --transform <a>,<b>,<c>,<d>,<e>,<f>,<g>,<h>,<i>\n");
     fprintf(stderr, "      --off\n");
     fprintf(stderr, "      --crtc <crtc>\n");
@@ -324,6 +325,7 @@ struct _output {
     XRRPanning      panning;
 
     Bool    	    automatic;
+    int     	    scale_from_w, scale_from_h;
     transform_t	    transform;
 
     struct {
@@ -1166,6 +1168,30 @@ set_output_info (output_t *output, RROutput xid, XRROutputInfo *output_info)
 	    copy_transform (&output->transform, &output->crtc_info->current_transform);
 	else
 	    init_transform (&output->transform);
+    } else {
+	/* transform was already set for --scale or --transform */
+
+	/* for --scale-from, figure out the mode size and compute the transform
+	 * for the target framebuffer area */
+	if (output->scale_from_w > 0 && output->mode_info) {
+	    double sx = (double)output->scale_from_w /
+				output->mode_info->width;
+	    double sy = (double)output->scale_from_h /
+				output->mode_info->height;
+	    if (verbose)
+		printf("scaling %s by %lfx%lf\n", output->output.string, sx,
+		       sy);
+	    init_transform (&output->transform);
+	    output->transform.transform.matrix[0][0] = XDoubleToFixed (sx);
+	    output->transform.transform.matrix[1][1] = XDoubleToFixed (sy);
+	    output->transform.transform.matrix[2][2] = XDoubleToFixed (1.0);
+	    if (sx != 1 || sy != 1)
+		output->transform.filter = "bilinear";
+	    else
+		output->transform.filter = "nearest";
+	    output->transform.nparams = 0;
+	    output->transform.params = NULL;
+	}
     }
 
     /* set primary */
@@ -2490,6 +2516,20 @@ main (int argc, char **argv)
 	    output->changes |= changes_transform;
 	    continue;
 	}
+	if (!strcmp ("--scale-from", argv[i]))
+	{
+	    int w, h;
+	    if (!output) usage();
+	    if (++i>=argc) usage();
+	    if (sscanf (argv[i], "%dx%d", &w, &h) != 2)
+		usage ();
+	    if (w <=0 || h <= 0)
+		usage ();
+	    output->scale_from_w = w;
+	    output->scale_from_h = h;
+	    output->changes |= changes_transform;
+	    continue;
+	}
 	if (!strcmp ("--transform", argv[i])) {
 	    double  transform[3][3];
 	    int	    k, l;
-- 
1.7.8.4.1.gb3fe


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------


More information about the xorg-devel mailing list