summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/radeon.h9
-rw-r--r--src/radeon_driver.c96
-rw-r--r--src/radeon_mergedfb.c824
-rw-r--r--src/radeon_mergedfb.h4
4 files changed, 702 insertions, 231 deletions
diff --git a/src/radeon.h b/src/radeon.h
index a99e7cd4..593baf2b 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -87,6 +87,10 @@ typedef enum {
radeonClone
} RADEONScrn2Rel;
+typedef struct _region {
+ int x0,x1,y0,y1;
+} region;
+
/* ------------------------------------- */
#define RADEON_DEBUG 0 /* Turn off debugging output */
@@ -237,6 +241,7 @@ typedef struct {
int bitsPerPixel;
int depth;
int displayWidth;
+ int displayHeight;
int pixel_code;
int pixel_bytes;
DisplayModePtr mode;
@@ -636,6 +641,10 @@ typedef struct {
Bool AtLeastOneNonClone;
int MergedFBXDPI, MergedFBYDPI;
Bool NoVirtual;
+ int CRT1XOffs, CRT1YOffs, CRT2XOffs, CRT2YOffs;
+ int MBXNR1XMAX, MBXNR1YMAX, MBXNR2XMAX, MBXNR2YMAX;
+ Bool NonRect, HaveNonRect, HaveOffsRegions, MouseRestrictions;
+ region NonRectDead, OffDead1, OffDead2;
/* special handlings for DELL triple-head server */
Bool IsDellServer;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 5b078b92..77a14da2 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -156,8 +156,10 @@ typedef enum {
OPTION_CRT2POS,
OPTION_METAMODES,
OPTION_MERGEDDPI,
- OPTION_NORADEONXINERAMA,
+ OPTION_RADEONXINERAMA,
OPTION_CRT2ISSCRN0,
+ OPTION_MERGEDFBNONRECT,
+ OPTION_MERGEDFBMOUSER,
OPTION_DISP_PRIORITY,
OPTION_PANEL_SIZE,
OPTION_MIN_DOTCLOCK,
@@ -215,8 +217,10 @@ static const OptionInfoRec RADEONOptions[] = {
{ OPTION_CRT2POS, "CRT2Position", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_METAMODES, "MetaModes", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_MERGEDDPI, "MergedDPI", OPTV_ANYSTR, {0}, FALSE },
- { OPTION_NORADEONXINERAMA, "NoMergedXinerama", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RADEONXINERAMA, "MergedXinerama", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_CRT2ISSCRN0, "MergedXineramaCRT2IsScreen0", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MERGEDFBNONRECT, "MergedNonRectangular", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MERGEDFBMOUSER, "MergedMouseRestriction", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_DISP_PRIORITY, "DisplayPriority", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_MIN_DOTCLOCK, "ForceMinDotClock", OPTV_FREQ, {0}, FALSE },
@@ -5574,6 +5578,8 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if(info->UseRADEONXinerama) {
RADEONnoPanoramiXExtension = FALSE;
RADEONXineramaExtensionInit(pScrn);
+ } else {
+ info->MouseRestrictions = FALSE;
}
}
@@ -8562,6 +8568,10 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pScrn)
info->CRT2IsScrn0 = FALSE;
info->CRT2Position = radeonClone;
info->MergedFBXDPI = info->MergedFBYDPI = 0;
+ info->CRT1XOffs = info->CRT1YOffs = info->CRT2XOffs = info->CRT2YOffs = 0;
+ info->NonRect = info->HaveNonRect = info->HaveOffsRegions = FALSE;
+ info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536;
+ info->MouseRestrictions = TRUE;
if (info->MergeType == MT_NONE) {
info->MergedFB = FALSE;
@@ -8597,36 +8607,60 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pScrn)
}
}
if(info->MergedFB) {
+ int result, ival;
+ Bool valid = FALSE;
+ char *tempstr;
strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2POS);
- if(strptr) {
- if((!strcmp(strptr,"LeftOf")) || (!strcmp(strptr,"leftof"))) {
- info->CRT2Position = radeonLeftOf;
- info->CRT2IsScrn0 = TRUE;
- }
- else if((!strcmp(strptr,"RightOf")) || (!strcmp(strptr,"rightof"))) {
- info->CRT2Position = radeonRightOf;
- info->CRT2IsScrn0 = FALSE;
- }
- else if((!strcmp(strptr,"Above")) || (!strcmp(strptr,"above"))) {
- info->CRT2Position = radeonAbove;
- info->CRT2IsScrn0 = FALSE;
- }
- else if((!strcmp(strptr,"Below")) || (!strcmp(strptr,"below"))) {
- info->CRT2Position = radeonBelow;
- info->CRT2IsScrn0 = TRUE;
- }
- else if((!strcmp(strptr,"Clone")) || (!strcmp(strptr,"clone"))) {
- info->CRT2Position = radeonClone;
- /*info->CRT2IsScrn0 = FALSE; */
- info->CRT2IsScrn0 = TRUE;
- }
- else {
+ tempstr = xalloc(strlen(strptr) + 1);
+ result = sscanf(strptr, "%s %d", tempstr, &ival);
+ if(result >= 1) {
+ if(!xf86NameCmp(tempstr,"LeftOf")) {
+ info->CRT2Position = radeonLeftOf;
+ valid = TRUE;
+ if(result == 2) {
+ if(ival < 0) info->CRT1YOffs = -ival;
+ else info->CRT2YOffs = ival;
+ }
+ info->CRT2IsScrn0 = TRUE;
+ } else if(!xf86NameCmp(tempstr,"RightOf")) {
+ info->CRT2Position = radeonRightOf;
+ if(result == 2) {
+ if(ival < 0) info->CRT1YOffs = -ival;
+ else info->CRT2YOffs = ival;
+ }
+ info->CRT2IsScrn0 = FALSE;
+ } else if(!xf86NameCmp(tempstr,"Above")) {
+ info->CRT2Position = radeonAbove;
+ valid = TRUE;
+ if(result == 2) {
+ if(ival < 0) info->CRT1XOffs = -ival;
+ else info->CRT2XOffs = ival;
+ }
+ info->CRT2IsScrn0 = FALSE;
+ } else if(!xf86NameCmp(tempstr,"Below")) {
+ info->CRT2Position = radeonBelow;
+ valid = TRUE;
+ if(result == 2) {
+ if(ival < 0) info->CRT1XOffs = -ival;
+ else info->CRT2XOffs = ival;
+ }
+ info->CRT2IsScrn0 = TRUE;
+ } else if(!xf86NameCmp(tempstr,"Clone")) {
+ info->CRT2Position = radeonClone;
+ if(result == 1) valid = TRUE;
+ /*info->CRT2IsScrn0 = TRUE;*/
+ }
+ }
+ if(!valid) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"\"%s\" is not a valid parameter for Option \"CRT2Position\"\n", strptr);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Valid parameters are \"RightOf\", \"LeftOf\", \"Above\", \"Below\", or \"Clone\"\n");
- }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Except for \"Clone\", the parameter may be followed by an integer.\n");
}
+ xfree(tempstr);
+
strptr = (char *)xf86GetOptValString(info->Options, OPTION_METAMODES);
if(strptr) {
info->MetaModes = xalloc(strlen(strptr) + 1);
@@ -8643,8 +8677,8 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pScrn)
if(info->CRT2VRefresh) memcpy(info->CRT2VRefresh, strptr, strlen(strptr) + 1);
}
- if(xf86GetOptValBool(info->Options, OPTION_NORADEONXINERAMA, &val)) {
- if (val)
+ if(xf86GetOptValBool(info->Options, OPTION_RADEONXINERAMA, &val)) {
+ if (!val)
info->UseRADEONXinerama = FALSE;
}
if(info->UseRADEONXinerama) {
@@ -8652,6 +8686,12 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pScrn)
if(val) info->CRT2IsScrn0 = TRUE;
else info->CRT2IsScrn0 = FALSE;
}
+ if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBNONRECT, &val)) {
+ info->NonRect = val ? TRUE : FALSE;
+ }
+ if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBMOUSER, &val)) {
+ info->MouseRestrictions = val ? TRUE : FALSE;
+ }
}
strptr = (char *)xf86GetOptValString(info->Options, OPTION_MERGEDDPI);
if(strptr) {
diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 94102b9a..91934768 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -286,6 +286,48 @@ RADEONFindWidestTallestMode(DisplayModePtr i, Bool tallest)
return d;
}
+static void
+RADEONFindWidestTallestCommonMode(DisplayModePtr i, DisplayModePtr j, Bool tallest,
+ DisplayModePtr *a, DisplayModePtr *b)
+{
+ DisplayModePtr c = i, d;
+ int max = 0;
+ Bool foundone;
+
+ (*a) = (*b) = NULL;
+
+ if(!i || !j) return;
+
+ do {
+ d = j;
+ foundone = FALSE;
+ do {
+ if( (c->HDisplay == d->HDisplay) &&
+ (c->VDisplay == d->VDisplay) ) {
+ foundone = TRUE;
+ break;
+ }
+ d = d->next;
+ } while(d != j);
+ if(foundone) {
+ if(tallest) {
+ if(c->VDisplay > max) {
+ max = c->VDisplay;
+ (*a) = c;
+ (*b) = d;
+ }
+ } else {
+ if(c->HDisplay > max) {
+ max = c->HDisplay;
+ (*a) = c;
+ (*b) = d;
+ }
+ }
+ }
+ c = c->next;
+ } while(c != i);
+}
+
static DisplayModePtr
RADEONGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
DisplayModePtr i, DisplayModePtr j,
@@ -295,43 +337,66 @@ RADEONGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
RADEONInfoPtr info = RADEONPTR(pScrn);
DisplayModePtr mode1 = NULL;
DisplayModePtr mode2 = NULL;
+ DisplayModePtr mode3 = NULL;
+ DisplayModePtr mode4 = NULL;
DisplayModePtr result = NULL;
int p = 0;
int count = 0;
info->AtLeastOneNonClone = FALSE;
+ /* Now build a default list of MetaModes.
+ * - Non-clone: If the user enabled NonRectangular, we use the
+ * largest mode for each CRT1 and CRT2. If not, we use the largest
+ * common mode for CRT1 and CRT2 (if available). Additionally, and
+ * regardless if the above, we produce a clone mode consisting of
+ * the largest common mode (if available) in order to use DGA.
+ * - Clone: If the (global) CRT2Position is Clone, we use the
+ * largest common mode if available, otherwise the first two modes
+ * in each list.
+ */
switch(srel) {
case radeonLeftOf:
case radeonRightOf:
mode1 = RADEONFindWidestTallestMode(i, FALSE);
mode2 = RADEONFindWidestTallestMode(j, FALSE);
+ RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);
break;
case radeonAbove:
case radeonBelow:
mode1 = RADEONFindWidestTallestMode(i, TRUE);
mode2 = RADEONFindWidestTallestMode(j, TRUE);
+ RADEONFindWidestTallestCommonMode(i, j, TRUE, &mode3, &mode4);
break;
case radeonClone:
- mode1 = i;
- mode2 = j;
- while (pScrn->display->modes[count]) count++;
- for (p = 0; p < count; p++) {
- result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, srel);
- mode1 = mode1->next;
- mode2 = mode2->next;
- }
+ RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);
+ if(mode3 && mode4) {
+ mode1 = mode3;
+ mode2 = mode4;
+ } else {
+ mode1 = i;
+ mode2 = j;
+ }
+ }
+
+ if(srel != radeonClone) {
+ if(mode3 && mode4 && !info->NonRect) {
+ mode1 = mode3;
+ mode2 = mode2;
+ }
}
if(mode1 && mode2) {
- if (srel == radeonClone)
- return result;
- else
- return(RADEONCopyModeNLink(pScrn, result, mode1, mode2, srel));
- } else {
- return NULL;
+ result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, srel);
+ }
+
+ if(srel != radeonClone) {
+ if(mode3 && mode4) {
+ result = RADEONCopyModeNLink(pScrn, result, mode3, mode4, radeonClone);
+ }
}
+ return result;
}
/* Generate the merged-fb mode modelist
@@ -452,12 +517,18 @@ RADEONGenerateModeList(ScrnInfoPtr pScrn, char* str,
DisplayModePtr i, DisplayModePtr j,
RADEONScrn2Rel srel)
{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
if(str != NULL) {
return(RADEONGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "No MetaModes given, linking %s modes by default\n",
- (srel == radeonClone) ? "first" : "largest");
+ "No MetaModes given, linking %s modes by default\n",
+ (srel == radeonClone) ? "largest common" :
+ (info->NonRect ?
+ (((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest" : "tallest")
+ :
+ (((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest common" : "tallest common")) );
return(RADEONGenerateModeListFromLargestModes(pScrn, i, j, srel));
}
}
@@ -465,30 +536,47 @@ RADEONGenerateModeList(ScrnInfoPtr pScrn, char* str,
void
RADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
DisplayModePtr mode, bmode;
- int max;
+ int maxh, maxv;
static const char *str = "MergedFB: Virtual %s %d\n";
+ static const char *errstr = "Virtual %s to small for given CRT2Position offset\n";
+
+ mode = bmode = pScrn->modes;
+ maxh = maxv = 0;
+ do {
+ if(mode->HDisplay > maxh) maxh = mode->HDisplay;
+ if(mode->VDisplay > maxv) maxv = mode->VDisplay;
+ mode = mode->next;
+ } while(mode != bmode);
+ maxh += info->CRT1XOffs + info->CRT2XOffs;
+ maxv += info->CRT1YOffs + info->CRT2YOffs;
if(!(pScrn->display->virtualX)) {
- mode = bmode = pScrn->modes;
- max = 0;
- do {
- if(mode->HDisplay > max) max = mode->HDisplay;
- mode = mode->next;
- } while(mode != bmode);
- pScrn->virtualX = max;
- pScrn->displayWidth = max;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", max);
+ if(maxh > 8191) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Virtual width with CRT2Position offset beyond hardware specs\n");
+ info->CRT1XOffs = info->CRT2XOffs = 0;
+ maxh -= (info->CRT1XOffs + info->CRT2XOffs);
+ }
+ pScrn->virtualX = maxh;
+ pScrn->displayWidth = maxh;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh);
+ } else {
+ if(maxh < pScrn->display->virtualX) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "width");
+ info->CRT1XOffs = info->CRT2XOffs = 0;
+ }
}
+
if(!(pScrn->display->virtualY)) {
- mode = bmode = pScrn->modes;
- max = 0;
- do {
- if(mode->VDisplay > max) max = mode->VDisplay;
- mode = mode->next;
- } while(mode != bmode);
- pScrn->virtualY = max;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", max);
+ pScrn->virtualY = maxv;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv);
+ } else {
+ if(maxv < pScrn->display->virtualY) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "height");
+ info->CRT1YOffs = info->CRT2YOffs = 0;
+ }
}
}
@@ -500,8 +588,14 @@ RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
ScrnInfoPtr pScrn2 = NULL;
int crt1scrnnum = 0, crt2scrnnum = 1;
int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0;
+ int realvirtX, realvirtY;
DisplayModePtr currentMode, firstMode;
Bool infochanged = FALSE;
+ Bool usenonrect = info->NonRect;
+ const char *rectxine = "\t... setting up rectangular Xinerama layout\n";
+
+ info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536;
+ info->HaveNonRect = info->HaveOffsRegions = FALSE;
if(!info->MergedFB) return;
@@ -521,6 +615,10 @@ RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
* the maxCRT fields here (and not somewhere else, like in CopyNLink)
*/
+ /* "Real" virtual: Virtual without the Offset */
+ realvirtX = pScrn1->virtualX - info->CRT1XOffs - info->CRT2XOffs;
+ realvirtY = pScrn1->virtualY - info->CRT1YOffs - info->CRT2YOffs;
+
if((info->RADEONXineramaVX != pScrn1->virtualX) || (info->RADEONXineramaVY != pScrn1->virtualY)) {
if(!(pScrn1->modes)) {
@@ -545,50 +643,59 @@ RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
DisplayModePtr j = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2;
RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2Position;
- if((i->HDisplay <= pScrn1->virtualX) && (j->HDisplay <= pScrn1->virtualX) &&
- (i->VDisplay <= pScrn1->virtualY) && (j->VDisplay <= pScrn1->virtualY)) {
-
- if(srel != radeonClone) {
- if(info->maxCRT1_X1 <= i->HDisplay) {
- info->maxCRT1_X1 = i->HDisplay; /* Largest CRT1 mode */
- if(info->maxCRT1_X2 < j->HDisplay) {
- info->maxCRT1_X2 = j->HDisplay; /* Largest X of CRT2 mode displayed with largest CRT1 mode */
- }
- }
- if(info->maxCRT2_X2 <= j->HDisplay) {
- info->maxCRT2_X2 = j->HDisplay; /* Largest CRT2 mode */
- if(info->maxCRT2_X1 < i->HDisplay) {
- info->maxCRT2_X1 = i->HDisplay; /* Largest X of CRT1 mode displayed with largest CRT2 mode */
- }
- }
- if(info->maxCRT1_Y1 <= i->VDisplay) {
- info->maxCRT1_Y1 = i->VDisplay;
- if(info->maxCRT1_Y2 < j->VDisplay) {
- info->maxCRT1_Y2 = j->VDisplay;
- }
- }
- if(info->maxCRT2_Y2 <= j->VDisplay) {
- info->maxCRT2_Y2 = j->VDisplay;
- if(info->maxCRT2_Y1 < i->VDisplay) {
- info->maxCRT2_Y1 = i->VDisplay;
- }
- }
- } else {
- if(info->maxClone_X1 < i->HDisplay) {
- info->maxClone_X1 = i->HDisplay;
- }
- if(info->maxClone_X2 < j->HDisplay) {
- info->maxClone_X2 = j->HDisplay;
- }
- if(info->maxClone_Y1 < i->VDisplay) {
- info->maxClone_Y1 = i->VDisplay;
- }
- if(info->maxClone_Y2 < j->VDisplay) {
- info->maxClone_Y2 = j->VDisplay;
- }
- }
- }
- currentMode = p;
+ if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) &&
+ (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) &&
+ (i->VDisplay <= realvirtY) && (j->VDisplay <= realvirtY)) {
+
+ if(srel != radeonClone) {
+ if(info->maxCRT1_X1 == i->HDisplay) {
+ if(info->maxCRT1_X2 < j->HDisplay) {
+ info->maxCRT1_X2 = j->HDisplay; /* Widest CRT2 mode displayed with widest CRT1 mode */
+ }
+ } else if(info->maxCRT1_X1 < i->HDisplay) {
+ info->maxCRT1_X1 = i->HDisplay; /* Widest CRT1 mode */
+ info->maxCRT1_X2 = j->HDisplay;
+ }
+ if(info->maxCRT2_X2 == j->HDisplay) {
+ if(info->maxCRT2_X1 < i->HDisplay) {
+ info->maxCRT2_X1 = i->HDisplay; /* Widest CRT1 mode displayed with widest CRT2 mode */
+ }
+ } else if(info->maxCRT2_X2 < j->HDisplay) {
+ info->maxCRT2_X2 = j->HDisplay; /* Widest CRT2 mode */
+ info->maxCRT2_X1 = i->HDisplay;
+ }
+ if(info->maxCRT1_Y1 == i->VDisplay) { /* Same as above, but tallest instead of widest */
+ if(info->maxCRT1_Y2 < j->VDisplay) {
+ info->maxCRT1_Y2 = j->VDisplay;
+ }
+ } else if(info->maxCRT1_Y1 < i->VDisplay) {
+ info->maxCRT1_Y1 = i->VDisplay;
+ info->maxCRT1_Y2 = j->VDisplay;
+ }
+ if(info->maxCRT2_Y2 == j->VDisplay) {
+ if(info->maxCRT2_Y1 < i->VDisplay) {
+ info->maxCRT2_Y1 = i->VDisplay;
+ }
+ } else if(info->maxCRT2_Y2 < j->VDisplay) {
+ info->maxCRT2_Y2 = j->VDisplay;
+ info->maxCRT2_Y1 = i->VDisplay;
+ }
+ } else {
+ if(info->maxClone_X1 < i->HDisplay) {
+ info->maxClone_X1 = i->HDisplay;
+ }
+ if(info->maxClone_X2 < j->HDisplay) {
+ info->maxClone_X2 = j->HDisplay;
+ }
+ if(info->maxClone_Y1 < i->VDisplay) {
+ info->maxClone_Y1 = i->VDisplay;
+ }
+ if(info->maxClone_Y2 < j->VDisplay) {
+ info->maxClone_Y2 = j->VDisplay;
+ }
+ }
+ }
+ currentMode = p;
} while((currentMode) && (currentMode != firstMode));
@@ -598,97 +705,216 @@ RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
}
- /* leftof
-
- V 1:
- CRT2: x = 0
- y = 0
- w = (maxCRT2 X)
- h = (virtual Y)
- CRT1: x = (virtual X) - (maxCRT1 X)
- y = 0
- w = (maxCRT1 X)
- h = (virtual Y)
-
- V 2:
- CRT2: x = 0
- y = 0
- w = max CRT2 mode X
- h = virtual Y size
- CRT1: x = (max) CRT2 mode X von dem Metamode, wo CRT1 mode maximal breit ist
- y = 0
- w = max CRT1 mode X
- h = virtual Y size
-
- V 3: (current)
- CRT1: x = (maxCRT2 X von dem MMode, wo maxCRT1 X)
- y = 0
- w = (virtual X) - x
- h = (virtual Y)
- CRT2: x = 0
- y = 0
- w = (virtual X) - (maxCRT1 X von dem MMode, wo maxCRT2 X)
- h = (virtual Y)
+ if((usenonrect) && (info->CRT2Position != radeonClone) && info->maxCRT1_X1) {
+#if 0
+ switch(info->CRT2Position) {
+ case radeonLeftOf:
+ case radeonRightOf:
+ if((info->maxCRT1_Y1 != realvirtY) && (info->maxCRT2_Y1 != realvirtY)) {
+ usenonrect = FALSE;
+ }
+ break;
+ case radeonAbove:
+ case radeonBelow:
+ if((info->maxCRT1_X1 != realvirtX) && (info->maxCRT2_X1 != realvirtX)) {
+ usenonrect = FALSE;
+ }
+ break;
+ case radeonClone:
+ break;
+ }
+#endif
+ if(infochanged && !usenonrect) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Virtual screen size does not match maximum display modes...\n");
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
+
+ }
+ } else if(infochanged && usenonrect) {
+ usenonrect = FALSE;
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Only clone modes available for this virtual screen size...\n");
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
+ }
+
+ if(info->maxCRT1_X1) { /* Means we have at least one non-clone mode */
+ switch(info->CRT2Position) {
+ case radeonLeftOf:
+ x1 = min(info->maxCRT1_X2, pScrn1->virtualX - info->maxCRT1_X1);
+ if(x1 < 0) x1 = 0;
+ y1 = info->CRT1YOffs;
+ w1 = pScrn1->virtualX - x1;
+ h1 = realvirtY;
+ if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) {
+ h1 = info->MBXNR1YMAX = info->maxCRT1_Y1;
+ info->NonRectDead.x0 = x1;
+ info->NonRectDead.x1 = x1 + w1 - 1;
+ info->NonRectDead.y0 = y1 + h1;
+ info->NonRectDead.y1 = pScrn1->virtualY - 1;
+ info->HaveNonRect = TRUE;
+ }
+ x2 = 0;
+ y2 = info->CRT2YOffs;
+ w2 = max(info->maxCRT2_X2, pScrn1->virtualX - info->maxCRT2_X1);
+ if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX;
+ h2 = realvirtY;
+ if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) {
+ h2 = info->MBXNR2YMAX = info->maxCRT2_Y2;
+ info->NonRectDead.x0 = x2;
+ info->NonRectDead.x1 = x2 + w2 - 1;
+ info->NonRectDead.y0 = y2 + h2;
+ info->NonRectDead.y1 = pScrn1->virtualY - 1;
+ info->HaveNonRect = TRUE;
+ }
+ break;
+ case radeonRightOf:
+ x1 = 0;
+ y1 = info->CRT1YOffs;
+ w1 = max(info->maxCRT1_X1, pScrn1->virtualX - info->maxCRT1_X2);
+ if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX;
+ h1 = realvirtY;
+ if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) {
+ h1 = info->MBXNR1YMAX = info->maxCRT1_Y1;
+ info->NonRectDead.x0 = x1;
+ info->NonRectDead.x1 = x1 + w1 - 1;
+ info->NonRectDead.y0 = y1 + h1;
+ info->NonRectDead.y1 = pScrn1->virtualY - 1;
+ info->HaveNonRect = TRUE;
+ }
+ x2 = min(info->maxCRT2_X1, pScrn1->virtualX - info->maxCRT2_X2);
+ if(x2 < 0) x2 = 0;
+ y2 = info->CRT2YOffs;
+ w2 = pScrn1->virtualX - x2;
+ h2 = realvirtY;
+ if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) {
+ h2 = info->MBXNR2YMAX = info->maxCRT2_Y2;
+ info->NonRectDead.x0 = x2;
+ info->NonRectDead.x1 = x2 + w2 - 1;
+ info->NonRectDead.y0 = y2 + h2;
+ info->NonRectDead.y1 = pScrn1->virtualY - 1;
+ info->HaveNonRect = TRUE;
+ }
+ break;
+ case radeonAbove:
+ x1 = info->CRT1XOffs;
+ y1 = min(info->maxCRT1_Y2, pScrn1->virtualY - info->maxCRT1_Y1);
+ if(y1 < 0) y1 = 0;
+ w1 = realvirtX;
+ h1 = pScrn1->virtualY - y1;
+ if((usenonrect) && (info->maxCRT1_X1 != realvirtX)) {
+ w1 = info->MBXNR1XMAX = info->maxCRT1_X1;
+ info->NonRectDead.x0 = x1 + w1;
+ info->NonRectDead.x1 = pScrn1->virtualX - 1;
+ info->NonRectDead.y0 = y1;
+ info->NonRectDead.y1 = y1 + h1 - 1;
+ info->HaveNonRect = TRUE;
+ }
+ x2 = info->CRT2XOffs;
+ y2 = 0;
+ w2 = realvirtX;
+ h2 = max(info->maxCRT2_Y2, pScrn1->virtualY - info->maxCRT2_Y1);
+ if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY;
+ if((usenonrect) && (info->maxCRT2_X2 != realvirtX)) {
+ w2 = info->MBXNR2XMAX = info->maxCRT2_X2;
+ info->NonRectDead.x0 = x2 + w2;
+ info->NonRectDead.x1 = pScrn1->virtualX - 1;
+ info->NonRectDead.y0 = y2;
+ info->NonRectDead.y1 = y2 + h2 - 1;
+ info->HaveNonRect = TRUE;
+ }
+ break;
+ case radeonBelow:
+ x1 = info->CRT1XOffs;
+ y1 = 0;
+ w1 = realvirtX;
+ h1 = max(info->maxCRT1_Y1, pScrn1->virtualY - info->maxCRT1_Y2);
+ if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY;
+ if((usenonrect) && (info->maxCRT1_X1 != realvirtX)) {
+ w1 = info->MBXNR1XMAX = info->maxCRT1_X1;
+ info->NonRectDead.x0 = x1 + w1;
+ info->NonRectDead.x1 = pScrn1->virtualX - 1;
+ info->NonRectDead.y0 = y1;
+ info->NonRectDead.y1 = y1 + h1 - 1;
+ info->HaveNonRect = TRUE;
+ }
+ x2 = info->CRT2XOffs;
+ y2 = min(info->maxCRT2_Y1, pScrn1->virtualY - info->maxCRT2_Y2);
+ if(y2 < 0) y2 = 0;
+ w2 = realvirtX;
+ h2 = pScrn1->virtualY - y2;
+ if((usenonrect) && (info->maxCRT2_X2 != realvirtX)) {
+ w2 = info->MBXNR2XMAX = info->maxCRT2_X2;
+ info->NonRectDead.x0 = x2 + w2;
+ info->NonRectDead.x1 = pScrn1->virtualX - 1;
+ info->NonRectDead.y0 = y2;
+ info->NonRectDead.y1 = y2 + h2 - 1;
+ info->HaveNonRect = TRUE;
+ }
+ default:
+ break;
+ }
+
+ switch(info->CRT2Position) {
+ case radeonLeftOf:
+ case radeonRightOf:
+ if(info->CRT1YOffs) {
+ info->OffDead1.x0 = x1;
+ info->OffDead1.x1 = x1 + w1 - 1;
+ info->OffDead1.y0 = 0;
+ info->OffDead1.y1 = y1 - 1;
+ info->OffDead2.x0 = x2;
+ info->OffDead2.x1 = x2 + w2 - 1;
+ info->OffDead2.y0 = y2 + h2;
+ info->OffDead2.y1 = pScrn1->virtualY - 1;
+ info->HaveOffsRegions = TRUE;
+ } else if(info->CRT2YOffs) {
+ info->OffDead1.x0 = x2;
+ info->OffDead1.x1 = x2 + w2 - 1;
+ info->OffDead1.y0 = 0;
+ info->OffDead1.y1 = y2 - 1;
+ info->OffDead2.x0 = x1;
+ info->OffDead2.x1 = x1 + w1 - 1;
+ info->OffDead2.y0 = y1 + h1;
+ info->OffDead2.y1 = pScrn1->virtualY - 1;
+ info->HaveOffsRegions = TRUE;
+ }
+ break;
+ case radeonAbove:
+ case radeonBelow:
+ if(info->CRT1XOffs) {
+ info->OffDead1.x0 = x2 + w2;
+ info->OffDead1.x1 = pScrn1->virtualX - 1;
+ info->OffDead1.y0 = y2;
+ info->OffDead1.y1 = y2 + h2 - 1;
+ info->OffDead2.x0 = 0;
+ info->OffDead2.x1 = x1 - 1;
+ info->OffDead2.y0 = y1;
+ info->OffDead2.y1 = y1 + h1 - 1;
+ info->HaveOffsRegions = TRUE;
+ } else if(info->CRT2XOffs) {
+ info->OffDead1.x0 = x1 + w1;
+ info->OffDead1.x1 = pScrn1->virtualX - 1;
+ info->OffDead1.y0 = y1;
+ info->OffDead1.y1 = y1 + h1 - 1;
+ info->OffDead2.x0 = 0;
+ info->OffDead2.x1 = x2 - 1;
+ info->OffDead2.y0 = y2;
+ info->OffDead2.y1 = y2 + h2 - 1;
+ info->HaveOffsRegions = TRUE;
+ }
+ default:
+ break;
+ }
+
+ } else { /* Only clone-modes left */
+
+ x1 = x2 = 0;
+ y1 = y2 = 0;
+ w1 = w2 = max(info->maxClone_X1, info->maxClone_X2);
+ h1 = h2 = max(info->maxClone_Y1, info->maxClone_Y2);
- */
- switch(info->CRT2Position) {
- case radeonLeftOf: /* V 1 */
- x1 = min(info->maxCRT1_X2, pScrn1->virtualX - info->maxCRT1_X1); /* pScrn1->virtualX - pSiS->maxCRT1_X1;
-*/
- if(x1 < 0) x1 = 0;
- y1 = 0; /* 0; */
- w1 = pScrn1->virtualX - x1; /* pSiS->maxCRT1_X1; */
- h1 = pScrn1->virtualY; /* pScrn1->virtualY; */
- x2 = 0; /* 0; */
- y2 = 0; /* 0; */
- w2 = max(info->maxCRT2_X2, pScrn1->virtualX - info->maxCRT2_X1); /* pSiS->maxCRT2_X2; */
- if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX;
- h2 = pScrn1->virtualY; /* pScrn1->virtualY; */
- break;
- case radeonRightOf:
- x1 = 0; /* 0; */
- y1 = 0; /* 0; */
- w1 = max(info->maxCRT1_X1, pScrn1->virtualX - info->maxCRT1_X2); /* pSiS->maxCRT1_X1; */
- if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX;
- h1 = pScrn1->virtualY; /* pScrn1->virtualY; */
- x2 = min(info->maxCRT2_X1, pScrn1->virtualX - info->maxCRT2_X2); /* pScrn1->virtualX - pSiS->maxCRT2_X2;
-*/
- if(x2 < 0) x2 = 0;
- y2 = 0; /* 0; */
- w2 = pScrn1->virtualX - x2; /* pSiS->maxCRT2_X2; */
- h2 = pScrn1->virtualY; /* pScrn1->virtualY; */
- break;
- case radeonAbove:
- x1 = 0; /* 0; */
- y1 = min(info->maxCRT1_Y2, pScrn1->virtualY - info->maxCRT1_Y1); /* pScrn1->virtualY - pSiS->maxCRT1_Y1;
-*/
- if(y1 < 0) y1 = 0;
- w1 = pScrn1->virtualX; /* pScrn1->virtualX; */
- h1 = pScrn1->virtualY - y1; /* pSiS->maxCRT1_Y1; */
- x2 = 0; /* 0; */
- y2 = 0; /* 0; */
- w2 = pScrn1->virtualX; /* pScrn1->virtualX; */
- h2 = max(info->maxCRT2_Y2, pScrn1->virtualY - info->maxCRT2_Y1); /* pSiS->maxCRT2_Y2; */
- if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY;
- break;
- case radeonBelow:
- x1 = 0; /* 0; */
- y1 = 0; /* 0; */
- w1 = pScrn1->virtualX; /* pScrn1->virtualX; */
- h1 = max(info->maxCRT1_Y1, pScrn1->virtualY - info->maxCRT1_Y2); /* pSiS->maxCRT1_Y1; */
- if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY;
- x2 = 0; /* 0; */
- y2 = min(info->maxCRT2_Y1, pScrn1->virtualY - info->maxCRT2_Y2); /* pScrn1->virtualY - pSiS->maxCRT2_Y2;
-*/
- if(y2 < 0) y2 = 0;
- w2 = pScrn1->virtualX; /* pScrn1->virtualX; */
- h2 = pScrn1->virtualY - y2; /* pSiS->maxCRT2_Y2; */
- break;
- default:
- xf86DrvMsg(pScrn1->scrnIndex, X_ERROR,
- "Internal error: UpdateXineramaInfo(): unsupported CRT2Position (%d)\n",
- info->CRT2Position);
}
+
RADEONXineramadataPtr[crt1scrnnum].x = x1;
RADEONXineramadataPtr[crt1scrnnum].y = y1;
RADEONXineramadataPtr[crt1scrnnum].width = w1;
@@ -700,15 +926,34 @@ RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
if(infochanged) {
xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Pseudo-Xinerama: CRT1 (Screen %d) (%d,%d)-(%d,%d)\n",
- crt1scrnnum, x1, y1, w1+x1-1, h1+y1-1);
+ "Pseudo-Xinerama: CRT1 (Screen %d) (%d,%d)-(%d,%d)\n",
+ crt1scrnnum, x1, y1, w1+x1-1, h1+y1-1);
xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
- "Pseudo-Xinerama: CRT2 (Screen %d) (%d,%d)-(%d,%d)\n",
- crt2scrnnum, x2, y2, w2+x2-1, h2+y2-1);
+ "Pseudo-Xinerama: CRT2 (Screen %d) (%d,%d)-(%d,%d)\n",
+ crt2scrnnum, x2, y2, w2+x2-1, h2+y2-1);
+ if(info->HaveNonRect) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: Inaccessible area (%d,%d)-(%d,%d)\n",
+ info->NonRectDead.x0, info->NonRectDead.y0,
+ info->NonRectDead.x1, info->NonRectDead.y1);
+ }
+ if(info->HaveOffsRegions) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
+ info->OffDead1.x0, info->OffDead1.y0,
+ info->OffDead1.x1, info->OffDead1.y1);
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
+ info->OffDead2.x0, info->OffDead2.y0,
+ info->OffDead2.x1, info->OffDead2.y1);
+ }
+ if(info->HaveNonRect || info->HaveOffsRegions) {
+ xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
+ "Mouse restriction for inaccessible areas is %s\n",
+ info->MouseRestrictions ? "enabled" : "disabled");
+ }
}
-
}
-
/* Proc */
int
@@ -997,6 +1242,7 @@ RADEONXineramaExtensionInit(ScrnInfoPtr pScrn)
if(!info->MergedFB) {
RADEONnoPanoramiXExtension = TRUE;
+ info->MouseRestrictions = FALSE;
return;
}
@@ -1005,6 +1251,7 @@ RADEONXineramaExtensionInit(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Xinerama active, not initializing Radeon Pseudo-Xinerama\n");
RADEONnoPanoramiXExtension = TRUE;
+ info->MouseRestrictions = FALSE;
return;
}
#endif
@@ -1012,6 +1259,7 @@ RADEONXineramaExtensionInit(ScrnInfoPtr pScrn)
if(RADEONnoPanoramiXExtension) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Radeon Pseudo-Xinerama disabled\n");
+ info->MouseRestrictions = FALSE;
return;
}
@@ -1019,6 +1267,7 @@ RADEONXineramaExtensionInit(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Running MergedFB in Clone mode, Radeon Pseudo-Xinerama disabled\n");
RADEONnoPanoramiXExtension = TRUE;
+ info->MouseRestrictions = FALSE;
return;
}
@@ -1026,6 +1275,7 @@ RADEONXineramaExtensionInit(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Only Clone modes defined, Radeon Pseudo-Xinerama disabled\n");
RADEONnoPanoramiXExtension = TRUE;
+ info->MouseRestrictions = FALSE;
return;
}
@@ -1054,6 +1304,7 @@ RADEONXineramaExtensionInit(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize Radeon Pseudo-Xinerama extension\n");
RADEONnoPanoramiXExtension = TRUE;
+ info->MouseRestrictions = FALSE;
return;
}
@@ -1084,14 +1335,89 @@ RADEONMergePointerMoved(int scrnIndex, int x, int y)
ScrnInfoPtr pScrn2 = info->CRT2pScrn;
region out, in1, in2, f2, f1;
int deltax, deltay;
+ int temp1, temp2;
+ int old1x0, old1y0, old2x0, old2y0;
+ int CRT1XOffs = 0, CRT1YOffs = 0, CRT2XOffs = 0, CRT2YOffs = 0;
+ int HVirt = pScrn1->virtualX;
+ int VVirt = pScrn1->virtualY;
+ int sigstate;
+ Bool doit = FALSE, HaveNonRect = FALSE, HaveOffsRegions = FALSE;
+ RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
+
+ if(info->DGAactive) {
+ return;
+ /* DGA: There is no cursor and no panning while DGA is active. */
+ /* If it were, we would need to do: */
+ /* HVirt = info->CurrentLayout.displayWidth;
+ VVirt = info->CurrentLayout.displayHeight;
+ BOUND(x, info->CurrentLayout.DGAViewportX, HVirt);
+ BOUND(y, info->CurrentLayout.DGAViewportY, VVirt); */
+ } else {
+ CRT1XOffs = info->CRT1XOffs;
+ CRT1YOffs = info->CRT1YOffs;
+ CRT2XOffs = info->CRT2XOffs;
+ CRT2YOffs = info->CRT2YOffs;
+ HaveNonRect = info->HaveNonRect;
+ HaveOffsRegions = info->HaveOffsRegions;
+ }
+
+ /* Check if the pointer is inside our dead areas */
+ if((info->MouseRestrictions) && (srel != radeonClone) && !RADEONnoPanoramiXExtension) {
+ if(HaveNonRect) {
+ if(InRegion(x, y, info->NonRectDead)) {
+ switch(srel) {
+ case radeonLeftOf:
+ case radeonRightOf: y = info->NonRectDead.y0 - 1;
+ doit = TRUE;
+ break;
+ case radeonAbove:
+ case radeonBelow: x = info->NonRectDead.x0 - 1;
+ doit = TRUE;
+ default: break;
+ }
+ }
+ }
+ if(HaveOffsRegions) {
+ if(InRegion(x, y, info->OffDead1)) {
+ switch(srel) {
+ case radeonLeftOf:
+ case radeonRightOf: y = info->OffDead1.y1;
+ doit = TRUE;
+ break;
+ case radeonAbove:
+ case radeonBelow: x = info->OffDead1.x1;
+ doit = TRUE;
+ default: break;
+ }
+ } else if(InRegion(x, y, info->OffDead2)) {
+ switch(srel) {
+ case radeonLeftOf:
+ case radeonRightOf: y = info->OffDead2.y0 - 1;
+ doit = TRUE;
+ break;
+ case radeonAbove:
+ case radeonBelow: x = info->OffDead2.x0 - 1;
+ doit = TRUE;
+ default: break;
+ }
+ }
+ }
+ if(doit) {
+ UpdateCurrentTime();
+ sigstate = xf86BlockSIGIO();
+ miPointerAbsoluteCursor(x, y, currentTime.milliseconds);
+ xf86UnblockSIGIO(sigstate);
+ return;
+ }
+ }
- f1.x0 = info->CRT1frameX0;
+ f1.x0 = old1x0 = info->CRT1frameX0;
f1.x1 = info->CRT1frameX1;
- f1.y0 = info->CRT1frameY0;
+ f1.y0 = old1y0 = info->CRT1frameY0;
f1.y1 = info->CRT1frameY1;
- f2.x0 = pScrn2->frameX0;
+ f2.x0 = old2x0 = pScrn2->frameX0;
f2.x1 = pScrn2->frameX1;
- f2.y0 = pScrn2->frameY0;
+ f2.y0 = old2y0 = pScrn2->frameY0;
f2.y1 = pScrn2->frameY1;
/* Define the outer region. Crossing this causes all frames to move */
@@ -1106,7 +1432,7 @@ RADEONMergePointerMoved(int scrnIndex, int x, int y)
*/
in1 = out;
in2 = out;
- switch(((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position) {
+ switch(srel) {
case radeonLeftOf:
in1.x0 = f1.x0;
in2.x1 = f2.x1;
@@ -1185,7 +1511,7 @@ RADEONMergePointerMoved(int scrnIndex, int x, int y)
f2.y1 += deltay;
}
- switch(((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position) {
+ switch(srel) {
case radeonLeftOf:
if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); }
if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); }
@@ -1214,12 +1540,65 @@ RADEONMergePointerMoved(int scrnIndex, int x, int y)
pScrn2->frameX0 = f2.x0;
pScrn2->frameY0 = f2.y0;
+ switch(((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position) {
+ case radeonLeftOf:
+ case radeonRightOf:
+ if(info->CRT1YOffs || info->CRT2YOffs || HaveNonRect) {
+ if(info->CRT1frameY0 != old1y0) {
+ if(info->CRT1frameY0 < info->CRT1YOffs)
+ info->CRT1frameY0 = info->CRT1YOffs;
+ temp1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay;
+ /*temp2 = pScrn1->virtualY - info->CRT2YOffs;*/
+ temp2 = min((VVirt - CRT2YOffs), (CRT1YOffs + info->MBXNR1YMAX));
+ if(temp1 > temp2)
+ info->CRT1frameY0 -= (temp1 - temp2);
+ }
+ if(pScrn2->frameY0 != old2y0) {
+ if(pScrn2->frameY0 < info->CRT2YOffs)
+ pScrn2->frameY0 = info->CRT2YOffs;
+ temp1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay;
+ /*temp2 = pScrn1->virtualY - info->CRT1YOffs;*/
+ temp2 = min((VVirt - CRT1YOffs), (CRT2YOffs + info->MBXNR2YMAX));
+ if(temp1 > temp2)
+ pScrn2->frameY0 -= (temp1 - temp2);
+ }
+ }
+ break;
+ case radeonBelow:
+ case radeonAbove:
+ if(info->CRT1XOffs || info->CRT2XOffs || HaveNonRect) {
+ if(info->CRT1frameX0 != old1x0) {
+ if(info->CRT1frameX0 < info->CRT1XOffs)
+ info->CRT1frameX0 = info->CRT1XOffs;
+ temp1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay;
+ /*temp2 = pScrn1->virtualX - info->CRT2XOffs;*/
+ temp2 = min((HVirt - CRT2XOffs), (CRT1XOffs + info->MBXNR1XMAX));
+ if(temp1 > temp2)
+ info->CRT1frameX0 -= (temp1 - temp2);
+ }
+ if(pScrn2->frameX0 != old2x0) {
+ if(pScrn2->frameX0 < info->CRT2XOffs)
+ pScrn2->frameX0 = info->CRT2XOffs;
+ temp1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay;
+ /*temp2 = pScrn1->virtualX - info->CRT1XOffs;*/
+ temp2 = min((HVirt - CRT1XOffs), (CRT2XOffs + info->MBXNR2XMAX));
+ if(temp1 > temp2)
+ pScrn2->frameX0 -= (temp1 - temp2);
+ }
+ }
+ break;
+ case radeonClone:
+ break;
+ }
+
info->CRT1frameX1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
info->CRT1frameY1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
+#if 0
pScrn1->frameX1 = pScrn1->frameX0 + info->CurrentLayout.mode->HDisplay - 1;
pScrn1->frameY1 = pScrn1->frameY0 + info->CurrentLayout.mode->VDisplay - 1;
+#endif
RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE);
RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);
@@ -1236,40 +1615,81 @@ RADEONAdjustFrameMergedHelper(int scrnIndex, int x, int y, int flags)
int HTotal = info->CurrentLayout.mode->HDisplay;
int VMax = VTotal;
int HMax = HTotal;
+ int HVirt = pScrn1->virtualX;
+ int VVirt = pScrn1->virtualY;
+ int x1 = x, x2 = x;
+ int y1 = y, y2 = y;
+ int CRT1XOffs = 0, CRT1YOffs = 0, CRT2XOffs = 0, CRT2YOffs = 0;
+ int MBXNR1XMAX = 65536, MBXNR1YMAX = 65536, MBXNR2XMAX = 65536, MBXNR2YMAX = 65536;
+
+ if(info->DGAactive) {
+ HVirt = info->CurrentLayout.displayWidth;
+ VVirt = info->CurrentLayout.displayHeight;
+ } else {
+ CRT1XOffs = info->CRT1XOffs;
+ CRT1YOffs = info->CRT1YOffs;
+ CRT2XOffs = info->CRT2XOffs;
+ CRT2YOffs = info->CRT2YOffs;
+ MBXNR1XMAX = info->MBXNR1XMAX;
+ MBXNR1YMAX = info->MBXNR1YMAX;
+ MBXNR2XMAX = info->MBXNR2XMAX;
+ MBXNR2YMAX = info->MBXNR2YMAX;
+ }
+
BOUND(x, 0, pScrn1->virtualX - HTotal);
BOUND(y, 0, pScrn1->virtualY - VTotal);
+ if(SDMPTR(pScrn1)->CRT2Position != radeonClone) {
+#if 0
+ BOUND(x1, info->CRT1XOffs, pScrn1->virtualX - HTotal - info->CRT2XOffs);
+ BOUND(y1, info->CRT1YOffs, pScrn1->virtualY - VTotal - info->CRT2YOffs);
+ BOUND(x2, info->CRT2XOffs, pScrn1->virtualX - HTotal - info->CRT1XOffs);
+ BOUND(y2, info->CRT2YOffs, pScrn1->virtualY - VTotal - info->CRT1YOffs);
+#endif
+ BOUND(x1, CRT1XOffs, min(HVirt, MBXNR1XMAX + CRT1XOffs) - min(HTotal, MBXNR1XMAX) - CRT2XOffs);
+ BOUND(y1, CRT1YOffs, min(VVirt, MBXNR1YMAX + CRT1YOffs) - min(VTotal, MBXNR1YMAX) - CRT2YOffs);
+ BOUND(x2, CRT2XOffs, min(HVirt, MBXNR2XMAX + CRT2XOffs) - min(HTotal, MBXNR2XMAX) - CRT1XOffs);
+ BOUND(y2, CRT2YOffs, min(VVirt, MBXNR2YMAX + CRT2YOffs) - min(VTotal, MBXNR2YMAX) - CRT1YOffs);
+ }
switch(SDMPTR(pScrn1)->CRT2Position) {
case radeonLeftOf:
- pScrn2->frameX0 = x;
- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
- info->CRT1frameX0 = x + CDMPTR->CRT2->HDisplay;
- BOUND(info->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+ pScrn2->frameX0 = x2;
+ /*BOUND(pScrn2->frameY0, y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/
+ BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay);
+ info->CRT1frameX0 = x1 + CDMPTR->CRT2->HDisplay;
+ /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/
+ BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay);
break;
case radeonRightOf:
- info->CRT1frameX0 = x;
- BOUND(info->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
- pScrn2->frameX0 = x + CDMPTR->CRT1->HDisplay;
- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+ info->CRT1frameX0 = x1;
+ /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/
+ BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay);
+ pScrn2->frameX0 = x2 + CDMPTR->CRT1->HDisplay;
+ /*BOUND(pScrn2->frameY0, y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/
+ BOUND(pScrn2->frameY0, y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay);
break;
case radeonAbove:
- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
- pScrn2->frameY0 = y;
- BOUND(info->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
- info->CRT1frameY0 = y + CDMPTR->CRT2->VDisplay;
+ /*BOUND(pScrn2->frameX0, x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/
+ BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay);
+ pScrn2->frameY0 = y2;
+ /*BOUND(info->CRT1frameX0, x1, x1 + HMax - CDMPTR->CRT1->HDisplay);*/
+ BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay);
+ info->CRT1frameY0 = y1 + CDMPTR->CRT2->VDisplay;
break;
case radeonBelow:
- BOUND(info->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
- info->CRT1frameY0 = y;
- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
- pScrn2->frameY0 = y + CDMPTR->CRT1->VDisplay;
+ /*BOUND(info->CRT1frameX0, x1, x1 + HMax - CDMPTR->CRT1->HDisplay);*/
+ BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay);
+ info->CRT1frameY0 = y1;
+ /*BOUND(pScrn2->frameX0, x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/
+ BOUND(pScrn2->frameX0, x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay);
+ pScrn2->frameY0 = y2 + CDMPTR->CRT1->VDisplay;
break;
case radeonClone:
- BOUND(info->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
- BOUND(info->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+ BOUND(info->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+ BOUND(info->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
break;
}
@@ -1287,6 +1707,12 @@ RADEONAdjustFrameMergedHelper(int scrnIndex, int x, int y, int flags)
pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
pScrn1->frameX1 = pScrn1->frameX0 + info->CurrentLayout.mode->HDisplay - 1;
pScrn1->frameY1 = pScrn1->frameY0 + info->CurrentLayout.mode->VDisplay - 1;
+
+ if(SDMPTR(pScrn1)->CRT2Position != radeonClone) {
+ pScrn1->frameX1 += CRT1XOffs + CRT2XOffs;
+ pScrn1->frameY1 += CRT1YOffs + CRT2YOffs;
+ }
+
/*
RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE);
RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);
diff --git a/src/radeon_mergedfb.h b/src/radeon_mergedfb.h
index 3ad65a68..a2c792c5 100644
--- a/src/radeon_mergedfb.h
+++ b/src/radeon_mergedfb.h
@@ -82,10 +82,6 @@ typedef struct _MergedDisplayModeRec {
RADEONScrn2Rel CRT2Position;
} RADEONMergedDisplayModeRec, *RADEONMergedDisplayModePtr;
-typedef struct _region {
- int x0,x1,y0,y1;
-} region;
-
typedef struct _RADEONXineramaData {
int x;
int y;