[PATCH 11/12] xrandr: Add panning support.

Matthias Hopf mhopf at suse.de
Fri Nov 28 08:16:11 PST 2008


---
 xrandr.c |  114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 113 insertions(+), 1 deletions(-)

diff --git a/xrandr.c b/xrandr.c
index b1e133e..9dcd72a 100644
--- a/xrandr.c
+++ b/xrandr.c
@@ -131,6 +131,7 @@ usage(void)
     fprintf(stderr, "      --set <property> <value>\n");
     fprintf(stderr, "      --off\n");
     fprintf(stderr, "      --crtc <crtc>\n");
+    fprintf(stderr, "      --panning <w>x<h>[+<x>+<y>[/<track:w>x<h>+<x>+<y>[/<border:l>/<t>/<r>/<b>]]]\n");
     fprintf(stderr, "  --newmode <name> <clock MHz>\n");
     fprintf(stderr, "            <hdisp> <hsync-start> <hsync-end> <htotal>\n");
     fprintf(stderr, "            <vdisp> <vsync-start> <vsync-end> <vtotal>\n");
@@ -207,6 +208,7 @@ typedef enum _changes {
     changes_automatic = (1 << 6),
     changes_refresh = (1 << 7),
     changes_property = (1 << 8),
+    changes_panning = (1 << 9),
 } changes_t;
 
 typedef enum _name_kind {
@@ -235,6 +237,7 @@ struct _crtc {
     XRRCrtcInfo	    *crtc_info;
 
     XRRModeInfo	    *mode_info;
+    XRRPanning      *panning_info;
     int		    x;
     int		    y;
     Rotation	    rotation;
@@ -274,6 +277,8 @@ struct _output {
     int		    x, y;
     Rotation	    rotation;
     
+    char            *panning;
+
     Bool    	    automatic;
 };
 
@@ -322,6 +327,7 @@ static char	*dpi_output = NULL;
 static Bool	dryrun = False;
 static int	minWidth, maxWidth, minHeight, maxHeight;
 static Bool    	has_1_2 = False;
+static Bool    	has_1_3 = False;
 
 static int
 mode_height (XRRModeInfo *mode_info, Rotation rotation)
@@ -871,10 +877,16 @@ get_crtcs (void)
     for (c = 0; c < res->ncrtc; c++)
     {
 	XRRCrtcInfo *crtc_info = XRRGetCrtcInfo (dpy, res, res->crtcs[c]);
+	XRRPanning  *panning_info = NULL;
+
+	if (has_1_3)
+	    panning_info = XRRGetPanning  (dpy, res, res->crtcs[c]);
+
 	set_name_xid (&crtcs[c].crtc, res->crtcs[c]);
 	set_name_index (&crtcs[c].crtc, c);
 	if (!crtc_info) fatal ("could not get crtc 0x%x information", res->crtcs[c]);
 	crtcs[c].crtc_info = crtc_info;
+	crtcs[c].panning_info = panning_info;
 	if (crtc_info->mode == None)
 	{
 	    crtcs[c].mode_info = NULL;
@@ -914,6 +926,55 @@ set_crtcs (void)
     }
 }
 
+static void
+crtc_set_panning (crtc_t *crtc, char *panning)
+{
+    XRRPanning *pan = crtc->panning_info;
+
+    if (!pan)
+	pan = malloc (sizeof(XRRPanning));
+    memset (pan, 0, sizeof(XRRPanning));
+
+    switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d",
+		    &pan->width, &pan->height, &pan->left, &pan->top,
+		    &pan->track_width, &pan->track_height,
+		    &pan->track_left, &pan->track_top,
+		    &pan->border_left, &pan->border_top,
+		    &pan->border_right, &pan->border_bottom)) {
+    case 2:
+	pan->left = pan->top = 0;
+	/* fall through */
+    case 4:
+	pan->track_left   = pan->left;
+	pan->track_top    = pan->top;
+	pan->track_width  = pan->width;
+	pan->track_height = pan->height;
+	/* fall through */
+    case 8:
+	pan->border_left = pan->border_top =
+	    pan->border_right = pan->border_bottom = 0;
+	/* fall through */
+    case 12:
+	break;
+    default:
+	usage ();
+    }
+    crtc->changing = 1;
+}
+
+static void
+set_panning (void)
+{
+    output_t	*output;
+
+    for (output = outputs; output; output = output->next)
+    {
+	if (!output->panning) continue;
+	if (!output->crtc_info) fatal ("no crtc assigned");
+	crtc_set_panning (output->crtc_info, output->panning);
+    }
+}
+
 static Status
 crtc_disable (crtc_t *crtc)
 {
@@ -970,10 +1031,17 @@ crtc_apply (crtc_t *crtc)
     
     if (dryrun)
 	s = RRSetConfigSuccess;
-    else
+    else {
 	s = XRRSetCrtcConfig (dpy, res, crtc->crtc.xid, CurrentTime,
 			      crtc->x, crtc->y, mode, crtc->rotation,
 			      rr_outputs, crtc->noutput);
+	if (s == RRSetConfigSuccess && crtc->panning_info) {
+	    if (has_1_3)
+		s = XRRSetPanning (dpy, res, crtc->crtc.xid, crtc->panning_info);
+	    else
+		fatal ("panning needs RandR 1.3");
+	}
+    }
     free (rr_outputs);
     return s;
 }
