2009/6/8 Matthias Hopf <[email protected]>:

> Yes, you're right - I forgot how it was on the Amiga. Shame on me.
> You're more than welcome to add this to the panning code.
>

Turns out doing the panning itself is the easy bit, there's extending the randr
protocol to include a panning mode field and xrandr command line tool to
grok it too to worry about...

Attached please find an initial patch anyway, though only settable
from xorg.conf
as it stands owing to the above, just adds another field to the end of
the lengthy
"Panning" option string:
   /b (or nothing - default) for border push,
   /l for the proportional panning.

Obviously, without an extended protocol and xrandr tool, you can't
change the panning mode at run time, however you can adjust
the panning area, tracking area and borders without having to restart
the server.

e.g.

Section "Monitor"
...
   Option "PreferredMode" "1600x1200"
   Option "Panning"  "3200x2400+0+0/3200x2400+0+0/160/120/160/120/l"
...
EndSection

(Don't forget to set "Virtual" large enough to cover
the whole area if necessary if you're trying the patch...)

Note that the border values are still used and relevant in the proportional
code path:
1. as you get close to the edge of the crtc it can be nice to
have unpanned zones to facilitate window placement, it made
sense to reuse the border fields, use positive
border values to have such zones, as in the first example below.

2. it turns out negative border values also allow a potentially quite
useful effect with the proportional panning mode:
Say you had two 1024x768 monitors, one above the other.  You want
a larger virtual desktop, say 2048x3072.   Well, you can e.g. do the
following, and as you pan around the edges will line up on
both heads at all times, which is neat:

Section "Monitor"
   Identifier   "Monitor0"
...
   Option "PreferredMode" "1024x768"
   Option "Panning"  "2048x3072+0+0/2048x3072+0+0/80/0/80/-768/l"
...
EndSection

Section "Monitor"
   Identifier   "Monitor1"
...
   Option "PreferredMode" "1024x768"
   Option "Panning"  "2048x3072+0+0/2048x3072+0+0/80/-768/80/0/l"
...
EndSection
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 51fe115..d16775e 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1317,18 +1317,28 @@ xf86InitialPanning (ScrnInfoPtr scrn)
 	int		width, height, left, top;
 	int		track_width, track_height, track_left, track_top;
 	int		brdr[4];
+        char            pm;
 
 	memset (&output->initialTotalArea,    0, sizeof(BoxRec));
 	memset (&output->initialTrackingArea, 0, sizeof(BoxRec));
 	memset (output->initialBorder,        0, 4*sizeof(INT16));
-
+	output->initialPanningMode = XF86CrtcPanningModeBorderPush;
 	if (! panning)
 	    continue;
 
-	switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d",
+	switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d/%c",
 			&width, &height, &left, &top,
 			&track_width, &track_height, &track_left, &track_top,
-			&brdr[0], &brdr[1], &brdr[2], &brdr[3])) {
+			&brdr[0], &brdr[1], &brdr[2], &brdr[3], &pm)) {
+	case 13:
+	    switch (pm) {
+            case 'l':
+	        output->initialPanningMode = XF86CrtcPanningModeLinear;
+    	        break;
+            case 'b':
+            default:
+		output->initialPanningMode = XF86CrtcPanningModeBorderPush;
+	    }
 	case 12:
 	    output->initialBorder[0] = brdr[0];
 	    output->initialBorder[1] = brdr[1];
@@ -2431,6 +2441,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
 	    memcpy (&crtc->panningTotalArea,    &output->initialTotalArea,    sizeof(BoxRec));
 	    memcpy (&crtc->panningTrackingArea, &output->initialTrackingArea, sizeof(BoxRec));
 	    memcpy (crtc->panningBorder,        output->initialBorder,        4*sizeof(INT16));
+	    crtc->panningMode = output->initialPanningMode;
 	    output->crtc = crtc;
 	    if (!xf86OutputSetInitialGamma(output))
 		xf86DrvMsg (scrn->scrnIndex, X_WARNING, "Initial gamma correction for output %s: failed.\n", output->name);
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 69afaa5..7916063 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -72,6 +72,12 @@ typedef enum _xf86OutputStatus {
    XF86OutputStatusUnknown
 } xf86OutputStatus;
 
+typedef enum _xf86CrtcPanningMode {
+   XF86CrtcPanningModeBorderPush,
+   XF86CrtcPanningModeLinear,
+} xf86CrtcPanningMode;
+
+
 typedef struct _xf86CrtcFuncs {
    /**
     * Turns the crtc on/off, or sets intermediate power levels if available.
@@ -336,10 +342,13 @@ struct _xf86Crtc {
      * TrackingArea: Area of the pointer for which the CRTC is panned
      * border: Borders of the displayed CRTC area which induces panning if the pointer reaches them
      * Added in ABI version 2
+     * panningMode: e.g. push against border or proportional to pointer position.
+     * Added in ABI version ???
      */
     BoxRec          panningTotalArea;
     BoxRec          panningTrackingArea;
     INT16           panningBorder[4];
+    xf86CrtcPanningMode panningMode;
 
     /**
      * Current gamma, especially useful after initial config.
@@ -605,6 +614,7 @@ struct _xf86Output {
     BoxRec          initialTotalArea;
     BoxRec          initialTrackingArea;
     INT16           initialBorder[4];
+    xf86CrtcPanningMode initialPanningMode;
 };
 
 typedef struct _xf86CrtcConfigFuncs {
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 0de21e2..4548b34 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -391,25 +391,59 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
 	    c.v[1] -= crtc->y;
 	}
 
-	if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
-	    if (c.v[0] < crtc->panningBorder[0]) {
-		c.v[0] = crtc->panningBorder[0];
-		panned = TRUE;
+	switch (crtc->panningMode) {
+	case XF86CrtcPanningModeBorderPush:
+	    if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+	        if (c.v[0] < crtc->panningBorder[0]) {
+	            c.v[0] = crtc->panningBorder[0];
+		    panned = TRUE;
+		}
+	        if (c.v[0] >= width - crtc->panningBorder[2]) {
+	            c.v[0] = width - crtc->panningBorder[2] - 1;
+		    panned = TRUE;
+	        }
 	    }
-	    if (c.v[0] >= width - crtc->panningBorder[2]) {
-		c.v[0] = width - crtc->panningBorder[2] - 1;
-		panned = TRUE;
+	    if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+	        if (c.v[1] < crtc->panningBorder[1]) {
+	            c.v[1] = crtc->panningBorder[1];
+		    panned = TRUE;
+	        }
+	        if (c.v[1] >= height - crtc->panningBorder[3]) {
+		    c.v[1] = height - crtc->panningBorder[3] - 1;
+		    panned = TRUE;
+	        }
 	    }
-	}
-	if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
-	    if (c.v[1] < crtc->panningBorder[1]) {
-		c.v[1] = crtc->panningBorder[1];
-		panned = TRUE;
+	    break;
+	case XF86CrtcPanningModeLinear:
+	    if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+		if ((c.v[0] >= crtc->panningBorder[0])
+		    || (c.v[0] < width - crtc->panningBorder[2])) {
+		    int propx;
+		    propx = crtc->panningBorder[0] +
+                            (((x - crtc->panningTotalArea.x1) *
+                              (width - crtc->panningBorder[0] - crtc->panningBorder[2])) /
+                             (crtc->panningTotalArea.x2 - crtc->panningTotalArea.x1));
+                    if (c.v[0] != propx) {
+			c.v[0] = propx;
+			panned = TRUE;
+		    }
+		}
 	    }
-	    if (c.v[1] >= height - crtc->panningBorder[3]) {
-		c.v[1] = height - crtc->panningBorder[3] - 1;
-		panned = TRUE;
+	    if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+		if ((c.v[1] >= crtc->panningBorder[1])
+		    || (c.v[1] < width - crtc->panningBorder[3])) {
+		    int propy;
+		    propy = crtc->panningBorder[1] +
+			    (((y - crtc->panningTotalArea.y1) *
+			      (height - crtc->panningBorder[1] - crtc->panningBorder[3])) /
+		             (crtc->panningTotalArea.y2 - crtc->panningTotalArea.y1));
+		    if (c.v[1] != propy) {
+		        c.v[1] = propy;
+		        panned = TRUE;
+		    }
+	        }
 	    }
+	    break;
 	}
 	if (panned)
 	    xf86ComputeCrtcPan (crtc->transform_in_use,
_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to