summaryrefslogtreecommitdiff
path: root/xrandr.c
diff options
context:
space:
mode:
authorMatthias Hopf <mhopf@suse.de>2008-11-28 17:16:11 +0100
committerMatthias Hopf <mhopf@suse.de>2008-12-08 12:12:39 +0100
commitf6b5862f87ba7e1729c46136ef7754a06301853f (patch)
tree483d7693174194b6e75e88a7ec4b0d2f0241eb87 /xrandr.c
parent1dc67ca918446cb7db4819f60f36e7bc6f4c047b (diff)
Add panning support.
Diffstat (limited to 'xrandr.c')
-rw-r--r--xrandr.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/xrandr.c b/xrandr.c
index e8e28df..45200c5 100644
--- a/xrandr.c
+++ b/xrandr.c
@@ -133,6 +133,7 @@ usage(void)
fprintf(stderr, " --transform <a>,<b>,<c>,<d>,<e>,<f>,<g>,<h>,<i>\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");
@@ -233,6 +234,7 @@ typedef enum _changes {
changes_refresh = (1 << 7),
changes_property = (1 << 8),
changes_transform = (1 << 9),
+ changes_panning = (1 << 10),
} changes_t;
typedef enum _name_kind {
@@ -269,6 +271,7 @@ struct _crtc {
XRRCrtcInfo *crtc_info;
XRRModeInfo *mode_info;
+ XRRPanning *panning_info;
int x;
int y;
Rotation rotation;
@@ -309,6 +312,8 @@ struct _output {
int x, y;
Rotation rotation;
+ char *panning;
+
Bool automatic;
transform_t transform;
};
@@ -358,6 +363,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)
@@ -1053,10 +1059,16 @@ get_crtcs (void)
XRRCrtcTransformAttributes *attr;
#endif
int x;
+ 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;
@@ -1112,6 +1124,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)
{
@@ -1190,6 +1251,12 @@ crtc_apply (crtc_t *crtc)
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;
@@ -2069,6 +2136,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();
@@ -2307,6 +2381,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)
{
@@ -2507,6 +2583,11 @@ main (int argc, char **argv)
}
/*
+ * Set panning
+ */
+ set_panning ();
+
+ /*
* Now apply all of the changes
*/
apply ();
@@ -2591,6 +2672,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)
@@ -2616,6 +2715,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)
{