@@ -1841,6 +1909,13 @@ main (int argc, char **argv)
 	    output->changes |= changes_relation;
 	    continue;
 	}
+	if (!strcmp ("--panning", argv[i])) {
+	    if (++i>=argc) usage ();
+	    if (!output) usage();
+	    output->panning = argv[i];
+	    output->changes |= changes_panning;
+	    continue;
+	}
 	if (!strcmp ("--set", argv[i])) {
 	    output_prop_t   *prop;
 	    if (!output) usage();
@@ -2035,6 +2110,8 @@ main (int argc, char **argv)
     }
     if (major > 1 || (major == 1 && minor >= 2))
 	has_1_2 = True;
+    if (major > 1 || (major == 1 && minor >= 3))
+	has_1_3 = True;
 	
     if (has_1_2 && modeit)
     {
@@ -2235,6 +2312,11 @@ main (int argc, char **argv)
 	}
 	
 	/*
+	 * Set panning
+	 */
+	set_panning ();
+	
+	/*
 	 * Now apply all of the changes
 	 */
 	apply ();
@@ -2266,6 +2348,7 @@ main (int argc, char **argv)
 	    int		    j, k, nprop;
 	    Bool	    *mode_shown;
 	    Rotation	    rotations = output_rotations (output);
+	    crtc_t          *crtc = output->crtc_info;
 
 	    printf ("%s %s", output_info->name, connection[output_info->connection]);
 	    if (mode)
@@ -2313,6 +2396,24 @@ main (int argc, char **argv)
 		printf (" %dmm x %dmm",
 			output_info->mm_width, output_info->mm_height);
 	    }
+
+	    if (crtc && crtc->panning_info && crtc->panning_info->width > 0)
+	    {
+		XRRPanning *pan = crtc->panning_info;
+		printf (" panning %dx%d+%d+%d",
+			pan->width, pan->height, pan->left, pan->top);
+		if (pan->track_left   != pan->left			||
+		    pan->track_top    != pan->top			||
+		    pan->track_width  != pan->width			||
+		    pan->track_height != pan->height			||
+		    pan->border_left  != 0 || pan->border_top != 0	||
+		    pan->border_right != 0 || pan->border_bottom != 0)
+		    printf (" tracking %dx%d+%d+%d border %d/%d/%d/%d",
+			    pan->track_width,  pan->track_height,
+			    pan->track_left,   pan->track_top,
+			    pan->border_left,  pan->border_top,
+			    pan->border_right, pan->border_bottom);
+	    }
 	    printf ("\n");
 
 	    if (verbose)
@@ -2338,6 +2439,17 @@ main (int argc, char **argv)
 			printf (" %d", crtc->crtc.index);
 		}
 		printf ("\n");
+		if (output->crtc_info && output->crtc_info->panning_info) {
+		    XRRPanning *pan = output->crtc_info->panning_info;
+		    printf ("\tPanning:    %dx%d+%d+%d\n",
+			    pan->width, pan->height, pan->left, pan->top);
+		    printf ("\tTracking:   %dx%d+%d+%d\n",
+			    pan->track_width,  pan->track_height,
+			    pan->track_left,   pan->track_top);
+		    printf ("\tBorder:     %d/%d/%d/%d\n",
+			    pan->border_left,  pan->border_top,
+			    pan->border_right, pan->border_bottom);
+		}
 	    }
 	    if (verbose || properties)
 	    {
-- 
1.5.6



More information about the xorg mailing list