---
 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
_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to